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