]>
Commit | Line | Data |
---|---|---|
b7080c8e A |
1 | /* |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
ac2f15b3 A |
6 | * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. |
7 | * | |
8 | * This file contains Original Code and/or Modifications of Original Code | |
9 | * as defined in and that are subject to the Apple Public Source License | |
10 | * Version 2.0 (the 'License'). You may not use this file except in | |
11 | * compliance with the License. Please obtain a copy of the License at | |
12 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
13 | * file. | |
b7080c8e A |
14 | * |
15 | * The Original Code and all software distributed under the License are | |
16 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
17 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
18 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
ac2f15b3 A |
19 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
20 | * Please see the License for the specific language governing rights and | |
21 | * limitations under the License. | |
b7080c8e A |
22 | * |
23 | * @APPLE_LICENSE_HEADER_END@ | |
24 | */ | |
25 | /* $OpenBSD: ypserv_proc.c,v 1.14 1997/09/12 01:44:57 deraadt Exp $ */ | |
26 | ||
27 | /* | |
28 | * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se> | |
29 | * All rights reserved. | |
30 | * | |
31 | * Redistribution and use in source and binary forms, with or without | |
32 | * modification, are permitted provided that the following conditions | |
33 | * are met: | |
34 | * 1. Redistributions of source code must retain the above copyright | |
35 | * notice, this list of conditions and the following disclaimer. | |
36 | * 2. Redistributions in binary form must reproduce the above copyright | |
37 | * notice, this list of conditions and the following disclaimer in the | |
38 | * documentation and/or other materials provided with the distribution. | |
39 | * 3. All advertising materials mentioning features or use of this software | |
40 | * must display the following acknowledgement: | |
41 | * This product includes software developed by Mats O Jansson | |
42 | * 4. The name of the author may not be used to endorse or promote products | |
43 | * derived from this software without specific prior written permission. | |
44 | * | |
45 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | |
46 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
47 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
49 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
55 | * SUCH DAMAGE. | |
56 | */ | |
57 | ||
58 | #ifndef LINT | |
59 | static char rcsid[] = "$OpenBSD: ypserv_proc.c,v 1.14 1997/09/12 01:44:57 deraadt Exp $"; | |
60 | #endif | |
61 | ||
62 | #include <rpc/rpc.h> | |
63 | #include "yp.h" | |
64 | #include "ypv1.h" | |
65 | #include <rpcsvc/ypclnt.h> | |
66 | #include <sys/stat.h> | |
67 | #include <sys/socket.h> | |
68 | #include <sys/param.h> | |
69 | #include <netinet/in.h> | |
70 | #include <arpa/inet.h> | |
71 | #include "ypdb.h" | |
72 | #include <fcntl.h> | |
73 | #include <dirent.h> | |
74 | #include <stdio.h> | |
75 | #include <string.h> | |
76 | #include <unistd.h> | |
77 | #include <stdlib.h> | |
78 | #include "yplog.h" | |
79 | #include "ypdef.h" | |
80 | ||
81 | #ifdef DEBUG | |
82 | #define YPLOG yplog | |
83 | #else /* DEBUG */ | |
84 | #define YPLOG if (!ok) yplog | |
85 | #endif /* DEBUG */ | |
86 | ||
87 | extern ypresp_val ypdb_get_record(); | |
88 | extern ypresp_key_val ypdb_get_first(); | |
89 | extern ypresp_key_val ypdb_get_next(); | |
90 | extern ypresp_order ypdb_get_order(); | |
91 | extern ypresp_master ypdb_get_master(); | |
92 | extern bool_t ypdb_xdr_get_all(); | |
93 | extern void ypdb_close_all(); | |
94 | extern int ypdb_secure(); | |
95 | ||
96 | static char *True = "true"; | |
97 | static char *False = "FALSE"; | |
98 | #define TORF(N) ((N) ? True : False) | |
99 | void * | |
100 | ypproc_null_2_svc(argp, rqstp) | |
101 | void *argp; | |
102 | struct svc_req *rqstp; | |
103 | { | |
104 | static char *result; | |
105 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
106 | int ok = acl_check_host(&caller->sin_addr); | |
107 | ||
108 | YPLOG("null_2: caller=[%s].%d, auth_ok=%s", | |
109 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok)); | |
110 | ||
111 | if (!ok) { | |
112 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
113 | return(NULL); | |
114 | } | |
115 | ||
116 | result = NULL; | |
117 | ||
118 | return ((void *)&result); | |
119 | } | |
120 | ||
121 | bool_t * | |
122 | ypproc_domain_2_svc(argp, rqstp) | |
123 | domainname *argp; | |
124 | struct svc_req *rqstp; | |
125 | { | |
126 | static bool_t result; /* is domain_served? */ | |
127 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
128 | int ok = acl_check_host(&caller->sin_addr); | |
129 | static char domain_path[MAXPATHLEN]; | |
130 | struct stat finfo; | |
131 | ||
132 | if (strchr(*argp, '/')) | |
133 | goto bail; | |
134 | snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp); | |
135 | result = (bool_t) ((stat(domain_path, &finfo) == 0) && | |
136 | (finfo.st_mode & S_IFDIR)); | |
137 | ||
138 | YPLOG("domain_2: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s", | |
139 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
140 | TORF(ok), *argp, TORF(result)); | |
141 | ||
142 | if (!ok) { | |
143 | bail: | |
144 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
145 | return(NULL); | |
146 | } | |
147 | ||
148 | return (&result); | |
149 | } | |
150 | ||
151 | bool_t * | |
152 | ypproc_domain_nonack_2_svc(argp, rqstp) | |
153 | domainname *argp; | |
154 | struct svc_req *rqstp; | |
155 | { | |
156 | static bool_t result; /* is domain served? */ | |
157 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
158 | int ok = acl_check_host(&caller->sin_addr); | |
159 | static char domain_path[MAXPATHLEN]; | |
160 | struct stat finfo; | |
161 | ||
162 | if (strchr(*argp, '/')) | |
163 | goto bail; | |
164 | snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp); | |
165 | result = (bool_t) ((stat(domain_path, &finfo) == 0) && | |
166 | (finfo.st_mode & S_IFDIR)); | |
167 | ||
168 | YPLOG( | |
169 | "domain_nonack_2: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s", | |
170 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), | |
171 | *argp, TORF(result)); | |
172 | ||
173 | if (!ok) { | |
174 | bail: | |
175 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
176 | return(NULL); | |
177 | } | |
178 | ||
179 | if (!result) { | |
180 | return(NULL); /* don't send nack */ | |
181 | } | |
182 | ||
183 | return (&result); | |
184 | } | |
185 | ||
186 | ypresp_val * | |
187 | ypproc_match_2_svc(argp, rqstp) | |
188 | ypreq_key *argp; | |
189 | struct svc_req *rqstp; | |
190 | { | |
191 | static ypresp_val res; | |
192 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
193 | int ok = acl_check_host(&caller->sin_addr); | |
194 | int secure = ypdb_secure(argp->domain,argp->map); | |
195 | ||
196 | if (strchr(argp->domain, '/') || strchr(argp->map, '/')) | |
197 | goto bail; | |
198 | YPLOG( | |
199 | "match_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s", | |
200 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
201 | TORF(ok), TORF(secure), | |
202 | argp->domain, argp->map, argp->key.keydat_len, argp->key.keydat_val); | |
203 | ||
204 | if (!ok) { | |
205 | bail: | |
206 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
207 | return(NULL); | |
208 | } | |
209 | ||
210 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
211 | res.stat = YP_YPERR; | |
212 | } else { | |
213 | res = ypdb_get_record(argp->domain,argp->map,argp->key, FALSE); | |
214 | } | |
215 | ||
216 | #ifdef DEBUG | |
217 | yplog(" match2_status: %s", yperr_string(ypprot_err(res.stat))); | |
218 | #endif | |
219 | ||
220 | return (&res); | |
221 | } | |
222 | ||
223 | ypresp_key_val * | |
224 | ypproc_first_2_svc(argp, rqstp) | |
225 | ypreq_nokey *argp; | |
226 | struct svc_req *rqstp; | |
227 | { | |
228 | static ypresp_key_val res; | |
229 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
230 | int ok = acl_check_host(&caller->sin_addr); | |
231 | int secure = ypdb_secure(argp->domain,argp->map); | |
232 | ||
233 | if (strchr(argp->domain, '/') || strchr(argp->map, '/')) | |
234 | goto bail; | |
235 | YPLOG( "first_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
236 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
237 | TORF(ok), TORF(secure), | |
238 | argp->domain, argp->map); | |
239 | ||
240 | if (!ok) { | |
241 | bail: | |
242 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
243 | return(NULL); | |
244 | } | |
245 | ||
246 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
247 | res.stat = YP_YPERR; | |
248 | } else { | |
249 | res = ypdb_get_first(argp->domain,argp->map,FALSE); | |
250 | } | |
251 | ||
252 | #ifdef DEBUG | |
253 | yplog(" first2_status: %s", yperr_string(ypprot_err(res.stat))); | |
254 | #endif | |
255 | ||
256 | return (&res); | |
257 | } | |
258 | ||
259 | ypresp_key_val * | |
260 | ypproc_next_2_svc(argp, rqstp) | |
261 | ypreq_key *argp; | |
262 | struct svc_req *rqstp; | |
263 | { | |
264 | static ypresp_key_val res; | |
265 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
266 | int ok = acl_check_host(&caller->sin_addr); | |
267 | int secure = ypdb_secure(argp->domain,argp->map); | |
268 | ||
269 | if (strchr(argp->domain, '/') || strchr(argp->map, '/')) | |
270 | goto bail; | |
271 | YPLOG( | |
272 | "next_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s", | |
273 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
274 | TORF(ok), TORF(secure), | |
275 | argp->domain, argp->map, argp->key.keydat_len, argp->key.keydat_val); | |
276 | ||
277 | if (!ok) { | |
278 | bail: | |
279 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
280 | return(NULL); | |
281 | } | |
282 | ||
283 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
284 | res.stat = YP_YPERR; | |
285 | } else { | |
286 | res = ypdb_get_next(argp->domain,argp->map,argp->key,FALSE); | |
287 | } | |
288 | ||
289 | #ifdef DEBUG | |
290 | yplog(" next2_status: %s", yperr_string(ypprot_err(res.stat))); | |
291 | #endif | |
292 | ||
293 | return (&res); | |
294 | } | |
295 | ||
296 | ypresp_xfr * | |
297 | ypproc_xfr_2_svc(argp, rqstp) | |
298 | ypreq_xfr *argp; | |
299 | struct svc_req *rqstp; | |
300 | { | |
301 | static ypresp_xfr res; | |
302 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
303 | int ok = acl_check_host(&caller->sin_addr); | |
304 | pid_t pid; | |
305 | char tid[11]; | |
306 | char prog[11]; | |
307 | char port[11]; | |
308 | char ypxfr_proc[] = YPXFR_PROC; | |
309 | char *ipadd; | |
310 | ||
311 | bzero((char *)&res, sizeof(res)); | |
312 | ||
313 | YPLOG("xfr_2: caller=[%s].%d, auth_ok=%s, domain=%s, tid=%d, prog=%d", | |
314 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), | |
315 | argp->map_parms.domain, argp->transid, argp->prog); | |
316 | YPLOG(" ipadd=%s, port=%d, map=%s", inet_ntoa(caller->sin_addr), | |
317 | argp->port, argp->map_parms.map); | |
318 | ||
319 | if (strchr(argp->map_parms.domain, '/') || | |
320 | strchr(argp->map_parms.map, '/') || | |
321 | ntohs(caller->sin_port) >= IPPORT_RESERVED) { | |
322 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
323 | return(NULL); | |
324 | } | |
325 | ||
326 | snprintf(tid, sizeof(tid), "%d",argp->transid); | |
327 | snprintf(prog, sizeof(prog), "%d", argp->prog); | |
328 | snprintf(port, sizeof(port), "%d", argp->port); | |
329 | ipadd = inet_ntoa(caller->sin_addr); | |
330 | ||
331 | pid = vfork(); | |
332 | if (pid == -1) { | |
333 | svcerr_systemerr(rqstp->rq_xprt); | |
334 | return(NULL); | |
335 | } | |
336 | if (pid == 0) { | |
337 | execl(ypxfr_proc, "ypxfr", "-d", argp->map_parms.domain, | |
338 | "-C",tid, prog, ipadd, port, argp->map_parms.map, NULL); | |
339 | _exit(1); | |
340 | } | |
341 | ||
342 | /* | |
343 | * XXX: fill in res | |
344 | */ | |
345 | return (&res); | |
346 | } | |
347 | ||
348 | void * | |
349 | ypproc_clear_2_svc(argp, rqstp) | |
350 | void *argp; | |
351 | struct svc_req *rqstp; | |
352 | { | |
353 | static char *res; | |
354 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
355 | int ok = acl_check_host(&caller->sin_addr); | |
356 | ||
357 | YPLOG( "clear_2: caller=[%s].%d, auth_ok=%s, opt=%s", | |
358 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), | |
359 | #ifdef OPTDB | |
360 | True | |
361 | #else | |
362 | False | |
363 | #endif | |
364 | ); | |
365 | ||
366 | if (ntohs(caller->sin_port) >= IPPORT_RESERVED) | |
367 | ok = FALSE; | |
368 | ||
369 | if (!ok) { | |
370 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
371 | return(NULL); | |
372 | } | |
373 | ||
374 | res = NULL; | |
375 | ||
376 | #ifdef OPTDB | |
377 | ypdb_close_all(); | |
378 | #endif | |
379 | ||
380 | return ((void *)&res); | |
381 | } | |
382 | ||
383 | ypresp_all * | |
384 | ypproc_all_2_svc(argp, rqstp) | |
385 | ypreq_nokey *argp; | |
386 | struct svc_req *rqstp; | |
387 | { | |
388 | static ypresp_all res; | |
389 | pid_t pid; | |
390 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
391 | int ok = acl_check_host(&caller->sin_addr); | |
392 | int secure = ypdb_secure(argp->domain,argp->map); | |
393 | ||
394 | if (strchr(argp->domain, '/') || strchr(argp->map, '/')) | |
395 | goto bail; | |
396 | YPLOG( "all_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
397 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
398 | TORF(ok), TORF(secure), argp->domain, argp->map); | |
399 | ||
400 | if (!ok) { | |
401 | bail: | |
402 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
403 | return(NULL); | |
404 | } | |
405 | ||
406 | bzero((char *)&res, sizeof(res)); | |
407 | ||
408 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
409 | res.ypresp_all_u.val.stat = YP_YPERR; | |
410 | return(&res); | |
411 | } | |
412 | ||
413 | pid = fork(); | |
414 | ||
415 | if (pid) { | |
416 | ||
417 | if (pid == -1) { | |
418 | /* XXXCDC An error has occurred */ | |
419 | } | |
420 | ||
421 | return(NULL); /* PARENT: continue */ | |
422 | ||
423 | } | |
424 | /* CHILD: send result, then exit */ | |
425 | ||
426 | if (!svc_sendreply(rqstp->rq_xprt, ypdb_xdr_get_all, (char *) argp)) { | |
427 | svcerr_systemerr(rqstp->rq_xprt); | |
428 | } | |
429 | ||
430 | /* note: no need to free args, we are exiting */ | |
431 | ||
432 | exit(0); | |
433 | } | |
434 | ||
435 | ypresp_master * | |
436 | ypproc_master_2_svc(argp, rqstp) | |
437 | ypreq_nokey *argp; | |
438 | struct svc_req *rqstp; | |
439 | { | |
440 | static ypresp_master res; | |
441 | static peername nopeer = ""; | |
442 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
443 | int ok = acl_check_host(&caller->sin_addr); | |
444 | int secure = ypdb_secure(argp->domain,argp->map); | |
445 | ||
446 | if (strchr(argp->domain, '/') || strchr(argp->map, '/')) | |
447 | goto bail; | |
448 | YPLOG( "master_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
449 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
450 | TORF(ok), TORF(secure), argp->domain, argp->map); | |
451 | ||
452 | if (!ok) { | |
453 | bail: | |
454 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
455 | return(NULL); | |
456 | } | |
457 | ||
458 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
459 | res.stat = YP_YPERR; | |
460 | } else { | |
461 | res = ypdb_get_master(argp->domain,argp->map); | |
462 | } | |
463 | ||
464 | #ifdef DEBUG | |
465 | yplog(" master2_status: %s", yperr_string(ypprot_err(res.stat))); | |
466 | #endif | |
467 | ||
468 | /* This code was added because a yppoll <unknown-domain> */ | |
469 | /* from a sun crashed the server in xdr_string, trying */ | |
470 | /* to access the peer through a NULL-pointer. yppoll in */ | |
471 | /* this server start asking for order. If order is ok */ | |
472 | /* then it will ask for master. SunOS 4 asks for both */ | |
473 | /* always. I'm not sure this is the best place for the */ | |
474 | /* fix, but for now it will do. xdr_peername or */ | |
475 | /* xdr_string in ypserv_xdr.c may be a better place? */ | |
476 | ||
477 | if (res.peer == NULL) { | |
478 | res.peer = nopeer; | |
479 | } | |
480 | ||
481 | /* End of fix */ | |
482 | ||
483 | return (&res); | |
484 | } | |
485 | ||
486 | ||
487 | ypresp_order * | |
488 | ypproc_order_2_svc(argp, rqstp) | |
489 | ypreq_nokey *argp; | |
490 | struct svc_req *rqstp; | |
491 | { | |
492 | static ypresp_order res; | |
493 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
494 | int ok = acl_check_host(&caller->sin_addr); | |
495 | int secure = ypdb_secure(argp->domain,argp->map); | |
496 | ||
497 | if (strchr(argp->domain, '/')) | |
498 | goto bail; | |
499 | YPLOG( "order_2: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
500 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
501 | TORF(ok), TORF(secure), argp->domain, argp->map); | |
502 | ||
503 | if (!ok) { | |
504 | bail: | |
505 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
506 | return(NULL); | |
507 | } | |
508 | ||
509 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
510 | res.stat = YP_YPERR; | |
511 | } else if (strchr(argp->map, '/')) { | |
512 | res.stat = YP_NOMAP; | |
513 | } else { | |
514 | res = ypdb_get_order(argp->domain,argp->map); | |
515 | } | |
516 | ||
517 | #ifdef DEBUG | |
518 | yplog(" order2_status: %s", yperr_string(ypprot_err(res.stat))); | |
519 | #endif | |
520 | ||
521 | return (&res); | |
522 | } | |
523 | ||
524 | ||
525 | ypresp_maplist * | |
526 | ypproc_maplist_2_svc(argp, rqstp) | |
527 | domainname *argp; | |
528 | struct svc_req *rqstp; | |
529 | { | |
530 | static ypresp_maplist res; | |
531 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
532 | int ok = acl_check_host(&caller->sin_addr); | |
533 | static char domain_path[MAXPATHLEN]; | |
534 | struct stat finfo; | |
535 | DIR *dirp = NULL; | |
536 | struct dirent *dp; | |
537 | char *suffix; | |
538 | ypstat status; | |
539 | struct ypmaplist *m; | |
540 | char *map_name; | |
541 | ||
542 | if (strchr(*argp, '/')) | |
543 | goto bail; | |
544 | YPLOG("maplist_2: caller=[%s].%d, auth_ok=%s, domain=%s", | |
545 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), | |
546 | *argp); | |
547 | ||
548 | if (!ok) { | |
549 | bail: | |
550 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
551 | return(NULL); | |
552 | } | |
553 | ||
554 | bzero((char *)&res, sizeof(res)); | |
555 | ||
556 | snprintf(domain_path,MAXPATHLEN, "%s/%s",YP_DB_PATH,*argp); | |
557 | ||
558 | status = YP_TRUE; | |
559 | ||
560 | res.maps = NULL; | |
561 | ||
562 | if (!((stat(domain_path, &finfo) == 0) && | |
563 | ((finfo.st_mode & S_IFMT) == S_IFDIR))) | |
564 | status = YP_NODOM; | |
565 | ||
566 | if (status >= 0) { | |
567 | if ((dirp = opendir(domain_path)) == NULL) { | |
568 | status = YP_NODOM; | |
569 | } | |
570 | } | |
571 | ||
572 | if (status >= 0) { | |
573 | for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { | |
574 | if ((!strcmp(dp->d_name, ".")) || | |
575 | ((!strcmp(dp->d_name, ".."))) || | |
576 | (dp->d_namlen < 4)) | |
577 | continue; | |
578 | suffix = (char *) &dp->d_name[dp->d_namlen-3]; | |
579 | if (strcmp(suffix,".db") == 0) { | |
580 | ||
581 | if ((m = (struct ypmaplist *) | |
582 | malloc((unsigned) sizeof(struct ypmaplist))) == NULL) { | |
583 | status = YP_YPERR; | |
584 | break; | |
585 | } | |
586 | ||
587 | if ((map_name = (char *) | |
588 | malloc((unsigned) dp->d_namlen - 2)) == NULL) { | |
589 | status = YP_YPERR; | |
590 | break; | |
591 | } | |
592 | ||
593 | m->next = res.maps; | |
594 | m->map = map_name; | |
595 | res.maps = m; | |
596 | strncpy(map_name, dp->d_name, dp->d_namlen - 3); | |
597 | m->map[dp->d_namlen - 3] = '\0'; | |
598 | ||
599 | } | |
600 | } | |
601 | } | |
602 | ||
603 | if (dirp != NULL) { | |
604 | closedir(dirp); | |
605 | } | |
606 | ||
607 | res.stat = status; | |
608 | ||
609 | #ifdef DEBUG | |
610 | yplog(" maplist_status: %s", yperr_string(ypprot_err(res.stat))); | |
611 | #endif | |
612 | ||
613 | return (&res); | |
614 | } | |
615 | ||
616 | void * | |
617 | ypproc_null_1_svc(argp, rqstp) | |
618 | void *argp; | |
619 | struct svc_req *rqstp; | |
620 | { | |
621 | static char *result; | |
622 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
623 | int ok = acl_check_host(&caller->sin_addr); | |
624 | ||
625 | YPLOG("null_1: caller=[%s].%d, auth_ok=%s", | |
626 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok)); | |
627 | ||
628 | if (!ok) { | |
629 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
630 | return(NULL); | |
631 | } | |
632 | ||
633 | result = NULL; | |
634 | ||
635 | return ((void *)&result); | |
636 | } | |
637 | ||
638 | bool_t * | |
639 | ypproc_domain_1_svc(argp, rqstp) | |
640 | domainname *argp; | |
641 | struct svc_req *rqstp; | |
642 | { | |
643 | static bool_t result; /* is domain_served? */ | |
644 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
645 | int ok = acl_check_host(&caller->sin_addr); | |
646 | static char domain_path[MAXPATHLEN]; | |
647 | struct stat finfo; | |
648 | ||
649 | if (strchr(*argp, '/')) | |
650 | goto bail; | |
651 | snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp); | |
652 | result = (bool_t) ((stat(domain_path, &finfo) == 0) && | |
653 | (finfo.st_mode & S_IFDIR)); | |
654 | ||
655 | YPLOG("domain_1: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s", | |
656 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
657 | TORF(ok), *argp, TORF(result)); | |
658 | ||
659 | if (!ok) { | |
660 | bail: | |
661 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
662 | return(NULL); | |
663 | } | |
664 | ||
665 | return (&result); | |
666 | } | |
667 | ||
668 | bool_t * | |
669 | ypproc_domain_nonack_1_svc(argp, rqstp) | |
670 | domainname *argp; | |
671 | struct svc_req *rqstp; | |
672 | { | |
673 | static bool_t result; /* is domain served? */ | |
674 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
675 | int ok = acl_check_host(&caller->sin_addr); | |
676 | static char domain_path[MAXPATHLEN]; | |
677 | struct stat finfo; | |
678 | ||
679 | if (strchr(*argp, '/')) | |
680 | goto bail; | |
681 | snprintf(domain_path, sizeof(domain_path), "%s/%s", YP_DB_PATH, *argp); | |
682 | result = (bool_t) ((stat(domain_path, &finfo) == 0) && | |
683 | (finfo.st_mode & S_IFDIR)); | |
684 | ||
685 | YPLOG( | |
686 | "domain_nonack_1: caller=[%s].%d, auth_ok=%s, domain=%s, served=%s", | |
687 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), TORF(ok), | |
688 | *argp, TORF(result)); | |
689 | ||
690 | if (!ok) { | |
691 | bail: | |
692 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
693 | return(NULL); | |
694 | } | |
695 | ||
696 | if (!result) { | |
697 | return(NULL); /* don't send nack */ | |
698 | } | |
699 | ||
700 | return (&result); | |
701 | } | |
702 | ||
703 | ypresponse * | |
704 | ypproc_match_1_svc(argp, rqstp) | |
705 | yprequest *argp; | |
706 | struct svc_req *rqstp; | |
707 | { | |
708 | static ypresponse res; | |
709 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
710 | int ok = acl_check_host(&caller->sin_addr); | |
711 | int secure; | |
712 | ||
713 | if (strchr(argp->ypmatch_req_domain, '/') || | |
714 | strchr(argp->ypmatch_req_map, '/')) | |
715 | goto bail; | |
716 | res.yp_resptype = YPMATCH_RESPTYPE; | |
717 | res.ypmatch_resp_valptr = ""; | |
718 | res.ypmatch_resp_valsize = 0; | |
719 | ||
720 | if (argp->yp_reqtype != YPMATCH_REQTYPE) { | |
721 | res.ypmatch_resp_status = YP_BADARGS; | |
722 | return(&res); | |
723 | } | |
724 | ||
725 | secure = ypdb_secure(argp->ypmatch_req_domain, argp->ypmatch_req_map); | |
726 | ||
727 | YPLOG( | |
728 | "match_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s", | |
729 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
730 | TORF(ok), TORF(secure), | |
731 | argp->ypmatch_req_domain, argp->ypmatch_req_map, | |
732 | argp->ypmatch_req_keysize, argp->ypmatch_req_keyptr); | |
733 | ||
734 | if (!ok) { | |
735 | bail: | |
736 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
737 | return(NULL); | |
738 | } | |
739 | ||
740 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
741 | res.ypmatch_resp_status = YP_YPERR; | |
742 | } else { | |
743 | res.ypmatch_resp_val = | |
744 | ypdb_get_record(argp->ypmatch_req_domain, | |
745 | argp->ypmatch_req_map, | |
746 | argp->ypmatch_req_keydat, | |
747 | FALSE); | |
748 | } | |
749 | ||
750 | #ifdef DEBUG | |
751 | yplog(" match1_status: %s", | |
752 | yperr_string(ypprot_err(res.ypmatch_resp_status))); | |
753 | #endif | |
754 | ||
755 | return (&res); | |
756 | } | |
757 | ||
758 | ypresponse * | |
759 | ypproc_first_1_svc(argp, rqstp) | |
760 | yprequest *argp; | |
761 | struct svc_req *rqstp; | |
762 | { | |
763 | static ypresponse res; | |
764 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
765 | int ok = acl_check_host(&caller->sin_addr); | |
766 | int secure; | |
767 | ||
768 | if (strchr(argp->ypfirst_req_domain, '/') || | |
769 | strchr(argp->ypfirst_req_map, '/')) | |
770 | goto bail; | |
771 | res.yp_resptype = YPFIRST_RESPTYPE; | |
772 | res.ypfirst_resp_valptr = res.ypfirst_resp_keyptr = ""; | |
773 | res.ypfirst_resp_valsize = res.ypfirst_resp_keysize = 0; | |
774 | ||
775 | if (argp->yp_reqtype != YPREQ_NOKEY) { | |
776 | res.ypfirst_resp_status = YP_BADARGS; | |
777 | return(&res); | |
778 | } | |
779 | ||
780 | secure = ypdb_secure(argp->ypfirst_req_domain, argp->ypfirst_req_map); | |
781 | ||
782 | YPLOG( "first_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
783 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
784 | TORF(ok), TORF(secure), | |
785 | argp->ypfirst_req_domain, argp->ypfirst_req_map); | |
786 | ||
787 | if (!ok) { | |
788 | bail: | |
789 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
790 | return(NULL); | |
791 | } | |
792 | ||
793 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
794 | res.ypfirst_resp_status = YP_YPERR; | |
795 | } else { | |
796 | res.ypfirst_resp_val = | |
797 | ypdb_get_first(argp->ypfirst_req_domain, | |
798 | argp->ypfirst_req_map, | |
799 | FALSE); | |
800 | } | |
801 | ||
802 | #ifdef DEBUG | |
803 | yplog(" first1_status: %s", | |
804 | yperr_string(ypprot_err(res.ypfirst_resp_status))); | |
805 | #endif | |
806 | ||
807 | return (&res); | |
808 | } | |
809 | ||
810 | ypresponse * | |
811 | ypproc_next_1_svc(argp, rqstp) | |
812 | yprequest *argp; | |
813 | struct svc_req *rqstp; | |
814 | { | |
815 | static ypresponse res; | |
816 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
817 | int ok = acl_check_host(&caller->sin_addr); | |
818 | int secure; | |
819 | ||
820 | if (strchr(argp->ypnext_req_domain, '/') || | |
821 | strchr(argp->ypnext_req_map, '/')) | |
822 | goto bail; | |
823 | res.yp_resptype = YPNEXT_RESPTYPE; | |
824 | res.ypnext_resp_valptr = res.ypnext_resp_keyptr = ""; | |
825 | res.ypnext_resp_valsize = res.ypnext_resp_keysize = 0; | |
826 | ||
827 | if (argp->yp_reqtype != YPNEXT_REQTYPE) { | |
828 | res.ypnext_resp_status = YP_BADARGS; | |
829 | return(&res); | |
830 | } | |
831 | ||
832 | secure = ypdb_secure(argp->ypnext_req_domain, argp->ypnext_req_map); | |
833 | ||
834 | YPLOG( | |
835 | "next_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, key=%.*s", | |
836 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
837 | TORF(ok), TORF(secure), | |
838 | argp->ypnext_req_domain, argp->ypnext_req_map, | |
839 | argp->ypnext_req_keysize, argp->ypnext_req_keyptr); | |
840 | ||
841 | if (!ok) { | |
842 | bail: | |
843 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
844 | return(NULL); | |
845 | } | |
846 | ||
847 | if (secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED)) { | |
848 | res.ypnext_resp_status = YP_YPERR; | |
849 | } else { | |
850 | res.ypnext_resp_val = | |
851 | ypdb_get_next(argp->ypnext_req_domain, | |
852 | argp->ypnext_req_map, | |
853 | argp->ypnext_req_keydat, | |
854 | FALSE); | |
855 | } | |
856 | ||
857 | #ifdef DEBUG | |
858 | yplog(" next1_status: %s", | |
859 | yperr_string(ypprot_err(res.ypnext_resp_status))); | |
860 | #endif | |
861 | ||
862 | return (&res); | |
863 | } | |
864 | ||
865 | ypresponse * | |
866 | ypproc_poll_1_svc(argp, rqstp) | |
867 | yprequest *argp; | |
868 | struct svc_req *rqstp; | |
869 | { | |
870 | static ypresponse res; | |
871 | ypresp_order order; | |
872 | ypresp_master master; | |
873 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
874 | int ok = acl_check_host(&caller->sin_addr); | |
875 | int secure; | |
876 | ||
877 | if (strchr(argp->yppoll_req_domain, '/') || | |
878 | strchr(argp->yppoll_req_map, '/')) | |
879 | goto bail; | |
880 | res.yp_resptype = YPPOLL_RESPTYPE; | |
881 | res.yppoll_resp_domain = argp->yppoll_req_domain; | |
882 | res.yppoll_resp_map = argp->yppoll_req_map; | |
883 | res.yppoll_resp_ordernum = 0; | |
884 | res.yppoll_resp_owner = ""; | |
885 | ||
886 | if (argp->yp_reqtype != YPPOLL_REQTYPE) { | |
887 | return(&res); | |
888 | } | |
889 | ||
890 | secure = ypdb_secure(argp->yppoll_req_domain, argp->yppoll_req_map); | |
891 | ||
892 | YPLOG( "poll_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
893 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
894 | TORF(ok), TORF(secure), | |
895 | argp->yppoll_req_domain, argp->yppoll_req_map); | |
896 | ||
897 | if (!ok) { | |
898 | bail: | |
899 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
900 | return(NULL); | |
901 | } | |
902 | ||
903 | if (!(secure && (ntohs(caller->sin_port) >= IPPORT_RESERVED))) { | |
904 | order = ypdb_get_order(argp->yppoll_req_domain, | |
905 | argp->yppoll_req_map); | |
906 | master = ypdb_get_master(argp->yppoll_req_domain, | |
907 | argp->yppoll_req_map); | |
908 | res.yppoll_resp_ordernum = order.ordernum; | |
909 | res.yppoll_resp_owner = master.peer; | |
910 | } | |
911 | ||
912 | #ifdef DEBUG | |
913 | yplog(" poll1_status: %s", "none"); | |
914 | #endif | |
915 | return (&res); | |
916 | } | |
917 | ||
918 | void * | |
919 | ypproc_push_1_svc(argp, rqstp) | |
920 | yprequest *argp; | |
921 | struct svc_req *rqstp; | |
922 | { | |
923 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
924 | int ok = acl_check_host(&caller->sin_addr); | |
925 | int secure; | |
926 | pid_t pid; | |
927 | char yppush_proc[] = YPPUSH_PROC; | |
928 | ||
929 | if (strchr(argp->yppush_req_domain, '/') || | |
930 | strchr(argp->yppush_req_map, '/')) | |
931 | goto bail; | |
932 | if (argp->yp_reqtype != YPPUSH_REQTYPE) { | |
933 | return(NULL); | |
934 | } | |
935 | ||
936 | secure = ypdb_secure(argp->yppush_req_domain, argp->yppush_req_map); | |
937 | ||
938 | YPLOG( "push_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
939 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
940 | TORF(ok), TORF(secure), | |
941 | argp->yppush_req_domain, argp->yppush_req_map); | |
942 | ||
943 | if (ntohs(caller->sin_port) >= IPPORT_RESERVED) | |
944 | ok = FALSE; | |
945 | ||
946 | if (!ok) { | |
947 | bail: | |
948 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
949 | return(NULL); | |
950 | } | |
951 | ||
952 | pid = vfork(); | |
953 | if (pid == -1) { | |
954 | svcerr_systemerr(rqstp->rq_xprt); | |
955 | return(NULL); | |
956 | } | |
957 | if (pid == 0) { | |
958 | execl(yppush_proc, "yppush", "-d", argp->yppush_req_domain, | |
959 | argp->yppush_req_map, NULL); | |
960 | _exit(1); | |
961 | } | |
962 | ||
963 | return (NULL); | |
964 | } | |
965 | ||
966 | void * | |
967 | ypproc_pull_1_svc(argp, rqstp) | |
968 | yprequest *argp; | |
969 | struct svc_req *rqstp; | |
970 | { | |
971 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
972 | int ok = acl_check_host(&caller->sin_addr); | |
973 | int secure; | |
974 | pid_t pid; | |
975 | char ypxfr_proc[] = YPXFR_PROC; | |
976 | ||
977 | if (strchr(argp->yppull_req_domain, '/') || | |
978 | strchr(argp->yppull_req_map, '/')) | |
979 | goto bail; | |
980 | if (argp->yp_reqtype != YPPULL_REQTYPE) { | |
981 | return(NULL); | |
982 | } | |
983 | ||
984 | secure = ypdb_secure(argp->yppull_req_domain, argp->yppull_req_map); | |
985 | ||
986 | YPLOG( "pull_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s", | |
987 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
988 | TORF(ok), TORF(secure), | |
989 | argp->yppull_req_domain, argp->yppull_req_map); | |
990 | ||
991 | if (ntohs(caller->sin_port) >= IPPORT_RESERVED) | |
992 | ok = FALSE; | |
993 | ||
994 | if (!ok) { | |
995 | bail: | |
996 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
997 | return(NULL); | |
998 | } | |
999 | ||
1000 | pid = vfork(); | |
1001 | if (pid == -1) { | |
1002 | svcerr_systemerr(rqstp->rq_xprt); | |
1003 | return(NULL); | |
1004 | } | |
1005 | if (pid == 0) { | |
1006 | execl(ypxfr_proc, "ypxfr", "-d", argp->yppull_req_domain, | |
1007 | argp->yppull_req_map, NULL); | |
1008 | _exit(1); | |
1009 | } | |
1010 | ||
1011 | return (NULL); | |
1012 | } | |
1013 | ||
1014 | void * | |
1015 | ypproc_get_1_svc(argp, rqstp) | |
1016 | yprequest *argp; | |
1017 | struct svc_req *rqstp; | |
1018 | { | |
1019 | char *res; | |
1020 | struct sockaddr_in *caller = svc_getcaller(rqstp->rq_xprt); | |
1021 | int ok = acl_check_host(&caller->sin_addr); | |
1022 | int secure; | |
1023 | pid_t pid; | |
1024 | char ypxfr_proc[] = YPXFR_PROC; | |
1025 | ||
1026 | if (strchr(argp->ypget_req_domain, '/') || | |
1027 | strchr(argp->ypget_req_map, '/')) | |
1028 | goto bail; | |
1029 | if (argp->yp_reqtype != YPGET_REQTYPE) { | |
1030 | return(NULL); | |
1031 | } | |
1032 | ||
1033 | secure = ypdb_secure(argp->ypget_req_domain, argp->ypget_req_map); | |
1034 | ||
1035 | YPLOG( "get_1: caller=[%s].%d, auth_ok=%s, secure=%s, domain=%s, map=%s, owner=%s", | |
1036 | inet_ntoa(caller->sin_addr), ntohs(caller->sin_port), | |
1037 | TORF(ok), TORF(secure), | |
1038 | argp->ypget_req_domain, argp->ypget_req_map, | |
1039 | argp->ypget_req_owner); | |
1040 | ||
1041 | if (ntohs(caller->sin_port) >= IPPORT_RESERVED) | |
1042 | ok = FALSE; | |
1043 | ||
1044 | if (!ok) { | |
1045 | bail: | |
1046 | svcerr_auth(rqstp->rq_xprt, AUTH_FAILED); | |
1047 | return(NULL); | |
1048 | } | |
1049 | ||
1050 | pid = vfork(); | |
1051 | if (pid == -1) { | |
1052 | svcerr_systemerr(rqstp->rq_xprt); | |
1053 | return(NULL); | |
1054 | } | |
1055 | if (pid == 0) { | |
1056 | execl(ypxfr_proc, "ypxfr", "-d", argp->ypget_req_domain, "-h", | |
1057 | argp->ypget_req_owner, argp->yppush_req_map, NULL); | |
1058 | _exit(1); | |
1059 | } | |
1060 | ||
1061 | return (NULL); | |
1062 | } |