xref: /illumos-gate/usr/src/cmd/ypcmd/ypxfr.c (revision 48bbca81)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  *
22a506a34cSth  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24*48bbca81SDaniel Hoffman  * Copyright (c) 2016 by Delphix. All rights reserved.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved   */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley
327c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of
337c478bd9Sstevel@tonic-gate  * California.
347c478bd9Sstevel@tonic-gate  */
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate  * This is a user command which gets a NIS data base from some running
387c478bd9Sstevel@tonic-gate  * server, and gets it to the local site by using the normal NIS client
397c478bd9Sstevel@tonic-gate  * enumeration functions.  The map is copied to a temp name, then the real
407c478bd9Sstevel@tonic-gate  * map is removed and the temp map is moved to the real name.  ypxfr then
41*48bbca81SDaniel Hoffman  * sends a "YPPROC_CLEAR" message to the local server to insure that it will
427c478bd9Sstevel@tonic-gate  * not hold a removed map open, so serving an obsolete version.
437c478bd9Sstevel@tonic-gate  *
447c478bd9Sstevel@tonic-gate  * ypxfr [ -h <host> ] [ -d <domainname> ]
457c478bd9Sstevel@tonic-gate  *		[ -s <domainname> ] [-f] [-c] [-C tid prot name] map
467c478bd9Sstevel@tonic-gate  *
477c478bd9Sstevel@tonic-gate  * If the host is ommitted, ypxfr will attempt to discover the master by
487c478bd9Sstevel@tonic-gate  * using normal NIS services.  If it can't get the record, it will use
497c478bd9Sstevel@tonic-gate  * the address of the callback, if specified. If the host is specified
507c478bd9Sstevel@tonic-gate  * as an internet address, no NIS services need to be locally available.
517c478bd9Sstevel@tonic-gate  *
527c478bd9Sstevel@tonic-gate  * If the domain is not specified, the default domain of the local machine
537c478bd9Sstevel@tonic-gate  * is used.
547c478bd9Sstevel@tonic-gate  *
557c478bd9Sstevel@tonic-gate  * If the -f flag is used, the transfer will be done even if the master's
567c478bd9Sstevel@tonic-gate  * copy is not newer than the local copy.
577c478bd9Sstevel@tonic-gate  *
587c478bd9Sstevel@tonic-gate  * The -c flag suppresses the YPPROC_CLEAR request to the local ypserv.  It
597c478bd9Sstevel@tonic-gate  * may be used if ypserv isn't currently running to suppress the error message.
607c478bd9Sstevel@tonic-gate  *
617c478bd9Sstevel@tonic-gate  * The -C flag is used to pass callback information to ypxfr when it is
627c478bd9Sstevel@tonic-gate  * activated by ypserv.  The callback information is used to send a
637c478bd9Sstevel@tonic-gate  * yppushresp_xfr message with transaction id "tid" to a yppush process
647c478bd9Sstevel@tonic-gate  * speaking a transient protocol number "prot".  The yppush program is
657c478bd9Sstevel@tonic-gate  * running on the host "name".
667c478bd9Sstevel@tonic-gate  *
677c478bd9Sstevel@tonic-gate  * The -s option is used to specify a source domain which may be
687c478bd9Sstevel@tonic-gate  * different from the destination domain, for transfer of maps
697c478bd9Sstevel@tonic-gate  * that are identical in different domains (e.g. services.byname)
707c478bd9Sstevel@tonic-gate  *
717c478bd9Sstevel@tonic-gate  */
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate #include <ndbm.h>
747c478bd9Sstevel@tonic-gate #define	DATUM
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate #include <stdio.h>
777c478bd9Sstevel@tonic-gate #include <errno.h>
787c478bd9Sstevel@tonic-gate #include <time.h>
797c478bd9Sstevel@tonic-gate #include <ctype.h>
807c478bd9Sstevel@tonic-gate #include <netdb.h>
817c478bd9Sstevel@tonic-gate #include <netconfig.h>
827c478bd9Sstevel@tonic-gate #include <netdir.h>
837c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
847c478bd9Sstevel@tonic-gate #include <sys/file.h>
857c478bd9Sstevel@tonic-gate #include <sys/stat.h>
867c478bd9Sstevel@tonic-gate #include <dirent.h>
877c478bd9Sstevel@tonic-gate #include <rpcsvc/ypclnt.h>
887c478bd9Sstevel@tonic-gate #include <rpcsvc/yp_prot.h>
897c478bd9Sstevel@tonic-gate #include <unistd.h>
907c478bd9Sstevel@tonic-gate #include <stdlib.h>
917c478bd9Sstevel@tonic-gate #include <rpcsvc/nis.h>
927c478bd9Sstevel@tonic-gate #include "ypdefs.h"
937c478bd9Sstevel@tonic-gate #include "yp_b.h"
947c478bd9Sstevel@tonic-gate #include "shim.h"
957c478bd9Sstevel@tonic-gate #include "yptol.h"
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate USE_YP_MASTER_NAME
987c478bd9Sstevel@tonic-gate USE_YP_SECURE
997c478bd9Sstevel@tonic-gate USE_YP_INTERDOMAIN
1007c478bd9Sstevel@tonic-gate USE_YP_LAST_MODIFIED
1017c478bd9Sstevel@tonic-gate USE_YPDBPATH
1027c478bd9Sstevel@tonic-gate USE_DBM
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate #define	PARANOID 1	/* make sure maps have the right # entries */
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate #define	CALLINTER_TRY 10		/* Seconds between callback tries */
1077c478bd9Sstevel@tonic-gate #define	CALLTIMEOUT CALLINTER_TRY*6	/* Total timeout for callback */
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate DBM *db;
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate /* ypxfr never uses N2L mode */
1127c478bd9Sstevel@tonic-gate bool_t yptol_mode = FALSE;
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate int	debug = FALSE;
1157c478bd9Sstevel@tonic-gate int	treepush = FALSE;
1167c478bd9Sstevel@tonic-gate #define	TREEPUSH 1
1177c478bd9Sstevel@tonic-gate int	defwrite = TRUE;
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate char *domain = NULL;
1207c478bd9Sstevel@tonic-gate char *source = NULL;
1217c478bd9Sstevel@tonic-gate char *map = NULL;
1227c478bd9Sstevel@tonic-gate char *master = NULL;
1237c478bd9Sstevel@tonic-gate char *pushhost = NULL;
1247c478bd9Sstevel@tonic-gate /*
1257c478bd9Sstevel@tonic-gate  * The name of the xfer peer as specified as a
1267c478bd9Sstevel@tonic-gate  * -h option, -C name option or from querying the NIS
1277c478bd9Sstevel@tonic-gate  */
1287c478bd9Sstevel@tonic-gate struct dom_binding master_server; /* To talk to above */
1297c478bd9Sstevel@tonic-gate unsigned int master_prog_vers;	/* YPVERS (barfs at YPOLDVERS !) */
1307c478bd9Sstevel@tonic-gate char *master_name = NULL;	/* Map's master as contained in the map */
1317c478bd9Sstevel@tonic-gate unsigned *master_version = NULL; /* Order number as contained in the map */
1327c478bd9Sstevel@tonic-gate char *master_ascii_version;	/* ASCII order number as contained in the map */
1337c478bd9Sstevel@tonic-gate bool fake_master_version = FALSE;
1347c478bd9Sstevel@tonic-gate /*
1357c478bd9Sstevel@tonic-gate  * TRUE only if there's no order number in
1367c478bd9Sstevel@tonic-gate  *  the map, and the user specified -f
1377c478bd9Sstevel@tonic-gate  */
1387c478bd9Sstevel@tonic-gate bool force = FALSE;		/* TRUE iff user specified -f flag */
1397c478bd9Sstevel@tonic-gate bool logging = FALSE;		/* TRUE iff no tty, but log file exists */
1407c478bd9Sstevel@tonic-gate bool check_count = FALSE;	/* TRUE causes counts to be checked */
1417c478bd9Sstevel@tonic-gate bool send_clear = TRUE;		/* FALSE iff user specified -c flag */
1427c478bd9Sstevel@tonic-gate bool callback = FALSE;
1437c478bd9Sstevel@tonic-gate /*
1447c478bd9Sstevel@tonic-gate  * TRUE iff -C flag set.  tid, proto and name
1457c478bd9Sstevel@tonic-gate  * will be set to point to the command line args.
1467c478bd9Sstevel@tonic-gate  */
1477c478bd9Sstevel@tonic-gate bool secure_map = FALSE;	/* TRUE if there is yp_secure in the map */
1487c478bd9Sstevel@tonic-gate bool interdomain_map = FALSE;
1497c478bd9Sstevel@tonic-gate /*
1507c478bd9Sstevel@tonic-gate  * TRUE if there is yp_interdomain in either
1517c478bd9Sstevel@tonic-gate  * the local or the master version of the map
1527c478bd9Sstevel@tonic-gate  */
1537c478bd9Sstevel@tonic-gate int interdomain_sz = 0;		/* Size of the interdomain value */
1547c478bd9Sstevel@tonic-gate #define	UDPINTER_TRY 10		/* Seconds between tries for udp */
1557c478bd9Sstevel@tonic-gate #define	UDPTIMEOUT UDPINTER_TRY*4	/* Total timeout for udp */
1567c478bd9Sstevel@tonic-gate #define	CALLINTER_TRY 10	/* Seconds between callback tries */
1577c478bd9Sstevel@tonic-gate #define	CALLTIMEOUT CALLINTER_TRY*6	/* Total timeout for callback */
1587c478bd9Sstevel@tonic-gate struct timeval udp_timeout = { UDPTIMEOUT, 0};
1597c478bd9Sstevel@tonic-gate struct timeval tcp_timeout = { 180, 0}; /* Timeout for map enumeration */
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate char *interdomain_value; 	/* place to store the interdomain value */
1627c478bd9Sstevel@tonic-gate char *tid;
1637c478bd9Sstevel@tonic-gate char *proto;
1647c478bd9Sstevel@tonic-gate int entry_count;		/* counts entries in the map */
1657c478bd9Sstevel@tonic-gate char logfile[] = "/var/yp/ypxfr.log";
1667c478bd9Sstevel@tonic-gate static char err_usage[] =
1677c478bd9Sstevel@tonic-gate "Usage:\n\
1687c478bd9Sstevel@tonic-gate ypxfr [-f] [ -h host ] [ -d domainname ]\n\
1697c478bd9Sstevel@tonic-gate 	[ -s domainname ] [-c] [-C tid prot servname ] map\n\n\
1707c478bd9Sstevel@tonic-gate where\n\
1717c478bd9Sstevel@tonic-gate 	-f forces transfer even if the master's copy is not newer.\n\
1727c478bd9Sstevel@tonic-gate 	host is the server from where the map should be transfered\n\
1737c478bd9Sstevel@tonic-gate 	-d domainname is specified if other than the default domain\n\
1747c478bd9Sstevel@tonic-gate 	-s domainname is a source for the map that is same across domains\n\
1757c478bd9Sstevel@tonic-gate 	-c inhibits sending a \"Clear map\" message to the local ypserv.\n\
1767c478bd9Sstevel@tonic-gate 	-C is for use only by ypserv to pass callback information.\n";
1777c478bd9Sstevel@tonic-gate char err_bad_args[] =
1787c478bd9Sstevel@tonic-gate 	"%s argument is bad.\n";
1797c478bd9Sstevel@tonic-gate char err_cant_get_kname[] =
1807c478bd9Sstevel@tonic-gate 	"Can't get %s back from system call.\n";
1817c478bd9Sstevel@tonic-gate char err_null_kname[] =
1827c478bd9Sstevel@tonic-gate 	"%s hasn't been set on this machine.\n";
1837c478bd9Sstevel@tonic-gate char err_bad_hostname[] = "hostname";
1847c478bd9Sstevel@tonic-gate char err_bad_mapname[] = "mapname";
1857c478bd9Sstevel@tonic-gate char err_bad_domainname[] = "domainname";
1867c478bd9Sstevel@tonic-gate char err_udp_failure[] =
1877c478bd9Sstevel@tonic-gate 	"Can't set up a udp connection to ypserv on host %s.\n";
1887c478bd9Sstevel@tonic-gate char yptempname_prefix[] = "ypxfr_map.";
1897c478bd9Sstevel@tonic-gate char ypbkupname_prefix[] = "ypxfr_bkup.";
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate void get_command_line_args();
1927c478bd9Sstevel@tonic-gate bool bind_to_server();
1937c478bd9Sstevel@tonic-gate bool ping_server();
1947c478bd9Sstevel@tonic-gate bool  get_private_recs();
1957c478bd9Sstevel@tonic-gate bool get_order();
1967c478bd9Sstevel@tonic-gate bool get_v1order();
1977c478bd9Sstevel@tonic-gate bool get_v2order();
1987c478bd9Sstevel@tonic-gate bool get_misc_recs();
1997c478bd9Sstevel@tonic-gate bool get_master_name();
2007c478bd9Sstevel@tonic-gate bool get_v1master_name();
2017c478bd9Sstevel@tonic-gate bool get_v2master_name();
2027c478bd9Sstevel@tonic-gate void find_map_master();
2037c478bd9Sstevel@tonic-gate bool move_map();
2047c478bd9Sstevel@tonic-gate unsigned get_local_version();
2057c478bd9Sstevel@tonic-gate void mkfilename();
2067c478bd9Sstevel@tonic-gate void mk_tmpname();
2077c478bd9Sstevel@tonic-gate bool get_map();
2087c478bd9Sstevel@tonic-gate bool add_private_entries();
2097c478bd9Sstevel@tonic-gate bool new_mapfiles();
2107c478bd9Sstevel@tonic-gate void del_mapfiles();
2117c478bd9Sstevel@tonic-gate void set_output();
2127c478bd9Sstevel@tonic-gate void logprintf();
2137c478bd9Sstevel@tonic-gate bool send_ypclear();
2147c478bd9Sstevel@tonic-gate void xfr_exit();
2157c478bd9Sstevel@tonic-gate void send_callback();
2167c478bd9Sstevel@tonic-gate int ypall_callback();
2177c478bd9Sstevel@tonic-gate int map_yperr_to_pusherr();
2187c478bd9Sstevel@tonic-gate extern CLIENT *__yp_clnt_create_rsvdport();
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate bool_t is_yptol_mode();
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate extern int errno;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate /*
2267c478bd9Sstevel@tonic-gate  * This is the mainline for the ypxfr process.
2277c478bd9Sstevel@tonic-gate  */
2287c478bd9Sstevel@tonic-gate 
229a506a34cSth int
main(argc,argv)2307c478bd9Sstevel@tonic-gate main(argc, argv)
2317c478bd9Sstevel@tonic-gate 	int argc;
2327c478bd9Sstevel@tonic-gate 	char **argv;
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate {
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 	static char default_domain_name[YPMAXDOMAIN];
2377c478bd9Sstevel@tonic-gate 	static unsigned big = 0xffffffff;
2387c478bd9Sstevel@tonic-gate 	int status;
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	set_output();
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 	/*
2437c478bd9Sstevel@tonic-gate 	 * Inter-process lock synchronization structure. Since slave servers
2447c478bd9Sstevel@tonic-gate 	 * get their maps from another NIS server rather than LDAP they can
2457c478bd9Sstevel@tonic-gate 	 * never run in N2L mode. We thus do not have to init the update
2467c478bd9Sstevel@tonic-gate 	 * locking mechanism.
2477c478bd9Sstevel@tonic-gate 	 */
2487c478bd9Sstevel@tonic-gate 	if (init_lock_map() == FALSE) {
2497c478bd9Sstevel@tonic-gate 		exit(1);
2507c478bd9Sstevel@tonic-gate 	}
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	get_command_line_args(argc, argv);
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 	if (!domain) {
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 		if (!getdomainname(default_domain_name, YPMAXDOMAIN)) {
2577c478bd9Sstevel@tonic-gate 			domain = default_domain_name;
2587c478bd9Sstevel@tonic-gate 		} else {
2597c478bd9Sstevel@tonic-gate 			logprintf(err_cant_get_kname,
2607c478bd9Sstevel@tonic-gate 			    err_bad_domainname);
2617c478bd9Sstevel@tonic-gate 			xfr_exit(YPPUSH_RSRC);
2627c478bd9Sstevel@tonic-gate 		}
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 		if (strlen(domain) == 0) {
2657c478bd9Sstevel@tonic-gate 			logprintf(err_null_kname,
2667c478bd9Sstevel@tonic-gate 			    err_bad_domainname);
2677c478bd9Sstevel@tonic-gate 			xfr_exit(YPPUSH_RSRC);
2687c478bd9Sstevel@tonic-gate 		}
2697c478bd9Sstevel@tonic-gate 	}
2707c478bd9Sstevel@tonic-gate 	if (!source)
2717c478bd9Sstevel@tonic-gate 		source = domain;
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate 	if (!master) {
2747c478bd9Sstevel@tonic-gate 		find_map_master();
2757c478bd9Sstevel@tonic-gate 	}
2767c478bd9Sstevel@tonic-gate 	/*
2777c478bd9Sstevel@tonic-gate 	 * if we were unable to get the master name, either from
2787c478bd9Sstevel@tonic-gate 	 * the -h option or from -C "name" option or from NIS,
2797c478bd9Sstevel@tonic-gate 	 * we are doomed !
2807c478bd9Sstevel@tonic-gate 	 */
2817c478bd9Sstevel@tonic-gate 	if (!master) {
2827c478bd9Sstevel@tonic-gate 		xfr_exit(YPPUSH_MADDR);
2837c478bd9Sstevel@tonic-gate 	}
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate 	if (!bind_to_server(master, &master_server,
2867c478bd9Sstevel@tonic-gate 	    &master_prog_vers, &status)) {
2877c478bd9Sstevel@tonic-gate 		xfr_exit(status);
2887c478bd9Sstevel@tonic-gate 	}
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	if (!get_private_recs(&status)) {
2917c478bd9Sstevel@tonic-gate 		xfr_exit(status);
2927c478bd9Sstevel@tonic-gate 	}
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	if (!master_version) {
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 		if (force) {
2977c478bd9Sstevel@tonic-gate 			master_version = &big;
2987c478bd9Sstevel@tonic-gate 			fake_master_version = TRUE;
2997c478bd9Sstevel@tonic-gate 		} else {
3007c478bd9Sstevel@tonic-gate 			logprintf(
3017c478bd9Sstevel@tonic-gate "Can't get order number for map %s from server at %s: use the -f flag.\n",
3027c478bd9Sstevel@tonic-gate 			    map, master);
3037c478bd9Sstevel@tonic-gate 			xfr_exit(YPPUSH_FORCE);
3047c478bd9Sstevel@tonic-gate 		}
3057c478bd9Sstevel@tonic-gate 	}
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 	if (!move_map(&status)) {
3087c478bd9Sstevel@tonic-gate 		xfr_exit(status);
3097c478bd9Sstevel@tonic-gate 	}
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate 	if (send_clear && !send_ypclear(&status)) {
3127c478bd9Sstevel@tonic-gate 		xfr_exit(status);
3137c478bd9Sstevel@tonic-gate 	}
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	if (logging) {
3167c478bd9Sstevel@tonic-gate 		logprintf("Transferred map %s from %s (%d entries).\n",
3177c478bd9Sstevel@tonic-gate 		    map, master, entry_count);
3187c478bd9Sstevel@tonic-gate 	}
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 	xfr_exit(YPPUSH_SUCC);
321a506a34cSth 	return (0);
3227c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
3237c478bd9Sstevel@tonic-gate }
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate /*
3267c478bd9Sstevel@tonic-gate  * This decides whether we're being run interactively or not, and, if not,
3277c478bd9Sstevel@tonic-gate  * whether we're supposed to be logging or not.  If we are logging, it sets
3287c478bd9Sstevel@tonic-gate  * up stderr to point to the log file, and sets the "logging"
3297c478bd9Sstevel@tonic-gate  * variable.  If there's no logging, the output goes in the bit bucket.
3307c478bd9Sstevel@tonic-gate  * Logging output differs from interactive output in the presence of a
3317c478bd9Sstevel@tonic-gate  * timestamp, present only in the log file.  stderr is reset, too, because it
3327c478bd9Sstevel@tonic-gate  * it's used by various library functions, including clnt_perror.
3337c478bd9Sstevel@tonic-gate  */
3347c478bd9Sstevel@tonic-gate void
set_output()3357c478bd9Sstevel@tonic-gate set_output()
3367c478bd9Sstevel@tonic-gate {
3377c478bd9Sstevel@tonic-gate 	if (!isatty(1)) {
3387c478bd9Sstevel@tonic-gate 		if (access(logfile, W_OK)) {
3397c478bd9Sstevel@tonic-gate 			(void) freopen("/dev/null", "w", stderr);
3407c478bd9Sstevel@tonic-gate 		} else {
3417c478bd9Sstevel@tonic-gate 			(void) freopen(logfile, "a", stderr);
3427c478bd9Sstevel@tonic-gate 			logging = TRUE;
3437c478bd9Sstevel@tonic-gate 		}
3447c478bd9Sstevel@tonic-gate 	}
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate /*
3477c478bd9Sstevel@tonic-gate  * This constructs a logging record.
3487c478bd9Sstevel@tonic-gate  */
3497c478bd9Sstevel@tonic-gate void
logprintf(arg1,arg2,arg3,arg4,arg5,arg6,arg7)3507c478bd9Sstevel@tonic-gate logprintf(arg1, arg2, arg3, arg4, arg5, arg6, arg7)
3517c478bd9Sstevel@tonic-gate /*VARARGS*/
3527c478bd9Sstevel@tonic-gate {
3537c478bd9Sstevel@tonic-gate 	struct timeval t;
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	fseek(stderr, 0, 2);
3567c478bd9Sstevel@tonic-gate 	if (logging) {
3577c478bd9Sstevel@tonic-gate 		(void) gettimeofday(&t, NULL);
3587c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%19.19s: ", ctime(&t.tv_sec));
3597c478bd9Sstevel@tonic-gate 	}
3607c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, (char *)arg1, arg2, arg3, arg4, arg5,
3617c478bd9Sstevel@tonic-gate 				arg6, arg7);
3627c478bd9Sstevel@tonic-gate 	fflush(stderr);
3637c478bd9Sstevel@tonic-gate }
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate /*
3667c478bd9Sstevel@tonic-gate  * This does the command line argument processing.
3677c478bd9Sstevel@tonic-gate  */
3687c478bd9Sstevel@tonic-gate void
get_command_line_args(argc,argv)3697c478bd9Sstevel@tonic-gate get_command_line_args(argc, argv)
3707c478bd9Sstevel@tonic-gate 	int argc;
3717c478bd9Sstevel@tonic-gate 	char **argv;
3727c478bd9Sstevel@tonic-gate 
3737c478bd9Sstevel@tonic-gate {
3747c478bd9Sstevel@tonic-gate 	argv++;
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	if (argc < 2) {
3777c478bd9Sstevel@tonic-gate 		logprintf(err_usage);
3787c478bd9Sstevel@tonic-gate 		xfr_exit(YPPUSH_BADARGS);
3797c478bd9Sstevel@tonic-gate 	}
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate 	while (--argc) {
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate 		if ((*argv)[0] == '-') {
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate 			switch ((*argv)[1]) {
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate 			case 'f': {
3887c478bd9Sstevel@tonic-gate 				force = TRUE;
3897c478bd9Sstevel@tonic-gate 				argv++;
3907c478bd9Sstevel@tonic-gate 				break;
3917c478bd9Sstevel@tonic-gate 			}
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 			case 'D': {
3947c478bd9Sstevel@tonic-gate 				debug = TRUE;
3957c478bd9Sstevel@tonic-gate 				argv++;
3967c478bd9Sstevel@tonic-gate 				break;
3977c478bd9Sstevel@tonic-gate 			}
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate 			case 'T': {
4007c478bd9Sstevel@tonic-gate 				treepush = TRUE;
4017c478bd9Sstevel@tonic-gate 				argv++;
4027c478bd9Sstevel@tonic-gate 				break;
4037c478bd9Sstevel@tonic-gate 			}
4047c478bd9Sstevel@tonic-gate 			case 'P': {
4057c478bd9Sstevel@tonic-gate 				check_count = TRUE;
4067c478bd9Sstevel@tonic-gate 				argv++;
4077c478bd9Sstevel@tonic-gate 				break;
4087c478bd9Sstevel@tonic-gate 			}
4097c478bd9Sstevel@tonic-gate 			case 'W': {
4107c478bd9Sstevel@tonic-gate 				defwrite = FALSE;
4117c478bd9Sstevel@tonic-gate 				argv++;
4127c478bd9Sstevel@tonic-gate 				break;
4137c478bd9Sstevel@tonic-gate 			}
4147c478bd9Sstevel@tonic-gate 			case 'c': {
4157c478bd9Sstevel@tonic-gate 				send_clear = FALSE;
4167c478bd9Sstevel@tonic-gate 				argv++;
4177c478bd9Sstevel@tonic-gate 				break;
4187c478bd9Sstevel@tonic-gate 			}
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 			case 'h': {
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate 				if (argc > 1) {
4237c478bd9Sstevel@tonic-gate 					argv++;
4247c478bd9Sstevel@tonic-gate 					argc--;
4257c478bd9Sstevel@tonic-gate 					master = *argv;
4267c478bd9Sstevel@tonic-gate 					argv++;
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 					if (strlen(master) > 256) {
4297c478bd9Sstevel@tonic-gate 						logprintf(
4307c478bd9Sstevel@tonic-gate 						    err_bad_args,
4317c478bd9Sstevel@tonic-gate 						    err_bad_hostname);
4327c478bd9Sstevel@tonic-gate 						xfr_exit(YPPUSH_BADARGS);
4337c478bd9Sstevel@tonic-gate 					}
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 				} else {
4367c478bd9Sstevel@tonic-gate 					logprintf(err_usage);
4377c478bd9Sstevel@tonic-gate 					xfr_exit(YPPUSH_BADARGS);
4387c478bd9Sstevel@tonic-gate 				}
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate 				break;
4417c478bd9Sstevel@tonic-gate 			}
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 			case 'd':
4447c478bd9Sstevel@tonic-gate 				if (argc > 1) {
4457c478bd9Sstevel@tonic-gate 					argv++;
4467c478bd9Sstevel@tonic-gate 					argc--;
4477c478bd9Sstevel@tonic-gate 					domain = *argv;
4487c478bd9Sstevel@tonic-gate 					argv++;
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 					if (strlen(domain) > YPMAXDOMAIN) {
4517c478bd9Sstevel@tonic-gate 						logprintf(
4527c478bd9Sstevel@tonic-gate 						    err_bad_args,
4537c478bd9Sstevel@tonic-gate 						    err_bad_domainname);
4547c478bd9Sstevel@tonic-gate 						xfr_exit(YPPUSH_BADARGS);
4557c478bd9Sstevel@tonic-gate 					}
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate 				} else {
4587c478bd9Sstevel@tonic-gate 					logprintf(err_usage);
4597c478bd9Sstevel@tonic-gate 					xfr_exit(YPPUSH_BADARGS);
4607c478bd9Sstevel@tonic-gate 				}
4617c478bd9Sstevel@tonic-gate 				break;
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate 			case 's':
4647c478bd9Sstevel@tonic-gate 				if (argc > 1) {
4657c478bd9Sstevel@tonic-gate 					argv++;
4667c478bd9Sstevel@tonic-gate 					argc--;
4677c478bd9Sstevel@tonic-gate 					source = *argv;
4687c478bd9Sstevel@tonic-gate 					argv++;
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 					if (strlen(source) > YPMAXDOMAIN) {
4717c478bd9Sstevel@tonic-gate 						logprintf(
4727c478bd9Sstevel@tonic-gate 						    err_bad_args,
4737c478bd9Sstevel@tonic-gate 						    err_bad_domainname);
4747c478bd9Sstevel@tonic-gate 						xfr_exit(YPPUSH_BADARGS);
4757c478bd9Sstevel@tonic-gate 					}
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate 				} else {
4787c478bd9Sstevel@tonic-gate 					logprintf(err_usage);
4797c478bd9Sstevel@tonic-gate 					xfr_exit(YPPUSH_BADARGS);
4807c478bd9Sstevel@tonic-gate 				}
4817c478bd9Sstevel@tonic-gate 				break;
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate 			case 'C':
4847c478bd9Sstevel@tonic-gate 			    if (argc > 3) {
4857c478bd9Sstevel@tonic-gate 				callback = TRUE;
4867c478bd9Sstevel@tonic-gate 				tid = *(++argv);
4877c478bd9Sstevel@tonic-gate 				proto = *(++argv);
4887c478bd9Sstevel@tonic-gate 				pushhost = *(++argv);
4897c478bd9Sstevel@tonic-gate 				if (strlen(pushhost) > 256) {
4907c478bd9Sstevel@tonic-gate 				    logprintf(err_bad_args, err_bad_hostname);
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate 				    xfr_exit(YPPUSH_BADARGS);
4937c478bd9Sstevel@tonic-gate 				}
4947c478bd9Sstevel@tonic-gate 				argc -= 3;
4957c478bd9Sstevel@tonic-gate 				argv++;
4967c478bd9Sstevel@tonic-gate 			    } else {
4977c478bd9Sstevel@tonic-gate 				logprintf(err_usage);
4987c478bd9Sstevel@tonic-gate 				xfr_exit(YPPUSH_BADARGS);
4997c478bd9Sstevel@tonic-gate 			    }
5007c478bd9Sstevel@tonic-gate 			    break;
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 			case 'b': {
5037c478bd9Sstevel@tonic-gate 				interdomain_map = TRUE;
5047c478bd9Sstevel@tonic-gate 				interdomain_value = "";
5057c478bd9Sstevel@tonic-gate 				interdomain_sz = 0;
5067c478bd9Sstevel@tonic-gate 				argv++;
5077c478bd9Sstevel@tonic-gate 				break;
5087c478bd9Sstevel@tonic-gate 			}
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate 			default: {
5127c478bd9Sstevel@tonic-gate 				logprintf(err_usage);
5137c478bd9Sstevel@tonic-gate 				xfr_exit(YPPUSH_BADARGS);
5147c478bd9Sstevel@tonic-gate 			}
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate 			}
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate 		} else {
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate 			if (!map) {
5217c478bd9Sstevel@tonic-gate 				map = *argv;
5227c478bd9Sstevel@tonic-gate 				argv++;
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate 				if (strlen(map) > YPMAXMAP) {
5257c478bd9Sstevel@tonic-gate 					logprintf(err_bad_args,
5267c478bd9Sstevel@tonic-gate 					err_bad_mapname);
5277c478bd9Sstevel@tonic-gate 					xfr_exit(YPPUSH_BADARGS);
5287c478bd9Sstevel@tonic-gate 				}
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 			} else {
5317c478bd9Sstevel@tonic-gate 				logprintf(err_usage);
5327c478bd9Sstevel@tonic-gate 				xfr_exit(YPPUSH_BADARGS);
5337c478bd9Sstevel@tonic-gate 			}
5347c478bd9Sstevel@tonic-gate 		}
5357c478bd9Sstevel@tonic-gate 	}
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate 	if (!map) {
5387c478bd9Sstevel@tonic-gate 		logprintf(err_usage);
5397c478bd9Sstevel@tonic-gate 		xfr_exit(YPPUSH_BADARGS);
5407c478bd9Sstevel@tonic-gate 	}
5417c478bd9Sstevel@tonic-gate }
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate /*
5447c478bd9Sstevel@tonic-gate  * This tries to get the master name for the named map, from any
5457c478bd9Sstevel@tonic-gate  * server's version, using the vanilla NIS client interface.  If we get a
5467c478bd9Sstevel@tonic-gate  * name back, the global "master" gets pointed to it.
5477c478bd9Sstevel@tonic-gate  */
5487c478bd9Sstevel@tonic-gate void
find_map_master()5497c478bd9Sstevel@tonic-gate find_map_master()
5507c478bd9Sstevel@tonic-gate {
5517c478bd9Sstevel@tonic-gate 	int err;
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	if (err = __yp_master_rsvdport(source, map, &master)) {
5547c478bd9Sstevel@tonic-gate 		logprintf("Can't get master of %s. Reason: %s.\n", map,
5557c478bd9Sstevel@tonic-gate 		    yperr_string(err));
5567c478bd9Sstevel@tonic-gate 	}
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate 	yp_unbind(source);
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate #ifdef TREEPUSH
562a506a34cSth int
chk_treepush(name)5637c478bd9Sstevel@tonic-gate chk_treepush(name)
5647c478bd9Sstevel@tonic-gate char *name;
5657c478bd9Sstevel@tonic-gate {
5667c478bd9Sstevel@tonic-gate 	char inmap[256];
5677c478bd9Sstevel@tonic-gate 	char inkey[256];
5687c478bd9Sstevel@tonic-gate 	int inkeylen;
5697c478bd9Sstevel@tonic-gate 	char *outval;
5707c478bd9Sstevel@tonic-gate 	int outvallen;
5717c478bd9Sstevel@tonic-gate 	int err;
5727c478bd9Sstevel@tonic-gate 	outval = NULL;
5737c478bd9Sstevel@tonic-gate 	inkey[0] = 0;
5747c478bd9Sstevel@tonic-gate 	strcpy(inmap, "ypslaves.");
5757c478bd9Sstevel@tonic-gate 	strcat(inmap, name);
5767c478bd9Sstevel@tonic-gate 	gethostname(inkey, 256);
5777c478bd9Sstevel@tonic-gate 	inkeylen = strlen(inkey);
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 	err = yp_match(source, inmap, inkey, inkeylen, &outval, &outvallen);
5807c478bd9Sstevel@tonic-gate 	yp_unbind(source);
5817c478bd9Sstevel@tonic-gate 	return (err);
5827c478bd9Sstevel@tonic-gate }
5837c478bd9Sstevel@tonic-gate #endif
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate /*
5867c478bd9Sstevel@tonic-gate  * This sets up a udp connection to speak the correct program and version
5877c478bd9Sstevel@tonic-gate  * to a NIS server.  vers is set to YPVERS, doesn't give a damn about
5887c478bd9Sstevel@tonic-gate  * YPOLDVERS.
5897c478bd9Sstevel@tonic-gate  */
5907c478bd9Sstevel@tonic-gate bool
bind_to_server(host,pdomb,vers,status)5917c478bd9Sstevel@tonic-gate bind_to_server(host, pdomb, vers, status)
5927c478bd9Sstevel@tonic-gate 	char *host;
5937c478bd9Sstevel@tonic-gate 	struct dom_binding *pdomb;
5947c478bd9Sstevel@tonic-gate 	unsigned int *vers;
5957c478bd9Sstevel@tonic-gate 	int *status;
5967c478bd9Sstevel@tonic-gate {
5977c478bd9Sstevel@tonic-gate 	if (ping_server(host, pdomb, YPVERS, status)) {
5987c478bd9Sstevel@tonic-gate 		*vers = YPVERS;
5997c478bd9Sstevel@tonic-gate 		return (TRUE);
6007c478bd9Sstevel@tonic-gate 	} else
6017c478bd9Sstevel@tonic-gate 		return (FALSE);
6027c478bd9Sstevel@tonic-gate }
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate /*
6057c478bd9Sstevel@tonic-gate  * This sets up a UDP channel to a server which is assumed to speak an input
6067c478bd9Sstevel@tonic-gate  * version of YPPROG.  The channel is tested by pinging the server.  In all
6077c478bd9Sstevel@tonic-gate  * error cases except "Program Version Number Mismatch", the error is
6087c478bd9Sstevel@tonic-gate  * reported, and in all error cases, the client handle is destroyed and the
6097c478bd9Sstevel@tonic-gate  * socket associated with the channel is closed.
6107c478bd9Sstevel@tonic-gate  */
6117c478bd9Sstevel@tonic-gate bool
ping_server(host,pdomb,vers,status)6127c478bd9Sstevel@tonic-gate ping_server(host, pdomb, vers, status)
6137c478bd9Sstevel@tonic-gate 	char *host;
6147c478bd9Sstevel@tonic-gate 	struct dom_binding *pdomb;
6157c478bd9Sstevel@tonic-gate 	unsigned int vers;
6167c478bd9Sstevel@tonic-gate 	int *status;
6177c478bd9Sstevel@tonic-gate {
6187c478bd9Sstevel@tonic-gate 	enum clnt_stat rpc_stat;
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate 	if ((pdomb->dom_client = __yp_clnt_create_rsvdport(host, YPPROG, vers,
6217c478bd9Sstevel@tonic-gate 							0, 0, 0)) != 0) {
6227c478bd9Sstevel@tonic-gate 
6237c478bd9Sstevel@tonic-gate 		/*
6247c478bd9Sstevel@tonic-gate 		 * if we are on a c2 system, we should only accept data
6257c478bd9Sstevel@tonic-gate 		 * from a server which is on a reserved port.
6267c478bd9Sstevel@tonic-gate 		 */
6277c478bd9Sstevel@tonic-gate 	/*
6287c478bd9Sstevel@tonic-gate 	 * NUKE this for 5.0DR.
6297c478bd9Sstevel@tonic-gate 	 *
6307c478bd9Sstevel@tonic-gate 	 *	if (issecure() &&
6317c478bd9Sstevel@tonic-gate 	 *	    (pdomb->dom_server_addr.sin_family != AF_INET ||
6327c478bd9Sstevel@tonic-gate 	 *	    pdomb->dom_server_addr.sin_port >= IPPORT_RESERVED)) {
6337c478bd9Sstevel@tonic-gate 	 *		clnt_destroy(pdomb->dom_client);
6347c478bd9Sstevel@tonic-gate 	 *		close(pdomb->dom_socket);
6357c478bd9Sstevel@tonic-gate 	 *		(void) logprintf("bind_to_server: \
6367c478bd9Sstevel@tonic-gate 	 *			server is not using a privileged port\n");
6377c478bd9Sstevel@tonic-gate 	 *		*status = YPPUSH_YPERR;
6387c478bd9Sstevel@tonic-gate 	 *		return (FALSE);
6397c478bd9Sstevel@tonic-gate 	 *	}
6407c478bd9Sstevel@tonic-gate 	 */
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate 		rpc_stat = clnt_call(pdomb->dom_client, YPBINDPROC_NULL,
6437c478bd9Sstevel@tonic-gate 		    xdr_void, 0, xdr_void, 0, udp_timeout);
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate 		if (rpc_stat == RPC_SUCCESS) {
6467c478bd9Sstevel@tonic-gate 			return (TRUE);
6477c478bd9Sstevel@tonic-gate 		} else {
6487c478bd9Sstevel@tonic-gate 			clnt_destroy(pdomb->dom_client);
6497c478bd9Sstevel@tonic-gate 			if (rpc_stat != RPC_PROGVERSMISMATCH) {
6507c478bd9Sstevel@tonic-gate 				(void) clnt_perror(pdomb->dom_client,
6517c478bd9Sstevel@tonic-gate 				    "ypxfr: bind_to_server clnt_call error");
6527c478bd9Sstevel@tonic-gate 			}
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate 			*status = YPPUSH_RPC;
6557c478bd9Sstevel@tonic-gate 			return (FALSE);
6567c478bd9Sstevel@tonic-gate 		}
6577c478bd9Sstevel@tonic-gate 	} else {
6587c478bd9Sstevel@tonic-gate 		logprintf("bind_to_server __clnt_create_rsvd error");
6597c478bd9Sstevel@tonic-gate 		(void) clnt_pcreateerror("");
6607c478bd9Sstevel@tonic-gate 		fflush(stderr);
6617c478bd9Sstevel@tonic-gate 		*status = YPPUSH_RPC;
6627c478bd9Sstevel@tonic-gate 		return (FALSE);
6637c478bd9Sstevel@tonic-gate 	}
6647c478bd9Sstevel@tonic-gate }
6657c478bd9Sstevel@tonic-gate 
6667c478bd9Sstevel@tonic-gate /*
6677c478bd9Sstevel@tonic-gate  * This gets values for the YP_LAST_MODIFIED and YP_MASTER_NAME keys from the
6687c478bd9Sstevel@tonic-gate  * master server's version of the map.  Values are held in static variables
6697c478bd9Sstevel@tonic-gate  * here.  In the success cases, global pointer variables are set to point at
6707c478bd9Sstevel@tonic-gate  * the local statics.
6717c478bd9Sstevel@tonic-gate  */
6727c478bd9Sstevel@tonic-gate bool
get_private_recs(pushstat)6737c478bd9Sstevel@tonic-gate get_private_recs(pushstat)
6747c478bd9Sstevel@tonic-gate 	int *pushstat;
6757c478bd9Sstevel@tonic-gate {
6767c478bd9Sstevel@tonic-gate 	static char anumber[20];
6777c478bd9Sstevel@tonic-gate 	static unsigned number;
6787c478bd9Sstevel@tonic-gate 	static char name[YPMAXPEER + 1];
6797c478bd9Sstevel@tonic-gate 	int status;
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 	status = 0;
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate 	if (get_order(anumber, &number, &status)) {
6847c478bd9Sstevel@tonic-gate 		master_version = &number;
6857c478bd9Sstevel@tonic-gate 		master_ascii_version = anumber;
6867c478bd9Sstevel@tonic-gate 		if (debug) fprintf(stderr,
6877c478bd9Sstevel@tonic-gate 			"ypxfr: Master Version is %s\n", master_ascii_version);
6887c478bd9Sstevel@tonic-gate 	} else {
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate 		if (status != 0) {
6917c478bd9Sstevel@tonic-gate 			*pushstat = status;
6927c478bd9Sstevel@tonic-gate 			if (debug) fprintf(stderr,
6937c478bd9Sstevel@tonic-gate 		"ypxfr: Couldn't get map's master version number, \
6947c478bd9Sstevel@tonic-gate 		status was %d\n", status);
6957c478bd9Sstevel@tonic-gate 			return (FALSE);
6967c478bd9Sstevel@tonic-gate 		}
6977c478bd9Sstevel@tonic-gate 	}
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate 	if (get_master_name(name, &status)) {
7007c478bd9Sstevel@tonic-gate 		master_name = name;
7017c478bd9Sstevel@tonic-gate 		if (debug) fprintf(stderr,
7027c478bd9Sstevel@tonic-gate 			"ypxfr: Maps master is '%s'\n", master_name);
7037c478bd9Sstevel@tonic-gate 	} else {
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate 		if (status != 0) {
7067c478bd9Sstevel@tonic-gate 			*pushstat = status;
7077c478bd9Sstevel@tonic-gate 			if (debug) fprintf(stderr,
7087c478bd9Sstevel@tonic-gate 		"ypxfr: Couldn't get map's master name, status was %d\n",
7097c478bd9Sstevel@tonic-gate 			status);
7107c478bd9Sstevel@tonic-gate 			return (FALSE);
7117c478bd9Sstevel@tonic-gate 		}
7127c478bd9Sstevel@tonic-gate 		master_name = master;
7137c478bd9Sstevel@tonic-gate 	}
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate 	if (debug)
7167c478bd9Sstevel@tonic-gate 		fprintf(stderr,
7177c478bd9Sstevel@tonic-gate 			"ypxfr: Getting private records from master.\n");
7187c478bd9Sstevel@tonic-gate 	if (get_misc_recs(&status)) {
7197c478bd9Sstevel@tonic-gate 		if (debug)
7207c478bd9Sstevel@tonic-gate 			fprintf(stderr,
7217c478bd9Sstevel@tonic-gate 		    "ypxfr: Masters map %s secure and %s an interdomain map.\n",
7227c478bd9Sstevel@tonic-gate 			(secure_map) ? "is" : "is not",
7237c478bd9Sstevel@tonic-gate 			(interdomain_map) ? "is" : "is not");
7247c478bd9Sstevel@tonic-gate 	} else {
7257c478bd9Sstevel@tonic-gate 		if (status != 0) {
7267c478bd9Sstevel@tonic-gate 			*pushstat = status;
7277c478bd9Sstevel@tonic-gate 			if (debug)
7287c478bd9Sstevel@tonic-gate 				fprintf(stderr,
7297c478bd9Sstevel@tonic-gate 	"ypxfr: Couldn't get state of secure and interdomain flags in map.\n");
7307c478bd9Sstevel@tonic-gate 			return (FALSE);
7317c478bd9Sstevel@tonic-gate 		}
7327c478bd9Sstevel@tonic-gate 	}
7337c478bd9Sstevel@tonic-gate 
7347c478bd9Sstevel@tonic-gate 	return (TRUE);
7357c478bd9Sstevel@tonic-gate }
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate /*
7387c478bd9Sstevel@tonic-gate  * This gets the map's order number from the master server
7397c478bd9Sstevel@tonic-gate  */
7407c478bd9Sstevel@tonic-gate bool
get_order(an,n,pushstat)7417c478bd9Sstevel@tonic-gate get_order(an, n, pushstat)
7427c478bd9Sstevel@tonic-gate 	char *an;
7437c478bd9Sstevel@tonic-gate 	unsigned *n;
7447c478bd9Sstevel@tonic-gate 	int *pushstat;
7457c478bd9Sstevel@tonic-gate {
7467c478bd9Sstevel@tonic-gate 	if (master_prog_vers == YPVERS) {
7477c478bd9Sstevel@tonic-gate 		return (get_v2order(an, n, pushstat));
7487c478bd9Sstevel@tonic-gate 	} else
7497c478bd9Sstevel@tonic-gate 		return (FALSE);
7507c478bd9Sstevel@tonic-gate }
7517c478bd9Sstevel@tonic-gate 
7527c478bd9Sstevel@tonic-gate bool
get_v2order(an,n,pushstat)7537c478bd9Sstevel@tonic-gate get_v2order(an, n, pushstat)
7547c478bd9Sstevel@tonic-gate 	char *an;
7557c478bd9Sstevel@tonic-gate 	unsigned *n;
7567c478bd9Sstevel@tonic-gate 	int *pushstat;
7577c478bd9Sstevel@tonic-gate {
7587c478bd9Sstevel@tonic-gate 	struct ypreq_nokey req;
7597c478bd9Sstevel@tonic-gate 	struct ypresp_order resp;
7607c478bd9Sstevel@tonic-gate 	int retval;
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate 	req.domain = source;
7637c478bd9Sstevel@tonic-gate 	req.map = map;
7647c478bd9Sstevel@tonic-gate 
7657c478bd9Sstevel@tonic-gate 	/*
7667c478bd9Sstevel@tonic-gate 	 * Get the map''s order number, null-terminate it and store it,
7677c478bd9Sstevel@tonic-gate 	 * and convert it to binary and store it again.
7687c478bd9Sstevel@tonic-gate 	 */
7697c478bd9Sstevel@tonic-gate 	retval = FALSE;
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate 	if ((enum clnt_stat) clnt_call(master_server.dom_client,
7727c478bd9Sstevel@tonic-gate 	    YPPROC_ORDER, (xdrproc_t)xdr_ypreq_nokey, (char *)&req,
7737c478bd9Sstevel@tonic-gate 	    (xdrproc_t)xdr_ypresp_order, (char *)&resp,
7747c478bd9Sstevel@tonic-gate 	    udp_timeout) == RPC_SUCCESS) {
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate 		if (resp.status == YP_TRUE) {
7777c478bd9Sstevel@tonic-gate 			sprintf(an, "%d", resp.ordernum);
7787c478bd9Sstevel@tonic-gate 			*n = resp.ordernum;
7797c478bd9Sstevel@tonic-gate 			retval = TRUE;
7807c478bd9Sstevel@tonic-gate 		} else if (resp.status != YP_BADDB) {
7817c478bd9Sstevel@tonic-gate 			*pushstat = ypprot_err(resp.status);
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate 			if (!logging) {
7847c478bd9Sstevel@tonic-gate 				logprintf(
7857c478bd9Sstevel@tonic-gate 	"(info) Can't get order number from ypserv at %s.  Reason: %s.\n",
7867c478bd9Sstevel@tonic-gate 				    master, yperr_string(
7877c478bd9Sstevel@tonic-gate 				    ypprot_err(resp.status)));
7887c478bd9Sstevel@tonic-gate 			}
7897c478bd9Sstevel@tonic-gate 		}
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate 		CLNT_FREERES(master_server.dom_client,
7927c478bd9Sstevel@tonic-gate 			(xdrproc_t)xdr_ypresp_order,
7937c478bd9Sstevel@tonic-gate 		    (char *)&resp);
7947c478bd9Sstevel@tonic-gate 	} else {
7957c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_RPC;
7967c478bd9Sstevel@tonic-gate 		logprintf("ypxfr(get_v2order) RPC call to %s failed", master);
7977c478bd9Sstevel@tonic-gate 		clnt_perror(master_server.dom_client, "");
7987c478bd9Sstevel@tonic-gate 	}
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate 	return (retval);
8017c478bd9Sstevel@tonic-gate }
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate /*
8047c478bd9Sstevel@tonic-gate  * Pick up the state of the YP_SECURE and YP_INTERDOMAIN records from the
8057c478bd9Sstevel@tonic-gate  * master. Only works on 4.0 V2 masters that will match a YP_ private key
8067c478bd9Sstevel@tonic-gate  * when asked to explicitly.
8077c478bd9Sstevel@tonic-gate  */
8087c478bd9Sstevel@tonic-gate bool
get_misc_recs(pushstat)8097c478bd9Sstevel@tonic-gate get_misc_recs(pushstat)
8107c478bd9Sstevel@tonic-gate 	int *pushstat;
8117c478bd9Sstevel@tonic-gate {
8127c478bd9Sstevel@tonic-gate 	struct ypreq_key req;
8137c478bd9Sstevel@tonic-gate 	struct ypresp_val resp;
8147c478bd9Sstevel@tonic-gate 	int retval;
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate 	req.domain = source;
8177c478bd9Sstevel@tonic-gate 	req.map = map;
8187c478bd9Sstevel@tonic-gate 	req.keydat.dptr   = yp_secure;
8197c478bd9Sstevel@tonic-gate 	req.keydat.dsize  = yp_secure_sz;
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 	resp.valdat.dptr = NULL;
8227c478bd9Sstevel@tonic-gate 	resp.valdat.dsize = 0;
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate 	/*
8257c478bd9Sstevel@tonic-gate 	 * Get the value of the IS_SECURE key in the map.
8267c478bd9Sstevel@tonic-gate 	 */
8277c478bd9Sstevel@tonic-gate 	retval = FALSE;
8287c478bd9Sstevel@tonic-gate 
8297c478bd9Sstevel@tonic-gate 	if (debug)
8307c478bd9Sstevel@tonic-gate 		fprintf(stderr, "ypxfr: Checking masters secure key.\n");
8317c478bd9Sstevel@tonic-gate 	if ((enum clnt_stat) clnt_call(master_server.dom_client,
8327c478bd9Sstevel@tonic-gate 	    YPPROC_MATCH, (xdrproc_t)xdr_ypreq_key, (char *)&req,
8337c478bd9Sstevel@tonic-gate 	(xdrproc_t)xdr_ypresp_val, (char *)&resp,
8347c478bd9Sstevel@tonic-gate 	    udp_timeout) == RPC_SUCCESS) {
8357c478bd9Sstevel@tonic-gate 		if (resp.status == YP_TRUE) {
8367c478bd9Sstevel@tonic-gate 			if (debug)
8377c478bd9Sstevel@tonic-gate 				fprintf(stderr, "ypxfr: SECURE\n");
8387c478bd9Sstevel@tonic-gate 			secure_map = TRUE;
8397c478bd9Sstevel@tonic-gate 			retval = TRUE;
8407c478bd9Sstevel@tonic-gate 		} else if ((resp.status != YP_NOKEY) &&
8417c478bd9Sstevel@tonic-gate 			    (resp.status != YP_VERS) &&
8427c478bd9Sstevel@tonic-gate 			    (resp.status != YP_NOMORE)) {
8437c478bd9Sstevel@tonic-gate 			*pushstat = ypprot_err(resp.status);
8447c478bd9Sstevel@tonic-gate 
8457c478bd9Sstevel@tonic-gate 			if (!logging) {
8467c478bd9Sstevel@tonic-gate 				logprintf(
8477c478bd9Sstevel@tonic-gate 	"(info) Can't get secure flag from ypserv at %s.  Reason: %s.\n",
8487c478bd9Sstevel@tonic-gate 				    master, yperr_string(
8497c478bd9Sstevel@tonic-gate 				    ypprot_err(resp.status)));
8507c478bd9Sstevel@tonic-gate 			}
8517c478bd9Sstevel@tonic-gate 		}
8527c478bd9Sstevel@tonic-gate 
8537c478bd9Sstevel@tonic-gate 		CLNT_FREERES(master_server.dom_client,
8547c478bd9Sstevel@tonic-gate 			(xdrproc_t)xdr_ypresp_val,
8557c478bd9Sstevel@tonic-gate 		    (char *)&resp);
8567c478bd9Sstevel@tonic-gate 	} else {
8577c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_RPC;
8587c478bd9Sstevel@tonic-gate 		logprintf("ypxfr(get_misc_recs) RPC call to %s failed", master);
8597c478bd9Sstevel@tonic-gate 		clnt_perror(master_server.dom_client, "");
8607c478bd9Sstevel@tonic-gate 	}
8617c478bd9Sstevel@tonic-gate 
8627c478bd9Sstevel@tonic-gate 	if (debug)
8637c478bd9Sstevel@tonic-gate 		fprintf(stderr, "ypxfr: Checking masters INTERDOMAIN key.\n");
8647c478bd9Sstevel@tonic-gate 	req.keydat.dptr   = yp_interdomain;
8657c478bd9Sstevel@tonic-gate 	req.keydat.dsize  = yp_interdomain_sz;
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate 	resp.valdat.dptr = NULL;
8687c478bd9Sstevel@tonic-gate 	resp.valdat.dsize = 0;
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate 	/*
8717c478bd9Sstevel@tonic-gate 	 * Get the value of the INTERDOMAIN key in the map.
8727c478bd9Sstevel@tonic-gate 	 */
8737c478bd9Sstevel@tonic-gate 
8747c478bd9Sstevel@tonic-gate 	if ((enum clnt_stat) clnt_call(master_server.dom_client,
8757c478bd9Sstevel@tonic-gate 	    YPPROC_MATCH, (xdrproc_t)xdr_ypreq_key, (char *)&req,
8767c478bd9Sstevel@tonic-gate 	(xdrproc_t)xdr_ypresp_val, (char *)&resp,
8777c478bd9Sstevel@tonic-gate 	    udp_timeout) == RPC_SUCCESS) {
8787c478bd9Sstevel@tonic-gate 		if (resp.status == YP_TRUE) {
8797c478bd9Sstevel@tonic-gate 			if (debug)
8807c478bd9Sstevel@tonic-gate 				fprintf(stderr, "ypxfr: INTERDOMAIN\n");
8817c478bd9Sstevel@tonic-gate 			interdomain_map = TRUE;
8827c478bd9Sstevel@tonic-gate 			interdomain_value = (char *)malloc(resp.valdat.dsize+1);
8837c478bd9Sstevel@tonic-gate 			(void) memmove(interdomain_value, resp.valdat.dptr,
8847c478bd9Sstevel@tonic-gate 					resp.valdat.dsize);
8857c478bd9Sstevel@tonic-gate 			*(interdomain_value+resp.valdat.dsize) = '\0';
8867c478bd9Sstevel@tonic-gate 			interdomain_sz = resp.valdat.dsize;
8877c478bd9Sstevel@tonic-gate 			retval = TRUE;
8887c478bd9Sstevel@tonic-gate 		} else if ((resp.status != YP_NOKEY) &&
8897c478bd9Sstevel@tonic-gate 			    (resp.status != YP_VERS) &&
8907c478bd9Sstevel@tonic-gate 			    (resp.status != YP_NOMORE)) {
8917c478bd9Sstevel@tonic-gate 			*pushstat = ypprot_err(resp.status);
8927c478bd9Sstevel@tonic-gate 
8937c478bd9Sstevel@tonic-gate 			if (!logging) {
8947c478bd9Sstevel@tonic-gate 				logprintf(
8957c478bd9Sstevel@tonic-gate 	"(info) Can't get interdomain flag from ypserv at %s.  Reason: %s.\n",
8967c478bd9Sstevel@tonic-gate 				    master, yperr_string(
8977c478bd9Sstevel@tonic-gate 				    ypprot_err(resp.status)));
8987c478bd9Sstevel@tonic-gate 			}
8997c478bd9Sstevel@tonic-gate 		}
9007c478bd9Sstevel@tonic-gate 
9017c478bd9Sstevel@tonic-gate 		CLNT_FREERES(master_server.dom_client,
9027c478bd9Sstevel@tonic-gate 			(xdrproc_t)xdr_ypresp_val,
9037c478bd9Sstevel@tonic-gate 		    (char *)&resp);
9047c478bd9Sstevel@tonic-gate 	} else {
9057c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_RPC;
9067c478bd9Sstevel@tonic-gate 		logprintf("ypxfr(get_misc_recs) RPC call to %s failed", master);
9077c478bd9Sstevel@tonic-gate 		clnt_perror(master_server.dom_client, "");
9087c478bd9Sstevel@tonic-gate 	}
9097c478bd9Sstevel@tonic-gate 
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate 	return (retval);
9127c478bd9Sstevel@tonic-gate }
9137c478bd9Sstevel@tonic-gate 
9147c478bd9Sstevel@tonic-gate /*
9157c478bd9Sstevel@tonic-gate  * This gets the map's master name from the master server
9167c478bd9Sstevel@tonic-gate  */
9177c478bd9Sstevel@tonic-gate bool
get_master_name(name,pushstat)9187c478bd9Sstevel@tonic-gate get_master_name(name, pushstat)
9197c478bd9Sstevel@tonic-gate 	char *name;
9207c478bd9Sstevel@tonic-gate 	int *pushstat;
9217c478bd9Sstevel@tonic-gate {
9227c478bd9Sstevel@tonic-gate 	if (master_prog_vers == YPVERS) {
9237c478bd9Sstevel@tonic-gate 		return (get_v2master_name(name, pushstat));
9247c478bd9Sstevel@tonic-gate 	} else
9257c478bd9Sstevel@tonic-gate 		return (FALSE);
9267c478bd9Sstevel@tonic-gate }
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate bool
get_v2master_name(name,pushstat)9297c478bd9Sstevel@tonic-gate get_v2master_name(name, pushstat)
9307c478bd9Sstevel@tonic-gate 	char *name;
9317c478bd9Sstevel@tonic-gate 	int *pushstat;
9327c478bd9Sstevel@tonic-gate {
9337c478bd9Sstevel@tonic-gate 	struct ypreq_nokey req;
9347c478bd9Sstevel@tonic-gate 	struct ypresp_master resp;
9357c478bd9Sstevel@tonic-gate 	int retval;
9367c478bd9Sstevel@tonic-gate 
9377c478bd9Sstevel@tonic-gate 	req.domain = source;
9387c478bd9Sstevel@tonic-gate 	req.map = map;
9397c478bd9Sstevel@tonic-gate 	resp.master = NULL;
9407c478bd9Sstevel@tonic-gate 	retval = FALSE;
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate 	if ((enum clnt_stat) clnt_call(master_server.dom_client,
9437c478bd9Sstevel@tonic-gate 	    YPPROC_MASTER, (xdrproc_t)xdr_ypreq_nokey, (char *)&req,
9447c478bd9Sstevel@tonic-gate 	    (xdrproc_t)xdr_ypresp_master, (char *)&resp,
9457c478bd9Sstevel@tonic-gate 	    udp_timeout) == RPC_SUCCESS) {
9467c478bd9Sstevel@tonic-gate 
9477c478bd9Sstevel@tonic-gate 		if (resp.status == YP_TRUE) {
9487c478bd9Sstevel@tonic-gate 			strcpy(name, resp.master);
9497c478bd9Sstevel@tonic-gate 			retval = TRUE;
9507c478bd9Sstevel@tonic-gate 		} else if (resp.status != YP_BADDB) {
9517c478bd9Sstevel@tonic-gate 			*pushstat = ypprot_err(resp.status);
9527c478bd9Sstevel@tonic-gate 
9537c478bd9Sstevel@tonic-gate 			if (!logging) {
9547c478bd9Sstevel@tonic-gate 				logprintf(
9557c478bd9Sstevel@tonic-gate "(info) Can't get master name from ypserv at %s. Reason: %s.\n",
9567c478bd9Sstevel@tonic-gate 				    master, yperr_string(
9577c478bd9Sstevel@tonic-gate 				    ypprot_err(resp.status)));
9587c478bd9Sstevel@tonic-gate 			}
9597c478bd9Sstevel@tonic-gate 		}
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 		CLNT_FREERES(master_server.dom_client,
9627c478bd9Sstevel@tonic-gate 			(xdrproc_t)xdr_ypresp_master,
9637c478bd9Sstevel@tonic-gate 		    (char *)&resp);
9647c478bd9Sstevel@tonic-gate 	} else {
9657c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_RPC;
9667c478bd9Sstevel@tonic-gate 		logprintf(
9677c478bd9Sstevel@tonic-gate 		    "ypxfr(get_v2master_name) RPC call to %s failed", master);
9687c478bd9Sstevel@tonic-gate 		clnt_perror(master_server.dom_client, "");
9697c478bd9Sstevel@tonic-gate 	}
9707c478bd9Sstevel@tonic-gate 
9717c478bd9Sstevel@tonic-gate 	return (retval);
9727c478bd9Sstevel@tonic-gate }
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate /*
9757c478bd9Sstevel@tonic-gate  * This does the work of transferring the map.
9767c478bd9Sstevel@tonic-gate  */
9777c478bd9Sstevel@tonic-gate bool
move_map(pushstat)9787c478bd9Sstevel@tonic-gate move_map(pushstat)
9797c478bd9Sstevel@tonic-gate 	int *pushstat;
9807c478bd9Sstevel@tonic-gate {
9817c478bd9Sstevel@tonic-gate 	unsigned local_version;
9827c478bd9Sstevel@tonic-gate 	char map_name[MAXNAMLEN + 1];
9837c478bd9Sstevel@tonic-gate 	char tmp_name[MAXNAMLEN + 1];
9847c478bd9Sstevel@tonic-gate 	char bkup_name[MAXNAMLEN + 1];
9857c478bd9Sstevel@tonic-gate 	char an[11];
9867c478bd9Sstevel@tonic-gate 	unsigned n;
9877c478bd9Sstevel@tonic-gate 	datum key;
9887c478bd9Sstevel@tonic-gate 	datum val;
9897c478bd9Sstevel@tonic-gate 	int  hgstatus;
9907c478bd9Sstevel@tonic-gate 
9917c478bd9Sstevel@tonic-gate 	mkfilename(map_name);
9927c478bd9Sstevel@tonic-gate 
9937c478bd9Sstevel@tonic-gate 	if (!force) {
9947c478bd9Sstevel@tonic-gate 		local_version = get_local_version(map_name);
9957c478bd9Sstevel@tonic-gate 		if (debug) fprintf(stderr,
9967c478bd9Sstevel@tonic-gate 			"ypxfr: Local version of map '%s' is %d\n",
9977c478bd9Sstevel@tonic-gate 			map_name, local_version);
9987c478bd9Sstevel@tonic-gate 
9997c478bd9Sstevel@tonic-gate 		if (local_version >= *master_version) {
10007c478bd9Sstevel@tonic-gate 			logprintf(
10017c478bd9Sstevel@tonic-gate 			    "Map %s at %s is not more recent than local.\n",
10027c478bd9Sstevel@tonic-gate 			    map, master);
10037c478bd9Sstevel@tonic-gate 			*pushstat = YPPUSH_AGE;
10047c478bd9Sstevel@tonic-gate 			return (FALSE);
10057c478bd9Sstevel@tonic-gate 		}
10067c478bd9Sstevel@tonic-gate 	}
10077c478bd9Sstevel@tonic-gate 
10087c478bd9Sstevel@tonic-gate 	mk_tmpname(yptempname_prefix, tmp_name);
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate 	if (!new_mapfiles(tmp_name)) {
10117c478bd9Sstevel@tonic-gate 		logprintf(
10127c478bd9Sstevel@tonic-gate 		    "Can't create temp map %s.\n", tmp_name);
10137c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_FILE;
10147c478bd9Sstevel@tonic-gate 		return (FALSE);
10157c478bd9Sstevel@tonic-gate 	}
10167c478bd9Sstevel@tonic-gate 
10177c478bd9Sstevel@tonic-gate 	if ((hgstatus = ypxfrd_getdbm(tmp_name, master, source, map)) < 0)
10187c478bd9Sstevel@tonic-gate 	{
10197c478bd9Sstevel@tonic-gate 	logprintf(
10207c478bd9Sstevel@tonic-gate "(info) %s %s %s ypxfrd getdbm failed (reason = %d) -- using ypxfr\n",
10217c478bd9Sstevel@tonic-gate 		master, domain, map, hgstatus);
10227c478bd9Sstevel@tonic-gate 
10237c478bd9Sstevel@tonic-gate 	    db = dbm_open(tmp_name, O_RDWR + O_CREAT + O_TRUNC, 0644);
10247c478bd9Sstevel@tonic-gate 	if (db == NULL) {
10257c478bd9Sstevel@tonic-gate 		logprintf(
10267c478bd9Sstevel@tonic-gate 		    "Can't dbm init temp map %s.\n", tmp_name);
10277c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
10287c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
10297c478bd9Sstevel@tonic-gate 		return (FALSE);
10307c478bd9Sstevel@tonic-gate 	}
10317c478bd9Sstevel@tonic-gate 	if (defwrite) dbm_setdefwrite(db);
10327c478bd9Sstevel@tonic-gate 
10337c478bd9Sstevel@tonic-gate 	if (!get_map(tmp_name, pushstat)) {
10347c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
10357c478bd9Sstevel@tonic-gate 		return (FALSE);
10367c478bd9Sstevel@tonic-gate 	}
10377c478bd9Sstevel@tonic-gate 
10387c478bd9Sstevel@tonic-gate 	if (!add_private_entries(tmp_name)) {
10397c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
10407c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
10417c478bd9Sstevel@tonic-gate 		return (FALSE);
10427c478bd9Sstevel@tonic-gate 	}
10437c478bd9Sstevel@tonic-gate 
10447c478bd9Sstevel@tonic-gate 	/*
10457c478bd9Sstevel@tonic-gate 	 * Decide whether the map just transferred is a secure map.
10467c478bd9Sstevel@tonic-gate 	 * If we already know the local version was secure, we do not
10477c478bd9Sstevel@tonic-gate 	 * need to check this version.
10487c478bd9Sstevel@tonic-gate 	 */
10497c478bd9Sstevel@tonic-gate 	if (!secure_map) {
10507c478bd9Sstevel@tonic-gate 		key.dptr = yp_secure;
10517c478bd9Sstevel@tonic-gate 		key.dsize = yp_secure_sz;
10527c478bd9Sstevel@tonic-gate 		val = dbm_fetch(db, key);
10537c478bd9Sstevel@tonic-gate 		if (val.dptr != NULL) {
10547c478bd9Sstevel@tonic-gate 			secure_map = TRUE;
10557c478bd9Sstevel@tonic-gate 		}
10567c478bd9Sstevel@tonic-gate 	}
10577c478bd9Sstevel@tonic-gate 
10587c478bd9Sstevel@tonic-gate 	if (dbm_close_status(db) < 0) {
10597c478bd9Sstevel@tonic-gate 		logprintf(
10607c478bd9Sstevel@tonic-gate 		    "Can't do dbm close operation on temp map %s.\n",
10617c478bd9Sstevel@tonic-gate 		    tmp_name);
10627c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
10637c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
10647c478bd9Sstevel@tonic-gate 		return (FALSE);
10657c478bd9Sstevel@tonic-gate 	}
10667c478bd9Sstevel@tonic-gate 
10677c478bd9Sstevel@tonic-gate 	if (!get_order(an, &n, pushstat)) {
10687c478bd9Sstevel@tonic-gate 		return (FALSE);
10697c478bd9Sstevel@tonic-gate 	}
10707c478bd9Sstevel@tonic-gate 	if (n != *master_version) {
10717c478bd9Sstevel@tonic-gate 		logprintf(
10727c478bd9Sstevel@tonic-gate 		    "Version skew at %s while transferring map %s.\n",
10737c478bd9Sstevel@tonic-gate 		    master, map);
10747c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
10757c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_SKEW;
10767c478bd9Sstevel@tonic-gate 		return (FALSE);
10777c478bd9Sstevel@tonic-gate 	}
10787c478bd9Sstevel@tonic-gate 
10797c478bd9Sstevel@tonic-gate 	if (check_count)
10807c478bd9Sstevel@tonic-gate 	if (!count_mismatch(tmp_name, entry_count)) {
10817c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
10827c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
10837c478bd9Sstevel@tonic-gate 		return (FALSE);
10847c478bd9Sstevel@tonic-gate 	}
10857c478bd9Sstevel@tonic-gate 	} else {
10867c478bd9Sstevel@tonic-gate 	/* touch up the map */
10877c478bd9Sstevel@tonic-gate 	    db = dbm_open(tmp_name, 2, 0644);
10887c478bd9Sstevel@tonic-gate 	if (db == NULL) {
10897c478bd9Sstevel@tonic-gate 		logprintf(
10907c478bd9Sstevel@tonic-gate 		    "Can't dbm init temp map %s.\n", tmp_name);
10917c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
10927c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
10937c478bd9Sstevel@tonic-gate 		return (FALSE);
10947c478bd9Sstevel@tonic-gate 		}
10957c478bd9Sstevel@tonic-gate 
10967c478bd9Sstevel@tonic-gate 
10977c478bd9Sstevel@tonic-gate 	if (!add_private_entries(tmp_name)) {
10987c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
10997c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
11007c478bd9Sstevel@tonic-gate 		return (FALSE);
11017c478bd9Sstevel@tonic-gate 	}
11027c478bd9Sstevel@tonic-gate 
11037c478bd9Sstevel@tonic-gate 	/*
11047c478bd9Sstevel@tonic-gate 	 * Decide whether the map just transferred is a secure map.
11057c478bd9Sstevel@tonic-gate 	 * If we already know the local version was secure, we do not
11067c478bd9Sstevel@tonic-gate 	 * need to check this version.
11077c478bd9Sstevel@tonic-gate 	 */
11087c478bd9Sstevel@tonic-gate 	if (!secure_map) {
11097c478bd9Sstevel@tonic-gate 		key.dptr = yp_secure;
11107c478bd9Sstevel@tonic-gate 		key.dsize = yp_secure_sz;
11117c478bd9Sstevel@tonic-gate 		val = dbm_fetch(db, key);
11127c478bd9Sstevel@tonic-gate 		if (val.dptr != NULL) {
11137c478bd9Sstevel@tonic-gate 			secure_map = TRUE;
11147c478bd9Sstevel@tonic-gate 		}
11157c478bd9Sstevel@tonic-gate 	}
11167c478bd9Sstevel@tonic-gate 
11177c478bd9Sstevel@tonic-gate 	if (dbm_close_status(db) < 0) {
11187c478bd9Sstevel@tonic-gate 		logprintf(
11197c478bd9Sstevel@tonic-gate 		    "Can't do dbm close operation on temp map %s.\n",
11207c478bd9Sstevel@tonic-gate 		    tmp_name);
11217c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
11227c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
11237c478bd9Sstevel@tonic-gate 		return (FALSE);
11247c478bd9Sstevel@tonic-gate 	}
11257c478bd9Sstevel@tonic-gate 
11267c478bd9Sstevel@tonic-gate 	}
11277c478bd9Sstevel@tonic-gate 
11287c478bd9Sstevel@tonic-gate 	if (lock_map(map_name) == 0) {
11297c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
11307c478bd9Sstevel@tonic-gate 		logprintf("Lock error on %s\n", map_name);
11317c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_FILE;
11327c478bd9Sstevel@tonic-gate 		return (FALSE);
11337c478bd9Sstevel@tonic-gate 	}
11347c478bd9Sstevel@tonic-gate 	if (!check_map_existence(map_name)) {
11357c478bd9Sstevel@tonic-gate 
11367c478bd9Sstevel@tonic-gate 		if (!rename_map(tmp_name, map_name, secure_map)) {
11377c478bd9Sstevel@tonic-gate 			del_mapfiles(tmp_name);
11387c478bd9Sstevel@tonic-gate 			logprintf(
11397c478bd9Sstevel@tonic-gate 			    "Rename error:  couldn't mv %s to %s.\n",
11407c478bd9Sstevel@tonic-gate 			    tmp_name, map_name);
11417c478bd9Sstevel@tonic-gate 			*pushstat = YPPUSH_FILE;
11427c478bd9Sstevel@tonic-gate 			unlock_map(map_name);
11437c478bd9Sstevel@tonic-gate 			return (FALSE);
11447c478bd9Sstevel@tonic-gate 		}
11457c478bd9Sstevel@tonic-gate 
11467c478bd9Sstevel@tonic-gate 	} else {
11477c478bd9Sstevel@tonic-gate 		mk_tmpname(ypbkupname_prefix, bkup_name);
11487c478bd9Sstevel@tonic-gate 
11497c478bd9Sstevel@tonic-gate 		if (!rename_map(map_name, bkup_name, secure_map)) {
11507c478bd9Sstevel@tonic-gate 			(void) rename_map(bkup_name, map_name, secure_map);
11517c478bd9Sstevel@tonic-gate 			logprintf(
11527c478bd9Sstevel@tonic-gate 		"Rename error:  check that old %s is still intact.\n",
11537c478bd9Sstevel@tonic-gate 		map_name);
11547c478bd9Sstevel@tonic-gate 			del_mapfiles(tmp_name);
11557c478bd9Sstevel@tonic-gate 			*pushstat = YPPUSH_FILE;
11567c478bd9Sstevel@tonic-gate 			unlock_map(map_name);
11577c478bd9Sstevel@tonic-gate 			return (FALSE);
11587c478bd9Sstevel@tonic-gate 		}
11597c478bd9Sstevel@tonic-gate 
11607c478bd9Sstevel@tonic-gate 		if (rename_map(tmp_name, map_name, secure_map)) {
11617c478bd9Sstevel@tonic-gate 			del_mapfiles(bkup_name);
11627c478bd9Sstevel@tonic-gate 		} else {
11637c478bd9Sstevel@tonic-gate 			del_mapfiles(tmp_name);
11647c478bd9Sstevel@tonic-gate 			(void) rename_map(bkup_name, map_name, secure_map);
11657c478bd9Sstevel@tonic-gate 				logprintf(
11667c478bd9Sstevel@tonic-gate 		"Rename error:  check that old %s is still intact.\n",
11677c478bd9Sstevel@tonic-gate 			    map_name);
11687c478bd9Sstevel@tonic-gate 			*pushstat = YPPUSH_FILE;
11697c478bd9Sstevel@tonic-gate 			unlock_map(map_name);
11707c478bd9Sstevel@tonic-gate 			return (FALSE);
11717c478bd9Sstevel@tonic-gate 		}
11727c478bd9Sstevel@tonic-gate 	}
11737c478bd9Sstevel@tonic-gate 	if (unlock_map(map_name) == 0)
11747c478bd9Sstevel@tonic-gate 		return (FALSE);
11757c478bd9Sstevel@tonic-gate 
11767c478bd9Sstevel@tonic-gate 	return (TRUE);
11777c478bd9Sstevel@tonic-gate }
11787c478bd9Sstevel@tonic-gate 
11797c478bd9Sstevel@tonic-gate /*
11807c478bd9Sstevel@tonic-gate  * This tries to get the order number out of the local version of the map.
11817c478bd9Sstevel@tonic-gate  * If the attempt fails for any version, the function will return "0"
11827c478bd9Sstevel@tonic-gate  */
11837c478bd9Sstevel@tonic-gate unsigned
get_local_version(name)11847c478bd9Sstevel@tonic-gate get_local_version(name)
11857c478bd9Sstevel@tonic-gate 	char *name;
11867c478bd9Sstevel@tonic-gate {
11877c478bd9Sstevel@tonic-gate 	datum key;
11887c478bd9Sstevel@tonic-gate 	datum val;
11897c478bd9Sstevel@tonic-gate 	char number[11];
11907c478bd9Sstevel@tonic-gate 	DBM *db;
11917c478bd9Sstevel@tonic-gate 
11927c478bd9Sstevel@tonic-gate 	if (!check_map_existence(name)) {
11937c478bd9Sstevel@tonic-gate 		return (0);
11947c478bd9Sstevel@tonic-gate 	}
11957c478bd9Sstevel@tonic-gate 	if (debug) fprintf(stderr,
11967c478bd9Sstevel@tonic-gate 		"ypxfr: Map does exist, checking version now.\n");
11977c478bd9Sstevel@tonic-gate 
11987c478bd9Sstevel@tonic-gate 	if ((db = dbm_open(name, 0, 0)) == 0) {
11997c478bd9Sstevel@tonic-gate 		return (0);
12007c478bd9Sstevel@tonic-gate 	}
12017c478bd9Sstevel@tonic-gate 
12027c478bd9Sstevel@tonic-gate 	key.dptr = yp_last_modified;
12037c478bd9Sstevel@tonic-gate 	key.dsize = yp_last_modified_sz;
12047c478bd9Sstevel@tonic-gate 	val = dbm_fetch(db, key);
12057c478bd9Sstevel@tonic-gate 	if (!val.dptr) {	/* Check to see if dptr is NULL */
12067c478bd9Sstevel@tonic-gate 		return (0);
12077c478bd9Sstevel@tonic-gate 	}
12087c478bd9Sstevel@tonic-gate 	if (val.dsize == 0 || val.dsize > 10) {
12097c478bd9Sstevel@tonic-gate 		return (0);
12107c478bd9Sstevel@tonic-gate 	}
12117c478bd9Sstevel@tonic-gate 	/* Now save this value while we have it available */
12127c478bd9Sstevel@tonic-gate 	(void) memmove(number, val.dptr, val.dsize);
12137c478bd9Sstevel@tonic-gate 	number[val.dsize] = '\0';
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 	/*
12167c478bd9Sstevel@tonic-gate 	 * Now check to see if it is 'secure'. If we haven't already
12177c478bd9Sstevel@tonic-gate 	 * determined that it is secure in get_private_recs() then we check
12187c478bd9Sstevel@tonic-gate 	 * the local map here.
12197c478bd9Sstevel@tonic-gate 	 */
12207c478bd9Sstevel@tonic-gate 	if (!secure_map) {
12217c478bd9Sstevel@tonic-gate 		key.dptr = yp_secure;
12227c478bd9Sstevel@tonic-gate 		key.dsize = yp_secure_sz;
12237c478bd9Sstevel@tonic-gate 		val = dbm_fetch(db, key);
12247c478bd9Sstevel@tonic-gate 		secure_map = (val.dptr != NULL);
12257c478bd9Sstevel@tonic-gate 	}
12267c478bd9Sstevel@tonic-gate 
12277c478bd9Sstevel@tonic-gate 	/*
12287c478bd9Sstevel@tonic-gate 	 * Now check to see if interdomain requests are made of the local
12297c478bd9Sstevel@tonic-gate 	 * map. Keep the value around if they are.
12307c478bd9Sstevel@tonic-gate 	 */
12317c478bd9Sstevel@tonic-gate 	if (!interdomain_map) {
12327c478bd9Sstevel@tonic-gate 		key.dptr = yp_interdomain;
12337c478bd9Sstevel@tonic-gate 		key.dsize = yp_interdomain_sz;
12347c478bd9Sstevel@tonic-gate 		val = dbm_fetch(db, key);
12357c478bd9Sstevel@tonic-gate 		if (interdomain_map = (val.dptr != NULL)) {
12367c478bd9Sstevel@tonic-gate 			interdomain_value = (char *)malloc(val.dsize+1);
12377c478bd9Sstevel@tonic-gate 			(void) memmove(interdomain_value, val.dptr, val.dsize);
12387c478bd9Sstevel@tonic-gate 			*(interdomain_value+val.dsize) = '\0';
12397c478bd9Sstevel@tonic-gate 			interdomain_sz = val.dsize;
12407c478bd9Sstevel@tonic-gate 		}
12417c478bd9Sstevel@tonic-gate 	}
12427c478bd9Sstevel@tonic-gate 
12437c478bd9Sstevel@tonic-gate 	/* finish up */
12447c478bd9Sstevel@tonic-gate 	(void) dbm_close_status(db);
12457c478bd9Sstevel@tonic-gate 
12467c478bd9Sstevel@tonic-gate 	return ((unsigned)atoi(number));
12477c478bd9