xref: /illumos-gate/usr/src/cmd/ypcmd/ypxfr.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  *
22*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
23*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24*7c478bd9Sstevel@tonic-gate  */
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved   */
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate /*
30*7c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley
31*7c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of
32*7c478bd9Sstevel@tonic-gate  * California.
33*7c478bd9Sstevel@tonic-gate  */
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate /*
38*7c478bd9Sstevel@tonic-gate  * This is a user command which gets a NIS data base from some running
39*7c478bd9Sstevel@tonic-gate  * server, and gets it to the local site by using the normal NIS client
40*7c478bd9Sstevel@tonic-gate  * enumeration functions.  The map is copied to a temp name, then the real
41*7c478bd9Sstevel@tonic-gate  * map is removed and the temp map is moved to the real name.  ypxfr then
42*7c478bd9Sstevel@tonic-gate  * sends a "YPPROC_CLEAR" message to the local server to insure that he will
43*7c478bd9Sstevel@tonic-gate  * not hold a removed map open, so serving an obsolete version.
44*7c478bd9Sstevel@tonic-gate  *
45*7c478bd9Sstevel@tonic-gate  * ypxfr [ -h <host> ] [ -d <domainname> ]
46*7c478bd9Sstevel@tonic-gate  *		[ -s <domainname> ] [-f] [-c] [-C tid prot name] map
47*7c478bd9Sstevel@tonic-gate  *
48*7c478bd9Sstevel@tonic-gate  * If the host is ommitted, ypxfr will attempt to discover the master by
49*7c478bd9Sstevel@tonic-gate  * using normal NIS services.  If it can't get the record, it will use
50*7c478bd9Sstevel@tonic-gate  * the address of the callback, if specified. If the host is specified
51*7c478bd9Sstevel@tonic-gate  * as an internet address, no NIS services need to be locally available.
52*7c478bd9Sstevel@tonic-gate  *
53*7c478bd9Sstevel@tonic-gate  * If the domain is not specified, the default domain of the local machine
54*7c478bd9Sstevel@tonic-gate  * is used.
55*7c478bd9Sstevel@tonic-gate  *
56*7c478bd9Sstevel@tonic-gate  * If the -f flag is used, the transfer will be done even if the master's
57*7c478bd9Sstevel@tonic-gate  * copy is not newer than the local copy.
58*7c478bd9Sstevel@tonic-gate  *
59*7c478bd9Sstevel@tonic-gate  * The -c flag suppresses the YPPROC_CLEAR request to the local ypserv.  It
60*7c478bd9Sstevel@tonic-gate  * may be used if ypserv isn't currently running to suppress the error message.
61*7c478bd9Sstevel@tonic-gate  *
62*7c478bd9Sstevel@tonic-gate  * The -C flag is used to pass callback information to ypxfr when it is
63*7c478bd9Sstevel@tonic-gate  * activated by ypserv.  The callback information is used to send a
64*7c478bd9Sstevel@tonic-gate  * yppushresp_xfr message with transaction id "tid" to a yppush process
65*7c478bd9Sstevel@tonic-gate  * speaking a transient protocol number "prot".  The yppush program is
66*7c478bd9Sstevel@tonic-gate  * running on the host "name".
67*7c478bd9Sstevel@tonic-gate  *
68*7c478bd9Sstevel@tonic-gate  * The -s option is used to specify a source domain which may be
69*7c478bd9Sstevel@tonic-gate  * different from the destination domain, for transfer of maps
70*7c478bd9Sstevel@tonic-gate  * that are identical in different domains (e.g. services.byname)
71*7c478bd9Sstevel@tonic-gate  *
72*7c478bd9Sstevel@tonic-gate  */
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate #include <ndbm.h>
75*7c478bd9Sstevel@tonic-gate #undef NULL
76*7c478bd9Sstevel@tonic-gate #define	DATUM
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate #include <stdio.h>
79*7c478bd9Sstevel@tonic-gate #include <errno.h>
80*7c478bd9Sstevel@tonic-gate #include <time.h>
81*7c478bd9Sstevel@tonic-gate #include <ctype.h>
82*7c478bd9Sstevel@tonic-gate #include <netdb.h>
83*7c478bd9Sstevel@tonic-gate #include <netconfig.h>
84*7c478bd9Sstevel@tonic-gate #include <netdir.h>
85*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
86*7c478bd9Sstevel@tonic-gate #include <sys/file.h>
87*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
88*7c478bd9Sstevel@tonic-gate #include <dirent.h>
89*7c478bd9Sstevel@tonic-gate #include <rpcsvc/ypclnt.h>
90*7c478bd9Sstevel@tonic-gate #include <rpcsvc/yp_prot.h>
91*7c478bd9Sstevel@tonic-gate #include <unistd.h>
92*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
93*7c478bd9Sstevel@tonic-gate #include <rpcsvc/nis.h>
94*7c478bd9Sstevel@tonic-gate #include "ypdefs.h"
95*7c478bd9Sstevel@tonic-gate #include "yp_b.h"
96*7c478bd9Sstevel@tonic-gate #include "shim.h"
97*7c478bd9Sstevel@tonic-gate #include "yptol.h"
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate USE_YP_MASTER_NAME
100*7c478bd9Sstevel@tonic-gate USE_YP_SECURE
101*7c478bd9Sstevel@tonic-gate USE_YP_INTERDOMAIN
102*7c478bd9Sstevel@tonic-gate USE_YP_LAST_MODIFIED
103*7c478bd9Sstevel@tonic-gate USE_YPDBPATH
104*7c478bd9Sstevel@tonic-gate USE_DBM
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate #define	PARANOID 1	/* make sure maps have the right # entries */
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate #define	CALLINTER_TRY 10		/* Seconds between callback tries */
109*7c478bd9Sstevel@tonic-gate #define	CALLTIMEOUT CALLINTER_TRY*6	/* Total timeout for callback */
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate DBM *db;
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate /* ypxfr never uses N2L mode */
114*7c478bd9Sstevel@tonic-gate bool_t yptol_mode = FALSE;
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate int	debug = FALSE;
117*7c478bd9Sstevel@tonic-gate int	treepush = FALSE;
118*7c478bd9Sstevel@tonic-gate #define	TREEPUSH 1
119*7c478bd9Sstevel@tonic-gate int	defwrite = TRUE;
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate char *domain = NULL;
122*7c478bd9Sstevel@tonic-gate char *source = NULL;
123*7c478bd9Sstevel@tonic-gate char *map = NULL;
124*7c478bd9Sstevel@tonic-gate char *master = NULL;
125*7c478bd9Sstevel@tonic-gate char *pushhost = NULL;
126*7c478bd9Sstevel@tonic-gate /*
127*7c478bd9Sstevel@tonic-gate  * The name of the xfer peer as specified as a
128*7c478bd9Sstevel@tonic-gate  * -h option, -C name option or from querying the NIS
129*7c478bd9Sstevel@tonic-gate  */
130*7c478bd9Sstevel@tonic-gate struct dom_binding master_server; /* To talk to above */
131*7c478bd9Sstevel@tonic-gate unsigned int master_prog_vers;	/* YPVERS (barfs at YPOLDVERS !) */
132*7c478bd9Sstevel@tonic-gate char *master_name = NULL;	/* Map's master as contained in the map */
133*7c478bd9Sstevel@tonic-gate unsigned *master_version = NULL; /* Order number as contained in the map */
134*7c478bd9Sstevel@tonic-gate char *master_ascii_version;	/* ASCII order number as contained in the map */
135*7c478bd9Sstevel@tonic-gate bool fake_master_version = FALSE;
136*7c478bd9Sstevel@tonic-gate /*
137*7c478bd9Sstevel@tonic-gate  * TRUE only if there's no order number in
138*7c478bd9Sstevel@tonic-gate  *  the map, and the user specified -f
139*7c478bd9Sstevel@tonic-gate  */
140*7c478bd9Sstevel@tonic-gate bool force = FALSE;		/* TRUE iff user specified -f flag */
141*7c478bd9Sstevel@tonic-gate bool logging = FALSE;		/* TRUE iff no tty, but log file exists */
142*7c478bd9Sstevel@tonic-gate bool check_count = FALSE;	/* TRUE causes counts to be checked */
143*7c478bd9Sstevel@tonic-gate bool send_clear = TRUE;		/* FALSE iff user specified -c flag */
144*7c478bd9Sstevel@tonic-gate bool callback = FALSE;
145*7c478bd9Sstevel@tonic-gate /*
146*7c478bd9Sstevel@tonic-gate  * TRUE iff -C flag set.  tid, proto and name
147*7c478bd9Sstevel@tonic-gate  * will be set to point to the command line args.
148*7c478bd9Sstevel@tonic-gate  */
149*7c478bd9Sstevel@tonic-gate bool secure_map = FALSE;	/* TRUE if there is yp_secure in the map */
150*7c478bd9Sstevel@tonic-gate bool interdomain_map = FALSE;
151*7c478bd9Sstevel@tonic-gate /*
152*7c478bd9Sstevel@tonic-gate  * TRUE if there is yp_interdomain in either
153*7c478bd9Sstevel@tonic-gate  * the local or the master version of the map
154*7c478bd9Sstevel@tonic-gate  */
155*7c478bd9Sstevel@tonic-gate int interdomain_sz = 0;		/* Size of the interdomain value */
156*7c478bd9Sstevel@tonic-gate #define	UDPINTER_TRY 10		/* Seconds between tries for udp */
157*7c478bd9Sstevel@tonic-gate #define	UDPTIMEOUT UDPINTER_TRY*4	/* Total timeout for udp */
158*7c478bd9Sstevel@tonic-gate #define	CALLINTER_TRY 10	/* Seconds between callback tries */
159*7c478bd9Sstevel@tonic-gate #define	CALLTIMEOUT CALLINTER_TRY*6	/* Total timeout for callback */
160*7c478bd9Sstevel@tonic-gate struct timeval udp_timeout = { UDPTIMEOUT, 0};
161*7c478bd9Sstevel@tonic-gate struct timeval tcp_timeout = { 180, 0}; /* Timeout for map enumeration */
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate char *interdomain_value; 	/* place to store the interdomain value */
164*7c478bd9Sstevel@tonic-gate char *tid;
165*7c478bd9Sstevel@tonic-gate char *proto;
166*7c478bd9Sstevel@tonic-gate int entry_count;		/* counts entries in the map */
167*7c478bd9Sstevel@tonic-gate char logfile[] = "/var/yp/ypxfr.log";
168*7c478bd9Sstevel@tonic-gate static char err_usage[] =
169*7c478bd9Sstevel@tonic-gate "Usage:\n\
170*7c478bd9Sstevel@tonic-gate ypxfr [-f] [ -h host ] [ -d domainname ]\n\
171*7c478bd9Sstevel@tonic-gate 	[ -s domainname ] [-c] [-C tid prot servname ] map\n\n\
172*7c478bd9Sstevel@tonic-gate where\n\
173*7c478bd9Sstevel@tonic-gate 	-f forces transfer even if the master's copy is not newer.\n\
174*7c478bd9Sstevel@tonic-gate 	host is the server from where the map should be transfered\n\
175*7c478bd9Sstevel@tonic-gate 	-d domainname is specified if other than the default domain\n\
176*7c478bd9Sstevel@tonic-gate 	-s domainname is a source for the map that is same across domains\n\
177*7c478bd9Sstevel@tonic-gate 	-c inhibits sending a \"Clear map\" message to the local ypserv.\n\
178*7c478bd9Sstevel@tonic-gate 	-C is for use only by ypserv to pass callback information.\n";
179*7c478bd9Sstevel@tonic-gate char err_bad_args[] =
180*7c478bd9Sstevel@tonic-gate 	"%s argument is bad.\n";
181*7c478bd9Sstevel@tonic-gate char err_cant_get_kname[] =
182*7c478bd9Sstevel@tonic-gate 	"Can't get %s back from system call.\n";
183*7c478bd9Sstevel@tonic-gate char err_null_kname[] =
184*7c478bd9Sstevel@tonic-gate 	"%s hasn't been set on this machine.\n";
185*7c478bd9Sstevel@tonic-gate char err_bad_hostname[] = "hostname";
186*7c478bd9Sstevel@tonic-gate char err_bad_mapname[] = "mapname";
187*7c478bd9Sstevel@tonic-gate char err_bad_domainname[] = "domainname";
188*7c478bd9Sstevel@tonic-gate char err_udp_failure[] =
189*7c478bd9Sstevel@tonic-gate 	"Can't set up a udp connection to ypserv on host %s.\n";
190*7c478bd9Sstevel@tonic-gate char yptempname_prefix[] = "ypxfr_map.";
191*7c478bd9Sstevel@tonic-gate char ypbkupname_prefix[] = "ypxfr_bkup.";
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate void get_command_line_args();
194*7c478bd9Sstevel@tonic-gate bool bind_to_server();
195*7c478bd9Sstevel@tonic-gate bool ping_server();
196*7c478bd9Sstevel@tonic-gate bool  get_private_recs();
197*7c478bd9Sstevel@tonic-gate bool get_order();
198*7c478bd9Sstevel@tonic-gate bool get_v1order();
199*7c478bd9Sstevel@tonic-gate bool get_v2order();
200*7c478bd9Sstevel@tonic-gate bool get_misc_recs();
201*7c478bd9Sstevel@tonic-gate bool get_master_name();
202*7c478bd9Sstevel@tonic-gate bool get_v1master_name();
203*7c478bd9Sstevel@tonic-gate bool get_v2master_name();
204*7c478bd9Sstevel@tonic-gate void find_map_master();
205*7c478bd9Sstevel@tonic-gate bool move_map();
206*7c478bd9Sstevel@tonic-gate unsigned get_local_version();
207*7c478bd9Sstevel@tonic-gate void mkfilename();
208*7c478bd9Sstevel@tonic-gate void mk_tmpname();
209*7c478bd9Sstevel@tonic-gate bool get_map();
210*7c478bd9Sstevel@tonic-gate bool add_private_entries();
211*7c478bd9Sstevel@tonic-gate bool new_mapfiles();
212*7c478bd9Sstevel@tonic-gate void del_mapfiles();
213*7c478bd9Sstevel@tonic-gate void set_output();
214*7c478bd9Sstevel@tonic-gate void logprintf();
215*7c478bd9Sstevel@tonic-gate bool send_ypclear();
216*7c478bd9Sstevel@tonic-gate void xfr_exit();
217*7c478bd9Sstevel@tonic-gate void send_callback();
218*7c478bd9Sstevel@tonic-gate int ypall_callback();
219*7c478bd9Sstevel@tonic-gate int map_yperr_to_pusherr();
220*7c478bd9Sstevel@tonic-gate extern CLIENT *__yp_clnt_create_rsvdport();
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate bool_t is_yptol_mode();
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate extern int errno;
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate /*
228*7c478bd9Sstevel@tonic-gate  * This is the mainline for the ypxfr process.
229*7c478bd9Sstevel@tonic-gate  */
230*7c478bd9Sstevel@tonic-gate 
231*7c478bd9Sstevel@tonic-gate void
232*7c478bd9Sstevel@tonic-gate main(argc, argv)
233*7c478bd9Sstevel@tonic-gate 	int argc;
234*7c478bd9Sstevel@tonic-gate 	char **argv;
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate {
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate 	static char default_domain_name[YPMAXDOMAIN];
239*7c478bd9Sstevel@tonic-gate 	static unsigned big = 0xffffffff;
240*7c478bd9Sstevel@tonic-gate 	int status;
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate 	set_output();
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate 	/*
245*7c478bd9Sstevel@tonic-gate 	 * Inter-process lock synchronization structure. Since slave servers
246*7c478bd9Sstevel@tonic-gate 	 * get their maps from another NIS server rather than LDAP they can
247*7c478bd9Sstevel@tonic-gate 	 * never run in N2L mode. We thus do not have to init the update
248*7c478bd9Sstevel@tonic-gate 	 * locking mechanism.
249*7c478bd9Sstevel@tonic-gate 	 */
250*7c478bd9Sstevel@tonic-gate 	if (init_lock_map() == FALSE) {
251*7c478bd9Sstevel@tonic-gate 		exit(1);
252*7c478bd9Sstevel@tonic-gate 	}
253*7c478bd9Sstevel@tonic-gate 
254*7c478bd9Sstevel@tonic-gate 	get_command_line_args(argc, argv);
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate 	if (!domain) {
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate 		if (!getdomainname(default_domain_name, YPMAXDOMAIN)) {
259*7c478bd9Sstevel@tonic-gate 			domain = default_domain_name;
260*7c478bd9Sstevel@tonic-gate 		} else {
261*7c478bd9Sstevel@tonic-gate 			logprintf(err_cant_get_kname,
262*7c478bd9Sstevel@tonic-gate 			    err_bad_domainname);
263*7c478bd9Sstevel@tonic-gate 			xfr_exit(YPPUSH_RSRC);
264*7c478bd9Sstevel@tonic-gate 		}
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate 		if (strlen(domain) == 0) {
267*7c478bd9Sstevel@tonic-gate 			logprintf(err_null_kname,
268*7c478bd9Sstevel@tonic-gate 			    err_bad_domainname);
269*7c478bd9Sstevel@tonic-gate 			xfr_exit(YPPUSH_RSRC);
270*7c478bd9Sstevel@tonic-gate 		}
271*7c478bd9Sstevel@tonic-gate 	}
272*7c478bd9Sstevel@tonic-gate 	if (!source)
273*7c478bd9Sstevel@tonic-gate 		source = domain;
274*7c478bd9Sstevel@tonic-gate 
275*7c478bd9Sstevel@tonic-gate 	if (!master) {
276*7c478bd9Sstevel@tonic-gate 		find_map_master();
277*7c478bd9Sstevel@tonic-gate 	}
278*7c478bd9Sstevel@tonic-gate 	/*
279*7c478bd9Sstevel@tonic-gate 	 * if we were unable to get the master name, either from
280*7c478bd9Sstevel@tonic-gate 	 * the -h option or from -C "name" option or from NIS,
281*7c478bd9Sstevel@tonic-gate 	 * we are doomed !
282*7c478bd9Sstevel@tonic-gate 	 */
283*7c478bd9Sstevel@tonic-gate 	if (!master) {
284*7c478bd9Sstevel@tonic-gate 		xfr_exit(YPPUSH_MADDR);
285*7c478bd9Sstevel@tonic-gate 	}
286*7c478bd9Sstevel@tonic-gate 
287*7c478bd9Sstevel@tonic-gate 	if (!bind_to_server(master, &master_server,
288*7c478bd9Sstevel@tonic-gate 	    &master_prog_vers, &status)) {
289*7c478bd9Sstevel@tonic-gate 		xfr_exit(status);
290*7c478bd9Sstevel@tonic-gate 	}
291*7c478bd9Sstevel@tonic-gate 
292*7c478bd9Sstevel@tonic-gate 	if (!get_private_recs(&status)) {
293*7c478bd9Sstevel@tonic-gate 		xfr_exit(status);
294*7c478bd9Sstevel@tonic-gate 	}
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 	if (!master_version) {
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 		if (force) {
299*7c478bd9Sstevel@tonic-gate 			master_version = &big;
300*7c478bd9Sstevel@tonic-gate 			fake_master_version = TRUE;
301*7c478bd9Sstevel@tonic-gate 		} else {
302*7c478bd9Sstevel@tonic-gate 			logprintf(
303*7c478bd9Sstevel@tonic-gate "Can't get order number for map %s from server at %s: use the -f flag.\n",
304*7c478bd9Sstevel@tonic-gate 			    map, master);
305*7c478bd9Sstevel@tonic-gate 			xfr_exit(YPPUSH_FORCE);
306*7c478bd9Sstevel@tonic-gate 		}
307*7c478bd9Sstevel@tonic-gate 	}
308*7c478bd9Sstevel@tonic-gate 
309*7c478bd9Sstevel@tonic-gate 	if (!move_map(&status)) {
310*7c478bd9Sstevel@tonic-gate 		xfr_exit(status);
311*7c478bd9Sstevel@tonic-gate 	}
312*7c478bd9Sstevel@tonic-gate 
313*7c478bd9Sstevel@tonic-gate 	if (send_clear && !send_ypclear(&status)) {
314*7c478bd9Sstevel@tonic-gate 		xfr_exit(status);
315*7c478bd9Sstevel@tonic-gate 	}
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate 	if (logging) {
318*7c478bd9Sstevel@tonic-gate 		logprintf("Transferred map %s from %s (%d entries).\n",
319*7c478bd9Sstevel@tonic-gate 		    map, master, entry_count);
320*7c478bd9Sstevel@tonic-gate 	}
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate 	xfr_exit(YPPUSH_SUCC);
323*7c478bd9Sstevel@tonic-gate 	/* NOTREACHED */
324*7c478bd9Sstevel@tonic-gate }
325*7c478bd9Sstevel@tonic-gate 
326*7c478bd9Sstevel@tonic-gate /*
327*7c478bd9Sstevel@tonic-gate  * This decides whether we're being run interactively or not, and, if not,
328*7c478bd9Sstevel@tonic-gate  * whether we're supposed to be logging or not.  If we are logging, it sets
329*7c478bd9Sstevel@tonic-gate  * up stderr to point to the log file, and sets the "logging"
330*7c478bd9Sstevel@tonic-gate  * variable.  If there's no logging, the output goes in the bit bucket.
331*7c478bd9Sstevel@tonic-gate  * Logging output differs from interactive output in the presence of a
332*7c478bd9Sstevel@tonic-gate  * timestamp, present only in the log file.  stderr is reset, too, because it
333*7c478bd9Sstevel@tonic-gate  * it's used by various library functions, including clnt_perror.
334*7c478bd9Sstevel@tonic-gate  */
335*7c478bd9Sstevel@tonic-gate void
336*7c478bd9Sstevel@tonic-gate set_output()
337*7c478bd9Sstevel@tonic-gate {
338*7c478bd9Sstevel@tonic-gate 	if (!isatty(1)) {
339*7c478bd9Sstevel@tonic-gate 		if (access(logfile, W_OK)) {
340*7c478bd9Sstevel@tonic-gate 			(void) freopen("/dev/null", "w", stderr);
341*7c478bd9Sstevel@tonic-gate 		} else {
342*7c478bd9Sstevel@tonic-gate 			(void) freopen(logfile, "a", stderr);
343*7c478bd9Sstevel@tonic-gate 			logging = TRUE;
344*7c478bd9Sstevel@tonic-gate 		}
345*7c478bd9Sstevel@tonic-gate 	}
346*7c478bd9Sstevel@tonic-gate }
347*7c478bd9Sstevel@tonic-gate /*
348*7c478bd9Sstevel@tonic-gate  * This constructs a logging record.
349*7c478bd9Sstevel@tonic-gate  */
350*7c478bd9Sstevel@tonic-gate void
351*7c478bd9Sstevel@tonic-gate logprintf(arg1, arg2, arg3, arg4, arg5, arg6, arg7)
352*7c478bd9Sstevel@tonic-gate /*VARARGS*/
353*7c478bd9Sstevel@tonic-gate {
354*7c478bd9Sstevel@tonic-gate 	struct timeval t;
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate 	fseek(stderr, 0, 2);
357*7c478bd9Sstevel@tonic-gate 	if (logging) {
358*7c478bd9Sstevel@tonic-gate 		(void) gettimeofday(&t, NULL);
359*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%19.19s: ", ctime(&t.tv_sec));
360*7c478bd9Sstevel@tonic-gate 	}
361*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, (char *)arg1, arg2, arg3, arg4, arg5,
362*7c478bd9Sstevel@tonic-gate 				arg6, arg7);
363*7c478bd9Sstevel@tonic-gate 	fflush(stderr);
364*7c478bd9Sstevel@tonic-gate }
365*7c478bd9Sstevel@tonic-gate 
366*7c478bd9Sstevel@tonic-gate /*
367*7c478bd9Sstevel@tonic-gate  * This does the command line argument processing.
368*7c478bd9Sstevel@tonic-gate  */
369*7c478bd9Sstevel@tonic-gate void
370*7c478bd9Sstevel@tonic-gate get_command_line_args(argc, argv)
371*7c478bd9Sstevel@tonic-gate 	int argc;
372*7c478bd9Sstevel@tonic-gate 	char **argv;
373*7c478bd9Sstevel@tonic-gate 
374*7c478bd9Sstevel@tonic-gate {
375*7c478bd9Sstevel@tonic-gate 	argv++;
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate 	if (argc < 2) {
378*7c478bd9Sstevel@tonic-gate 		logprintf(err_usage);
379*7c478bd9Sstevel@tonic-gate 		xfr_exit(YPPUSH_BADARGS);
380*7c478bd9Sstevel@tonic-gate 	}
381*7c478bd9Sstevel@tonic-gate 
382*7c478bd9Sstevel@tonic-gate 	while (--argc) {
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate 		if ((*argv)[0] == '-') {
385*7c478bd9Sstevel@tonic-gate 
386*7c478bd9Sstevel@tonic-gate 			switch ((*argv)[1]) {
387*7c478bd9Sstevel@tonic-gate 
388*7c478bd9Sstevel@tonic-gate 			case 'f': {
389*7c478bd9Sstevel@tonic-gate 				force = TRUE;
390*7c478bd9Sstevel@tonic-gate 				argv++;
391*7c478bd9Sstevel@tonic-gate 				break;
392*7c478bd9Sstevel@tonic-gate 			}
393*7c478bd9Sstevel@tonic-gate 
394*7c478bd9Sstevel@tonic-gate 			case 'D': {
395*7c478bd9Sstevel@tonic-gate 				debug = TRUE;
396*7c478bd9Sstevel@tonic-gate 				argv++;
397*7c478bd9Sstevel@tonic-gate 				break;
398*7c478bd9Sstevel@tonic-gate 			}
399*7c478bd9Sstevel@tonic-gate 
400*7c478bd9Sstevel@tonic-gate 			case 'T': {
401*7c478bd9Sstevel@tonic-gate 				treepush = TRUE;
402*7c478bd9Sstevel@tonic-gate 				argv++;
403*7c478bd9Sstevel@tonic-gate 				break;
404*7c478bd9Sstevel@tonic-gate 			}
405*7c478bd9Sstevel@tonic-gate 			case 'P': {
406*7c478bd9Sstevel@tonic-gate 				check_count = TRUE;
407*7c478bd9Sstevel@tonic-gate 				argv++;
408*7c478bd9Sstevel@tonic-gate 				break;
409*7c478bd9Sstevel@tonic-gate 			}
410*7c478bd9Sstevel@tonic-gate 			case 'W': {
411*7c478bd9Sstevel@tonic-gate 				defwrite = FALSE;
412*7c478bd9Sstevel@tonic-gate 				argv++;
413*7c478bd9Sstevel@tonic-gate 				break;
414*7c478bd9Sstevel@tonic-gate 			}
415*7c478bd9Sstevel@tonic-gate 			case 'c': {
416*7c478bd9Sstevel@tonic-gate 				send_clear = FALSE;
417*7c478bd9Sstevel@tonic-gate 				argv++;
418*7c478bd9Sstevel@tonic-gate 				break;
419*7c478bd9Sstevel@tonic-gate 			}
420*7c478bd9Sstevel@tonic-gate 
421*7c478bd9Sstevel@tonic-gate 			case 'h': {
422*7c478bd9Sstevel@tonic-gate 
423*7c478bd9Sstevel@tonic-gate 				if (argc > 1) {
424*7c478bd9Sstevel@tonic-gate 					argv++;
425*7c478bd9Sstevel@tonic-gate 					argc--;
426*7c478bd9Sstevel@tonic-gate 					master = *argv;
427*7c478bd9Sstevel@tonic-gate 					argv++;
428*7c478bd9Sstevel@tonic-gate 
429*7c478bd9Sstevel@tonic-gate 					if (strlen(master) > 256) {
430*7c478bd9Sstevel@tonic-gate 						logprintf(
431*7c478bd9Sstevel@tonic-gate 						    err_bad_args,
432*7c478bd9Sstevel@tonic-gate 						    err_bad_hostname);
433*7c478bd9Sstevel@tonic-gate 						xfr_exit(YPPUSH_BADARGS);
434*7c478bd9Sstevel@tonic-gate 					}
435*7c478bd9Sstevel@tonic-gate 
436*7c478bd9Sstevel@tonic-gate 				} else {
437*7c478bd9Sstevel@tonic-gate 					logprintf(err_usage);
438*7c478bd9Sstevel@tonic-gate 					xfr_exit(YPPUSH_BADARGS);
439*7c478bd9Sstevel@tonic-gate 				}
440*7c478bd9Sstevel@tonic-gate 
441*7c478bd9Sstevel@tonic-gate 				break;
442*7c478bd9Sstevel@tonic-gate 			}
443*7c478bd9Sstevel@tonic-gate 
444*7c478bd9Sstevel@tonic-gate 			case 'd':
445*7c478bd9Sstevel@tonic-gate 				if (argc > 1) {
446*7c478bd9Sstevel@tonic-gate 					argv++;
447*7c478bd9Sstevel@tonic-gate 					argc--;
448*7c478bd9Sstevel@tonic-gate 					domain = *argv;
449*7c478bd9Sstevel@tonic-gate 					argv++;
450*7c478bd9Sstevel@tonic-gate 
451*7c478bd9Sstevel@tonic-gate 					if (strlen(domain) > YPMAXDOMAIN) {
452*7c478bd9Sstevel@tonic-gate 						logprintf(
453*7c478bd9Sstevel@tonic-gate 						    err_bad_args,
454*7c478bd9Sstevel@tonic-gate 						    err_bad_domainname);
455*7c478bd9Sstevel@tonic-gate 						xfr_exit(YPPUSH_BADARGS);
456*7c478bd9Sstevel@tonic-gate 					}
457*7c478bd9Sstevel@tonic-gate 
458*7c478bd9Sstevel@tonic-gate 				} else {
459*7c478bd9Sstevel@tonic-gate 					logprintf(err_usage);
460*7c478bd9Sstevel@tonic-gate 					xfr_exit(YPPUSH_BADARGS);
461*7c478bd9Sstevel@tonic-gate 				}
462*7c478bd9Sstevel@tonic-gate 				break;
463*7c478bd9Sstevel@tonic-gate 
464*7c478bd9Sstevel@tonic-gate 			case 's':
465*7c478bd9Sstevel@tonic-gate 				if (argc > 1) {
466*7c478bd9Sstevel@tonic-gate 					argv++;
467*7c478bd9Sstevel@tonic-gate 					argc--;
468*7c478bd9Sstevel@tonic-gate 					source = *argv;
469*7c478bd9Sstevel@tonic-gate 					argv++;
470*7c478bd9Sstevel@tonic-gate 
471*7c478bd9Sstevel@tonic-gate 					if (strlen(source) > YPMAXDOMAIN) {
472*7c478bd9Sstevel@tonic-gate 						logprintf(
473*7c478bd9Sstevel@tonic-gate 						    err_bad_args,
474*7c478bd9Sstevel@tonic-gate 						    err_bad_domainname);
475*7c478bd9Sstevel@tonic-gate 						xfr_exit(YPPUSH_BADARGS);
476*7c478bd9Sstevel@tonic-gate 					}
477*7c478bd9Sstevel@tonic-gate 
478*7c478bd9Sstevel@tonic-gate 				} else {
479*7c478bd9Sstevel@tonic-gate 					logprintf(err_usage);
480*7c478bd9Sstevel@tonic-gate 					xfr_exit(YPPUSH_BADARGS);
481*7c478bd9Sstevel@tonic-gate 				}
482*7c478bd9Sstevel@tonic-gate 				break;
483*7c478bd9Sstevel@tonic-gate 
484*7c478bd9Sstevel@tonic-gate 			case 'C':
485*7c478bd9Sstevel@tonic-gate 			    if (argc > 3) {
486*7c478bd9Sstevel@tonic-gate 				callback = TRUE;
487*7c478bd9Sstevel@tonic-gate 				tid = *(++argv);
488*7c478bd9Sstevel@tonic-gate 				proto = *(++argv);
489*7c478bd9Sstevel@tonic-gate 				pushhost = *(++argv);
490*7c478bd9Sstevel@tonic-gate 				if (strlen(pushhost) > 256) {
491*7c478bd9Sstevel@tonic-gate 				    logprintf(err_bad_args, err_bad_hostname);
492*7c478bd9Sstevel@tonic-gate 
493*7c478bd9Sstevel@tonic-gate 				    xfr_exit(YPPUSH_BADARGS);
494*7c478bd9Sstevel@tonic-gate 				}
495*7c478bd9Sstevel@tonic-gate 				argc -= 3;
496*7c478bd9Sstevel@tonic-gate 				argv++;
497*7c478bd9Sstevel@tonic-gate 			    } else {
498*7c478bd9Sstevel@tonic-gate 				logprintf(err_usage);
499*7c478bd9Sstevel@tonic-gate 				xfr_exit(YPPUSH_BADARGS);
500*7c478bd9Sstevel@tonic-gate 			    }
501*7c478bd9Sstevel@tonic-gate 			    break;
502*7c478bd9Sstevel@tonic-gate 
503*7c478bd9Sstevel@tonic-gate 			case 'b': {
504*7c478bd9Sstevel@tonic-gate 				interdomain_map = TRUE;
505*7c478bd9Sstevel@tonic-gate 				interdomain_value = "";
506*7c478bd9Sstevel@tonic-gate 				interdomain_sz = 0;
507*7c478bd9Sstevel@tonic-gate 				argv++;
508*7c478bd9Sstevel@tonic-gate 				break;
509*7c478bd9Sstevel@tonic-gate 			}
510*7c478bd9Sstevel@tonic-gate 
511*7c478bd9Sstevel@tonic-gate 
512*7c478bd9Sstevel@tonic-gate 			default: {
513*7c478bd9Sstevel@tonic-gate 				logprintf(err_usage);
514*7c478bd9Sstevel@tonic-gate 				xfr_exit(YPPUSH_BADARGS);
515*7c478bd9Sstevel@tonic-gate 			}
516*7c478bd9Sstevel@tonic-gate 
517*7c478bd9Sstevel@tonic-gate 			}
518*7c478bd9Sstevel@tonic-gate 
519*7c478bd9Sstevel@tonic-gate 		} else {
520*7c478bd9Sstevel@tonic-gate 
521*7c478bd9Sstevel@tonic-gate 			if (!map) {
522*7c478bd9Sstevel@tonic-gate 				map = *argv;
523*7c478bd9Sstevel@tonic-gate 				argv++;
524*7c478bd9Sstevel@tonic-gate 
525*7c478bd9Sstevel@tonic-gate 				if (strlen(map) > YPMAXMAP) {
526*7c478bd9Sstevel@tonic-gate 					logprintf(err_bad_args,
527*7c478bd9Sstevel@tonic-gate 					err_bad_mapname);
528*7c478bd9Sstevel@tonic-gate 					xfr_exit(YPPUSH_BADARGS);
529*7c478bd9Sstevel@tonic-gate 				}
530*7c478bd9Sstevel@tonic-gate 
531*7c478bd9Sstevel@tonic-gate 			} else {
532*7c478bd9Sstevel@tonic-gate 				logprintf(err_usage);
533*7c478bd9Sstevel@tonic-gate 				xfr_exit(YPPUSH_BADARGS);
534*7c478bd9Sstevel@tonic-gate 			}
535*7c478bd9Sstevel@tonic-gate 		}
536*7c478bd9Sstevel@tonic-gate 	}
537*7c478bd9Sstevel@tonic-gate 
538*7c478bd9Sstevel@tonic-gate 	if (!map) {
539*7c478bd9Sstevel@tonic-gate 		logprintf(err_usage);
540*7c478bd9Sstevel@tonic-gate 		xfr_exit(YPPUSH_BADARGS);
541*7c478bd9Sstevel@tonic-gate 	}
542*7c478bd9Sstevel@tonic-gate }
543*7c478bd9Sstevel@tonic-gate 
544*7c478bd9Sstevel@tonic-gate /*
545*7c478bd9Sstevel@tonic-gate  * This tries to get the master name for the named map, from any
546*7c478bd9Sstevel@tonic-gate  * server's version, using the vanilla NIS client interface.  If we get a
547*7c478bd9Sstevel@tonic-gate  * name back, the global "master" gets pointed to it.
548*7c478bd9Sstevel@tonic-gate  */
549*7c478bd9Sstevel@tonic-gate void
550*7c478bd9Sstevel@tonic-gate find_map_master()
551*7c478bd9Sstevel@tonic-gate {
552*7c478bd9Sstevel@tonic-gate 	int err;
553*7c478bd9Sstevel@tonic-gate 
554*7c478bd9Sstevel@tonic-gate 	if (err = __yp_master_rsvdport(source, map, &master)) {
555*7c478bd9Sstevel@tonic-gate 		logprintf("Can't get master of %s. Reason: %s.\n", map,
556*7c478bd9Sstevel@tonic-gate 		    yperr_string(err));
557*7c478bd9Sstevel@tonic-gate 	}
558*7c478bd9Sstevel@tonic-gate 
559*7c478bd9Sstevel@tonic-gate 	yp_unbind(source);
560*7c478bd9Sstevel@tonic-gate }
561*7c478bd9Sstevel@tonic-gate 
562*7c478bd9Sstevel@tonic-gate #ifdef TREEPUSH
563*7c478bd9Sstevel@tonic-gate chk_treepush(name)
564*7c478bd9Sstevel@tonic-gate char *name;
565*7c478bd9Sstevel@tonic-gate {
566*7c478bd9Sstevel@tonic-gate 	char inmap[256];
567*7c478bd9Sstevel@tonic-gate 	char inkey[256];
568*7c478bd9Sstevel@tonic-gate 	int inkeylen;
569*7c478bd9Sstevel@tonic-gate 	char *outval;
570*7c478bd9Sstevel@tonic-gate 	int outvallen;
571*7c478bd9Sstevel@tonic-gate 	int err;
572*7c478bd9Sstevel@tonic-gate 	outval = NULL;
573*7c478bd9Sstevel@tonic-gate 	inkey[0] = 0;
574*7c478bd9Sstevel@tonic-gate 	strcpy(inmap, "ypslaves.");
575*7c478bd9Sstevel@tonic-gate 	strcat(inmap, name);
576*7c478bd9Sstevel@tonic-gate 	gethostname(inkey, 256);
577*7c478bd9Sstevel@tonic-gate 	inkeylen = strlen(inkey);
578*7c478bd9Sstevel@tonic-gate 
579*7c478bd9Sstevel@tonic-gate 	err = yp_match(source, inmap, inkey, inkeylen, &outval, &outvallen);
580*7c478bd9Sstevel@tonic-gate 	yp_unbind(source);
581*7c478bd9Sstevel@tonic-gate 	return (err);
582*7c478bd9Sstevel@tonic-gate }
583*7c478bd9Sstevel@tonic-gate #endif
584*7c478bd9Sstevel@tonic-gate 
585*7c478bd9Sstevel@tonic-gate /*
586*7c478bd9Sstevel@tonic-gate  * This sets up a udp connection to speak the correct program and version
587*7c478bd9Sstevel@tonic-gate  * to a NIS server.  vers is set to YPVERS, doesn't give a damn about
588*7c478bd9Sstevel@tonic-gate  * YPOLDVERS.
589*7c478bd9Sstevel@tonic-gate  */
590*7c478bd9Sstevel@tonic-gate bool
591*7c478bd9Sstevel@tonic-gate bind_to_server(host, pdomb, vers, status)
592*7c478bd9Sstevel@tonic-gate 	char *host;
593*7c478bd9Sstevel@tonic-gate 	struct dom_binding *pdomb;
594*7c478bd9Sstevel@tonic-gate 	unsigned int *vers;
595*7c478bd9Sstevel@tonic-gate 	int *status;
596*7c478bd9Sstevel@tonic-gate {
597*7c478bd9Sstevel@tonic-gate 	if (ping_server(host, pdomb, YPVERS, status)) {
598*7c478bd9Sstevel@tonic-gate 		*vers = YPVERS;
599*7c478bd9Sstevel@tonic-gate 		return (TRUE);
600*7c478bd9Sstevel@tonic-gate 	} else
601*7c478bd9Sstevel@tonic-gate 		return (FALSE);
602*7c478bd9Sstevel@tonic-gate }
603*7c478bd9Sstevel@tonic-gate 
604*7c478bd9Sstevel@tonic-gate /*
605*7c478bd9Sstevel@tonic-gate  * This sets up a UDP channel to a server which is assumed to speak an input
606*7c478bd9Sstevel@tonic-gate  * version of YPPROG.  The channel is tested by pinging the server.  In all
607*7c478bd9Sstevel@tonic-gate  * error cases except "Program Version Number Mismatch", the error is
608*7c478bd9Sstevel@tonic-gate  * reported, and in all error cases, the client handle is destroyed and the
609*7c478bd9Sstevel@tonic-gate  * socket associated with the channel is closed.
610*7c478bd9Sstevel@tonic-gate  */
611*7c478bd9Sstevel@tonic-gate bool
612*7c478bd9Sstevel@tonic-gate ping_server(host, pdomb, vers, status)
613*7c478bd9Sstevel@tonic-gate 	char *host;
614*7c478bd9Sstevel@tonic-gate 	struct dom_binding *pdomb;
615*7c478bd9Sstevel@tonic-gate 	unsigned int vers;
616*7c478bd9Sstevel@tonic-gate 	int *status;
617*7c478bd9Sstevel@tonic-gate {
618*7c478bd9Sstevel@tonic-gate 	enum clnt_stat rpc_stat;
619*7c478bd9Sstevel@tonic-gate 
620*7c478bd9Sstevel@tonic-gate 	if ((pdomb->dom_client = __yp_clnt_create_rsvdport(host, YPPROG, vers,
621*7c478bd9Sstevel@tonic-gate 							0, 0, 0)) != 0) {
622*7c478bd9Sstevel@tonic-gate 
623*7c478bd9Sstevel@tonic-gate 		/*
624*7c478bd9Sstevel@tonic-gate 		 * if we are on a c2 system, we should only accept data
625*7c478bd9Sstevel@tonic-gate 		 * from a server which is on a reserved port.
626*7c478bd9Sstevel@tonic-gate 		 */
627*7c478bd9Sstevel@tonic-gate 	/*
628*7c478bd9Sstevel@tonic-gate 	 * NUKE this for 5.0DR.
629*7c478bd9Sstevel@tonic-gate 	 *
630*7c478bd9Sstevel@tonic-gate 	 *	if (issecure() &&
631*7c478bd9Sstevel@tonic-gate 	 *	    (pdomb->dom_server_addr.sin_family != AF_INET ||
632*7c478bd9Sstevel@tonic-gate 	 *	    pdomb->dom_server_addr.sin_port >= IPPORT_RESERVED)) {
633*7c478bd9Sstevel@tonic-gate 	 *		clnt_destroy(pdomb->dom_client);
634*7c478bd9Sstevel@tonic-gate 	 *		close(pdomb->dom_socket);
635*7c478bd9Sstevel@tonic-gate 	 *		(void) logprintf("bind_to_server: \
636*7c478bd9Sstevel@tonic-gate 	 *			server is not using a privileged port\n");
637*7c478bd9Sstevel@tonic-gate 	 *		*status = YPPUSH_YPERR;
638*7c478bd9Sstevel@tonic-gate 	 *		return (FALSE);
639*7c478bd9Sstevel@tonic-gate 	 *	}
640*7c478bd9Sstevel@tonic-gate 	 */
641*7c478bd9Sstevel@tonic-gate 
642*7c478bd9Sstevel@tonic-gate 		rpc_stat = clnt_call(pdomb->dom_client, YPBINDPROC_NULL,
643*7c478bd9Sstevel@tonic-gate 		    xdr_void, 0, xdr_void, 0, udp_timeout);
644*7c478bd9Sstevel@tonic-gate 
645*7c478bd9Sstevel@tonic-gate 		if (rpc_stat == RPC_SUCCESS) {
646*7c478bd9Sstevel@tonic-gate 			return (TRUE);
647*7c478bd9Sstevel@tonic-gate 		} else {
648*7c478bd9Sstevel@tonic-gate 			clnt_destroy(pdomb->dom_client);
649*7c478bd9Sstevel@tonic-gate 			if (rpc_stat != RPC_PROGVERSMISMATCH) {
650*7c478bd9Sstevel@tonic-gate 				(void) clnt_perror(pdomb->dom_client,
651*7c478bd9Sstevel@tonic-gate 				    "ypxfr: bind_to_server clnt_call error");
652*7c478bd9Sstevel@tonic-gate 			}
653*7c478bd9Sstevel@tonic-gate 
654*7c478bd9Sstevel@tonic-gate 			*status = YPPUSH_RPC;
655*7c478bd9Sstevel@tonic-gate 			return (FALSE);
656*7c478bd9Sstevel@tonic-gate 		}
657*7c478bd9Sstevel@tonic-gate 	} else {
658*7c478bd9Sstevel@tonic-gate 		logprintf("bind_to_server __clnt_create_rsvd error");
659*7c478bd9Sstevel@tonic-gate 		(void) clnt_pcreateerror("");
660*7c478bd9Sstevel@tonic-gate 		fflush(stderr);
661*7c478bd9Sstevel@tonic-gate 		*status = YPPUSH_RPC;
662*7c478bd9Sstevel@tonic-gate 		return (FALSE);
663*7c478bd9Sstevel@tonic-gate 	}
664*7c478bd9Sstevel@tonic-gate }
665*7c478bd9Sstevel@tonic-gate 
666*7c478bd9Sstevel@tonic-gate /*
667*7c478bd9Sstevel@tonic-gate  * This gets values for the YP_LAST_MODIFIED and YP_MASTER_NAME keys from the
668*7c478bd9Sstevel@tonic-gate  * master server's version of the map.  Values are held in static variables
669*7c478bd9Sstevel@tonic-gate  * here.  In the success cases, global pointer variables are set to point at
670*7c478bd9Sstevel@tonic-gate  * the local statics.
671*7c478bd9Sstevel@tonic-gate  */
672*7c478bd9Sstevel@tonic-gate bool
673*7c478bd9Sstevel@tonic-gate get_private_recs(pushstat)
674*7c478bd9Sstevel@tonic-gate 	int *pushstat;
675*7c478bd9Sstevel@tonic-gate {
676*7c478bd9Sstevel@tonic-gate 	static char anumber[20];
677*7c478bd9Sstevel@tonic-gate 	static unsigned number;
678*7c478bd9Sstevel@tonic-gate 	static char name[YPMAXPEER + 1];
679*7c478bd9Sstevel@tonic-gate 	int status;
680*7c478bd9Sstevel@tonic-gate 
681*7c478bd9Sstevel@tonic-gate 	status = 0;
682*7c478bd9Sstevel@tonic-gate 
683*7c478bd9Sstevel@tonic-gate 	if (get_order(anumber, &number, &status)) {
684*7c478bd9Sstevel@tonic-gate 		master_version = &number;
685*7c478bd9Sstevel@tonic-gate 		master_ascii_version = anumber;
686*7c478bd9Sstevel@tonic-gate 		if (debug) fprintf(stderr,
687*7c478bd9Sstevel@tonic-gate 			"ypxfr: Master Version is %s\n", master_ascii_version);
688*7c478bd9Sstevel@tonic-gate 	} else {
689*7c478bd9Sstevel@tonic-gate 
690*7c478bd9Sstevel@tonic-gate 		if (status != 0) {
691*7c478bd9Sstevel@tonic-gate 			*pushstat = status;
692*7c478bd9Sstevel@tonic-gate 			if (debug) fprintf(stderr,
693*7c478bd9Sstevel@tonic-gate 		"ypxfr: Couldn't get map's master version number, \
694*7c478bd9Sstevel@tonic-gate 		status was %d\n", status);
695*7c478bd9Sstevel@tonic-gate 			return (FALSE);
696*7c478bd9Sstevel@tonic-gate 		}
697*7c478bd9Sstevel@tonic-gate 	}
698*7c478bd9Sstevel@tonic-gate 
699*7c478bd9Sstevel@tonic-gate 	if (get_master_name(name, &status)) {
700*7c478bd9Sstevel@tonic-gate 		master_name = name;
701*7c478bd9Sstevel@tonic-gate 		if (debug) fprintf(stderr,
702*7c478bd9Sstevel@tonic-gate 			"ypxfr: Maps master is '%s'\n", master_name);
703*7c478bd9Sstevel@tonic-gate 	} else {
704*7c478bd9Sstevel@tonic-gate 
705*7c478bd9Sstevel@tonic-gate 		if (status != 0) {
706*7c478bd9Sstevel@tonic-gate 			*pushstat = status;
707*7c478bd9Sstevel@tonic-gate 			if (debug) fprintf(stderr,
708*7c478bd9Sstevel@tonic-gate 		"ypxfr: Couldn't get map's master name, status was %d\n",
709*7c478bd9Sstevel@tonic-gate 			status);
710*7c478bd9Sstevel@tonic-gate 			return (FALSE);
711*7c478bd9Sstevel@tonic-gate 		}
712*7c478bd9Sstevel@tonic-gate 		master_name = master;
713*7c478bd9Sstevel@tonic-gate 	}
714*7c478bd9Sstevel@tonic-gate 
715*7c478bd9Sstevel@tonic-gate 	if (debug)
716*7c478bd9Sstevel@tonic-gate 		fprintf(stderr,
717*7c478bd9Sstevel@tonic-gate 			"ypxfr: Getting private records from master.\n");
718*7c478bd9Sstevel@tonic-gate 	if (get_misc_recs(&status)) {
719*7c478bd9Sstevel@tonic-gate 		if (debug)
720*7c478bd9Sstevel@tonic-gate 			fprintf(stderr,
721*7c478bd9Sstevel@tonic-gate 		    "ypxfr: Masters map %s secure and %s an interdomain map.\n",
722*7c478bd9Sstevel@tonic-gate 			(secure_map) ? "is" : "is not",
723*7c478bd9Sstevel@tonic-gate 			(interdomain_map) ? "is" : "is not");
724*7c478bd9Sstevel@tonic-gate 	} else {
725*7c478bd9Sstevel@tonic-gate 		if (status != 0) {
726*7c478bd9Sstevel@tonic-gate 			*pushstat = status;
727*7c478bd9Sstevel@tonic-gate 			if (debug)
728*7c478bd9Sstevel@tonic-gate 				fprintf(stderr,
729*7c478bd9Sstevel@tonic-gate 	"ypxfr: Couldn't get state of secure and interdomain flags in map.\n");
730*7c478bd9Sstevel@tonic-gate 			return (FALSE);
731*7c478bd9Sstevel@tonic-gate 		}
732*7c478bd9Sstevel@tonic-gate 	}
733*7c478bd9Sstevel@tonic-gate 
734*7c478bd9Sstevel@tonic-gate 	return (TRUE);
735*7c478bd9Sstevel@tonic-gate }
736*7c478bd9Sstevel@tonic-gate 
737*7c478bd9Sstevel@tonic-gate /*
738*7c478bd9Sstevel@tonic-gate  * This gets the map's order number from the master server
739*7c478bd9Sstevel@tonic-gate  */
740*7c478bd9Sstevel@tonic-gate bool
741*7c478bd9Sstevel@tonic-gate get_order(an, n, pushstat)
742*7c478bd9Sstevel@tonic-gate 	char *an;
743*7c478bd9Sstevel@tonic-gate 	unsigned *n;
744*7c478bd9Sstevel@tonic-gate 	int *pushstat;
745*7c478bd9Sstevel@tonic-gate {
746*7c478bd9Sstevel@tonic-gate 	if (master_prog_vers == YPVERS) {
747*7c478bd9Sstevel@tonic-gate 		return (get_v2order(an, n, pushstat));
748*7c478bd9Sstevel@tonic-gate 	} else
749*7c478bd9Sstevel@tonic-gate 		return (FALSE);
750*7c478bd9Sstevel@tonic-gate }
751*7c478bd9Sstevel@tonic-gate 
752*7c478bd9Sstevel@tonic-gate bool
753*7c478bd9Sstevel@tonic-gate get_v2order(an, n, pushstat)
754*7c478bd9Sstevel@tonic-gate 	char *an;
755*7c478bd9Sstevel@tonic-gate 	unsigned *n;
756*7c478bd9Sstevel@tonic-gate 	int *pushstat;
757*7c478bd9Sstevel@tonic-gate {
758*7c478bd9Sstevel@tonic-gate 	struct ypreq_nokey req;
759*7c478bd9Sstevel@tonic-gate 	struct ypresp_order resp;
760*7c478bd9Sstevel@tonic-gate 	int retval;
761*7c478bd9Sstevel@tonic-gate 
762*7c478bd9Sstevel@tonic-gate 	req.domain = source;
763*7c478bd9Sstevel@tonic-gate 	req.map = map;
764*7c478bd9Sstevel@tonic-gate 
765*7c478bd9Sstevel@tonic-gate 	/*
766*7c478bd9Sstevel@tonic-gate 	 * Get the map''s order number, null-terminate it and store it,
767*7c478bd9Sstevel@tonic-gate 	 * and convert it to binary and store it again.
768*7c478bd9Sstevel@tonic-gate 	 */
769*7c478bd9Sstevel@tonic-gate 	retval = FALSE;
770*7c478bd9Sstevel@tonic-gate 
771*7c478bd9Sstevel@tonic-gate 	if ((enum clnt_stat) clnt_call(master_server.dom_client,
772*7c478bd9Sstevel@tonic-gate 	    YPPROC_ORDER, (xdrproc_t)xdr_ypreq_nokey, (char *)&req,
773*7c478bd9Sstevel@tonic-gate 	    (xdrproc_t)xdr_ypresp_order, (char *)&resp,
774*7c478bd9Sstevel@tonic-gate 	    udp_timeout) == RPC_SUCCESS) {
775*7c478bd9Sstevel@tonic-gate 
776*7c478bd9Sstevel@tonic-gate 		if (resp.status == YP_TRUE) {
777*7c478bd9Sstevel@tonic-gate 			sprintf(an, "%d", resp.ordernum);
778*7c478bd9Sstevel@tonic-gate 			*n = resp.ordernum;
779*7c478bd9Sstevel@tonic-gate 			retval = TRUE;
780*7c478bd9Sstevel@tonic-gate 		} else if (resp.status != YP_BADDB) {
781*7c478bd9Sstevel@tonic-gate 			*pushstat = ypprot_err(resp.status);
782*7c478bd9Sstevel@tonic-gate 
783*7c478bd9Sstevel@tonic-gate 			if (!logging) {
784*7c478bd9Sstevel@tonic-gate 				logprintf(
785*7c478bd9Sstevel@tonic-gate 	"(info) Can't get order number from ypserv at %s.  Reason: %s.\n",
786*7c478bd9Sstevel@tonic-gate 				    master, yperr_string(
787*7c478bd9Sstevel@tonic-gate 				    ypprot_err(resp.status)));
788*7c478bd9Sstevel@tonic-gate 			}
789*7c478bd9Sstevel@tonic-gate 		}
790*7c478bd9Sstevel@tonic-gate 
791*7c478bd9Sstevel@tonic-gate 		CLNT_FREERES(master_server.dom_client,
792*7c478bd9Sstevel@tonic-gate 			(xdrproc_t)xdr_ypresp_order,
793*7c478bd9Sstevel@tonic-gate 		    (char *)&resp);
794*7c478bd9Sstevel@tonic-gate 	} else {
795*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_RPC;
796*7c478bd9Sstevel@tonic-gate 		logprintf("ypxfr(get_v2order) RPC call to %s failed", master);
797*7c478bd9Sstevel@tonic-gate 		clnt_perror(master_server.dom_client, "");
798*7c478bd9Sstevel@tonic-gate 	}
799*7c478bd9Sstevel@tonic-gate 
800*7c478bd9Sstevel@tonic-gate 	return (retval);
801*7c478bd9Sstevel@tonic-gate }
802*7c478bd9Sstevel@tonic-gate 
803*7c478bd9Sstevel@tonic-gate /*
804*7c478bd9Sstevel@tonic-gate  * Pick up the state of the YP_SECURE and YP_INTERDOMAIN records from the
805*7c478bd9Sstevel@tonic-gate  * master. Only works on 4.0 V2 masters that will match a YP_ private key
806*7c478bd9Sstevel@tonic-gate  * when asked to explicitly.
807*7c478bd9Sstevel@tonic-gate  */
808*7c478bd9Sstevel@tonic-gate bool
809*7c478bd9Sstevel@tonic-gate get_misc_recs(pushstat)
810*7c478bd9Sstevel@tonic-gate 	int *pushstat;
811*7c478bd9Sstevel@tonic-gate {
812*7c478bd9Sstevel@tonic-gate 	struct ypreq_key req;
813*7c478bd9Sstevel@tonic-gate 	struct ypresp_val resp;
814*7c478bd9Sstevel@tonic-gate 	int retval;
815*7c478bd9Sstevel@tonic-gate 
816*7c478bd9Sstevel@tonic-gate 	req.domain = source;
817*7c478bd9Sstevel@tonic-gate 	req.map = map;
818*7c478bd9Sstevel@tonic-gate 	req.keydat.dptr   = yp_secure;
819*7c478bd9Sstevel@tonic-gate 	req.keydat.dsize  = yp_secure_sz;
820*7c478bd9Sstevel@tonic-gate 
821*7c478bd9Sstevel@tonic-gate 	resp.valdat.dptr = NULL;
822*7c478bd9Sstevel@tonic-gate 	resp.valdat.dsize = 0;
823*7c478bd9Sstevel@tonic-gate 
824*7c478bd9Sstevel@tonic-gate 	/*
825*7c478bd9Sstevel@tonic-gate 	 * Get the value of the IS_SECURE key in the map.
826*7c478bd9Sstevel@tonic-gate 	 */
827*7c478bd9Sstevel@tonic-gate 	retval = FALSE;
828*7c478bd9Sstevel@tonic-gate 
829*7c478bd9Sstevel@tonic-gate 	if (debug)
830*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "ypxfr: Checking masters secure key.\n");
831*7c478bd9Sstevel@tonic-gate 	if ((enum clnt_stat) clnt_call(master_server.dom_client,
832*7c478bd9Sstevel@tonic-gate 	    YPPROC_MATCH, (xdrproc_t)xdr_ypreq_key, (char *)&req,
833*7c478bd9Sstevel@tonic-gate 	(xdrproc_t)xdr_ypresp_val, (char *)&resp,
834*7c478bd9Sstevel@tonic-gate 	    udp_timeout) == RPC_SUCCESS) {
835*7c478bd9Sstevel@tonic-gate 		if (resp.status == YP_TRUE) {
836*7c478bd9Sstevel@tonic-gate 			if (debug)
837*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, "ypxfr: SECURE\n");
838*7c478bd9Sstevel@tonic-gate 			secure_map = TRUE;
839*7c478bd9Sstevel@tonic-gate 			retval = TRUE;
840*7c478bd9Sstevel@tonic-gate 		} else if ((resp.status != YP_NOKEY) &&
841*7c478bd9Sstevel@tonic-gate 			    (resp.status != YP_VERS) &&
842*7c478bd9Sstevel@tonic-gate 			    (resp.status != YP_NOMORE)) {
843*7c478bd9Sstevel@tonic-gate 			*pushstat = ypprot_err(resp.status);
844*7c478bd9Sstevel@tonic-gate 
845*7c478bd9Sstevel@tonic-gate 			if (!logging) {
846*7c478bd9Sstevel@tonic-gate 				logprintf(
847*7c478bd9Sstevel@tonic-gate 	"(info) Can't get secure flag from ypserv at %s.  Reason: %s.\n",
848*7c478bd9Sstevel@tonic-gate 				    master, yperr_string(
849*7c478bd9Sstevel@tonic-gate 				    ypprot_err(resp.status)));
850*7c478bd9Sstevel@tonic-gate 			}
851*7c478bd9Sstevel@tonic-gate 		}
852*7c478bd9Sstevel@tonic-gate 
853*7c478bd9Sstevel@tonic-gate 		CLNT_FREERES(master_server.dom_client,
854*7c478bd9Sstevel@tonic-gate 			(xdrproc_t)xdr_ypresp_val,
855*7c478bd9Sstevel@tonic-gate 		    (char *)&resp);
856*7c478bd9Sstevel@tonic-gate 	} else {
857*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_RPC;
858*7c478bd9Sstevel@tonic-gate 		logprintf("ypxfr(get_misc_recs) RPC call to %s failed", master);
859*7c478bd9Sstevel@tonic-gate 		clnt_perror(master_server.dom_client, "");
860*7c478bd9Sstevel@tonic-gate 	}
861*7c478bd9Sstevel@tonic-gate 
862*7c478bd9Sstevel@tonic-gate 	if (debug)
863*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "ypxfr: Checking masters INTERDOMAIN key.\n");
864*7c478bd9Sstevel@tonic-gate 	req.keydat.dptr   = yp_interdomain;
865*7c478bd9Sstevel@tonic-gate 	req.keydat.dsize  = yp_interdomain_sz;
866*7c478bd9Sstevel@tonic-gate 
867*7c478bd9Sstevel@tonic-gate 	resp.valdat.dptr = NULL;
868*7c478bd9Sstevel@tonic-gate 	resp.valdat.dsize = 0;
869*7c478bd9Sstevel@tonic-gate 
870*7c478bd9Sstevel@tonic-gate 	/*
871*7c478bd9Sstevel@tonic-gate 	 * Get the value of the INTERDOMAIN key in the map.
872*7c478bd9Sstevel@tonic-gate 	 */
873*7c478bd9Sstevel@tonic-gate 
874*7c478bd9Sstevel@tonic-gate 	if ((enum clnt_stat) clnt_call(master_server.dom_client,
875*7c478bd9Sstevel@tonic-gate 	    YPPROC_MATCH, (xdrproc_t)xdr_ypreq_key, (char *)&req,
876*7c478bd9Sstevel@tonic-gate 	(xdrproc_t)xdr_ypresp_val, (char *)&resp,
877*7c478bd9Sstevel@tonic-gate 	    udp_timeout) == RPC_SUCCESS) {
878*7c478bd9Sstevel@tonic-gate 		if (resp.status == YP_TRUE) {
879*7c478bd9Sstevel@tonic-gate 			if (debug)
880*7c478bd9Sstevel@tonic-gate 				fprintf(stderr, "ypxfr: INTERDOMAIN\n");
881*7c478bd9Sstevel@tonic-gate 			interdomain_map = TRUE;
882*7c478bd9Sstevel@tonic-gate 			interdomain_value = (char *)malloc(resp.valdat.dsize+1);
883*7c478bd9Sstevel@tonic-gate 			(void) memmove(interdomain_value, resp.valdat.dptr,
884*7c478bd9Sstevel@tonic-gate 					resp.valdat.dsize);
885*7c478bd9Sstevel@tonic-gate 			*(interdomain_value+resp.valdat.dsize) = '\0';
886*7c478bd9Sstevel@tonic-gate 			interdomain_sz = resp.valdat.dsize;
887*7c478bd9Sstevel@tonic-gate 			retval = TRUE;
888*7c478bd9Sstevel@tonic-gate 		} else if ((resp.status != YP_NOKEY) &&
889*7c478bd9Sstevel@tonic-gate 			    (resp.status != YP_VERS) &&
890*7c478bd9Sstevel@tonic-gate 			    (resp.status != YP_NOMORE)) {
891*7c478bd9Sstevel@tonic-gate 			*pushstat = ypprot_err(resp.status);
892*7c478bd9Sstevel@tonic-gate 
893*7c478bd9Sstevel@tonic-gate 			if (!logging) {
894*7c478bd9Sstevel@tonic-gate 				logprintf(
895*7c478bd9Sstevel@tonic-gate 	"(info) Can't get interdomain flag from ypserv at %s.  Reason: %s.\n",
896*7c478bd9Sstevel@tonic-gate 				    master, yperr_string(
897*7c478bd9Sstevel@tonic-gate 				    ypprot_err(resp.status)));
898*7c478bd9Sstevel@tonic-gate 			}
899*7c478bd9Sstevel@tonic-gate 		}
900*7c478bd9Sstevel@tonic-gate 
901*7c478bd9Sstevel@tonic-gate 		CLNT_FREERES(master_server.dom_client,
902*7c478bd9Sstevel@tonic-gate 			(xdrproc_t)xdr_ypresp_val,
903*7c478bd9Sstevel@tonic-gate 		    (char *)&resp);
904*7c478bd9Sstevel@tonic-gate 	} else {
905*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_RPC;
906*7c478bd9Sstevel@tonic-gate 		logprintf("ypxfr(get_misc_recs) RPC call to %s failed", master);
907*7c478bd9Sstevel@tonic-gate 		clnt_perror(master_server.dom_client, "");
908*7c478bd9Sstevel@tonic-gate 	}
909*7c478bd9Sstevel@tonic-gate 
910*7c478bd9Sstevel@tonic-gate 
911*7c478bd9Sstevel@tonic-gate 	return (retval);
912*7c478bd9Sstevel@tonic-gate }
913*7c478bd9Sstevel@tonic-gate 
914*7c478bd9Sstevel@tonic-gate /*
915*7c478bd9Sstevel@tonic-gate  * This gets the map's master name from the master server
916*7c478bd9Sstevel@tonic-gate  */
917*7c478bd9Sstevel@tonic-gate bool
918*7c478bd9Sstevel@tonic-gate get_master_name(name, pushstat)
919*7c478bd9Sstevel@tonic-gate 	char *name;
920*7c478bd9Sstevel@tonic-gate 	int *pushstat;
921*7c478bd9Sstevel@tonic-gate {
922*7c478bd9Sstevel@tonic-gate 	if (master_prog_vers == YPVERS) {
923*7c478bd9Sstevel@tonic-gate 		return (get_v2master_name(name, pushstat));
924*7c478bd9Sstevel@tonic-gate 	} else
925*7c478bd9Sstevel@tonic-gate 		return (FALSE);
926*7c478bd9Sstevel@tonic-gate }
927*7c478bd9Sstevel@tonic-gate 
928*7c478bd9Sstevel@tonic-gate bool
929*7c478bd9Sstevel@tonic-gate get_v2master_name(name, pushstat)
930*7c478bd9Sstevel@tonic-gate 	char *name;
931*7c478bd9Sstevel@tonic-gate 	int *pushstat;
932*7c478bd9Sstevel@tonic-gate {
933*7c478bd9Sstevel@tonic-gate 	struct ypreq_nokey req;
934*7c478bd9Sstevel@tonic-gate 	struct ypresp_master resp;
935*7c478bd9Sstevel@tonic-gate 	int retval;
936*7c478bd9Sstevel@tonic-gate 
937*7c478bd9Sstevel@tonic-gate 	req.domain = source;
938*7c478bd9Sstevel@tonic-gate 	req.map = map;
939*7c478bd9Sstevel@tonic-gate 	resp.master = NULL;
940*7c478bd9Sstevel@tonic-gate 	retval = FALSE;
941*7c478bd9Sstevel@tonic-gate 
942*7c478bd9Sstevel@tonic-gate 	if ((enum clnt_stat) clnt_call(master_server.dom_client,
943*7c478bd9Sstevel@tonic-gate 	    YPPROC_MASTER, (xdrproc_t)xdr_ypreq_nokey, (char *)&req,
944*7c478bd9Sstevel@tonic-gate 	    (xdrproc_t)xdr_ypresp_master, (char *)&resp,
945*7c478bd9Sstevel@tonic-gate 	    udp_timeout) == RPC_SUCCESS) {
946*7c478bd9Sstevel@tonic-gate 
947*7c478bd9Sstevel@tonic-gate 		if (resp.status == YP_TRUE) {
948*7c478bd9Sstevel@tonic-gate 			strcpy(name, resp.master);
949*7c478bd9Sstevel@tonic-gate 			retval = TRUE;
950*7c478bd9Sstevel@tonic-gate 		} else if (resp.status != YP_BADDB) {
951*7c478bd9Sstevel@tonic-gate 			*pushstat = ypprot_err(resp.status);
952*7c478bd9Sstevel@tonic-gate 
953*7c478bd9Sstevel@tonic-gate 			if (!logging) {
954*7c478bd9Sstevel@tonic-gate 				logprintf(
955*7c478bd9Sstevel@tonic-gate "(info) Can't get master name from ypserv at %s. Reason: %s.\n",
956*7c478bd9Sstevel@tonic-gate 				    master, yperr_string(
957*7c478bd9Sstevel@tonic-gate 				    ypprot_err(resp.status)));
958*7c478bd9Sstevel@tonic-gate 			}
959*7c478bd9Sstevel@tonic-gate 		}
960*7c478bd9Sstevel@tonic-gate 
961*7c478bd9Sstevel@tonic-gate 		CLNT_FREERES(master_server.dom_client,
962*7c478bd9Sstevel@tonic-gate 			(xdrproc_t)xdr_ypresp_master,
963*7c478bd9Sstevel@tonic-gate 		    (char *)&resp);
964*7c478bd9Sstevel@tonic-gate 	} else {
965*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_RPC;
966*7c478bd9Sstevel@tonic-gate 		logprintf(
967*7c478bd9Sstevel@tonic-gate 		    "ypxfr(get_v2master_name) RPC call to %s failed", master);
968*7c478bd9Sstevel@tonic-gate 		clnt_perror(master_server.dom_client, "");
969*7c478bd9Sstevel@tonic-gate 	}
970*7c478bd9Sstevel@tonic-gate 
971*7c478bd9Sstevel@tonic-gate 	return (retval);
972*7c478bd9Sstevel@tonic-gate }
973*7c478bd9Sstevel@tonic-gate 
974*7c478bd9Sstevel@tonic-gate /*
975*7c478bd9Sstevel@tonic-gate  * This does the work of transferring the map.
976*7c478bd9Sstevel@tonic-gate  */
977*7c478bd9Sstevel@tonic-gate bool
978*7c478bd9Sstevel@tonic-gate move_map(pushstat)
979*7c478bd9Sstevel@tonic-gate 	int *pushstat;
980*7c478bd9Sstevel@tonic-gate {
981*7c478bd9Sstevel@tonic-gate 	unsigned local_version;
982*7c478bd9Sstevel@tonic-gate 	char map_name[MAXNAMLEN + 1];
983*7c478bd9Sstevel@tonic-gate 	char tmp_name[MAXNAMLEN + 1];
984*7c478bd9Sstevel@tonic-gate 	char bkup_name[MAXNAMLEN + 1];
985*7c478bd9Sstevel@tonic-gate 	char an[11];
986*7c478bd9Sstevel@tonic-gate 	unsigned n;
987*7c478bd9Sstevel@tonic-gate 	datum key;
988*7c478bd9Sstevel@tonic-gate 	datum val;
989*7c478bd9Sstevel@tonic-gate 	int  hgstatus;
990*7c478bd9Sstevel@tonic-gate 
991*7c478bd9Sstevel@tonic-gate 	mkfilename(map_name);
992*7c478bd9Sstevel@tonic-gate 
993*7c478bd9Sstevel@tonic-gate 	if (!force) {
994*7c478bd9Sstevel@tonic-gate 		local_version = get_local_version(map_name);
995*7c478bd9Sstevel@tonic-gate 		if (debug) fprintf(stderr,
996*7c478bd9Sstevel@tonic-gate 			"ypxfr: Local version of map '%s' is %d\n",
997*7c478bd9Sstevel@tonic-gate 			map_name, local_version);
998*7c478bd9Sstevel@tonic-gate 
999*7c478bd9Sstevel@tonic-gate 		if (local_version >= *master_version) {
1000*7c478bd9Sstevel@tonic-gate 			logprintf(
1001*7c478bd9Sstevel@tonic-gate 			    "Map %s at %s is not more recent than local.\n",
1002*7c478bd9Sstevel@tonic-gate 			    map, master);
1003*7c478bd9Sstevel@tonic-gate 			*pushstat = YPPUSH_AGE;
1004*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1005*7c478bd9Sstevel@tonic-gate 		}
1006*7c478bd9Sstevel@tonic-gate 	}
1007*7c478bd9Sstevel@tonic-gate 
1008*7c478bd9Sstevel@tonic-gate 	mk_tmpname(yptempname_prefix, tmp_name);
1009*7c478bd9Sstevel@tonic-gate 
1010*7c478bd9Sstevel@tonic-gate 	if (!new_mapfiles(tmp_name)) {
1011*7c478bd9Sstevel@tonic-gate 		logprintf(
1012*7c478bd9Sstevel@tonic-gate 		    "Can't create temp map %s.\n", tmp_name);
1013*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_FILE;
1014*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1015*7c478bd9Sstevel@tonic-gate 	}
1016*7c478bd9Sstevel@tonic-gate 
1017*7c478bd9Sstevel@tonic-gate 	if ((hgstatus = ypxfrd_getdbm(tmp_name, master, source, map)) < 0)
1018*7c478bd9Sstevel@tonic-gate 	{
1019*7c478bd9Sstevel@tonic-gate 	logprintf(
1020*7c478bd9Sstevel@tonic-gate "(info) %s %s %s ypxfrd getdbm failed (reason = %d) -- using ypxfr\n",
1021*7c478bd9Sstevel@tonic-gate 		master, domain, map, hgstatus);
1022*7c478bd9Sstevel@tonic-gate 
1023*7c478bd9Sstevel@tonic-gate 	    db = dbm_open(tmp_name, O_RDWR + O_CREAT + O_TRUNC, 0644);
1024*7c478bd9Sstevel@tonic-gate 	if (db == NULL) {
1025*7c478bd9Sstevel@tonic-gate 		logprintf(
1026*7c478bd9Sstevel@tonic-gate 		    "Can't dbm init temp map %s.\n", tmp_name);
1027*7c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
1028*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
1029*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1030*7c478bd9Sstevel@tonic-gate 	}
1031*7c478bd9Sstevel@tonic-gate 	if (defwrite) dbm_setdefwrite(db);
1032*7c478bd9Sstevel@tonic-gate 
1033*7c478bd9Sstevel@tonic-gate 	if (!get_map(tmp_name, pushstat)) {
1034*7c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
1035*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1036*7c478bd9Sstevel@tonic-gate 	}
1037*7c478bd9Sstevel@tonic-gate 
1038*7c478bd9Sstevel@tonic-gate 	if (!add_private_entries(tmp_name)) {
1039*7c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
1040*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
1041*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1042*7c478bd9Sstevel@tonic-gate 	}
1043*7c478bd9Sstevel@tonic-gate 
1044*7c478bd9Sstevel@tonic-gate 	/*
1045*7c478bd9Sstevel@tonic-gate 	 * Decide whether the map just transferred is a secure map.
1046*7c478bd9Sstevel@tonic-gate 	 * If we already know the local version was secure, we do not
1047*7c478bd9Sstevel@tonic-gate 	 * need to check this version.
1048*7c478bd9Sstevel@tonic-gate 	 */
1049*7c478bd9Sstevel@tonic-gate 	if (!secure_map) {
1050*7c478bd9Sstevel@tonic-gate 		key.dptr = yp_secure;
1051*7c478bd9Sstevel@tonic-gate 		key.dsize = yp_secure_sz;
1052*7c478bd9Sstevel@tonic-gate 		val = dbm_fetch(db, key);
1053*7c478bd9Sstevel@tonic-gate 		if (val.dptr != NULL) {
1054*7c478bd9Sstevel@tonic-gate 			secure_map = TRUE;
1055*7c478bd9Sstevel@tonic-gate 		}
1056*7c478bd9Sstevel@tonic-gate 	}
1057*7c478bd9Sstevel@tonic-gate 
1058*7c478bd9Sstevel@tonic-gate 	if (dbm_close_status(db) < 0) {
1059*7c478bd9Sstevel@tonic-gate 		logprintf(
1060*7c478bd9Sstevel@tonic-gate 		    "Can't do dbm close operation on temp map %s.\n",
1061*7c478bd9Sstevel@tonic-gate 		    tmp_name);
1062*7c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
1063*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
1064*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1065*7c478bd9Sstevel@tonic-gate 	}
1066*7c478bd9Sstevel@tonic-gate 
1067*7c478bd9Sstevel@tonic-gate 	if (!get_order(an, &n, pushstat)) {
1068*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1069*7c478bd9Sstevel@tonic-gate 	}
1070*7c478bd9Sstevel@tonic-gate 	if (n != *master_version) {
1071*7c478bd9Sstevel@tonic-gate 		logprintf(
1072*7c478bd9Sstevel@tonic-gate 		    "Version skew at %s while transferring map %s.\n",
1073*7c478bd9Sstevel@tonic-gate 		    master, map);
1074*7c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
1075*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_SKEW;
1076*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1077*7c478bd9Sstevel@tonic-gate 	}
1078*7c478bd9Sstevel@tonic-gate 
1079*7c478bd9Sstevel@tonic-gate 	if (check_count)
1080*7c478bd9Sstevel@tonic-gate 	if (!count_mismatch(tmp_name, entry_count)) {
1081*7c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
1082*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
1083*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1084*7c478bd9Sstevel@tonic-gate 	}
1085*7c478bd9Sstevel@tonic-gate 	} else {
1086*7c478bd9Sstevel@tonic-gate 	/* touch up the map */
1087*7c478bd9Sstevel@tonic-gate 	    db = dbm_open(tmp_name, 2, 0644);
1088*7c478bd9Sstevel@tonic-gate 	if (db == NULL) {
1089*7c478bd9Sstevel@tonic-gate 		logprintf(
1090*7c478bd9Sstevel@tonic-gate 		    "Can't dbm init temp map %s.\n", tmp_name);
1091*7c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
1092*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
1093*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1094*7c478bd9Sstevel@tonic-gate 		}
1095*7c478bd9Sstevel@tonic-gate 
1096*7c478bd9Sstevel@tonic-gate 
1097*7c478bd9Sstevel@tonic-gate 	if (!add_private_entries(tmp_name)) {
1098*7c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
1099*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
1100*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1101*7c478bd9Sstevel@tonic-gate 	}
1102*7c478bd9Sstevel@tonic-gate 
1103*7c478bd9Sstevel@tonic-gate 	/*
1104*7c478bd9Sstevel@tonic-gate 	 * Decide whether the map just transferred is a secure map.
1105*7c478bd9Sstevel@tonic-gate 	 * If we already know the local version was secure, we do not
1106*7c478bd9Sstevel@tonic-gate 	 * need to check this version.
1107*7c478bd9Sstevel@tonic-gate 	 */
1108*7c478bd9Sstevel@tonic-gate 	if (!secure_map) {
1109*7c478bd9Sstevel@tonic-gate 		key.dptr = yp_secure;
1110*7c478bd9Sstevel@tonic-gate 		key.dsize = yp_secure_sz;
1111*7c478bd9Sstevel@tonic-gate 		val = dbm_fetch(db, key);
1112*7c478bd9Sstevel@tonic-gate 		if (val.dptr != NULL) {
1113*7c478bd9Sstevel@tonic-gate 			secure_map = TRUE;
1114*7c478bd9Sstevel@tonic-gate 		}
1115*7c478bd9Sstevel@tonic-gate 	}
1116*7c478bd9Sstevel@tonic-gate 
1117*7c478bd9Sstevel@tonic-gate 	if (dbm_close_status(db) < 0) {
1118*7c478bd9Sstevel@tonic-gate 		logprintf(
1119*7c478bd9Sstevel@tonic-gate 		    "Can't do dbm close operation on temp map %s.\n",
1120*7c478bd9Sstevel@tonic-gate 		    tmp_name);
1121*7c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
1122*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_DBM;
1123*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1124*7c478bd9Sstevel@tonic-gate 	}
1125*7c478bd9Sstevel@tonic-gate 
1126*7c478bd9Sstevel@tonic-gate 	}
1127*7c478bd9Sstevel@tonic-gate 
1128*7c478bd9Sstevel@tonic-gate 	if (lock_map(map_name) == 0) {
1129*7c478bd9Sstevel@tonic-gate 		del_mapfiles(tmp_name);
1130*7c478bd9Sstevel@tonic-gate 		logprintf("Lock error on %s\n", map_name);
1131*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_FILE;
1132*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1133*7c478bd9Sstevel@tonic-gate 	}
1134*7c478bd9Sstevel@tonic-gate 	if (!check_map_existence(map_name)) {
1135*7c478bd9Sstevel@tonic-gate 
1136*7c478bd9Sstevel@tonic-gate 		if (!rename_map(tmp_name, map_name, secure_map)) {
1137*7c478bd9Sstevel@tonic-gate 			del_mapfiles(tmp_name);
1138*7c478bd9Sstevel@tonic-gate 			logprintf(
1139*7c478bd9Sstevel@tonic-gate 			    "Rename error:  couldn't mv %s to %s.\n",
1140*7c478bd9Sstevel@tonic-gate 			    tmp_name, map_name);
1141*7c478bd9Sstevel@tonic-gate 			*pushstat = YPPUSH_FILE;
1142*7c478bd9Sstevel@tonic-gate 			unlock_map(map_name);
1143*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1144*7c478bd9Sstevel@tonic-gate 		}
1145*7c478bd9Sstevel@tonic-gate 
1146*7c478bd9Sstevel@tonic-gate 	} else {
1147*7c478bd9Sstevel@tonic-gate 		mk_tmpname(ypbkupname_prefix, bkup_name);
1148*7c478bd9Sstevel@tonic-gate 
1149*7c478bd9Sstevel@tonic-gate 		if (!rename_map(map_name, bkup_name, secure_map)) {
1150*7c478bd9Sstevel@tonic-gate 			(void) rename_map(bkup_name, map_name, secure_map);
1151*7c478bd9Sstevel@tonic-gate 			logprintf(
1152*7c478bd9Sstevel@tonic-gate 		"Rename error:  check that old %s is still intact.\n",
1153*7c478bd9Sstevel@tonic-gate 		map_name);
1154*7c478bd9Sstevel@tonic-gate 			del_mapfiles(tmp_name);
1155*7c478bd9Sstevel@tonic-gate 			*pushstat = YPPUSH_FILE;
1156*7c478bd9Sstevel@tonic-gate 			unlock_map(map_name);
1157*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1158*7c478bd9Sstevel@tonic-gate 		}
1159*7c478bd9Sstevel@tonic-gate 
1160*7c478bd9Sstevel@tonic-gate 		if (rename_map(tmp_name, map_name, secure_map)) {
1161*7c478bd9Sstevel@tonic-gate 			del_mapfiles(bkup_name);
1162*7c478bd9Sstevel@tonic-gate 		} else {
1163*7c478bd9Sstevel@tonic-gate 			del_mapfiles(tmp_name);
1164*7c478bd9Sstevel@tonic-gate 			(void) rename_map(bkup_name, map_name, secure_map);
1165*7c478bd9Sstevel@tonic-gate 				logprintf(
1166*7c478bd9Sstevel@tonic-gate 		"Rename error:  check that old %s is still intact.\n",
1167*7c478bd9Sstevel@tonic-gate 			    map_name);
1168*7c478bd9Sstevel@tonic-gate 			*pushstat = YPPUSH_FILE;
1169*7c478bd9Sstevel@tonic-gate 			unlock_map(map_name);
1170*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1171*7c478bd9Sstevel@tonic-gate 		}
1172*7c478bd9Sstevel@tonic-gate 	}
1173*7c478bd9Sstevel@tonic-gate 	if (unlock_map(map_name) == 0)
1174*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1175*7c478bd9Sstevel@tonic-gate 
1176*7c478bd9Sstevel@tonic-gate 	return (TRUE);
1177*7c478bd9Sstevel@tonic-gate }
1178*7c478bd9Sstevel@tonic-gate 
1179*7c478bd9Sstevel@tonic-gate /*
1180*7c478bd9Sstevel@tonic-gate  * This tries to get the order number out of the local version of the map.
1181*7c478bd9Sstevel@tonic-gate  * If the attempt fails for any version, the function will return "0"
1182*7c478bd9Sstevel@tonic-gate  */
1183*7c478bd9Sstevel@tonic-gate unsigned
1184*7c478bd9Sstevel@tonic-gate get_local_version(name)
1185*7c478bd9Sstevel@tonic-gate 	char *name;
1186*7c478bd9Sstevel@tonic-gate {
1187*7c478bd9Sstevel@tonic-gate 	datum key;
1188*7c478bd9Sstevel@tonic-gate 	datum val;
1189*7c478bd9Sstevel@tonic-gate 	char number[11];
1190*7c478bd9Sstevel@tonic-gate 	DBM *db;
1191*7c478bd9Sstevel@tonic-gate 
1192*7c478bd9Sstevel@tonic-gate 	if (!check_map_existence(name)) {
1193*7c478bd9Sstevel@tonic-gate 		return (0);
1194*7c478bd9Sstevel@tonic-gate 	}
1195*7c478bd9Sstevel@tonic-gate 	if (debug) fprintf(stderr,
1196*7c478bd9Sstevel@tonic-gate 		"ypxfr: Map does exist, checking version now.\n");
1197*7c478bd9Sstevel@tonic-gate 
1198*7c478bd9Sstevel@tonic-gate 	if ((db = dbm_open(name, 0, 0)) == 0) {
1199*7c478bd9Sstevel@tonic-gate 		return (0);
1200*7c478bd9Sstevel@tonic-gate 	}
1201*7c478bd9Sstevel@tonic-gate 
1202*7c478bd9Sstevel@tonic-gate 	key.dptr = yp_last_modified;
1203*7c478bd9Sstevel@tonic-gate 	key.dsize = yp_last_modified_sz;
1204*7c478bd9Sstevel@tonic-gate 	val = dbm_fetch(db, key);
1205*7c478bd9Sstevel@tonic-gate 	if (!val.dptr) {	/* Check to see if dptr is NULL */
1206*7c478bd9Sstevel@tonic-gate 		return (0);
1207*7c478bd9Sstevel@tonic-gate 	}
1208*7c478bd9Sstevel@tonic-gate 	if (val.dsize == 0 || val.dsize > 10) {
1209*7c478bd9Sstevel@tonic-gate 		return (0);
1210*7c478bd9Sstevel@tonic-gate 	}
1211*7c478bd9Sstevel@tonic-gate 	/* Now save this value while we have it available */
1212*7c478bd9Sstevel@tonic-gate 	(void) memmove(number, val.dptr, val.dsize);
1213*7c478bd9Sstevel@tonic-gate 	number[val.dsize] = '\0';
1214*7c478bd9Sstevel@tonic-gate 
1215*7c478bd9Sstevel@tonic-gate 	/*
1216*7c478bd9Sstevel@tonic-gate 	 * Now check to see if it is 'secure'. If we haven't already
1217*7c478bd9Sstevel@tonic-gate 	 * determined that it is secure in get_private_recs() then we check
1218*7c478bd9Sstevel@tonic-gate 	 * the local map here.
1219*7c478bd9Sstevel@tonic-gate 	 */
1220*7c478bd9Sstevel@tonic-gate 	if (!secure_map) {
1221*7c478bd9Sstevel@tonic-gate 		key.dptr = yp_secure;
1222*7c478bd9Sstevel@tonic-gate 		key.dsize = yp_secure_sz;
1223*7c478bd9Sstevel@tonic-gate 		val = dbm_fetch(db, key);
1224*7c478bd9Sstevel@tonic-gate 		secure_map = (val.dptr != NULL);
1225*7c478bd9Sstevel@tonic-gate 	}
1226*7c478bd9Sstevel@tonic-gate 
1227*7c478bd9Sstevel@tonic-gate 	/*
1228*7c478bd9Sstevel@tonic-gate 	 * Now check to see if interdomain requests are made of the local
1229*7c478bd9Sstevel@tonic-gate 	 * map. Keep the value around if they are.
1230*7c478bd9Sstevel@tonic-gate 	 */
1231*7c478bd9Sstevel@tonic-gate 	if (!interdomain_map) {
1232*7c478bd9Sstevel@tonic-gate 		key.dptr = yp_interdomain;
1233*7c478bd9Sstevel@tonic-gate 		key.dsize = yp_interdomain_sz;
1234*7c478bd9Sstevel@tonic-gate 		val = dbm_fetch(db, key);
1235*7c478bd9Sstevel@tonic-gate 		if (interdomain_map = (val.dptr != NULL)) {
1236*7c478bd9Sstevel@tonic-gate 			interdomain_value = (char *)malloc(val.dsize+1);
1237*7c478bd9Sstevel@tonic-gate 			(void) memmove(interdomain_value, val.dptr, val.dsize);
1238*7c478bd9Sstevel@tonic-gate 			*(interdomain_value+val.dsize) = '\0';
1239*7c478bd9Sstevel@tonic-gate 			interdomain_sz = val.dsize;
1240*7c478bd9Sstevel@tonic-gate 		}
1241*7c478bd9Sstevel@tonic-gate 	}
1242*7c478bd9Sstevel@tonic-gate 
1243*7c478bd9Sstevel@tonic-gate 	/* finish up */
1244*7c478bd9Sstevel@tonic-gate 	(void) dbm_close_status(db);
1245*7c478bd9Sstevel@tonic-gate 
1246*7c478bd9Sstevel@tonic-gate 	return ((unsigned)atoi(number));
1247*7c478bd9Sstevel@tonic-gate }
1248*7c478bd9Sstevel@tonic-gate 
1249*7c478bd9Sstevel@tonic-gate /*
1250*7c478bd9Sstevel@tonic-gate  * This constructs a file name for a map, minus its dbm_dir
1251*7c478bd9Sstevel@tonic-gate  * or dbm_pag extensions
1252*7c478bd9Sstevel@tonic-gate  */
1253*7c478bd9Sstevel@tonic-gate void
1254*7c478bd9Sstevel@tonic-gate mkfilename(ppath)
1255*7c478bd9Sstevel@tonic-gate 	char *ppath;
1256*7c478bd9Sstevel@tonic-gate {
1257*7c478bd9Sstevel@tonic-gate 	bool_t yptol_mode;
1258*7c478bd9Sstevel@tonic-gate 	int len;
1259*7c478bd9Sstevel@tonic-gate 
1260*7c478bd9Sstevel@tonic-gate 	/* Work out if we are in yptol mode */
1261*7c478bd9Sstevel@tonic-gate 	yptol_mode = is_yptol_mode();
1262*7c478bd9Sstevel@tonic-gate 
1263*7c478bd9Sstevel@tonic-gate 	len = strlen(domain) + strlen(map) + strlen(ypdbpath) + 3;
1264*7c478bd9Sstevel@tonic-gate 	if (yptol_mode)
1265*7c478bd9Sstevel@tonic-gate 		len += strlen(NTOL_PREFIX);
1266*7c478bd9Sstevel@tonic-gate 
1267*7c478bd9Sstevel@tonic-gate 	if (len > (MAXNAMLEN + 1)) {
1268*7c478bd9Sstevel@tonic-gate 		logprintf("Map name string too long.\n");
1269*7c478bd9Sstevel@tonic-gate 	}
1270*7c478bd9Sstevel@tonic-gate 
1271*7c478bd9Sstevel@tonic-gate 	(void) strcpy(ppath, ypdbpath);
1272*7c478bd9Sstevel@tonic-gate 	(void) strcat(ppath, "/");
1273*7c478bd9Sstevel@tonic-gate 	(void) strcat(ppath, domain);
1274*7c478bd9Sstevel@tonic-gate 	(void) strcat(ppath, "/");
1275*7c478bd9Sstevel@tonic-gate 	if (yptol_mode)
1276*7c478bd9Sstevel@tonic-gate 		(void) strcat(ppath, NTOL_PREFIX);
1277*7c478bd9Sstevel@tonic-gate 	(void) strcat(ppath, map);
1278*7c478bd9Sstevel@tonic-gate }
1279*7c478bd9Sstevel@tonic-gate 
1280*7c478bd9Sstevel@tonic-gate /*
1281*7c478bd9Sstevel@tonic-gate  * This returns a temporary name for a map transfer minus its dbm_dir or
1282*7c478bd9Sstevel@tonic-gate  * dbm_pag extensions.
1283*7c478bd9Sstevel@tonic-gate  */
1284*7c478bd9Sstevel@tonic-gate void
1285*7c478bd9Sstevel@tonic-gate mk_tmpname(prefix, xfr_name)
1286*7c478bd9Sstevel@tonic-gate 	char *prefix;
1287*7c478bd9Sstevel@tonic-gate 	char *xfr_name;
1288*7c478bd9Sstevel@tonic-gate {
1289*7c478bd9Sstevel@tonic-gate 	char xfr_anumber[10];
1290*7c478bd9Sstevel@tonic-gate 	long xfr_number;
1291*7c478bd9Sstevel@tonic-gate 
1292*7c478bd9Sstevel@tonic-gate 	if (!xfr_name) {
1293*7c478bd9Sstevel@tonic-gate 		return;
1294*7c478bd9Sstevel@tonic-gate 	}
1295*7c478bd9Sstevel@tonic-gate 
1296*7c478bd9Sstevel@tonic-gate 	xfr_number = getpid();
1297*7c478bd9Sstevel@tonic-gate 	(void) sprintf(xfr_anumber, "%d", xfr_number);
1298*7c478bd9Sstevel@tonic-gate 
1299*7c478bd9Sstevel@tonic-gate 	(void) strcpy(xfr_name, ypdbpath);
1300*7c478bd9Sstevel@tonic-gate 	(void) strcat(xfr_name, "/");
1301*7c478bd9Sstevel@tonic-gate 	(void) strcat(xfr_name, domain);
1302*7c478bd9Sstevel@tonic-gate 	(void) strcat(xfr_name, "/");
1303*7c478bd9Sstevel@tonic-gate 	(void) strcat(xfr_name, prefix);
1304*7c478bd9Sstevel@tonic-gate 	(void) strcat(xfr_name, map);
1305*7c478bd9Sstevel@tonic-gate 	(void) strcat(xfr_name, ".");
1306*7c478bd9Sstevel@tonic-gate 	(void) strcat(xfr_name, xfr_anumber);
1307*7c478bd9Sstevel@tonic-gate }
1308*7c478bd9Sstevel@tonic-gate 
1309*7c478bd9Sstevel@tonic-gate /*
1310*7c478bd9Sstevel@tonic-gate  * This deletes the .pag and .dir files which implement a map.
1311*7c478bd9Sstevel@tonic-gate  *
1312*7c478bd9Sstevel@tonic-gate  * Note:  No error checking is done here for a garbage input file name or for
1313*7c478bd9Sstevel@tonic-gate  * failed unlink operations.
1314*7c478bd9Sstevel@tonic-gate  */
1315*7c478bd9Sstevel@tonic-gate void
1316*7c478bd9Sstevel@tonic-gate del_mapfiles(basename)
1317*7c478bd9Sstevel@tonic-gate 	char *basename;
1318*7c478bd9Sstevel@tonic-gate {
1319*7c478bd9Sstevel@tonic-gate 	char dbfilename[MAXNAMLEN + 1];
1320*7c478bd9Sstevel@tonic-gate 
1321*7c478bd9Sstevel@tonic-gate 	if (!basename) {
1322*7c478bd9Sstevel@tonic-gate 		return;
1323*7c478bd9Sstevel@tonic-gate 	}
1324*7c478bd9Sstevel@tonic-gate 
1325*7c478bd9Sstevel@tonic-gate 	strcpy(dbfilename, basename);
1326*7c478bd9Sstevel@tonic-gate 	strcat(dbfilename, dbm_pag);
1327*7c478bd9Sstevel@tonic-gate 	unlink(dbfilename);
1328*7c478bd9Sstevel@tonic-gate 	strcpy(dbfilename, basename);
1329*7c478bd9Sstevel@tonic-gate 	strcat(dbfilename, dbm_dir);
1330*7c478bd9Sstevel@tonic-gate 	unlink(dbfilename);
1331*7c478bd9Sstevel@tonic-gate }
1332*7c478bd9Sstevel@tonic-gate 
1333*7c478bd9Sstevel@tonic-gate /*
1334*7c478bd9Sstevel@tonic-gate  * This creates <pname>.dir and <pname>.pag
1335*7c478bd9Sstevel@tonic-gate  */
1336*7c478bd9Sstevel@tonic-gate bool
1337*7c478bd9Sstevel@tonic-gate new_mapfiles(pname)
1338*7c478bd9Sstevel@tonic-gate 	char *pname;
1339*7c478bd9Sstevel@tonic-gate {
1340*7c478bd9Sstevel@tonic-gate 	char dbfile[MAXNAMLEN + 1];
1341*7c478bd9Sstevel@tonic-gate 	int f;
1342*7c478bd9Sstevel@tonic-gate 	int len;
1343*7c478bd9Sstevel@tonic-gate 
1344*7c478bd9Sstevel@tonic-gate 	if (!pname || ((len = strlen(pname)) == 0) ||
1345*7c478bd9Sstevel@tonic-gate 	    (len + 5) > (MAXNAMLEN + 1)) {
1346*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1347*7c478bd9Sstevel@tonic-gate 	}
1348*7c478bd9Sstevel@tonic-gate 
1349*7c478bd9Sstevel@tonic-gate 	errno = 0;
1350*7c478bd9Sstevel@tonic-gate 	(void) strcpy(dbfile, pname);
1351*7c478bd9Sstevel@tonic-gate 	(void) strcat(dbfile, dbm_dir);
1352*7c478bd9Sstevel@tonic-gate 
1353*7c478bd9Sstevel@tonic-gate 	if ((f = open(dbfile, (O_WRONLY | O_CREAT | O_TRUNC), 0600)) >= 0) {
1354*7c478bd9Sstevel@tonic-gate 		(void) close(f);
1355*7c478bd9Sstevel@tonic-gate 		(void) strcpy(dbfile, pname);
1356*7c478bd9Sstevel@tonic-gate 		(void) strcat(dbfile, dbm_pag);
1357*7c478bd9Sstevel@tonic-gate 
1358*7c478bd9Sstevel@tonic-gate 		if ((f = open(dbfile, (O_WRONLY | O_CREAT | O_TRUNC),
1359*7c478bd9Sstevel@tonic-gate 		    0600)) >= 0) {
1360*7c478bd9Sstevel@tonic-gate 			(void) close(f);
1361*7c478bd9Sstevel@tonic-gate 			return (TRUE);
1362*7c478bd9Sstevel@tonic-gate 		} else {
1363*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1364*7c478bd9Sstevel@tonic-gate 		}
1365*7c478bd9Sstevel@tonic-gate 
1366*7c478bd9Sstevel@tonic-gate 	} else {
1367*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1368*7c478bd9Sstevel@tonic-gate 	}
1369*7c478bd9Sstevel@tonic-gate }
1370*7c478bd9Sstevel@tonic-gate 
1371*7c478bd9Sstevel@tonic-gate count_callback(status)
1372*7c478bd9Sstevel@tonic-gate 	int status;
1373*7c478bd9Sstevel@tonic-gate {
1374*7c478bd9Sstevel@tonic-gate 	if (status != YP_TRUE) {
1375*7c478bd9Sstevel@tonic-gate 
1376*7c478bd9Sstevel@tonic-gate 		if (status != YP_NOMORE) {
1377*7c478bd9Sstevel@tonic-gate 			logprintf(
1378*7c478bd9Sstevel@tonic-gate 			    "Error from ypserv on %s (ypall_callback) = %s.\n",
1379*7c478bd9Sstevel@tonic-gate 			    master, yperr_string(ypprot_err(status)));
1380*7c478bd9Sstevel@tonic-gate 		}
1381*7c478bd9Sstevel@tonic-gate 
1382*7c478bd9Sstevel@tonic-gate 		return (TRUE);
1383*7c478bd9Sstevel@tonic-gate 	}
1384*7c478bd9Sstevel@tonic-gate 
1385*7c478bd9Sstevel@tonic-gate 	entry_count++;
1386*7c478bd9Sstevel@tonic-gate 	return (FALSE);
1387*7c478bd9Sstevel@tonic-gate }
1388*7c478bd9Sstevel@tonic-gate 
1389*7c478bd9Sstevel@tonic-gate /*
1390*7c478bd9Sstevel@tonic-gate  * This counts the entries in the dbm file after the transfer to
1391*7c478bd9Sstevel@tonic-gate  * make sure that the dbm file was built correctly.
1392*7c478bd9Sstevel@tonic-gate  * Returns TRUE if everything is OK, FALSE if they mismatch.
1393*7c478bd9Sstevel@tonic-gate  */
1394*7c478bd9Sstevel@tonic-gate count_mismatch(pname, oldcount)
1395*7c478bd9Sstevel@tonic-gate 	char *pname;
1396*7c478bd9Sstevel@tonic-gate 	int oldcount;
1397*7c478bd9Sstevel@tonic-gate {
1398*7c478bd9Sstevel@tonic-gate 	datum key;
1399*7c478bd9Sstevel@tonic-gate 	DBM *db;
1400*7c478bd9Sstevel@tonic-gate #ifdef REALLY_PARANOID
1401*7c478bd9Sstevel@tonic-gate 	struct ypall_callback cbinfo;
1402*7c478bd9Sstevel@tonic-gate 	struct ypreq_nokey allreq;
1403*7c478bd9Sstevel@tonic-gate 	enum clnt_stat s;
1404*7c478bd9Sstevel@tonic-gate 	struct dom_binding domb;
1405*7c478bd9Sstevel@tonic-gate 	datum value;
1406*7c478bd9Sstevel@tonic-gate #endif /* REALLY_PARANOID */
1407*7c478bd9Sstevel@tonic-gate 
1408*7c478bd9Sstevel@tonic-gate 	entry_count = 0;
1409*7c478bd9Sstevel@tonic-gate 	db = dbm_open(pname, 0, 0);
1410*7c478bd9Sstevel@tonic-gate 	if (db) {
1411*7c478bd9Sstevel@tonic-gate 	    for (key = dbm_firstkey(db);
1412*7c478bd9Sstevel@tonic-gate 				key.dptr != NULL; key = dbm_nextkey(db))
1413*7c478bd9Sstevel@tonic-gate 		entry_count++;
1414*7c478bd9Sstevel@tonic-gate 	    dbm_close_status(db);
1415*7c478bd9Sstevel@tonic-gate 	}
1416*7c478bd9Sstevel@tonic-gate 
1417*7c478bd9Sstevel@tonic-gate 	if (oldcount != entry_count) {
1418*7c478bd9Sstevel@tonic-gate 	logprintf(
1419*7c478bd9Sstevel@tonic-gate 		    "*** Count mismatch in dbm file %s: old=%d, new=%d ***\n",
1420*7c478bd9Sstevel@tonic-gate 		    map, oldcount, entry_count);
1421*7c478bd9Sstevel@tonic-gate 	return (FALSE);
1422*7c478bd9Sstevel@tonic-gate 	}
1423*7c478bd9Sstevel@tonic-gate 
1424*7c478bd9Sstevel@tonic-gate #ifdef REALLY_PARANOID
1425*7c478bd9Sstevel@tonic-gate 
1426*7c478bd9Sstevel@tonic-gate 	if ((domb.dom_client = __yp_clnt_create_rsvdport(master, YPPROG,
1427*7c478bd9Sstevel@tonic-gate 						    master_prog_vers,
1428*7c478bd9Sstevel@tonic-gate 						    "tcp6", 0, 0)) == 0 &&
1429*7c478bd9Sstevel@tonic-gate 		(domb.dom_client = __yp_clnt_create_rsvdport(master, YPPROG,
1430*7c478bd9Sstevel@tonic-gate 						    master_prog_vers,
1431*7c478bd9Sstevel@tonic-gate 						    "tcp", 0, 0)) == 0) {
1432*7c478bd9Sstevel@tonic-gate 		clnt_pcreateerror("ypxfr (mismatch) - TCP channel "
1433*7c478bd9Sstevel@tonic-gate 					"create failure");
1434*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1435*7c478bd9Sstevel@tonic-gate 	}
1436*7c478bd9Sstevel@tonic-gate 
1437*7c478bd9Sstevel@tonic-gate 	if (master_prog_vers == YPVERS) {
1438*7c478bd9Sstevel@tonic-gate 		int tmpstat;
1439*7c478bd9Sstevel@tonic-gate 
1440*7c478bd9Sstevel@tonic-gate 		allreq.domain = source;
1441*7c478bd9Sstevel@tonic-gate 		allreq.map = map;
1442*7c478bd9Sstevel@tonic-gate 		cbinfo.foreach = count_callback;
1443*7c478bd9Sstevel@tonic-gate 		tmpstat = 0;
1444*7c478bd9Sstevel@tonic-gate 		cbinfo.data = (char *)&tmpstat;
1445*7c478bd9Sstevel@tonic-gate 
1446*7c478bd9Sstevel@tonic-gate 		entry_count = 0;
1447*7c478bd9Sstevel@tonic-gate 		s = clnt_call(domb.dom_client, YPPROC_ALL, xdr_ypreq_nokey,
1448*7c478bd9Sstevel@tonic-gate 		    &allreq, xdr_ypall, &cbinfo, tcp_timeout);
1449*7c478bd9Sstevel@tonic-gate 
1450*7c478bd9Sstevel@tonic-gate 		if (tmpstat == 0) {
1451*7c478bd9Sstevel@tonic-gate 			if (s == RPC_SUCCESS) {
1452*7c478bd9Sstevel@tonic-gate 			} else {
1453*7c478bd9Sstevel@tonic-gate 				clnt_perror(domb.dom_client,
1454*7c478bd9Sstevel@tonic-gate 		"ypxfr (get_map/all) - RPC clnt_call (TCP) failure");
1455*7c478bd9Sstevel@tonic-gate 		    return (FALSE);
1456*7c478bd9Sstevel@tonic-gate 			}
1457*7c478bd9Sstevel@tonic-gate 
1458*7c478bd9Sstevel@tonic-gate 		} else {
1459*7c478bd9Sstevel@tonic-gate 		    return (FALSE);
1460*7c478bd9Sstevel@tonic-gate 		}
1461*7c478bd9Sstevel@tonic-gate 
1462*7c478bd9Sstevel@tonic-gate 	} else {
1463*7c478bd9Sstevel@tonic-gate 	    logprintf("Wrong version number!\n");
1464*7c478bd9Sstevel@tonic-gate 	    return (FALSE);
1465*7c478bd9Sstevel@tonic-gate 	}
1466*7c478bd9Sstevel@tonic-gate 	clnt_destroy(domb.dom_client);
1467*7c478bd9Sstevel@tonic-gate 	close(domb.dom_socket);
1468*7c478bd9Sstevel@tonic-gate 	entry_count += 2;			/* add in YP_entries */
1469*7c478bd9Sstevel@tonic-gate 	if (oldcount != entry_count) {
1470*7c478bd9Sstevel@tonic-gate 		logprintf(
1471*7c478bd9Sstevel@tonic-gate 	"*** Count mismatch after enumerate %s: old=%d, new=%d ***\n",
1472*7c478bd9Sstevel@tonic-gate 		    map, oldcount, entry_count);
1473*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1474*7c478bd9Sstevel@tonic-gate 	}
1475*7c478bd9Sstevel@tonic-gate #endif /* REALLY_PARANOID */
1476*7c478bd9Sstevel@tonic-gate 
1477*7c478bd9Sstevel@tonic-gate 	return (TRUE);
1478*7c478bd9Sstevel@tonic-gate }
1479*7c478bd9Sstevel@tonic-gate 
1480*7c478bd9Sstevel@tonic-gate /*
1481*7c478bd9Sstevel@tonic-gate  * This sets up a TCP connection to the master server, and either gets
1482*7c478bd9Sstevel@tonic-gate  * ypall_callback to do all the work of writing it to the local dbm file
1483*7c478bd9Sstevel@tonic-gate  * (if the ypserv is current version), or does it itself for an old ypserv.
1484*7c478bd9Sstevel@tonic-gate  */
1485*7c478bd9Sstevel@tonic-gate bool
1486*7c478bd9Sstevel@tonic-gate get_map(pname, pushstat)
1487*7c478bd9Sstevel@tonic-gate 	char *pname;
1488*7c478bd9Sstevel@tonic-gate 	int *pushstat;
1489*7c478bd9Sstevel@tonic-gate {
1490*7c478bd9Sstevel@tonic-gate 	struct dom_binding domb;
1491*7c478bd9Sstevel@tonic-gate 	enum clnt_stat s;
1492*7c478bd9Sstevel@tonic-gate 	struct ypreq_nokey allreq;
1493*7c478bd9Sstevel@tonic-gate 	struct ypall_callback cbinfo;
1494*7c478bd9Sstevel@tonic-gate 	bool retval = FALSE;
1495*7c478bd9Sstevel@tonic-gate 	int tmpstat;
1496*7c478bd9Sstevel@tonic-gate 	int	recvsiz = 24 * 1024;
1497*7c478bd9Sstevel@tonic-gate 	struct netconfig *nconf;
1498*7c478bd9Sstevel@tonic-gate 	int fd;
1499*7c478bd9Sstevel@tonic-gate 	struct netbuf *svcaddr;
1500*7c478bd9Sstevel@tonic-gate 	char *netid[] = { "tcp6", "tcp" };
1501*7c478bd9Sstevel@tonic-gate 	int i, lastnetid = (sizeof (netid)/sizeof (netid[0])) - 1;
1502*7c478bd9Sstevel@tonic-gate 
1503*7c478bd9Sstevel@tonic-gate 	svcaddr = (struct netbuf *)calloc(1, sizeof (struct netbuf));
1504*7c478bd9Sstevel@tonic-gate 	if (! svcaddr)
1505*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1506*7c478bd9Sstevel@tonic-gate 	svcaddr->maxlen = 32;
1507*7c478bd9Sstevel@tonic-gate 	svcaddr->len = 32;
1508*7c478bd9Sstevel@tonic-gate 	svcaddr->buf = (char *)malloc(32);
1509*7c478bd9Sstevel@tonic-gate 	if (! svcaddr->buf) {
1510*7c478bd9Sstevel@tonic-gate 		free(svcaddr);
1511*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1512*7c478bd9Sstevel@tonic-gate 	}
1513*7c478bd9Sstevel@tonic-gate 
1514*7c478bd9Sstevel@tonic-gate 	for (i = 0; i <= lastnetid; i++) {
1515*7c478bd9Sstevel@tonic-gate 		fd = RPC_ANYFD;
1516*7c478bd9Sstevel@tonic-gate 		if ((nconf = getnetconfigent(netid[i])) == NULL) {
1517*7c478bd9Sstevel@tonic-gate 			if (i != lastnetid)
1518*7c478bd9Sstevel@tonic-gate 				continue;
1519*7c478bd9Sstevel@tonic-gate 			logprintf("ypxfr: tcp transport not supported\n");
1520*7c478bd9Sstevel@tonic-gate 			free(svcaddr->buf);
1521*7c478bd9Sstevel@tonic-gate 			free(svcaddr);
1522*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1523*7c478bd9Sstevel@tonic-gate 		}
1524*7c478bd9Sstevel@tonic-gate 		if (rpcb_getaddr(YPPROG, master_prog_vers, nconf, svcaddr,
1525*7c478bd9Sstevel@tonic-gate 				master) == FALSE) {
1526*7c478bd9Sstevel@tonic-gate 			freenetconfigent(nconf);
1527*7c478bd9Sstevel@tonic-gate 			if (i != lastnetid)
1528*7c478bd9Sstevel@tonic-gate 				continue;
1529*7c478bd9Sstevel@tonic-gate 			logprintf("ypxfr: could not get %s address\n", master);
1530*7c478bd9Sstevel@tonic-gate 			free(svcaddr->buf);
1531*7c478bd9Sstevel@tonic-gate 			free(svcaddr);
1532*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1533*7c478bd9Sstevel@tonic-gate 		}
1534*7c478bd9Sstevel@tonic-gate 		if ((domb.dom_client = __nis_clnt_create(fd, nconf, 0, svcaddr,
1535*7c478bd9Sstevel@tonic-gate 			0, YPPROG, master_prog_vers, recvsiz, 0)) == 0) {
1536*7c478bd9Sstevel@tonic-gate 			freenetconfigent(nconf);
1537*7c478bd9Sstevel@tonic-gate 			if (i != lastnetid)
1538*7c478bd9Sstevel@tonic-gate 				continue;
1539*7c478bd9Sstevel@tonic-gate 			clnt_pcreateerror(
1540*7c478bd9Sstevel@tonic-gate 				"ypxfr (get_map) - TCP channel create failure");
1541*7c478bd9Sstevel@tonic-gate 			*pushstat = YPPUSH_RPC;
1542*7c478bd9Sstevel@tonic-gate 			free(svcaddr->buf);
1543*7c478bd9Sstevel@tonic-gate 			free(svcaddr);
1544*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1545*7c478bd9Sstevel@tonic-gate 		}
1546*7c478bd9Sstevel@tonic-gate 		break;
1547*7c478bd9Sstevel@tonic-gate 	}
1548*7c478bd9Sstevel@tonic-gate 
1549*7c478bd9Sstevel@tonic-gate 	entry_count = 0;
1550*7c478bd9Sstevel@tonic-gate 	if (master_prog_vers == YPVERS) {
1551*7c478bd9Sstevel@tonic-gate 		allreq.domain = source;
1552*7c478bd9Sstevel@tonic-gate 		allreq.map = map;
1553*7c478bd9Sstevel@tonic-gate 		cbinfo.foreach = ypall_callback;
1554*7c478bd9Sstevel@tonic-gate 		tmpstat = 0;
1555*7c478bd9Sstevel@tonic-gate 		cbinfo.data = (char *)&tmpstat;
1556*7c478bd9Sstevel@tonic-gate 
1557*7c478bd9Sstevel@tonic-gate 		s = clnt_call(domb.dom_client, YPPROC_ALL,
1558*7c478bd9Sstevel@tonic-gate 			(xdrproc_t)xdr_ypreq_nokey,
1559*7c478bd9Sstevel@tonic-gate 			(char *)&allreq, (xdrproc_t)xdr_ypall, (char *)&cbinfo,
1560*7c478bd9Sstevel@tonic-gate 			tcp_timeout);
1561*7c478bd9Sstevel@tonic-gate 
1562*7c478bd9Sstevel@tonic-gate 		if (tmpstat == 0) {
1563*7c478bd9Sstevel@tonic-gate 
1564*7c478bd9Sstevel@tonic-gate 			if (s == RPC_SUCCESS) {
1565*7c478bd9Sstevel@tonic-gate 				retval = TRUE;
1566*7c478bd9Sstevel@tonic-gate 			} else {
1567*7c478bd9Sstevel@tonic-gate 				clnt_perror(domb.dom_client,
1568*7c478bd9Sstevel@tonic-gate 			"ypxfr (get_map/all) - RPC clnt_call (TCP) failure");
1569*7c478bd9Sstevel@tonic-gate 				*pushstat = YPPUSH_RPC;
1570*7c478bd9Sstevel@tonic-gate 			}
1571*7c478bd9Sstevel@tonic-gate 
1572*7c478bd9Sstevel@tonic-gate 		} else {
1573*7c478bd9Sstevel@tonic-gate 			*pushstat = tmpstat;
1574*7c478bd9Sstevel@tonic-gate 		}
1575*7c478bd9Sstevel@tonic-gate 
1576*7c478bd9Sstevel@tonic-gate 	} else
1577*7c478bd9Sstevel@tonic-gate 		retval = FALSE; /* barf again at YPOLDVERS */
1578*7c478bd9Sstevel@tonic-gate cleanup:
1579*7c478bd9Sstevel@tonic-gate 	clnt_destroy(domb.dom_client);
1580*7c478bd9Sstevel@tonic-gate 	return (retval);
1581*7c478bd9Sstevel@tonic-gate }
1582*7c478bd9Sstevel@tonic-gate 
1583*7c478bd9Sstevel@tonic-gate /*
1584*7c478bd9Sstevel@tonic-gate  * This sticks each key-value pair into the current map.  It returns FALSE as
1585*7c478bd9Sstevel@tonic-gate  * long as it wants to keep getting called back, and TRUE on error conditions
1586*7c478bd9Sstevel@tonic-gate  * and "No more k-v pairs".
1587*7c478bd9Sstevel@tonic-gate  */
1588*7c478bd9Sstevel@tonic-gate int
1589*7c478bd9Sstevel@tonic-gate ypall_callback(status, key, kl, val, vl, pushstat)
1590*7c478bd9Sstevel@tonic-gate 	int status;
1591*7c478bd9Sstevel@tonic-gate 	char *key;
1592*7c478bd9Sstevel@tonic-gate 	int kl;
1593*7c478bd9Sstevel@tonic-gate 	char *val;
1594*7c478bd9Sstevel@tonic-gate 	int vl;
1595*7c478bd9Sstevel@tonic-gate 	int *pushstat;
1596*7c478bd9Sstevel@tonic-gate {
1597*7c478bd9Sstevel@tonic-gate 	datum keydat;
1598*7c478bd9Sstevel@tonic-gate 	datum valdat;
1599*7c478bd9Sstevel@tonic-gate 	datum test;
1600*7c478bd9Sstevel@tonic-gate 
1601*7c478bd9Sstevel@tonic-gate 	if (status != YP_TRUE) {
1602*7c478bd9Sstevel@tonic-gate 
1603*7c478bd9Sstevel@tonic-gate 		if (status != YP_NOMORE) {
1604*7c478bd9Sstevel@tonic-gate 			logprintf(
1605*7c478bd9Sstevel@tonic-gate 			    "Error from ypserv on %s (ypall_callback) = %s.\n",
1606*7c478bd9Sstevel@tonic-gate 			    master, yperr_string(ypprot_err(status)));
1607*7c478bd9Sstevel@tonic-gate 			*pushstat = map_yperr_to_pusherr(status);
1608*7c478bd9Sstevel@tonic-gate 		}
1609*7c478bd9Sstevel@tonic-gate 
1610*7c478bd9Sstevel@tonic-gate 		return (TRUE);
1611*7c478bd9Sstevel@tonic-gate 	}
1612*7c478bd9Sstevel@tonic-gate 
1613*7c478bd9Sstevel@tonic-gate 	keydat.dptr = key;
1614*7c478bd9Sstevel@tonic-gate 	keydat.dsize = kl;
1615*7c478bd9Sstevel@tonic-gate 	valdat.dptr = val;
1616*7c478bd9Sstevel@tonic-gate 	valdat.dsize = vl;
1617*7c478bd9Sstevel@tonic-gate 	entry_count++;
1618*7c478bd9Sstevel@tonic-gate /* way too many fetches */
1619*7c478bd9Sstevel@tonic-gate 
1620*7c478bd9Sstevel@tonic-gate #ifdef PARANOID
1621*7c478bd9Sstevel@tonic-gate 	test = dbm_fetch(db, keydat);
1622*7c478bd9Sstevel@tonic-gate 	if (test.dptr != NULL) {
1623*7c478bd9Sstevel@tonic-gate 		logprintf("Duplicate key %s in map %s\n", key, map);
1624*7c478bd9Sstevel@tonic-gate 		*pushstat  = YPPUSH_DBM;
1625*7c478bd9Sstevel@tonic-gate 		return (TRUE);
1626*7c478bd9Sstevel@tonic-gate 	}
1627*7c478bd9Sstevel@tonic-gate #endif /* PARANOID */
1628*7c478bd9Sstevel@tonic-gate 	if (dbm_store(db, keydat, valdat, 0) < 0) {
1629*7c478bd9Sstevel@tonic-gate 		logprintf(
1630*7c478bd9Sstevel@tonic-gate 		    "Can't do dbm store into temp map %s.\n", map);
1631*7c478bd9Sstevel@tonic-gate 		*pushstat  = YPPUSH_DBM;
1632*7c478bd9Sstevel@tonic-gate 		return (TRUE);
1633*7c478bd9Sstevel@tonic-gate 	}
1634*7c478bd9Sstevel@tonic-gate #ifdef PARANOID
1635*7c478bd9Sstevel@tonic-gate 	test = dbm_fetch(db, keydat);
1636*7c478bd9Sstevel@tonic-gate 	if (test.dptr == NULL) {
1637*7c478bd9Sstevel@tonic-gate 		logprintf("Key %s was not inserted into dbm file %s\n",
1638*7c478bd9Sstevel@tonic-gate 			key, map);
1639*7c478bd9Sstevel@tonic-gate 		*pushstat  = YPPUSH_DBM;
1640*7c478bd9Sstevel@tonic-gate 		return (TRUE);
1641*7c478bd9Sstevel@tonic-gate 	}
1642*7c478bd9Sstevel@tonic-gate #endif /* PARANOID */
1643*7c478bd9Sstevel@tonic-gate 
1644*7c478bd9Sstevel@tonic-gate 	if (dbm_error(db)) {
1645*7c478bd9Sstevel@tonic-gate 		logprintf("Key %s dbm_error raised in file %s\n",
1646*7c478bd9Sstevel@tonic-gate 			key, map);
1647*7c478bd9Sstevel@tonic-gate 		*pushstat  = YPPUSH_DBM;
1648*7c478bd9Sstevel@tonic-gate 		return (TRUE);
1649*7c478bd9Sstevel@tonic-gate 	}
1650*7c478bd9Sstevel@tonic-gate 	return (FALSE);
1651*7c478bd9Sstevel@tonic-gate }
1652*7c478bd9Sstevel@tonic-gate 
1653*7c478bd9Sstevel@tonic-gate /*
1654*7c478bd9Sstevel@tonic-gate  * This maps a YP_xxxx error code into a YPPUSH_xxxx error code
1655*7c478bd9Sstevel@tonic-gate  */
1656*7c478bd9Sstevel@tonic-gate int
1657*7c478bd9Sstevel@tonic-gate map_yperr_to_pusherr(yperr)
1658*7c478bd9Sstevel@tonic-gate 	int yperr;
1659*7c478bd9Sstevel@tonic-gate {
1660*7c478bd9Sstevel@tonic-gate 	int reason;
1661*7c478bd9Sstevel@tonic-gate 
1662*7c478bd9Sstevel@tonic-gate 	switch (yperr) {
1663*7c478bd9Sstevel@tonic-gate 
1664*7c478bd9Sstevel@tonic-gate 	case YP_NOMORE:
1665*7c478bd9Sstevel@tonic-gate 		reason = YPPUSH_SUCC;
1666*7c478bd9Sstevel@tonic-gate 		break;
1667*7c478bd9Sstevel@tonic-gate 
1668*7c478bd9Sstevel@tonic-gate 	case YP_NOMAP:
1669*7c478bd9Sstevel@tonic-gate 		reason = YPPUSH_NOMAP;
1670*7c478bd9Sstevel@tonic-gate 		break;
1671*7c478bd9Sstevel@tonic-gate 
1672*7c478bd9Sstevel@tonic-gate 	case YP_NODOM:
1673*7c478bd9Sstevel@tonic-gate 		reason = YPPUSH_NODOM;
1674*7c478bd9Sstevel@tonic-gate 		break;
1675*7c478bd9Sstevel@tonic-gate 
1676*7c478bd9Sstevel@tonic-gate 	case YP_NOKEY:
1677*7c478bd9Sstevel@tonic-gate 		reason = YPPUSH_YPERR;
1678*7c478bd9Sstevel@tonic-gate 		break;
1679*7c478bd9Sstevel@tonic-gate 
1680*7c478bd9Sstevel@tonic-gate 	case YP_BADARGS:
1681*7c478bd9Sstevel@tonic-gate 		reason = YPPUSH_BADARGS;
1682*7c478bd9Sstevel@tonic-gate 		break;
1683*7c478bd9Sstevel@tonic-gate 
1684*7c478bd9Sstevel@tonic-gate 	case YP_BADDB:
1685*7c478bd9Sstevel@tonic-gate 		reason = YPPUSH_YPERR;
1686*7c478bd9Sstevel@tonic-gate 		break;
1687*7c478bd9Sstevel@tonic-gate 
1688*7c478bd9Sstevel@tonic-gate 	default:
1689*7c478bd9Sstevel@tonic-gate 		reason = YPPUSH_XFRERR;
1690*7c478bd9Sstevel@tonic-gate 		break;
1691*7c478bd9Sstevel@tonic-gate 	}
1692*7c478bd9Sstevel@tonic-gate 
1693*7c478bd9Sstevel@tonic-gate 	return (reason);
1694*7c478bd9Sstevel@tonic-gate }
1695*7c478bd9Sstevel@tonic-gate 
1696*7c478bd9Sstevel@tonic-gate /*
1697*7c478bd9Sstevel@tonic-gate  * This writes the last-modified and master entries into the new dbm file
1698*7c478bd9Sstevel@tonic-gate  */
1699*7c478bd9Sstevel@tonic-gate bool
1700*7c478bd9Sstevel@tonic-gate add_private_entries(pname)
1701*7c478bd9Sstevel@tonic-gate 	char *pname;
1702*7c478bd9Sstevel@tonic-gate {
1703*7c478bd9Sstevel@tonic-gate 	datum key;
1704*7c478bd9Sstevel@tonic-gate 	datum val;
1705*7c478bd9Sstevel@tonic-gate 
1706*7c478bd9Sstevel@tonic-gate 	if (!fake_master_version) {
1707*7c478bd9Sstevel@tonic-gate 		key.dptr = yp_last_modified;
1708*7c478bd9Sstevel@tonic-gate 		key.dsize = yp_last_modified_sz;
1709*7c478bd9Sstevel@tonic-gate 		val.dptr = master_ascii_version;
1710*7c478bd9Sstevel@tonic-gate 		val.dsize = strlen(master_ascii_version);
1711*7c478bd9Sstevel@tonic-gate 
1712*7c478bd9Sstevel@tonic-gate 		if (dbm_store(db, key, val, 1) < 0) {
1713*7c478bd9Sstevel@tonic-gate 			logprintf(
1714*7c478bd9Sstevel@tonic-gate 			    "Can't do dbm store into temp map %s.\n",
1715*7c478bd9Sstevel@tonic-gate 			    pname);
1716*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1717*7c478bd9Sstevel@tonic-gate 		}
1718*7c478bd9Sstevel@tonic-gate 		entry_count++;
1719*7c478bd9Sstevel@tonic-gate 	}
1720*7c478bd9Sstevel@tonic-gate 
1721*7c478bd9Sstevel@tonic-gate 	if (master_name) {
1722*7c478bd9Sstevel@tonic-gate 		key.dptr = yp_master_name;
1723*7c478bd9Sstevel@tonic-gate 		key.dsize = yp_master_name_sz;
1724*7c478bd9Sstevel@tonic-gate 		val.dptr = master_name;
1725*7c478bd9Sstevel@tonic-gate 		val.dsize = strlen(master_name);
1726*7c478bd9Sstevel@tonic-gate 		if (dbm_store(db, key, val, 1) < 0) {
1727*7c478bd9Sstevel@tonic-gate 			logprintf(
1728*7c478bd9Sstevel@tonic-gate 			    "Can't do dbm store into temp map %s.\n",
1729*7c478bd9Sstevel@tonic-gate 			    pname);
1730*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1731*7c478bd9Sstevel@tonic-gate 		}
1732*7c478bd9Sstevel@tonic-gate 		entry_count++;
1733*7c478bd9Sstevel@tonic-gate 	}
1734*7c478bd9Sstevel@tonic-gate 
1735*7c478bd9Sstevel@tonic-gate 	if (interdomain_map) {
1736*7c478bd9Sstevel@tonic-gate 		key.dptr = yp_interdomain;
1737*7c478bd9Sstevel@tonic-gate 		key.dsize = yp_interdomain_sz;
1738*7c478bd9Sstevel@tonic-gate 		val.dptr = interdomain_value;
1739*7c478bd9Sstevel@tonic-gate 		val.dsize = interdomain_sz;
1740*7c478bd9Sstevel@tonic-gate 		if (dbm_store(db, key, val, 1) < 0) {
1741*7c478bd9Sstevel@tonic-gate 			logprintf(
1742*7c478bd9Sstevel@tonic-gate 			    "Can't do dbm store into temp map %s.\n",
1743*7c478bd9Sstevel@tonic-gate 			    pname);
1744*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1745*7c478bd9Sstevel@tonic-gate 		}
1746*7c478bd9Sstevel@tonic-gate 		entry_count++;
1747*7c478bd9Sstevel@tonic-gate 	}
1748*7c478bd9Sstevel@tonic-gate 
1749*7c478bd9Sstevel@tonic-gate 	if (secure_map) {
1750*7c478bd9Sstevel@tonic-gate 		key.dptr = yp_secure;
1751*7c478bd9Sstevel@tonic-gate 		key.dsize = yp_secure_sz;
1752*7c478bd9Sstevel@tonic-gate 		val.dptr = yp_secure;
1753*7c478bd9Sstevel@tonic-gate 		val.dsize = yp_secure_sz;
1754*7c478bd9Sstevel@tonic-gate 		if (dbm_store(db, key, val, 1) < 0) {
1755*7c478bd9Sstevel@tonic-gate 			logprintf(
1756*7c478bd9Sstevel@tonic-gate 			    "Can't do dbm store into temp map %s.\n",
1757*7c478bd9Sstevel@tonic-gate 			    pname);
1758*7c478bd9Sstevel@tonic-gate 			return (FALSE);
1759*7c478bd9Sstevel@tonic-gate 		}
1760*7c478bd9Sstevel@tonic-gate 		entry_count++;
1761*7c478bd9Sstevel@tonic-gate 	}
1762*7c478bd9Sstevel@tonic-gate 
1763*7c478bd9Sstevel@tonic-gate 	return (TRUE);
1764*7c478bd9Sstevel@tonic-gate }
1765*7c478bd9Sstevel@tonic-gate 
1766*7c478bd9Sstevel@tonic-gate 
1767*7c478bd9Sstevel@tonic-gate /*
1768*7c478bd9Sstevel@tonic-gate  * This sends a YPPROC_CLEAR message to the local ypserv process.
1769*7c478bd9Sstevel@tonic-gate  */
1770*7c478bd9Sstevel@tonic-gate bool
1771*7c478bd9Sstevel@tonic-gate send_ypclear(pushstat)
1772*7c478bd9Sstevel@tonic-gate 	int *pushstat;
1773*7c478bd9Sstevel@tonic-gate {
1774*7c478bd9Sstevel@tonic-gate 	struct dom_binding domb;
1775*7c478bd9Sstevel@tonic-gate 	char local_host_name[256];
1776*7c478bd9Sstevel@tonic-gate 	unsigned int progvers;
1777*7c478bd9Sstevel@tonic-gate 	int status;
1778*7c478bd9Sstevel@tonic-gate 
1779*7c478bd9Sstevel@tonic-gate 	if (gethostname(local_host_name, 256)) {
1780*7c478bd9Sstevel@tonic-gate 		logprintf("Can't get local machine name.\n");
1781*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_RSRC;
1782*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1783*7c478bd9Sstevel@tonic-gate 	}
1784*7c478bd9Sstevel@tonic-gate 
1785*7c478bd9Sstevel@tonic-gate 	if (!bind_to_server(local_host_name, &domb,
1786*7c478bd9Sstevel@tonic-gate 	    &progvers, &status)) {
1787*7c478bd9Sstevel@tonic-gate 		*pushstat = YPPUSH_CLEAR;
1788*7c478bd9Sstevel@tonic-gate 		return (FALSE);
1789*7c478bd9Sstevel@tonic-gate 	}
1790*7c478bd9Sstevel@tonic-gate 
1791*7c478bd9Sstevel@tonic-gate 	if ((enum clnt_stat) clnt_call(domb.dom_client,
1792*7c478bd9Sstevel@tonic-gate 	    YPPROC_CLEAR, xdr_void, 0, xdr_void, 0,
1793*7c478bd9Sstevel@tonic-gate 	    udp_timeout) != RPC_SUCCESS) {
1794*7c478bd9Sstevel@tonic-gate 		logprintf(
1795*7c478bd9Sstevel@tonic-gate 		"Can't send ypclear message to ypserv on the local machine.\n");
1796*7c478bd9Sstevel@tonic-gate 		xfr_exit(YPPUSH_CLEAR);
1797*7c478bd9Sstevel@tonic-gate 	}
1798*7c478bd9Sstevel@tonic-gate 
1799*7c478bd9Sstevel@tonic-gate 	return (TRUE);
1800*7c478bd9Sstevel@tonic-gate }
1801*7c478bd9Sstevel@tonic-gate 
1802*7c478bd9Sstevel@tonic-gate /*
1803*7c478bd9Sstevel@tonic-gate  * This decides if send_callback has to get called, and does the process exit.
1804*7c478bd9Sstevel@tonic-gate  */
1805*7c478bd9Sstevel@tonic-gate void
1806*7c478bd9Sstevel@tonic-gate xfr_exit(status)
1807*7c478bd9Sstevel@tonic-gate 	int status;
1808*7c478bd9Sstevel@tonic-gate {
1809*7c478bd9Sstevel@tonic-gate 	if (callback) {
1810*7c478bd9Sstevel@tonic-gate 		send_callback(&status);
1811*7c478bd9Sstevel@tonic-gate 	}
1812*7c478bd9Sstevel@tonic-gate 
1813*7c478bd9Sstevel@tonic-gate 	if (status == YPPUSH_SUCC) {
1814*7c478bd9Sstevel@tonic-gate #ifdef TREEPUSH
1815*7c478bd9Sstevel@tonic-gate 		if (treepush) {
1816*7c478bd9Sstevel@tonic-gate 		if (debug)
1817*7c478bd9Sstevel@tonic-gate 		execlp("./yppush", "yppush", "-T", map, 0);
1818*7c478bd9Sstevel@tonic-gate 		execlp("/usr/etc/yp/yppush", "yppush", "-T", map, 0);
1819*7c478bd9Sstevel@tonic-gate 		perror("yppush");
1820*7c478bd9Sstevel@tonic-gate 		}
1821*7c478bd9Sstevel@tonic-gate #endif
1822*7c478bd9Sstevel@tonic-gate 		exit(0);
1823*7c478bd9Sstevel@tonic-gate 	} else {
1824*7c478bd9Sstevel@tonic-gate 		exit(1);
1825*7c478bd9Sstevel@tonic-gate 	}
1826*7c478bd9Sstevel@tonic-gate }
1827*7c478bd9Sstevel@tonic-gate 
1828*7c478bd9Sstevel@tonic-gate /*
1829*7c478bd9Sstevel@tonic-gate  * This sets up a UDP connection to the yppush process which contacted our
1830*7c478bd9Sstevel@tonic-gate  * parent ypserv, and sends him a status on the requested transfer.
1831*7c478bd9Sstevel@tonic-gate  */
1832*7c478bd9Sstevel@tonic-gate void
1833*7c478bd9Sstevel@tonic-gate send_callback(status)
1834*7c478bd9Sstevel@tonic-gate 	int *status;
1835*7c478bd9Sstevel@tonic-gate {
1836*7c478bd9Sstevel@tonic-gate 	struct yppushresp_xfr resp;
1837*7c478bd9Sstevel@tonic-gate 	struct dom_binding domb;
1838*7c478bd9Sstevel@tonic-gate 
1839*7c478bd9Sstevel@tonic-gate 	resp.transid = (unsigned long) atoi(tid);
1840*7c478bd9Sstevel@tonic-gate 	resp.status = (unsigned long) *status;
1841*7c478bd9Sstevel@tonic-gate 
1842*7c478bd9Sstevel@tonic-gate 	udp_timeout.tv_sec = CALLTIMEOUT;
1843*7c478bd9Sstevel@tonic-gate 
1844*7c478bd9Sstevel@tonic-gate 	if ((domb.dom_client = __yp_clnt_create_rsvdport(pushhost,
1845*7c478bd9Sstevel@tonic-gate 						    (ulong_t)atoi(proto),
1846*7c478bd9Sstevel@tonic-gate 						    YPPUSHVERS,
1847*7c478bd9Sstevel@tonic-gate 						    0, 0, 0)) == NULL) {
1848*7c478bd9Sstevel@tonic-gate 		*status = YPPUSH_RPC;
1849*7c478bd9Sstevel@tonic-gate 		return;
1850*7c478bd9Sstevel@tonic-gate 	}
1851*7c478bd9Sstevel@tonic-gate 
1852*7c478bd9Sstevel@tonic-gate 	if ((enum clnt_stat) clnt_call(domb.dom_client,
1853*7c478bd9Sstevel@tonic-gate 	    YPPUSHPROC_XFRRESP, (xdrproc_t)xdr_yppushresp_xfr,
1854*7c478bd9Sstevel@tonic-gate 	    (char *)&resp, xdr_void, 0,
1855*7c478bd9Sstevel@tonic-gate 	    udp_timeout) != RPC_SUCCESS) {
1856*7c478bd9Sstevel@tonic-gate 		*status = YPPUSH_RPC;
1857*7c478bd9Sstevel@tonic-gate 		return;
1858*7c478bd9Sstevel@tonic-gate 	}
1859*7c478bd9Sstevel@tonic-gate }
1860*7c478bd9Sstevel@tonic-gate 
1861*7c478bd9Sstevel@tonic-gate /*
1862*7c478bd9Sstevel@tonic-gate  * FUNCTION:    is_yptol_mode();
1863*7c478bd9Sstevel@tonic-gate  *
1864*7c478bd9Sstevel@tonic-gate  * DESCRIPTION: Determines if we should run in N2L or traditional mode based
1865*7c478bd9Sstevel@tonic-gate  *              on the presence of the N2L mapping file.
1866*7c478bd9Sstevel@tonic-gate  *
1867*7c478bd9Sstevel@tonic-gate  *		This is a copy of a function from libnisdb. If more than this
1868*7c478bd9Sstevel@tonic-gate  *		one function become required it may be worth linking the
1869*7c478bd9Sstevel@tonic-gate  *		entire lib.
1870*7c478bd9Sstevel@tonic-gate  *
1871*7c478bd9Sstevel@tonic-gate  * INPUTS:      Nothing
1872*7c478bd9Sstevel@tonic-gate  *
1873*7c478bd9Sstevel@tonic-gate  * OUTPUTS:     TRUE = Run in N2L mode
1874*7c478bd9Sstevel@tonic-gate  *              FALSE = Run in traditional mode.
1875*7c478bd9Sstevel@tonic-gate  */
1876*7c478bd9Sstevel@tonic-gate bool_t
1877*7c478bd9Sstevel@tonic-gate is_yptol_mode()
1878*7c478bd9Sstevel@tonic-gate {
1879*7c478bd9Sstevel@tonic-gate 	struct stat filestat;
1880*7c478bd9Sstevel@tonic-gate 
1881*7c478bd9Sstevel@tonic-gate 	if (stat(NTOL_MAP_FILE, &filestat) != -1)
1882*7c478bd9Sstevel@tonic-gate 		return (TRUE);
1883*7c478bd9Sstevel@tonic-gate 
1884*7c478bd9Sstevel@tonic-gate 	return (FALSE);
1885*7c478bd9Sstevel@tonic-gate }
1886