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$"); 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> 4313007Swpaul#include <rpcsvc/ypclnt.h> 4413007Swpaul#include "ypxfr_extern.h" 4513007Swpaul 4693979Sdesconst char * 4790298Sdesypxfrerr_string(ypxfrstat code) 4813007Swpaul{ 4990297Sdes switch (code) { 5013007Swpaul case YPXFR_SUCC: 5161187Sjlemon return ("Map successfully transferred"); 5213007Swpaul break; 5313007Swpaul case YPXFR_AGE: 5413007Swpaul return ("Master's version not newer"); 5513007Swpaul break; 5613007Swpaul case YPXFR_NOMAP: 5713007Swpaul return ("No such map in server's domain"); 5813007Swpaul break; 5913007Swpaul case YPXFR_NODOM: 6013007Swpaul return ("Domain not supported by server"); 6113007Swpaul break; 6213007Swpaul case YPXFR_RSRC: 6313007Swpaul return ("Local resource allocation failure"); 6413007Swpaul break; 6513007Swpaul case YPXFR_RPC: 6613007Swpaul return ("RPC failure talking to server"); 6713007Swpaul break; 6813007Swpaul case YPXFR_MADDR: 6913007Swpaul return ("Could not get master server address"); 7013007Swpaul break; 7113007Swpaul case YPXFR_YPERR: 7213007Swpaul return ("NIS server/map database error"); 7313007Swpaul break; 7413007Swpaul case YPXFR_BADARGS: 7513007Swpaul return ("Request arguments bad"); 7613007Swpaul break; 7713007Swpaul case YPXFR_DBM: 7813007Swpaul return ("Local database operation failed"); 7913007Swpaul break; 8013007Swpaul case YPXFR_FILE: 8113007Swpaul return ("Local file I/O operation failed"); 8213007Swpaul break; 8313007Swpaul case YPXFR_SKEW: 8413007Swpaul return ("Map version skew during transfer"); 8513007Swpaul break; 8613007Swpaul case YPXFR_CLEAR: 8713007Swpaul return ("Couldn't send \"clear\" request to local ypserv"); 8813007Swpaul break; 8913007Swpaul case YPXFR_FORCE: 9013007Swpaul return ("No local order number in map -- use -f flag"); 9113007Swpaul break; 9213007Swpaul case YPXFR_XFRERR: 9313007Swpaul return ("General ypxfr error"); 9413007Swpaul break; 9513007Swpaul case YPXFR_REFUSED: 9613007Swpaul return ("Transfer request refused by ypserv"); 9713007Swpaul break; 9813007Swpaul default: 9913007Swpaul return ("Unknown error code"); 10013007Swpaul break; 10113007Swpaul } 10213007Swpaul} 10313007Swpaul 10413007Swpaul/* 10513007Swpaul * These are wrappers for the usual yp_master() and yp_order() functions. 10613007Swpaul * They can use either local yplib functions (the real yp_master() and 10713007Swpaul * yp_order()) or do direct RPCs to a specified server. The latter is 10813007Swpaul * necessary if ypxfr is run on a machine that isn't configured as an 10913007Swpaul * NIS client (this can happen very easily: a given machine need not be 11013007Swpaul * an NIS client in order to be an NIS server). 11113007Swpaul */ 11213007Swpaul 11313895Swpaul/* 11413895Swpaul * Careful: yp_master() returns a pointer to a dynamically allocated 11513895Swpaul * buffer. Calling ypproc_master_2() ourselves also returns a pointer 11613895Swpaul * to dynamically allocated memory, though this time it's memory 11713895Swpaul * allocated by the XDR routines. We have to rememver to free() or 11813895Swpaul * xdr_free() the memory as required to avoid leaking memory. 11913895Swpaul */ 12090298Sdeschar * 12190298Sdesypxfr_get_master(char *domain, char *map, char *source, const int yplib) 12213007Swpaul{ 12313895Swpaul static char mastername[MAXPATHLEN + 2]; 12413895Swpaul 12513895Swpaul bzero((char *)&mastername, sizeof(mastername)); 12613895Swpaul 12713007Swpaul if (yplib) { 12813007Swpaul int res; 12913007Swpaul char *master; 13013007Swpaul if ((res = yp_master(domain, map, &master))) { 13113007Swpaul switch (res) { 13213007Swpaul case YPERR_DOMAIN: 133229142Sdim yp_errno = (enum ypstat)YPXFR_NODOM; 13413007Swpaul break; 13513007Swpaul case YPERR_MAP: 136229142Sdim yp_errno = (enum ypstat)YPXFR_NOMAP; 13713007Swpaul break; 13813007Swpaul case YPERR_YPERR: 13913007Swpaul default: 140229142Sdim yp_errno = (enum ypstat)YPXFR_YPERR; 14113007Swpaul break; 14213007Swpaul } 14313007Swpaul return(NULL); 14413895Swpaul } else { 14513895Swpaul snprintf(mastername, sizeof(mastername), "%s", master); 14613895Swpaul free(master); 14713895Swpaul return((char *)&mastername); 14813895Swpaul } 14913007Swpaul } else { 15013007Swpaul CLIENT *clnt; 15113007Swpaul ypresp_master *resp; 15213007Swpaul ypreq_nokey req; 15313007Swpaul 15413007Swpaul if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) { 15513007Swpaul yp_error("%s",clnt_spcreateerror("failed to \ 15613007Swpaulcreate udp handle to ypserv")); 157229142Sdim yp_errno = (enum ypstat)YPXFR_RPC; 15813007Swpaul return(NULL); 15913007Swpaul } 16013007Swpaul 16113007Swpaul req.map = map; 16213007Swpaul req.domain = domain; 16313007Swpaul if ((resp = ypproc_master_2(&req, clnt)) == NULL) { 16413007Swpaul yp_error("%s",clnt_sperror(clnt,"YPPROC_MASTER \ 16513007Swpaulfailed")); 16613007Swpaul clnt_destroy(clnt); 167229142Sdim yp_errno = (enum ypstat)YPXFR_RPC; 16813007Swpaul return(NULL); 16913007Swpaul } 17013007Swpaul clnt_destroy(clnt); 17113007Swpaul if (resp->stat != YP_TRUE) { 17213007Swpaul switch (resp->stat) { 17313007Swpaul case YP_NODOM: 174229142Sdim yp_errno = (enum ypstat)YPXFR_NODOM; 17513007Swpaul break; 17613007Swpaul case YP_NOMAP: 177229142Sdim yp_errno = (enum ypstat)YPXFR_NOMAP; 17813007Swpaul break; 17913007Swpaul case YP_YPERR: 18013007Swpaul default: 181229142Sdim yp_errno = (enum ypstat)YPXFR_YPERR; 18213007Swpaul break; 18313007Swpaul } 18413007Swpaul return(NULL); 18513007Swpaul } 18613895Swpaul snprintf(mastername, sizeof(mastername), "%s", resp->peer); 18716132Swpaul/* xdr_free(xdr_ypresp_master, (char *)&resp); */ 18813895Swpaul return((char *)&mastername); 18913007Swpaul } 19013007Swpaul} 19190297Sdes 19290298Sdesunsigned long 19390298Sdesypxfr_get_order(char *domain, char *map, char *source, const int yplib) 19413007Swpaul{ 19513007Swpaul if (yplib) { 196125868Sdas unsigned int order; 19713007Swpaul int res; 198125868Sdas if ((res = yp_order(domain, map, &order))) { 19913007Swpaul switch (res) { 20013895Swpaul case YPERR_DOMAIN: 201229142Sdim yp_errno = (enum ypstat)YPXFR_NODOM; 20213007Swpaul break; 20313895Swpaul case YPERR_MAP: 204229142Sdim yp_errno = (enum ypstat)YPXFR_NOMAP; 20513007Swpaul break; 20613895Swpaul case YPERR_YPERR: 20713007Swpaul default: 208229142Sdim yp_errno = (enum ypstat)YPXFR_YPERR; 20913007Swpaul break; 21013007Swpaul } 21113007Swpaul return(0); 21213007Swpaul } else 21313007Swpaul return(order); 21413007Swpaul } else { 21513007Swpaul CLIENT *clnt; 21613007Swpaul ypresp_order *resp; 21713007Swpaul ypreq_nokey req; 21813007Swpaul 21913007Swpaul if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) { 22013007Swpaul yp_error("%s",clnt_spcreateerror("couldn't create \ 22113007Swpauludp handle to ypserv")); 222229142Sdim yp_errno = (enum ypstat)YPXFR_RPC; 22313007Swpaul return(0); 22413007Swpaul } 22513007Swpaul req.map = map; 22613007Swpaul req.domain = domain; 22713007Swpaul if ((resp = ypproc_order_2(&req, clnt)) == NULL) { 22813007Swpaul yp_error("%s", clnt_sperror(clnt, "YPPROC_ORDER \ 22913007Swpaulfailed")); 23013007Swpaul clnt_destroy(clnt); 231229142Sdim yp_errno = (enum ypstat)YPXFR_RPC; 23213007Swpaul return(0); 23313007Swpaul } 23413007Swpaul clnt_destroy(clnt); 23513007Swpaul if (resp->stat != YP_TRUE) { 23613007Swpaul switch (resp->stat) { 23713895Swpaul case YP_NODOM: 238229142Sdim yp_errno = (enum ypstat)YPXFR_NODOM; 23913007Swpaul break; 24013895Swpaul case YP_NOMAP: 241229142Sdim yp_errno = (enum ypstat)YPXFR_NOMAP; 24213007Swpaul break; 24313895Swpaul case YP_YPERR: 24413007Swpaul default: 245229142Sdim yp_errno = (enum ypstat)YPXFR_YPERR; 24613007Swpaul break; 24713007Swpaul } 24813007Swpaul return(0); 24913007Swpaul } 25013007Swpaul return(resp->ordernum); 25113007Swpaul } 25213007Swpaul} 25319181Swpaul 25490298Sdesint 25590298Sdesypxfr_match(char *server, char *domain, char *map, char *key, 25690298Sdes unsigned long keylen) 25719181Swpaul{ 25819181Swpaul ypreq_key ypkey; 25919181Swpaul ypresp_val *ypval; 26019181Swpaul CLIENT *clnt; 26119181Swpaul static char buf[YPMAXRECORD + 2]; 26219181Swpaul 26395658Sdes bzero(buf, sizeof(buf)); 26419181Swpaul 26519181Swpaul if ((clnt = clnt_create(server, YPPROG,YPVERS,"udp")) == NULL) { 26619181Swpaul yp_error("failed to create UDP handle: %s", 26719181Swpaul clnt_spcreateerror(server)); 26819181Swpaul return(0); 26919181Swpaul } 27019181Swpaul 27119181Swpaul ypkey.domain = domain; 27219181Swpaul ypkey.map = map; 27319181Swpaul ypkey.key.keydat_len = keylen; 27419181Swpaul ypkey.key.keydat_val = key; 27519181Swpaul 27619181Swpaul if ((ypval = ypproc_match_2(&ypkey, clnt)) == NULL) { 27719181Swpaul clnt_destroy(clnt); 27819181Swpaul yp_error("%s: %s", server, 27919181Swpaul clnt_sperror(clnt,"YPPROC_MATCH failed")); 28019181Swpaul return(0); 28119181Swpaul } 28219181Swpaul 28319181Swpaul clnt_destroy(clnt); 28419181Swpaul 28519181Swpaul if (ypval->stat != YP_TRUE) { 28695658Sdes xdr_free((xdrproc_t)xdr_ypresp_val, ypval); 28719181Swpaul return(0); 28819181Swpaul } 28919181Swpaul 29095658Sdes xdr_free((xdrproc_t)xdr_ypresp_val, ypval); 29119181Swpaul 29219181Swpaul return(1); 29319181Swpaul} 294