1*df57947fSPedro F. Giffuni /*-
2*df57947fSPedro F. Giffuni * SPDX-License-Identifier: BSD-4-Clause
3*df57947fSPedro F. Giffuni *
4665823d0SBill Paul * Copyright (c) 1995
5665823d0SBill Paul * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
6665823d0SBill Paul *
7665823d0SBill Paul * Redistribution and use in source and binary forms, with or without
8665823d0SBill Paul * modification, are permitted provided that the following conditions
9665823d0SBill Paul * are met:
10665823d0SBill Paul * 1. Redistributions of source code must retain the above copyright
11665823d0SBill Paul * notice, this list of conditions and the following disclaimer.
12665823d0SBill Paul * 2. Redistributions in binary form must reproduce the above copyright
13665823d0SBill Paul * notice, this list of conditions and the following disclaimer in the
14665823d0SBill Paul * documentation and/or other materials provided with the distribution.
15665823d0SBill Paul * 3. All advertising materials mentioning features or use of this software
16665823d0SBill Paul * must display the following acknowledgement:
17665823d0SBill Paul * This product includes software developed by Bill Paul.
18665823d0SBill Paul * 4. Neither the name of the author nor the names of any co-contributors
19665823d0SBill Paul * may be used to endorse or promote products derived from this software
20665823d0SBill Paul * without specific prior written permission.
21665823d0SBill Paul *
22665823d0SBill Paul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23665823d0SBill Paul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24665823d0SBill Paul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25665823d0SBill Paul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
26665823d0SBill Paul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27665823d0SBill Paul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28665823d0SBill Paul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29665823d0SBill Paul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30665823d0SBill Paul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31665823d0SBill Paul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32665823d0SBill Paul * SUCH DAMAGE.
33665823d0SBill Paul */
3427eed7e3SPhilippe Charnier
3522e9bc15SDavid E. O'Brien #include <sys/cdefs.h>
3681a82d4dSBill Paul #include <stdio.h>
3781a82d4dSBill Paul #include <string.h>
38bc66df81SBill Paul #include <stdlib.h>
39bc66df81SBill Paul #include <unistd.h>
40bc66df81SBill Paul #include <sys/param.h>
41665823d0SBill Paul #include <rpc/rpc.h>
42665823d0SBill Paul #include <rpcsvc/yp.h>
43665823d0SBill Paul #include <rpcsvc/ypclnt.h>
44665823d0SBill Paul #include "ypxfr_extern.h"
45665823d0SBill Paul
46425dd8acSDag-Erling Smørgrav const char *
ypxfrerr_string(ypxfrstat code)47dc584ddbSDag-Erling Smørgrav ypxfrerr_string(ypxfrstat code)
48665823d0SBill Paul {
49665823d0SBill Paul switch (code) {
50665823d0SBill Paul case YPXFR_SUCC:
517d664a2fSJonathan Lemon return ("Map successfully transferred");
52665823d0SBill Paul break;
53665823d0SBill Paul case YPXFR_AGE:
54665823d0SBill Paul return ("Master's version not newer");
55665823d0SBill Paul break;
56665823d0SBill Paul case YPXFR_NOMAP:
57665823d0SBill Paul return ("No such map in server's domain");
58665823d0SBill Paul break;
59665823d0SBill Paul case YPXFR_NODOM:
60665823d0SBill Paul return ("Domain not supported by server");
61665823d0SBill Paul break;
62665823d0SBill Paul case YPXFR_RSRC:
63665823d0SBill Paul return ("Local resource allocation failure");
64665823d0SBill Paul break;
65665823d0SBill Paul case YPXFR_RPC:
66665823d0SBill Paul return ("RPC failure talking to server");
67665823d0SBill Paul break;
68665823d0SBill Paul case YPXFR_MADDR:
69665823d0SBill Paul return ("Could not get master server address");
70665823d0SBill Paul break;
71665823d0SBill Paul case YPXFR_YPERR:
72665823d0SBill Paul return ("NIS server/map database error");
73665823d0SBill Paul break;
74665823d0SBill Paul case YPXFR_BADARGS:
75665823d0SBill Paul return ("Request arguments bad");
76665823d0SBill Paul break;
77665823d0SBill Paul case YPXFR_DBM:
78665823d0SBill Paul return ("Local database operation failed");
79665823d0SBill Paul break;
80665823d0SBill Paul case YPXFR_FILE:
81665823d0SBill Paul return ("Local file I/O operation failed");
82665823d0SBill Paul break;
83665823d0SBill Paul case YPXFR_SKEW:
84665823d0SBill Paul return ("Map version skew during transfer");
85665823d0SBill Paul break;
86665823d0SBill Paul case YPXFR_CLEAR:
87665823d0SBill Paul return ("Couldn't send \"clear\" request to local ypserv");
88665823d0SBill Paul break;
89665823d0SBill Paul case YPXFR_FORCE:
90665823d0SBill Paul return ("No local order number in map -- use -f flag");
91665823d0SBill Paul break;
92665823d0SBill Paul case YPXFR_XFRERR:
93665823d0SBill Paul return ("General ypxfr error");
94665823d0SBill Paul break;
95665823d0SBill Paul case YPXFR_REFUSED:
96665823d0SBill Paul return ("Transfer request refused by ypserv");
97665823d0SBill Paul break;
98665823d0SBill Paul default:
99665823d0SBill Paul return ("Unknown error code");
100665823d0SBill Paul break;
101665823d0SBill Paul }
102665823d0SBill Paul }
103665823d0SBill Paul
104665823d0SBill Paul /*
105665823d0SBill Paul * These are wrappers for the usual yp_master() and yp_order() functions.
106665823d0SBill Paul * They can use either local yplib functions (the real yp_master() and
107665823d0SBill Paul * yp_order()) or do direct RPCs to a specified server. The latter is
108665823d0SBill Paul * necessary if ypxfr is run on a machine that isn't configured as an
109665823d0SBill Paul * NIS client (this can happen very easily: a given machine need not be
110665823d0SBill Paul * an NIS client in order to be an NIS server).
111665823d0SBill Paul */
112665823d0SBill Paul
113bc66df81SBill Paul /*
114bc66df81SBill Paul * Careful: yp_master() returns a pointer to a dynamically allocated
115bc66df81SBill Paul * buffer. Calling ypproc_master_2() ourselves also returns a pointer
116bc66df81SBill Paul * to dynamically allocated memory, though this time it's memory
117bc66df81SBill Paul * allocated by the XDR routines. We have to rememver to free() or
118bc66df81SBill Paul * xdr_free() the memory as required to avoid leaking memory.
119bc66df81SBill Paul */
120dc584ddbSDag-Erling Smørgrav char *
ypxfr_get_master(char * domain,char * map,char * source,const int yplib)121dc584ddbSDag-Erling Smørgrav ypxfr_get_master(char *domain, char *map, char *source, const int yplib)
122665823d0SBill Paul {
123bc66df81SBill Paul static char mastername[MAXPATHLEN + 2];
124bc66df81SBill Paul
125bc66df81SBill Paul bzero((char *)&mastername, sizeof(mastername));
126bc66df81SBill Paul
127665823d0SBill Paul if (yplib) {
128665823d0SBill Paul int res;
129665823d0SBill Paul char *master;
130665823d0SBill Paul if ((res = yp_master(domain, map, &master))) {
131665823d0SBill Paul switch (res) {
132665823d0SBill Paul case YPERR_DOMAIN:
1333eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_NODOM;
134665823d0SBill Paul break;
135665823d0SBill Paul case YPERR_MAP:
1363eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_NOMAP;
137665823d0SBill Paul break;
138665823d0SBill Paul case YPERR_YPERR:
139665823d0SBill Paul default:
1403eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_YPERR;
141665823d0SBill Paul break;
142665823d0SBill Paul }
143665823d0SBill Paul return(NULL);
144bc66df81SBill Paul } else {
145bc66df81SBill Paul snprintf(mastername, sizeof(mastername), "%s", master);
146bc66df81SBill Paul free(master);
147bc66df81SBill Paul return((char *)&mastername);
148bc66df81SBill Paul }
149665823d0SBill Paul } else {
150665823d0SBill Paul CLIENT *clnt;
151665823d0SBill Paul ypresp_master *resp;
152665823d0SBill Paul ypreq_nokey req;
153665823d0SBill Paul
154665823d0SBill Paul if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
155665823d0SBill Paul yp_error("%s",clnt_spcreateerror("failed to \
156665823d0SBill Paul create udp handle to ypserv"));
1573eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_RPC;
158665823d0SBill Paul return(NULL);
159665823d0SBill Paul }
160665823d0SBill Paul
161665823d0SBill Paul req.map = map;
162665823d0SBill Paul req.domain = domain;
163665823d0SBill Paul if ((resp = ypproc_master_2(&req, clnt)) == NULL) {
164665823d0SBill Paul yp_error("%s",clnt_sperror(clnt,"YPPROC_MASTER \
165665823d0SBill Paul failed"));
166665823d0SBill Paul clnt_destroy(clnt);
1673eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_RPC;
168665823d0SBill Paul return(NULL);
169665823d0SBill Paul }
170665823d0SBill Paul clnt_destroy(clnt);
171665823d0SBill Paul if (resp->stat != YP_TRUE) {
172665823d0SBill Paul switch (resp->stat) {
173665823d0SBill Paul case YP_NODOM:
1743eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_NODOM;
175665823d0SBill Paul break;
176665823d0SBill Paul case YP_NOMAP:
1773eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_NOMAP;
178665823d0SBill Paul break;
179665823d0SBill Paul case YP_YPERR:
180665823d0SBill Paul default:
1813eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_YPERR;
182665823d0SBill Paul break;
183665823d0SBill Paul }
184665823d0SBill Paul return(NULL);
185665823d0SBill Paul }
186bc66df81SBill Paul snprintf(mastername, sizeof(mastername), "%s", resp->peer);
187a7bd0e76SBill Paul /* xdr_free(xdr_ypresp_master, (char *)&resp); */
188bc66df81SBill Paul return((char *)&mastername);
189665823d0SBill Paul }
190665823d0SBill Paul }
191665823d0SBill Paul
192dc584ddbSDag-Erling Smørgrav unsigned long
ypxfr_get_order(char * domain,char * map,char * source,const int yplib)193dc584ddbSDag-Erling Smørgrav ypxfr_get_order(char *domain, char *map, char *source, const int yplib)
194665823d0SBill Paul {
195665823d0SBill Paul if (yplib) {
1964f70638eSDavid Schultz unsigned int order;
197665823d0SBill Paul int res;
1984f70638eSDavid Schultz if ((res = yp_order(domain, map, &order))) {
199665823d0SBill Paul switch (res) {
200bc66df81SBill Paul case YPERR_DOMAIN:
2013eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_NODOM;
202665823d0SBill Paul break;
203bc66df81SBill Paul case YPERR_MAP:
2043eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_NOMAP;
205665823d0SBill Paul break;
206bc66df81SBill Paul case YPERR_YPERR:
207665823d0SBill Paul default:
2083eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_YPERR;
209665823d0SBill Paul break;
210665823d0SBill Paul }
211665823d0SBill Paul return(0);
212665823d0SBill Paul } else
213665823d0SBill Paul return(order);
214665823d0SBill Paul } else {
215665823d0SBill Paul CLIENT *clnt;
216665823d0SBill Paul ypresp_order *resp;
217665823d0SBill Paul ypreq_nokey req;
218665823d0SBill Paul
219665823d0SBill Paul if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
220665823d0SBill Paul yp_error("%s",clnt_spcreateerror("couldn't create \
221665823d0SBill Paul udp handle to ypserv"));
2223eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_RPC;
223665823d0SBill Paul return(0);
224665823d0SBill Paul }
225665823d0SBill Paul req.map = map;
226665823d0SBill Paul req.domain = domain;
227665823d0SBill Paul if ((resp = ypproc_order_2(&req, clnt)) == NULL) {
228665823d0SBill Paul yp_error("%s", clnt_sperror(clnt, "YPPROC_ORDER \
229665823d0SBill Paul failed"));
230665823d0SBill Paul clnt_destroy(clnt);
2313eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_RPC;
232665823d0SBill Paul return(0);
233665823d0SBill Paul }
234665823d0SBill Paul clnt_destroy(clnt);
235665823d0SBill Paul if (resp->stat != YP_TRUE) {
236665823d0SBill Paul switch (resp->stat) {
237bc66df81SBill Paul case YP_NODOM:
2383eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_NODOM;
239665823d0SBill Paul break;
240bc66df81SBill Paul case YP_NOMAP:
2413eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_NOMAP;
242665823d0SBill Paul break;
243bc66df81SBill Paul case YP_YPERR:
244665823d0SBill Paul default:
2453eb9425cSDimitry Andric yp_errno = (enum ypstat)YPXFR_YPERR;
246665823d0SBill Paul break;
247665823d0SBill Paul }
248665823d0SBill Paul return(0);
249665823d0SBill Paul }
250665823d0SBill Paul return(resp->ordernum);
251665823d0SBill Paul }
252665823d0SBill Paul }
25381a82d4dSBill Paul
254dc584ddbSDag-Erling Smørgrav int
ypxfr_match(char * server,char * domain,char * map,char * key,unsigned long keylen)255dc584ddbSDag-Erling Smørgrav ypxfr_match(char *server, char *domain, char *map, char *key,
256dc584ddbSDag-Erling Smørgrav unsigned long keylen)
25781a82d4dSBill Paul {
25881a82d4dSBill Paul ypreq_key ypkey;
25981a82d4dSBill Paul ypresp_val *ypval;
26081a82d4dSBill Paul CLIENT *clnt;
26181a82d4dSBill Paul static char buf[YPMAXRECORD + 2];
26281a82d4dSBill Paul
263f249dbccSDag-Erling Smørgrav bzero(buf, sizeof(buf));
26481a82d4dSBill Paul
26581a82d4dSBill Paul if ((clnt = clnt_create(server, YPPROG,YPVERS,"udp")) == NULL) {
26681a82d4dSBill Paul yp_error("failed to create UDP handle: %s",
26781a82d4dSBill Paul clnt_spcreateerror(server));
26881a82d4dSBill Paul return(0);
26981a82d4dSBill Paul }
27081a82d4dSBill Paul
27181a82d4dSBill Paul ypkey.domain = domain;
27281a82d4dSBill Paul ypkey.map = map;
27381a82d4dSBill Paul ypkey.key.keydat_len = keylen;
27481a82d4dSBill Paul ypkey.key.keydat_val = key;
27581a82d4dSBill Paul
27681a82d4dSBill Paul if ((ypval = ypproc_match_2(&ypkey, clnt)) == NULL) {
27781a82d4dSBill Paul clnt_destroy(clnt);
27881a82d4dSBill Paul yp_error("%s: %s", server,
27981a82d4dSBill Paul clnt_sperror(clnt,"YPPROC_MATCH failed"));
28081a82d4dSBill Paul return(0);
28181a82d4dSBill Paul }
28281a82d4dSBill Paul
28381a82d4dSBill Paul clnt_destroy(clnt);
28481a82d4dSBill Paul
28581a82d4dSBill Paul if (ypval->stat != YP_TRUE) {
286f249dbccSDag-Erling Smørgrav xdr_free((xdrproc_t)xdr_ypresp_val, ypval);
28781a82d4dSBill Paul return(0);
28881a82d4dSBill Paul }
28981a82d4dSBill Paul
290f249dbccSDag-Erling Smørgrav xdr_free((xdrproc_t)xdr_ypresp_val, ypval);
29181a82d4dSBill Paul
29281a82d4dSBill Paul return(1);
29381a82d4dSBill Paul }
294