Merge branch 'vendor/BYACC'
[dragonfly.git] / libexec / ypxfr / ypxfr_misc.c
1 /*
2  * Copyright (c) 1995
3  *      Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Bill Paul.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD: src/libexec/ypxfr/ypxfr_misc.c,v 1.9.2.2 2002/02/15 00:46:54 des Exp $
33  */
34
35 #include <stdio.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <sys/param.h>
40 #include <rpc/rpc.h>
41 #include <rpcsvc/yp.h>
42 struct dom_binding {};
43 #include <rpcsvc/ypclnt.h>
44 #include "ypxfr_extern.h"
45
46 const char *
47 ypxfrerr_string(ypxfrstat code)
48 {
49         switch (code) {
50         case YPXFR_SUCC:
51                 return ("Map successfully transferred");
52                 break;
53         case YPXFR_AGE:
54                 return ("Master's version not newer");
55                 break;
56         case YPXFR_NOMAP:
57                 return ("No such map in server's domain");
58                 break;
59         case YPXFR_NODOM:
60                 return ("Domain not supported by server");
61                 break;
62         case YPXFR_RSRC:
63                 return ("Local resource allocation failure");
64                 break;
65         case YPXFR_RPC:
66                 return ("RPC failure talking to server");
67                 break;
68         case YPXFR_MADDR:
69                 return ("Could not get master server address");
70                 break;
71         case YPXFR_YPERR:
72                 return ("NIS server/map database error");
73                 break;
74         case YPXFR_BADARGS:
75                 return ("Request arguments bad");
76                 break;
77         case YPXFR_DBM:
78                 return ("Local database operation failed");
79                 break;
80         case YPXFR_FILE:
81                 return ("Local file I/O operation failed");
82                 break;
83         case YPXFR_SKEW:
84                 return ("Map version skew during transfer");
85                 break;
86         case YPXFR_CLEAR:
87                 return ("Couldn't send \"clear\" request to local ypserv");
88                 break;
89         case YPXFR_FORCE:
90                 return ("No local order number in map -- use -f flag");
91                 break;
92         case YPXFR_XFRERR:
93                 return ("General ypxfr error");
94                 break;
95         case YPXFR_REFUSED:
96                 return ("Transfer request refused by ypserv");
97                 break;
98         default:
99                 return ("Unknown error code");
100                 break;
101         }
102 }
103
104 /*
105  * These are wrappers for the usual yp_master() and yp_order() functions.
106  * They can use either local yplib functions (the real yp_master() and
107  * yp_order()) or do direct RPCs to a specified server. The latter is
108  * necessary if ypxfr is run on a machine that isn't configured as an
109  * NIS client (this can happen very easily: a given machine need not be
110  * an NIS client in order to be an NIS server).
111  */
112
113 /*
114  * Careful: yp_master() returns a pointer to a dynamically allocated
115  * buffer. Calling ypproc_master_2() ourselves also returns a pointer
116  * to dynamically allocated memory, though this time it's memory
117  * allocated by the XDR routines. We have to rememver to free() or
118  * xdr_free() the memory as required to avoid leaking memory.
119  */
120 char *
121 ypxfr_get_master(char *domain, char *map, char *source, const int yplib)
122 {
123         static char mastername[MAXPATHLEN + 2];
124
125         bzero((char *)&mastername, sizeof(mastername));
126
127         if (yplib) {
128                 int res;
129                 char *master;
130                 if ((res = yp_master(domain, map, &master))) {
131                         switch (res) {
132                         case YPERR_DOMAIN:
133                                 yp_errno = YPXFR_NODOM;
134                                 break;
135                         case YPERR_MAP:
136                                 yp_errno = YPXFR_NOMAP;
137                                 break;
138                         case YPERR_YPERR:
139                         default:
140                                 yp_errno = YPXFR_YPERR;
141                                 break;
142                         }
143                         return(NULL);
144                 } else {
145                         snprintf(mastername, sizeof(mastername), "%s", master);
146                         free(master);
147                         return((char *)&mastername);
148                 }
149         } else {
150                 CLIENT *clnt;
151                 ypresp_master *resp;
152                 ypreq_nokey req;
153
154                 if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
155                         yp_error("%s",clnt_spcreateerror("failed to \
156 create udp handle to ypserv"));
157                         yp_errno = YPXFR_RPC;
158                         return(NULL);
159                 }
160
161                 req.map = map;
162                 req.domain = domain;
163                 if ((resp = ypproc_master_2(&req, clnt)) == NULL) {
164                         yp_error("%s",clnt_sperror(clnt,"YPPROC_MASTER \
165 failed"));
166                         clnt_destroy(clnt);
167                         yp_errno = YPXFR_RPC;
168                         return(NULL);
169                 }
170                 clnt_destroy(clnt);
171                 if (resp->stat != YP_TRUE) {
172                         switch (resp->stat) {
173                         case YP_NODOM:
174                                 yp_errno = YPXFR_NODOM;
175                                 break;
176                         case YP_NOMAP:
177                                 yp_errno = YPXFR_NOMAP;
178                                 break;
179                         case YP_YPERR:
180                         default:
181                                 yp_errno = YPXFR_YPERR;
182                                 break;
183                         }
184                         return(NULL);
185                 }
186                 snprintf(mastername, sizeof(mastername), "%s", resp->peer);
187 /*              xdr_free(xdr_ypresp_master, (char *)&resp); */
188                 return((char *)&mastername);
189         }
190 }
191
192 unsigned long
193 ypxfr_get_order(char *domain, char *map, char *source, const int yplib)
194 {
195         if (yplib) {
196                 unsigned long order;
197                 int res;
198                 if ((res = yp_order(domain, map, (int *)&order))) {
199                         switch (res) {
200                         case YPERR_DOMAIN:
201                                 yp_errno = YPXFR_NODOM;
202                                 break;
203                         case YPERR_MAP:
204                                 yp_errno = YPXFR_NOMAP;
205                                 break;
206                         case YPERR_YPERR:
207                         default:
208                                 yp_errno = YPXFR_YPERR;
209                                 break;
210                         }
211                         return(0);
212                 } else
213                         return(order);
214         } else {
215                 CLIENT *clnt;
216                 ypresp_order *resp;
217                 ypreq_nokey req;
218
219                 if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
220                         yp_error("%s",clnt_spcreateerror("couldn't create \
221 udp handle to ypserv"));
222                         yp_errno = YPXFR_RPC;
223                         return(0);
224                 }
225                 req.map = map;
226                 req.domain = domain;
227                 if ((resp = ypproc_order_2(&req, clnt)) == NULL) {
228                         yp_error("%s", clnt_sperror(clnt, "YPPROC_ORDER \
229 failed"));
230                         clnt_destroy(clnt);
231                         yp_errno = YPXFR_RPC;
232                         return(0);
233                 }
234                 clnt_destroy(clnt);
235                 if (resp->stat != YP_TRUE) {
236                         switch (resp->stat) {
237                         case YP_NODOM:
238                                 yp_errno = YPXFR_NODOM;
239                                 break;
240                         case YP_NOMAP:
241                                 yp_errno = YPXFR_NOMAP;
242                                 break;
243                         case YP_YPERR:
244                         default:
245                                 yp_errno = YPXFR_YPERR;
246                                 break;
247                         }
248                         return(0);
249                 }
250                 return(resp->ordernum);
251         }
252 }
253
254 int
255 ypxfr_match(char *server, char *domain, char *map, char *key,
256     unsigned long keylen)
257 {
258         ypreq_key ypkey;
259         ypresp_val *ypval;
260         CLIENT *clnt;
261         static char buf[YPMAXRECORD + 2];
262
263         bzero((char *)buf, sizeof(buf));
264
265         if ((clnt = clnt_create(server, YPPROG,YPVERS,"udp")) == NULL) {
266                 yp_error("failed to create UDP handle: %s",
267                                         clnt_spcreateerror(server));
268                 return(0);
269         }
270
271         ypkey.domain = domain;
272         ypkey.map = map;
273         ypkey.key.keydat_len = keylen;
274         ypkey.key.keydat_val = key;
275
276         if ((ypval = ypproc_match_2(&ypkey, clnt)) == NULL) {
277                 clnt_destroy(clnt);
278                 yp_error("%s: %s", server,
279                                 clnt_sperror(clnt,"YPPROC_MATCH failed"));
280                 return(0);
281         }
282
283         clnt_destroy(clnt);
284
285         if (ypval->stat != YP_TRUE) {
286                 xdr_free((xdrproc_t)xdr_ypresp_val, ypval);
287                 return(0);
288         }
289
290         xdr_free((xdrproc_t)xdr_ypresp_val, ypval);
291
292         return(1);
293 }