ypxfr_misc.c revision 93979
113007Swpaul/*
213007Swpaul * Copyright (c) 1995
313007Swpaul *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
413007Swpaul *
513007Swpaul * Redistribution and use in source and binary forms, with or without
613007Swpaul * modification, are permitted provided that the following conditions
713007Swpaul * are met:
813007Swpaul * 1. Redistributions of source code must retain the above copyright
913007Swpaul *    notice, this list of conditions and the following disclaimer.
1013007Swpaul * 2. Redistributions in binary form must reproduce the above copyright
1113007Swpaul *    notice, this list of conditions and the following disclaimer in the
1213007Swpaul *    documentation and/or other materials provided with the distribution.
1313007Swpaul * 3. All advertising materials mentioning features or use of this software
1413007Swpaul *    must display the following acknowledgement:
1513007Swpaul *	This product includes software developed by Bill Paul.
1613007Swpaul * 4. Neither the name of the author nor the names of any co-contributors
1713007Swpaul *    may be used to endorse or promote products derived from this software
1813007Swpaul *    without specific prior written permission.
1913007Swpaul *
2013007Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2113007Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2213007Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2313007Swpaul * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
2413007Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2513007Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2613007Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2713007Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2813007Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2913007Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3013007Swpaul * SUCH DAMAGE.
3113007Swpaul */
3231626Scharnier
3331626Scharnier#ifndef lint
3431626Scharnierstatic const char rcsid[] =
3550476Speter  "$FreeBSD: head/libexec/ypxfr/ypxfr_misc.c 93979 2002-04-06 19:08:02Z des $";
3631626Scharnier#endif /* not lint */
3731626Scharnier
3819181Swpaul#include <stdio.h>
3919181Swpaul#include <string.h>
4013895Swpaul#include <stdlib.h>
4113895Swpaul#include <unistd.h>
4213895Swpaul#include <sys/param.h>
4313007Swpaul#include <rpc/rpc.h>
4413007Swpaul#include <rpcsvc/yp.h>
4513007Swpaulstruct dom_binding {};
4613007Swpaul#include <rpcsvc/ypclnt.h>
4713007Swpaul#include "ypxfr_extern.h"
4813007Swpaul
4993979Sdesconst char *
5090298Sdesypxfrerr_string(ypxfrstat code)
5113007Swpaul{
5290297Sdes	switch (code) {
5313007Swpaul	case YPXFR_SUCC:
5461187Sjlemon		return ("Map successfully transferred");
5513007Swpaul		break;
5613007Swpaul	case YPXFR_AGE:
5713007Swpaul		return ("Master's version not newer");
5813007Swpaul		break;
5913007Swpaul	case YPXFR_NOMAP:
6013007Swpaul		return ("No such map in server's domain");
6113007Swpaul		break;
6213007Swpaul	case YPXFR_NODOM:
6313007Swpaul		return ("Domain not supported by server");
6413007Swpaul		break;
6513007Swpaul	case YPXFR_RSRC:
6613007Swpaul		return ("Local resource allocation failure");
6713007Swpaul		break;
6813007Swpaul	case YPXFR_RPC:
6913007Swpaul		return ("RPC failure talking to server");
7013007Swpaul		break;
7113007Swpaul	case YPXFR_MADDR:
7213007Swpaul		return ("Could not get master server address");
7313007Swpaul		break;
7413007Swpaul	case YPXFR_YPERR:
7513007Swpaul		return ("NIS server/map database error");
7613007Swpaul		break;
7713007Swpaul	case YPXFR_BADARGS:
7813007Swpaul		return ("Request arguments bad");
7913007Swpaul		break;
8013007Swpaul	case YPXFR_DBM:
8113007Swpaul		return ("Local database operation failed");
8213007Swpaul		break;
8313007Swpaul	case YPXFR_FILE:
8413007Swpaul		return ("Local file I/O operation failed");
8513007Swpaul		break;
8613007Swpaul	case YPXFR_SKEW:
8713007Swpaul		return ("Map version skew during transfer");
8813007Swpaul		break;
8913007Swpaul	case YPXFR_CLEAR:
9013007Swpaul		return ("Couldn't send \"clear\" request to local ypserv");
9113007Swpaul		break;
9213007Swpaul	case YPXFR_FORCE:
9313007Swpaul		return ("No local order number in map -- use -f flag");
9413007Swpaul		break;
9513007Swpaul	case YPXFR_XFRERR:
9613007Swpaul		return ("General ypxfr error");
9713007Swpaul		break;
9813007Swpaul	case YPXFR_REFUSED:
9913007Swpaul		return ("Transfer request refused by ypserv");
10013007Swpaul		break;
10113007Swpaul	default:
10213007Swpaul		return ("Unknown error code");
10313007Swpaul		break;
10413007Swpaul	}
10513007Swpaul}
10613007Swpaul
10713007Swpaul/*
10813007Swpaul * These are wrappers for the usual yp_master() and yp_order() functions.
10913007Swpaul * They can use either local yplib functions (the real yp_master() and
11013007Swpaul * yp_order()) or do direct RPCs to a specified server. The latter is
11113007Swpaul * necessary if ypxfr is run on a machine that isn't configured as an
11213007Swpaul * NIS client (this can happen very easily: a given machine need not be
11313007Swpaul * an NIS client in order to be an NIS server).
11413007Swpaul */
11513007Swpaul
11613895Swpaul/*
11713895Swpaul * Careful: yp_master() returns a pointer to a dynamically allocated
11813895Swpaul * buffer. Calling ypproc_master_2() ourselves also returns a pointer
11913895Swpaul * to dynamically allocated memory, though this time it's memory
12013895Swpaul * allocated by the XDR routines. We have to rememver to free() or
12113895Swpaul * xdr_free() the memory as required to avoid leaking memory.
12213895Swpaul */
12390298Sdeschar *
12490298Sdesypxfr_get_master(char *domain, char *map, char *source, const int yplib)
12513007Swpaul{
12613895Swpaul	static char mastername[MAXPATHLEN + 2];
12713895Swpaul
12813895Swpaul	bzero((char *)&mastername, sizeof(mastername));
12913895Swpaul
13013007Swpaul	if (yplib) {
13113007Swpaul		int res;
13213007Swpaul		char *master;
13313007Swpaul		if ((res = yp_master(domain, map, &master))) {
13413007Swpaul			switch (res) {
13513007Swpaul			case YPERR_DOMAIN:
13613007Swpaul				yp_errno = YPXFR_NODOM;
13713007Swpaul				break;
13813007Swpaul			case YPERR_MAP:
13913007Swpaul				yp_errno = YPXFR_NOMAP;
14013007Swpaul				break;
14113007Swpaul			case YPERR_YPERR:
14213007Swpaul			default:
14313007Swpaul				yp_errno = YPXFR_YPERR;
14413007Swpaul				break;
14513007Swpaul			}
14613007Swpaul			return(NULL);
14713895Swpaul		} else {
14813895Swpaul			snprintf(mastername, sizeof(mastername), "%s", master);
14913895Swpaul			free(master);
15013895Swpaul			return((char *)&mastername);
15113895Swpaul		}
15213007Swpaul	} else {
15313007Swpaul		CLIENT *clnt;
15413007Swpaul		ypresp_master *resp;
15513007Swpaul		ypreq_nokey req;
15613007Swpaul
15713007Swpaul		if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
15813007Swpaul			yp_error("%s",clnt_spcreateerror("failed to \
15913007Swpaulcreate udp handle to ypserv"));
16013007Swpaul			yp_errno = YPXFR_RPC;
16113007Swpaul			return(NULL);
16213007Swpaul		}
16313007Swpaul
16413007Swpaul		req.map = map;
16513007Swpaul		req.domain = domain;
16613007Swpaul		if ((resp = ypproc_master_2(&req, clnt)) == NULL) {
16713007Swpaul			yp_error("%s",clnt_sperror(clnt,"YPPROC_MASTER \
16813007Swpaulfailed"));
16913007Swpaul			clnt_destroy(clnt);
17013007Swpaul			yp_errno = YPXFR_RPC;
17113007Swpaul			return(NULL);
17213007Swpaul		}
17313007Swpaul		clnt_destroy(clnt);
17413007Swpaul		if (resp->stat != YP_TRUE) {
17513007Swpaul			switch (resp->stat) {
17613007Swpaul			case YP_NODOM:
17713007Swpaul				yp_errno = YPXFR_NODOM;
17813007Swpaul				break;
17913007Swpaul			case YP_NOMAP:
18013007Swpaul				yp_errno = YPXFR_NOMAP;
18113007Swpaul				break;
18213007Swpaul			case YP_YPERR:
18313007Swpaul			default:
18413007Swpaul				yp_errno = YPXFR_YPERR;
18513007Swpaul				break;
18613007Swpaul			}
18713007Swpaul			return(NULL);
18813007Swpaul		}
18913895Swpaul		snprintf(mastername, sizeof(mastername), "%s", resp->peer);
19016132Swpaul/*		xdr_free(xdr_ypresp_master, (char *)&resp); */
19113895Swpaul		return((char *)&mastername);
19213007Swpaul	}
19313007Swpaul}
19490297Sdes
19590298Sdesunsigned long
19690298Sdesypxfr_get_order(char *domain, char *map, char *source, const int yplib)
19713007Swpaul{
19813007Swpaul	if (yplib) {
19913007Swpaul		unsigned long order;
20013007Swpaul		int res;
20113007Swpaul		if ((res = yp_order(domain, map, (int *)&order))) {
20213007Swpaul			switch (res) {
20313895Swpaul			case YPERR_DOMAIN:
20413007Swpaul				yp_errno = YPXFR_NODOM;
20513007Swpaul				break;
20613895Swpaul			case YPERR_MAP:
20713007Swpaul				yp_errno = YPXFR_NOMAP;
20813007Swpaul				break;
20913895Swpaul			case YPERR_YPERR:
21013007Swpaul			default:
21113007Swpaul				yp_errno = YPXFR_YPERR;
21213007Swpaul				break;
21313007Swpaul			}
21413007Swpaul			return(0);
21513007Swpaul		} else
21613007Swpaul			return(order);
21713007Swpaul	} else {
21813007Swpaul		CLIENT *clnt;
21913007Swpaul		ypresp_order *resp;
22013007Swpaul		ypreq_nokey req;
22113007Swpaul
22213007Swpaul		if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
22313007Swpaul			yp_error("%s",clnt_spcreateerror("couldn't create \
22413007Swpauludp handle to ypserv"));
22513007Swpaul			yp_errno = YPXFR_RPC;
22613007Swpaul			return(0);
22713007Swpaul		}
22813007Swpaul		req.map = map;
22913007Swpaul		req.domain = domain;
23013007Swpaul		if ((resp = ypproc_order_2(&req, clnt)) == NULL) {
23113007Swpaul			yp_error("%s", clnt_sperror(clnt, "YPPROC_ORDER \
23213007Swpaulfailed"));
23313007Swpaul			clnt_destroy(clnt);
23413007Swpaul			yp_errno = YPXFR_RPC;
23513007Swpaul			return(0);
23613007Swpaul		}
23713007Swpaul		clnt_destroy(clnt);
23813007Swpaul		if (resp->stat != YP_TRUE) {
23913007Swpaul			switch (resp->stat) {
24013895Swpaul			case YP_NODOM:
24113007Swpaul				yp_errno = YPXFR_NODOM;
24213007Swpaul				break;
24313895Swpaul			case YP_NOMAP:
24413007Swpaul				yp_errno = YPXFR_NOMAP;
24513007Swpaul				break;
24613895Swpaul			case YP_YPERR:
24713007Swpaul			default:
24813007Swpaul				yp_errno = YPXFR_YPERR;
24913007Swpaul				break;
25013007Swpaul			}
25113007Swpaul			return(0);
25213007Swpaul		}
25313007Swpaul		return(resp->ordernum);
25413007Swpaul	}
25513007Swpaul}
25619181Swpaul
25790298Sdesint
25890298Sdesypxfr_match(char *server, char *domain, char *map, char *key,
25990298Sdes    unsigned long keylen)
26019181Swpaul{
26119181Swpaul	ypreq_key ypkey;
26219181Swpaul	ypresp_val *ypval;
26319181Swpaul	CLIENT *clnt;
26419181Swpaul	static char buf[YPMAXRECORD + 2];
26519181Swpaul
26619181Swpaul	bzero((char *)buf, sizeof(buf));
26719181Swpaul
26819181Swpaul	if ((clnt = clnt_create(server, YPPROG,YPVERS,"udp")) == NULL) {
26919181Swpaul		yp_error("failed to create UDP handle: %s",
27019181Swpaul					clnt_spcreateerror(server));
27119181Swpaul		return(0);
27219181Swpaul	}
27319181Swpaul
27419181Swpaul	ypkey.domain = domain;
27519181Swpaul	ypkey.map = map;
27619181Swpaul	ypkey.key.keydat_len = keylen;
27719181Swpaul	ypkey.key.keydat_val = key;
27819181Swpaul
27919181Swpaul	if ((ypval = ypproc_match_2(&ypkey, clnt)) == NULL) {
28019181Swpaul		clnt_destroy(clnt);
28119181Swpaul		yp_error("%s: %s", server,
28219181Swpaul				clnt_sperror(clnt,"YPPROC_MATCH failed"));
28319181Swpaul		return(0);
28419181Swpaul	}
28519181Swpaul
28619181Swpaul	clnt_destroy(clnt);
28719181Swpaul
28819181Swpaul	if (ypval->stat != YP_TRUE) {
28919181Swpaul		xdr_free(xdr_ypresp_val, (char *)ypval);
29019181Swpaul		return(0);
29119181Swpaul	}
29219181Swpaul
29319181Swpaul	xdr_free(xdr_ypresp_val, (char *)ypval);
29419181Swpaul
29519181Swpaul	return(1);
29619181Swpaul}
297