ypxfr_misc.c revision 114626
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
33114626Sobrien#include <sys/cdefs.h>
34114626Sobrien__FBSDID("$FreeBSD: head/libexec/ypxfr/ypxfr_misc.c 114626 2003-05-04 00:59:13Z obrien $");
3531626Scharnier
3619181Swpaul#include <stdio.h>
3719181Swpaul#include <string.h>
3813895Swpaul#include <stdlib.h>
3913895Swpaul#include <unistd.h>
4013895Swpaul#include <sys/param.h>
4113007Swpaul#include <rpc/rpc.h>
4213007Swpaul#include <rpcsvc/yp.h>
4313007Swpaulstruct dom_binding {};
4413007Swpaul#include <rpcsvc/ypclnt.h>
4513007Swpaul#include "ypxfr_extern.h"
4613007Swpaul
4793979Sdesconst char *
4890298Sdesypxfrerr_string(ypxfrstat code)
4913007Swpaul{
5090297Sdes	switch (code) {
5113007Swpaul	case YPXFR_SUCC:
5261187Sjlemon		return ("Map successfully transferred");
5313007Swpaul		break;
5413007Swpaul	case YPXFR_AGE:
5513007Swpaul		return ("Master's version not newer");
5613007Swpaul		break;
5713007Swpaul	case YPXFR_NOMAP:
5813007Swpaul		return ("No such map in server's domain");
5913007Swpaul		break;
6013007Swpaul	case YPXFR_NODOM:
6113007Swpaul		return ("Domain not supported by server");
6213007Swpaul		break;
6313007Swpaul	case YPXFR_RSRC:
6413007Swpaul		return ("Local resource allocation failure");
6513007Swpaul		break;
6613007Swpaul	case YPXFR_RPC:
6713007Swpaul		return ("RPC failure talking to server");
6813007Swpaul		break;
6913007Swpaul	case YPXFR_MADDR:
7013007Swpaul		return ("Could not get master server address");
7113007Swpaul		break;
7213007Swpaul	case YPXFR_YPERR:
7313007Swpaul		return ("NIS server/map database error");
7413007Swpaul		break;
7513007Swpaul	case YPXFR_BADARGS:
7613007Swpaul		return ("Request arguments bad");
7713007Swpaul		break;
7813007Swpaul	case YPXFR_DBM:
7913007Swpaul		return ("Local database operation failed");
8013007Swpaul		break;
8113007Swpaul	case YPXFR_FILE:
8213007Swpaul		return ("Local file I/O operation failed");
8313007Swpaul		break;
8413007Swpaul	case YPXFR_SKEW:
8513007Swpaul		return ("Map version skew during transfer");
8613007Swpaul		break;
8713007Swpaul	case YPXFR_CLEAR:
8813007Swpaul		return ("Couldn't send \"clear\" request to local ypserv");
8913007Swpaul		break;
9013007Swpaul	case YPXFR_FORCE:
9113007Swpaul		return ("No local order number in map -- use -f flag");
9213007Swpaul		break;
9313007Swpaul	case YPXFR_XFRERR:
9413007Swpaul		return ("General ypxfr error");
9513007Swpaul		break;
9613007Swpaul	case YPXFR_REFUSED:
9713007Swpaul		return ("Transfer request refused by ypserv");
9813007Swpaul		break;
9913007Swpaul	default:
10013007Swpaul		return ("Unknown error code");
10113007Swpaul		break;
10213007Swpaul	}
10313007Swpaul}
10413007Swpaul
10513007Swpaul/*
10613007Swpaul * These are wrappers for the usual yp_master() and yp_order() functions.
10713007Swpaul * They can use either local yplib functions (the real yp_master() and
10813007Swpaul * yp_order()) or do direct RPCs to a specified server. The latter is
10913007Swpaul * necessary if ypxfr is run on a machine that isn't configured as an
11013007Swpaul * NIS client (this can happen very easily: a given machine need not be
11113007Swpaul * an NIS client in order to be an NIS server).
11213007Swpaul */
11313007Swpaul
11413895Swpaul/*
11513895Swpaul * Careful: yp_master() returns a pointer to a dynamically allocated
11613895Swpaul * buffer. Calling ypproc_master_2() ourselves also returns a pointer
11713895Swpaul * to dynamically allocated memory, though this time it's memory
11813895Swpaul * allocated by the XDR routines. We have to rememver to free() or
11913895Swpaul * xdr_free() the memory as required to avoid leaking memory.
12013895Swpaul */
12190298Sdeschar *
12290298Sdesypxfr_get_master(char *domain, char *map, char *source, const int yplib)
12313007Swpaul{
12413895Swpaul	static char mastername[MAXPATHLEN + 2];
12513895Swpaul
12613895Swpaul	bzero((char *)&mastername, sizeof(mastername));
12713895Swpaul
12813007Swpaul	if (yplib) {
12913007Swpaul		int res;
13013007Swpaul		char *master;
13113007Swpaul		if ((res = yp_master(domain, map, &master))) {
13213007Swpaul			switch (res) {
13313007Swpaul			case YPERR_DOMAIN:
13413007Swpaul				yp_errno = YPXFR_NODOM;
13513007Swpaul				break;
13613007Swpaul			case YPERR_MAP:
13713007Swpaul				yp_errno = YPXFR_NOMAP;
13813007Swpaul				break;
13913007Swpaul			case YPERR_YPERR:
14013007Swpaul			default:
14113007Swpaul				yp_errno = YPXFR_YPERR;
14213007Swpaul				break;
14313007Swpaul			}
14413007Swpaul			return(NULL);
14513895Swpaul		} else {
14613895Swpaul			snprintf(mastername, sizeof(mastername), "%s", master);
14713895Swpaul			free(master);
14813895Swpaul			return((char *)&mastername);
14913895Swpaul		}
15013007Swpaul	} else {
15113007Swpaul		CLIENT *clnt;
15213007Swpaul		ypresp_master *resp;
15313007Swpaul		ypreq_nokey req;
15413007Swpaul
15513007Swpaul		if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
15613007Swpaul			yp_error("%s",clnt_spcreateerror("failed to \
15713007Swpaulcreate udp handle to ypserv"));
15813007Swpaul			yp_errno = YPXFR_RPC;
15913007Swpaul			return(NULL);
16013007Swpaul		}
16113007Swpaul
16213007Swpaul		req.map = map;
16313007Swpaul		req.domain = domain;
16413007Swpaul		if ((resp = ypproc_master_2(&req, clnt)) == NULL) {
16513007Swpaul			yp_error("%s",clnt_sperror(clnt,"YPPROC_MASTER \
16613007Swpaulfailed"));
16713007Swpaul			clnt_destroy(clnt);
16813007Swpaul			yp_errno = YPXFR_RPC;
16913007Swpaul			return(NULL);
17013007Swpaul		}
17113007Swpaul		clnt_destroy(clnt);
17213007Swpaul		if (resp->stat != YP_TRUE) {
17313007Swpaul			switch (resp->stat) {
17413007Swpaul			case YP_NODOM:
17513007Swpaul				yp_errno = YPXFR_NODOM;
17613007Swpaul				break;
17713007Swpaul			case YP_NOMAP:
17813007Swpaul				yp_errno = YPXFR_NOMAP;
17913007Swpaul				break;
18013007Swpaul			case YP_YPERR:
18113007Swpaul			default:
18213007Swpaul				yp_errno = YPXFR_YPERR;
18313007Swpaul				break;
18413007Swpaul			}
18513007Swpaul			return(NULL);
18613007Swpaul		}
18713895Swpaul		snprintf(mastername, sizeof(mastername), "%s", resp->peer);
18816132Swpaul/*		xdr_free(xdr_ypresp_master, (char *)&resp); */
18913895Swpaul		return((char *)&mastername);
19013007Swpaul	}
19113007Swpaul}
19290297Sdes
19390298Sdesunsigned long
19490298Sdesypxfr_get_order(char *domain, char *map, char *source, const int yplib)
19513007Swpaul{
19613007Swpaul	if (yplib) {
19713007Swpaul		unsigned long order;
19813007Swpaul		int res;
19913007Swpaul		if ((res = yp_order(domain, map, (int *)&order))) {
20013007Swpaul			switch (res) {
20113895Swpaul			case YPERR_DOMAIN:
20213007Swpaul				yp_errno = YPXFR_NODOM;
20313007Swpaul				break;
20413895Swpaul			case YPERR_MAP:
20513007Swpaul				yp_errno = YPXFR_NOMAP;
20613007Swpaul				break;
20713895Swpaul			case YPERR_YPERR:
20813007Swpaul			default:
20913007Swpaul				yp_errno = YPXFR_YPERR;
21013007Swpaul				break;
21113007Swpaul			}
21213007Swpaul			return(0);
21313007Swpaul		} else
21413007Swpaul			return(order);
21513007Swpaul	} else {
21613007Swpaul		CLIENT *clnt;
21713007Swpaul		ypresp_order *resp;
21813007Swpaul		ypreq_nokey req;
21913007Swpaul
22013007Swpaul		if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
22113007Swpaul			yp_error("%s",clnt_spcreateerror("couldn't create \
22213007Swpauludp handle to ypserv"));
22313007Swpaul			yp_errno = YPXFR_RPC;
22413007Swpaul			return(0);
22513007Swpaul		}
22613007Swpaul		req.map = map;
22713007Swpaul		req.domain = domain;
22813007Swpaul		if ((resp = ypproc_order_2(&req, clnt)) == NULL) {
22913007Swpaul			yp_error("%s", clnt_sperror(clnt, "YPPROC_ORDER \
23013007Swpaulfailed"));
23113007Swpaul			clnt_destroy(clnt);
23213007Swpaul			yp_errno = YPXFR_RPC;
23313007Swpaul			return(0);
23413007Swpaul		}
23513007Swpaul		clnt_destroy(clnt);
23613007Swpaul		if (resp->stat != YP_TRUE) {
23713007Swpaul			switch (resp->stat) {
23813895Swpaul			case YP_NODOM:
23913007Swpaul				yp_errno = YPXFR_NODOM;
24013007Swpaul				break;
24113895Swpaul			case YP_NOMAP:
24213007Swpaul				yp_errno = YPXFR_NOMAP;
24313007Swpaul				break;
24413895Swpaul			case YP_YPERR:
24513007Swpaul			default:
24613007Swpaul				yp_errno = YPXFR_YPERR;
24713007Swpaul				break;
24813007Swpaul			}
24913007Swpaul			return(0);
25013007Swpaul		}
25113007Swpaul		return(resp->ordernum);
25213007Swpaul	}
25313007Swpaul}
25419181Swpaul
25590298Sdesint
25690298Sdesypxfr_match(char *server, char *domain, char *map, char *key,
25790298Sdes    unsigned long keylen)
25819181Swpaul{
25919181Swpaul	ypreq_key ypkey;
26019181Swpaul	ypresp_val *ypval;
26119181Swpaul	CLIENT *clnt;
26219181Swpaul	static char buf[YPMAXRECORD + 2];
26319181Swpaul
26495658Sdes	bzero(buf, sizeof(buf));
26519181Swpaul
26619181Swpaul	if ((clnt = clnt_create(server, YPPROG,YPVERS,"udp")) == NULL) {
26719181Swpaul		yp_error("failed to create UDP handle: %s",
26819181Swpaul					clnt_spcreateerror(server));
26919181Swpaul		return(0);
27019181Swpaul	}
27119181Swpaul
27219181Swpaul	ypkey.domain = domain;
27319181Swpaul	ypkey.map = map;
27419181Swpaul	ypkey.key.keydat_len = keylen;
27519181Swpaul	ypkey.key.keydat_val = key;
27619181Swpaul
27719181Swpaul	if ((ypval = ypproc_match_2(&ypkey, clnt)) == NULL) {
27819181Swpaul		clnt_destroy(clnt);
27919181Swpaul		yp_error("%s: %s", server,
28019181Swpaul				clnt_sperror(clnt,"YPPROC_MATCH failed"));
28119181Swpaul		return(0);
28219181Swpaul	}
28319181Swpaul
28419181Swpaul	clnt_destroy(clnt);
28519181Swpaul
28619181Swpaul	if (ypval->stat != YP_TRUE) {
28795658Sdes		xdr_free((xdrproc_t)xdr_ypresp_val, ypval);
28819181Swpaul		return(0);
28919181Swpaul	}
29019181Swpaul
29195658Sdes	xdr_free((xdrproc_t)xdr_ypresp_val, ypval);
29219181Swpaul
29319181Swpaul	return(1);
29419181Swpaul}
295