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