ypxfr_misc.c revision 61187
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 */
3219181Swpaul
3313007Swpaul#ifndef lint
3419181Swpaulstatic const char rcsid[] =
3519181Swpaul  "$FreeBSD: head/libexec/ypxfr/ypxfr_misc.c 61187 2000-06-02 21:22:09Z jlemon $";
3613895Swpaul#endif /* not lint */
3713895Swpaul
3813895Swpaul#include <stdio.h>
3913007Swpaul#include <string.h>
4013007Swpaul#include <stdlib.h>
4113007Swpaul#include <unistd.h>
4213007Swpaul#include <sys/param.h>
4313007Swpaul#include <rpc/rpc.h>
4413007Swpaul#include <rpcsvc/yp.h>
4513007Swpaulstruct dom_binding {};
4619181Swpaul#include <rpcsvc/ypclnt.h>
4713007Swpaul#include "ypxfr_extern.h"
4813007Swpaul
4913007Swpaulchar *ypxfrerr_string(code)
5013007Swpaul	ypxfrstat code;
5113007Swpaul{
5213007Swpaul	switch(code) {
5313007Swpaul	case YPXFR_SUCC:
5413007Swpaul		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 */
12313007Swpaulchar *ypxfr_get_master(domain,map,source,yplib)
12413007Swpaul	char *domain;
12513007Swpaul	char *map;
12613007Swpaul	char *source;
12713007Swpaul	const int yplib;
12813007Swpaul{
12913895Swpaul	static char mastername[MAXPATHLEN + 2];
13013895Swpaul
13113895Swpaul	bzero((char *)&mastername, sizeof(mastername));
13213895Swpaul
13313007Swpaul	if (yplib) {
13413007Swpaul		int res;
13513007Swpaul		char *master;
13613007Swpaul		if ((res = yp_master(domain, map, &master))) {
13713007Swpaul			switch (res) {
13813007Swpaul			case YPERR_DOMAIN:
13913007Swpaul				yp_errno = YPXFR_NODOM;
14013007Swpaul				break;
14113007Swpaul			case YPERR_MAP:
14213007Swpaul				yp_errno = YPXFR_NOMAP;
14313007Swpaul				break;
14413007Swpaul			case YPERR_YPERR:
14513007Swpaul			default:
14613007Swpaul				yp_errno = YPXFR_YPERR;
14713007Swpaul				break;
14813007Swpaul			}
14913007Swpaul			return(NULL);
15013895Swpaul		} else {
15113895Swpaul			snprintf(mastername, sizeof(mastername), "%s", master);
15213895Swpaul			free(master);
15313895Swpaul			return((char *)&mastername);
15413895Swpaul		}
15513007Swpaul	} else {
15613007Swpaul		CLIENT *clnt;
15713007Swpaul		ypresp_master *resp;
15813007Swpaul		ypreq_nokey req;
15913007Swpaul
16013007Swpaul		if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
16113007Swpaul			yp_error("%s",clnt_spcreateerror("failed to \
16213007Swpaulcreate udp handle to ypserv"));
16313007Swpaul			yp_errno = YPXFR_RPC;
16413007Swpaul			return(NULL);
16513007Swpaul		}
16613007Swpaul
16713007Swpaul		req.map = map;
16813007Swpaul		req.domain = domain;
16913007Swpaul		if ((resp = ypproc_master_2(&req, clnt)) == NULL) {
17013007Swpaul			yp_error("%s",clnt_sperror(clnt,"YPPROC_MASTER \
17113007Swpaulfailed"));
17213007Swpaul			clnt_destroy(clnt);
17313007Swpaul			yp_errno = YPXFR_RPC;
17413007Swpaul			return(NULL);
17513007Swpaul		}
17613007Swpaul		clnt_destroy(clnt);
17713007Swpaul		if (resp->stat != YP_TRUE) {
17813007Swpaul			switch (resp->stat) {
17913007Swpaul			case YP_NODOM:
18013007Swpaul				yp_errno = YPXFR_NODOM;
18113007Swpaul				break;
18213007Swpaul			case YP_NOMAP:
18313007Swpaul				yp_errno = YPXFR_NOMAP;
18413007Swpaul				break;
18513007Swpaul			case YP_YPERR:
18613007Swpaul			default:
18713007Swpaul				yp_errno = YPXFR_YPERR;
18813007Swpaul				break;
18913007Swpaul			}
19013007Swpaul			return(NULL);
19113007Swpaul		}
19213895Swpaul		snprintf(mastername, sizeof(mastername), "%s", resp->peer);
19316132Swpaul/*		xdr_free(xdr_ypresp_master, (char *)&resp); */
19413895Swpaul		return((char *)&mastername);
19513007Swpaul	}
19613007Swpaul}
19713007Swpaul
19813007Swpaulunsigned long ypxfr_get_order(domain, map, source, yplib)
19913007Swpaul	char *domain;
20013007Swpaul	char *map;
20113007Swpaul	char *source;
20213007Swpaul	const int yplib;
20313007Swpaul{
20413007Swpaul	if (yplib) {
20513007Swpaul		unsigned long order;
20613007Swpaul		int res;
20713007Swpaul		if ((res = yp_order(domain, map, (int *)&order))) {
20813007Swpaul			switch (res) {
20913895Swpaul			case YPERR_DOMAIN:
21013007Swpaul				yp_errno = YPXFR_NODOM;
21113007Swpaul				break;
21213895Swpaul			case YPERR_MAP:
21313007Swpaul				yp_errno = YPXFR_NOMAP;
21413007Swpaul				break;
21513895Swpaul			case YPERR_YPERR:
21613007Swpaul			default:
21713007Swpaul				yp_errno = YPXFR_YPERR;
21813007Swpaul				break;
21913007Swpaul			}
22013007Swpaul			return(0);
22113007Swpaul		} else
22213007Swpaul			return(order);
22313007Swpaul	} else {
22413007Swpaul		CLIENT *clnt;
22513007Swpaul		ypresp_order *resp;
22613007Swpaul		ypreq_nokey req;
22713007Swpaul
22813007Swpaul		if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
22913007Swpaul			yp_error("%s",clnt_spcreateerror("couldn't create \
23013007Swpauludp handle to ypserv"));
23113007Swpaul			yp_errno = YPXFR_RPC;
23213007Swpaul			return(0);
23313007Swpaul		}
23413007Swpaul		req.map = map;
23513007Swpaul		req.domain = domain;
23613007Swpaul		if ((resp = ypproc_order_2(&req, clnt)) == NULL) {
23713007Swpaul			yp_error("%s", clnt_sperror(clnt, "YPPROC_ORDER \
23813007Swpaulfailed"));
23913007Swpaul			clnt_destroy(clnt);
24013007Swpaul			yp_errno = YPXFR_RPC;
24113007Swpaul			return(0);
24213007Swpaul		}
24313007Swpaul		clnt_destroy(clnt);
24413007Swpaul		if (resp->stat != YP_TRUE) {
24513007Swpaul			switch (resp->stat) {
24613895Swpaul			case YP_NODOM:
24713007Swpaul				yp_errno = YPXFR_NODOM;
24813007Swpaul				break;
24913895Swpaul			case YP_NOMAP:
25013007Swpaul				yp_errno = YPXFR_NOMAP;
25113007Swpaul				break;
25213895Swpaul			case YP_YPERR:
25313007Swpaul			default:
25413007Swpaul				yp_errno = YPXFR_YPERR;
25513007Swpaul				break;
25613007Swpaul			}
25713007Swpaul			return(0);
25813007Swpaul		}
25913007Swpaul		return(resp->ordernum);
26013007Swpaul	}
26113007Swpaul}
26219181Swpaul
26319181Swpaulint ypxfr_match(server, domain, map, key, keylen)
26419181Swpaul	char *server;
26519181Swpaul	char *domain;
26619181Swpaul	char *map;
26719181Swpaul	char *key;
26819181Swpaul	unsigned long keylen;
26919181Swpaul{
27019181Swpaul	ypreq_key ypkey;
27119181Swpaul	ypresp_val *ypval;
27219181Swpaul	CLIENT *clnt;
27319181Swpaul	static char buf[YPMAXRECORD + 2];
27419181Swpaul
27519181Swpaul	bzero((char *)buf, sizeof(buf));
27619181Swpaul
27719181Swpaul	if ((clnt = clnt_create(server, YPPROG,YPVERS,"udp")) == NULL) {
27819181Swpaul		yp_error("failed to create UDP handle: %s",
27919181Swpaul					clnt_spcreateerror(server));
28019181Swpaul		return(0);
28119181Swpaul	}
28219181Swpaul
28319181Swpaul	ypkey.domain = domain;
28419181Swpaul	ypkey.map = map;
28519181Swpaul	ypkey.key.keydat_len = keylen;
28619181Swpaul	ypkey.key.keydat_val = key;
28719181Swpaul
28819181Swpaul	if ((ypval = ypproc_match_2(&ypkey, clnt)) == NULL) {
28919181Swpaul		clnt_destroy(clnt);
29019181Swpaul		yp_error("%s: %s", server,
29119181Swpaul				clnt_sperror(clnt,"YPPROC_MATCH failed"));
29219181Swpaul		return(0);
29319181Swpaul	}
29419181Swpaul
29519181Swpaul	clnt_destroy(clnt);
29619181Swpaul
29719181Swpaul	if (ypval->stat != YP_TRUE) {
29819181Swpaul		xdr_free(xdr_ypresp_val, (char *)ypval);
29919181Swpaul		return(0);
30019181Swpaul	}
30119181Swpaul
30219181Swpaul	xdr_free(xdr_ypresp_val, (char *)ypval);
30319181Swpaul
30419181Swpaul	return(1);
30519181Swpaul}
306