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 */ 33 34 #include "yp.h" 35 #include "yp_extern.h" 36 #include <stdlib.h> 37 #include <dirent.h> 38 #include <sys/stat.h> 39 #include <sys/param.h> 40 #include <errno.h> 41 #include <sys/types.h> 42 #include <sys/socket.h> 43 #include <netinet/in.h> 44 #include <arpa/inet.h> 45 #include <rpc/rpc.h> 46 47 #ifndef lint 48 static const char rcsid[] = "$Id$"; 49 #endif /* not lint */ 50 51 int forked = 0; 52 int children = 0; 53 static char *master_string = "YP_MASTER_NAME"; 54 static char *order_string = "YP_LAST_MODIFIED"; 55 static int master_sz = sizeof("YP_MASTER_NAME") - 1; 56 static int order_sz = sizeof("YP_LAST_MODIFIED") - 1; 57 58 /* 59 * NIS v2 support. This is where most of the action happens. 60 */ 61 62 void * 63 ypproc_null_2_svc(void *argp, struct svc_req *rqstp) 64 { 65 static char * result; 66 static char rval = 0; 67 68 #ifdef DB_CACHE 69 if (yp_access(NULL, NULL, (struct svc_req *)rqstp)) 70 #else 71 if (yp_access(NULL, (struct svc_req *)rqstp)) 72 #endif 73 return(NULL); 74 75 result = &rval; 76 77 return((void *) &result); 78 } 79 80 bool_t * 81 ypproc_domain_2_svc(domainname *argp, struct svc_req *rqstp) 82 { 83 static bool_t result; 84 85 #ifdef DB_CACHE 86 if (yp_access(NULL, NULL, (struct svc_req *)rqstp)) { 87 #else 88 if (yp_access(NULL, (struct svc_req *)rqstp)) { 89 #endif 90 result = FALSE; 91 return (&result); 92 } 93 94 if (argp == NULL || yp_validdomain(*argp)) 95 result = FALSE; 96 else 97 result = TRUE; 98 99 return (&result); 100 } 101 102 bool_t * 103 ypproc_domain_nonack_2_svc(domainname *argp, struct svc_req *rqstp) 104 { 105 static bool_t result; 106 107 #ifdef DB_CACHE 108 if (yp_access(NULL, NULL, (struct svc_req *)rqstp)) 109 #else 110 if (yp_access(NULL, (struct svc_req *)rqstp)) 111 #endif 112 return (NULL); 113 114 if (argp == NULL || yp_validdomain(*argp)) 115 return (NULL); 116 else 117 result = TRUE; 118 119 return (&result); 120 } 121 122 ypresp_val * 123 ypproc_match_2_svc(ypreq_key *argp, struct svc_req *rqstp) 124 { 125 static ypresp_val result; 126 127 result.val.valdat_val = ""; 128 result.val.valdat_len = 0; 129 130 #ifdef DB_CACHE 131 if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) { 132 #else 133 if (yp_access(argp->map, (struct svc_req *)rqstp)) { 134 #endif 135 result.stat = YP_YPERR; 136 return (&result); 137 } 138 139 if (argp->domain == NULL || argp->map == NULL) { 140 result.stat = YP_BADARGS; 141 return (&result); 142 } 143 144 if (yp_select_map(argp->map, argp->domain, &argp->key, 1) != YP_TRUE) { 145 result.stat = yp_errno; 146 return(&result); 147 } 148 149 result.stat = yp_getbykey(&argp->key, &result.val); 150 151 /* 152 * Do DNS lookups for hosts maps if database lookup failed. 153 */ 154 155 #ifdef DB_CACHE 156 if (result.stat != YP_TRUE && 157 (yp_testflag(argp->map, argp->domain, YP_INTERDOMAIN) || 158 (strstr(argp->map, "hosts") && do_dns))) { 159 #else 160 if (do_dns && result.stat != YP_TRUE && strstr(argp->map, "hosts")) { 161 #endif 162 163 /* NUL terminate! NUL terminate!! NUL TERMINATE!!! */ 164 argp->key.keydat_val[argp->key.keydat_len] = '\0'; 165 166 if (debug) 167 yp_error("Doing DNS lookup of %.*s", 168 argp->key.keydat_len, 169 argp->key.keydat_val); 170 171 if (!strcmp(argp->map, "hosts.byname")) 172 result.stat = yp_async_lookup_name(rqstp, 173 (char *)argp->key.keydat_val); 174 else if (!strcmp(argp->map, "hosts.byaddr")) 175 result.stat = yp_async_lookup_addr(rqstp, 176 (char *)argp->key.keydat_val); 177 178 if (result.stat == YP_TRUE) 179 return(NULL); 180 } 181 182 return (&result); 183 } 184 185 ypresp_key_val * 186 ypproc_first_2_svc(ypreq_nokey *argp, struct svc_req *rqstp) 187 { 188 static ypresp_key_val result; 189 190 result.val.valdat_val = result.key.keydat_val = ""; 191 result.val.valdat_len = result.key.keydat_len = 0; 192 193 #ifdef DB_CACHE 194 if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) { 195 #else 196 if (yp_access(argp->map, (struct svc_req *)rqstp)) { 197 #endif 198 result.stat = YP_YPERR; 199 return (&result); 200 } 201 202 if (argp->domain == NULL) { 203 result.stat = YP_BADARGS; 204 return (&result); 205 } 206 207 if (yp_select_map(argp->map, argp->domain, &result.key, 0) != YP_TRUE) { 208 result.stat = yp_errno; 209 return(&result); 210 } 211 212 result.stat = yp_firstbykey(&result.key, &result.val); 213 214 return (&result); 215 } 216 217 ypresp_key_val * 218 ypproc_next_2_svc(ypreq_key *argp, struct svc_req *rqstp) 219 { 220 static ypresp_key_val result; 221 222 result.val.valdat_val = result.key.keydat_val = ""; 223 result.val.valdat_len = result.key.keydat_len = 0; 224 225 #ifdef DB_CACHE 226 if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) { 227 #else 228 if (yp_access(argp->map, (struct svc_req *)rqstp)) { 229 #endif 230 result.stat = YP_YPERR; 231 return (&result); 232 } 233 234 if (argp->domain == NULL || argp->map == NULL) { 235 result.stat = YP_BADARGS; 236 return (&result); 237 } 238 239 if (yp_select_map(argp->map, argp->domain, &argp->key, 0) != YP_TRUE) { 240 result.stat = yp_errno; 241 return(&result); 242 } 243 244 result.key.keydat_len = argp->key.keydat_len; 245 result.key.keydat_val = argp->key.keydat_val; 246 247 result.stat = yp_nextbykey(&result.key, &result.val); 248 249 return (&result); 250 } 251 252 static void ypxfr_callback(rval,addr,transid,prognum,port) 253 ypxfrstat rval; 254 struct sockaddr_in *addr; 255 unsigned int transid; 256 unsigned int prognum; 257 unsigned long port; 258 { 259 CLIENT *clnt; 260 int sock = RPC_ANYSOCK; 261 struct timeval timeout; 262 yppushresp_xfr ypxfr_resp; 263 struct rpc_err err; 264 265 timeout.tv_sec = 5; 266 timeout.tv_usec = 0; 267 addr->sin_port = htons(port); 268 269 if ((clnt = clntudp_create(addr,prognum,1,timeout,&sock)) == NULL) { 270 yp_error("%s: %s", inet_ntoa(addr->sin_addr), 271 clnt_spcreateerror("failed to establish callback handle")); 272 return; 273 } 274 275 ypxfr_resp.status = rval; 276 ypxfr_resp.transid = transid; 277 278 /* Turn the timeout off -- we don't want to block. */ 279 timeout.tv_sec = 0; 280 if (clnt_control(clnt, CLSET_TIMEOUT, (char *)&timeout) == FALSE) 281 yp_error("failed to set timeout on ypproc_xfr callback"); 282 283 if (yppushproc_xfrresp_1(&ypxfr_resp, clnt) == NULL) { 284 clnt_geterr(clnt, &err); 285 if (err.re_status != RPC_SUCCESS && 286 err.re_status != RPC_TIMEDOUT) 287 yp_error("%s", clnt_sperror(clnt, 288 "ypxfr callback failed")); 289 } 290 291 clnt_destroy(clnt); 292 return; 293 } 294 295 #define YPXFR_RETURN(CODE) \ 296 /* Order is important: send regular RPC reply, then callback */ \ 297 result.xfrstat = CODE; \ 298 svc_sendreply(rqstp->rq_xprt, xdr_ypresp_xfr, (char *)&result); \ 299 ypxfr_callback(CODE,rqhost,argp->transid, \ 300 argp->prog,argp->port); \ 301 return(NULL); 302 303 ypresp_xfr * 304 ypproc_xfr_2_svc(ypreq_xfr *argp, struct svc_req *rqstp) 305 { 306 static ypresp_xfr result; 307 struct sockaddr_in *rqhost; 308 309 result.transid = argp->transid; 310 rqhost = svc_getcaller(rqstp->rq_xprt); 311 312 #ifdef DB_CACHE 313 if (yp_access(argp->map_parms.map, 314 argp->map_parms.domain, (struct svc_req *)rqstp)) { 315 #else 316 if (yp_access(argp->map_parms.map, (struct svc_req *)rqstp)) { 317 #endif 318 YPXFR_RETURN(YPXFR_REFUSED); 319 } 320 321 if (argp->map_parms.domain == NULL) { 322 YPXFR_RETURN(YPXFR_BADARGS); 323 } 324 325 if (yp_validdomain(argp->map_parms.domain)) { 326 YPXFR_RETURN(YPXFR_NODOM); 327 } 328 329 switch(fork()) { 330 case 0: 331 { 332 char g[11], t[11], p[11]; 333 char ypxfr_command[MAXPATHLEN + 2]; 334 335 sprintf (ypxfr_command, "%sypxfr", _PATH_LIBEXEC); 336 sprintf (t, "%u", argp->transid); 337 sprintf (g, "%u", argp->prog); 338 sprintf (p, "%u", argp->port); 339 if (debug) { 340 close(0); close(1); close(2); 341 } 342 if (strcmp(yp_dir, _PATH_YP)) { 343 execl(ypxfr_command, "ypxfr", 344 "-d", argp->map_parms.domain, 345 "-h", argp->map_parms.peer, 346 "-p", yp_dir, "-C", t, 347 g, inet_ntoa(rqhost->sin_addr), 348 p, argp->map_parms.map, 349 NULL); 350 } else { 351 execl(ypxfr_command, "ypxfr", 352 "-d", argp->map_parms.domain, 353 "-h", argp->map_parms.peer, 354 "-C", t, 355 g, inet_ntoa(rqhost->sin_addr), 356 p, argp->map_parms.map, 357 NULL); 358 } 359 forked++; 360 yp_error("ypxfr execl(%s): %s", ypxfr_command, strerror(errno)); 361 YPXFR_RETURN(YPXFR_XFRERR); 362 break; 363 } 364 case -1: 365 yp_error("ypxfr fork(): %s", strerror(errno)); 366 YPXFR_RETURN(YPXFR_XFRERR); 367 break; 368 default: 369 result.xfrstat = YPXFR_SUCC; 370 children++; 371 forked = 0; 372 break; 373 } 374 375 return (&result); 376 } 377 #undef YPXFR_RETURN 378 379 void * 380 ypproc_clear_2_svc(void *argp, struct svc_req *rqstp) 381 { 382 static char * result; 383 static char rval = 0; 384 385 #ifdef DB_CACHE 386 if (yp_access(NULL, NULL, (struct svc_req *)rqstp)) 387 #else 388 if (yp_access(NULL, (struct svc_req *)rqstp)) 389 #endif 390 return (NULL); 391 #ifdef DB_CACHE 392 /* clear out the database cache */ 393 yp_flush_all(); 394 #endif 395 /* Re-read the securenets database for the hell of it. */ 396 load_securenets(); 397 398 result = &rval; 399 return((void *) &result); 400 } 401 402 /* 403 * For ypproc_all, we have to send a stream of ypresp_all structures 404 * via TCP, but the XDR filter generated from the yp.x protocol 405 * definition file only serializes one such structure. This means that 406 * to send the whole stream, you need a wrapper which feeds all the 407 * records into the underlying XDR routine until it hits an 'EOF.' 408 * But to use the wrapper, you have to violate the boundaries between 409 * RPC layers by calling svc_sendreply() directly from the ypproc_all 410 * service routine instead of letting the RPC dispatcher do it. 411 * 412 * Bleah. 413 */ 414 415 /* 416 * Custom XDR routine for serialzing results of ypproc_all: keep 417 * reading from the database and spew until we run out of records 418 * or encounter an error. 419 */ 420 static bool_t 421 xdr_my_ypresp_all(register XDR *xdrs, ypresp_all *objp) 422 { 423 while (1) { 424 /* Get a record. */ 425 if ((objp->ypresp_all_u.val.stat = 426 yp_nextbykey(&objp->ypresp_all_u.val.key, 427 &objp->ypresp_all_u.val.val)) == YP_TRUE) { 428 objp->more = TRUE; 429 } else { 430 objp->more = FALSE; 431 } 432 433 /* Serialize. */ 434 if (!xdr_ypresp_all(xdrs, objp)) 435 return(FALSE); 436 if (objp->more == FALSE) 437 return(TRUE); 438 } 439 } 440 441 ypresp_all * 442 ypproc_all_2_svc(ypreq_nokey *argp, struct svc_req *rqstp) 443 { 444 static ypresp_all result; 445 446 /* 447 * Set this here so that the client will be forced to make 448 * at least one attempt to read from us even if all we're 449 * doing is returning an error. 450 */ 451 result.more = TRUE; 452 result.ypresp_all_u.val.key.keydat_len = 0; 453 result.ypresp_all_u.val.key.keydat_val = ""; 454 455 #ifdef DB_CACHE 456 if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) { 457 #else 458 if (yp_access(argp->map, (struct svc_req *)rqstp)) { 459 #endif 460 result.ypresp_all_u.val.stat = YP_YPERR; 461 return (&result); 462 } 463 464 if (argp->domain == NULL || argp->map == NULL) { 465 result.ypresp_all_u.val.stat = YP_BADARGS; 466 return (&result); 467 } 468 469 /* 470 * XXX If we hit the child limit, fail the request. 471 * If we don't, and the map is large, we could block for 472 * a long time in the parent. 473 */ 474 if (children >= MAX_CHILDREN) { 475 result.ypresp_all_u.val.stat = YP_YPERR; 476 return(&result); 477 } 478 479 /* 480 * The ypproc_all procedure can take a while to complete. 481 * Best to handle it in a subprocess so the parent doesn't 482 * block. (Is there a better way to do this? Maybe with 483 * async socket I/O?) 484 */ 485 if (!debug && children < MAX_CHILDREN && fork()) { 486 children++; 487 forked = 0; 488 return (NULL); 489 } else { 490 forked++; 491 } 492 493 if (yp_select_map(argp->map, argp->domain, 494 &result.ypresp_all_u.val.key, 0) != YP_TRUE) { 495 result.ypresp_all_u.val.stat = yp_errno; 496 return(&result); 497 } 498 499 /* Kick off the actual data transfer. */ 500 svc_sendreply(rqstp->rq_xprt, xdr_my_ypresp_all, (char *)&result); 501 502 /* 503 * Returning NULL prevents the dispatcher from calling 504 * svc_sendreply() since we already did it. 505 */ 506 return (NULL); 507 } 508 509 ypresp_master * 510 ypproc_master_2_svc(ypreq_nokey *argp, struct svc_req *rqstp) 511 { 512 static ypresp_master result; 513 static char ypvalbuf[YPMAXRECORD]; 514 keydat key = { master_sz, master_string }; 515 valdat val; 516 517 result.peer = ""; 518 519 #ifdef DB_CACHE 520 if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) { 521 #else 522 if (yp_access(argp->map, (struct svc_req *)rqstp)) { 523 #endif 524 result.stat = YP_YPERR; 525 return(&result); 526 } 527 528 if (argp->domain == NULL) { 529 result.stat = YP_BADARGS; 530 return (&result); 531 } 532 533 if (yp_select_map(argp->map, argp->domain, &key, 1) != YP_TRUE) { 534 result.stat = yp_errno; 535 return(&result); 536 } 537 538 /* 539 * Note that we copy the data retrieved from the database to 540 * a private buffer and NUL terminate the buffer rather than 541 * terminating the data in place. We do this because by stuffing 542 * a '\0' into data.data, we will actually be corrupting memory 543 * allocated by the DB package. This is a bad thing now that we 544 * cache DB handles rather than closing the database immediately. 545 */ 546 result.stat = yp_getbykey(&key, &val); 547 if (result.stat == YP_TRUE) { 548 bcopy((char *)val.valdat_val, (char *)&ypvalbuf, 549 val.valdat_len); 550 ypvalbuf[val.valdat_len] = '\0'; 551 result.peer = (char *)&ypvalbuf; 552 } else 553 result.peer = ""; 554 555 return (&result); 556 } 557 558 ypresp_order * 559 ypproc_order_2_svc(ypreq_nokey *argp, struct svc_req *rqstp) 560 { 561 static ypresp_order result; 562 keydat key = { order_sz, order_string }; 563 valdat val; 564 565 result.ordernum = 0; 566 567 #ifdef DB_CACHE 568 if (yp_access(argp->map, argp->domain, (struct svc_req *)rqstp)) { 569 #else 570 if (yp_access(argp->map, (struct svc_req *)rqstp)) { 571 #endif 572 result.stat = YP_YPERR; 573 return(&result); 574 } 575 576 if (argp->domain == NULL) { 577 result.stat = YP_BADARGS; 578 return (&result); 579 } 580 581 /* 582 * We could just check the timestamp on the map file, 583 * but that's a hack: we'll only know the last time the file 584 * was touched, not the last time the database contents were 585 * updated. 586 */ 587 588 if (yp_select_map(argp->map, argp->domain, &key, 1) != YP_TRUE) { 589 result.stat = yp_errno; 590 return(&result); 591 } 592 593 result.stat = yp_getbykey(&key, &val); 594 595 if (result.stat == YP_TRUE) 596 result.ordernum = atoi((char *)val.valdat_val); 597 else 598 result.ordernum = 0; 599 600 return (&result); 601 } 602 603 static void yp_maplist_free(yp_maplist) 604 struct ypmaplist *yp_maplist; 605 { 606 register struct ypmaplist *next; 607 608 while(yp_maplist) { 609 next = yp_maplist->next; 610 free(yp_maplist->map); 611 free(yp_maplist); 612 yp_maplist = next; 613 } 614 return; 615 } 616 617 static struct ypmaplist *yp_maplist_create(domain) 618 const char *domain; 619 { 620 char yp_mapdir[MAXPATHLEN + 2]; 621 char yp_mapname[MAXPATHLEN + 2]; 622 struct ypmaplist *cur = NULL; 623 struct ypmaplist *yp_maplist = NULL; 624 DIR *dird; 625 struct dirent *dirp; 626 struct stat statbuf; 627 628 snprintf(yp_mapdir, sizeof(yp_mapdir), "%s/%s", yp_dir, domain); 629 630 if ((dird = opendir(yp_mapdir)) == NULL) { 631 yp_error("opendir(%s) failed: %s", yp_mapdir, strerror(errno)); 632 return(NULL); 633 } 634 635 while ((dirp = readdir(dird)) != NULL) { 636 if (strcmp(dirp->d_name, ".") && strcmp(dirp->d_name, "..")) { 637 snprintf(yp_mapname, sizeof(yp_mapname), "%s/%s", 638 yp_mapdir,dirp->d_name); 639 if (stat(yp_mapname, &statbuf) < 0 || 640 !S_ISREG(statbuf.st_mode)) 641 continue; 642 if ((cur = (struct ypmaplist *) 643 malloc(sizeof(struct ypmaplist))) == NULL) { 644 yp_error("malloc() failed: %s",strerror(errno)); 645 closedir(dird); 646 yp_maplist_free(yp_maplist); 647 return(NULL); 648 } 649 if ((cur->map = (char *)strdup(dirp->d_name)) == NULL) { 650 yp_error("strdup() failed: %s",strerror(errno)); 651 closedir(dird); 652 yp_maplist_free(yp_maplist); 653 return(NULL); 654 } 655 cur->next = yp_maplist; 656 yp_maplist = cur; 657 if (debug) 658 yp_error("map: %s", yp_maplist->map); 659 } 660 661 } 662 closedir(dird); 663 return(yp_maplist); 664 } 665 666 ypresp_maplist * 667 ypproc_maplist_2_svc(domainname *argp, struct svc_req *rqstp) 668 { 669 static ypresp_maplist result = { 0, NULL }; 670 671 #ifdef DB_CACHE 672 if (yp_access(NULL, NULL, (struct svc_req *)rqstp)) { 673 #else 674 if (yp_access(NULL, (struct svc_req *)rqstp)) { 675 #endif 676 result.stat = YP_YPERR; 677 return(&result); 678 } 679 680 if (argp == NULL) { 681 result.stat = YP_BADARGS; 682 return (&result); 683 } 684 685 if (yp_validdomain(*argp)) { 686 result.stat = YP_NODOM; 687 return (&result); 688 } 689 690 /* 691 * We have to construct a linked list for the ypproc_maplist 692 * procedure using dynamically allocated memory. Since the XDR 693 * layer won't free this list for us, we have to deal with it 694 * ourselves. We call yp_maplist_free() first to free any 695 * previously allocated data we may have accumulated to insure 696 * that we have only one linked list in memory at any given 697 * time. 698 */ 699 700 yp_maplist_free(result.maps); 701 702 if ((result.maps = yp_maplist_create(*argp)) == NULL) { 703 yp_error("yp_maplist_create failed"); 704 result.stat = YP_YPERR; 705 return(&result); 706 } else 707 result.stat = YP_TRUE; 708 709 return (&result); 710 } 711 712 /* 713 * NIS v1 support. The nullproc, domain and domain_nonack 714 * functions from v1 are identical to those in v2, so all 715 * we have to do is hand off to them. 716 * 717 * The other functions are mostly just wrappers around their v2 718 * counterparts. For example, for the v1 'match' procedure, we 719 * crack open the argument structure, make a request to the v2 720 * 'match' function, repackage the data into a v1 response and 721 * then send it on its way. 722 * 723 * Note that we don't support the pull, push and get procedures. 724 * There's little documentation available to show what they 725 * do, and I suspect they're meant largely for map transfers 726 * between master and slave servers. 727 */ 728 729 void * 730 ypoldproc_null_1_svc(void *argp, struct svc_req *rqstp) 731 { 732 return(ypproc_null_2_svc(argp, rqstp)); 733 } 734 735 bool_t * 736 ypoldproc_domain_1_svc(domainname *argp, struct svc_req *rqstp) 737 { 738 return(ypproc_domain_2_svc(argp, rqstp)); 739 } 740 741 bool_t * 742 ypoldproc_domain_nonack_1_svc(domainname *argp, struct svc_req *rqstp) 743 { 744 return (ypproc_domain_nonack_2_svc(argp, rqstp)); 745 } 746 747 /* 748 * the 'match' procedure sends a response of type YPRESP_VAL 749 */ 750 ypresponse * 751 ypoldproc_match_1_svc(yprequest *argp, struct svc_req *rqstp) 752 { 753 static ypresponse result; 754 ypresp_val *v2_result; 755 756 result.yp_resptype = YPRESP_VAL; 757 result.ypresponse_u.yp_resp_valtype.val.valdat_val = ""; 758 result.ypresponse_u.yp_resp_valtype.val.valdat_len = 0; 759 760 if (argp->yp_reqtype != YPREQ_KEY) { 761 result.ypresponse_u.yp_resp_valtype.stat = YP_BADARGS; 762 return(&result); 763 } 764 765 v2_result = ypproc_match_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp); 766 if (v2_result == NULL) 767 return(NULL); 768 769 bcopy((char *)v2_result, 770 (char *)&result.ypresponse_u.yp_resp_valtype, 771 sizeof(ypresp_val)); 772 773 return (&result); 774 } 775 776 /* 777 * the 'first' procedure sends a response of type YPRESP_KEY_VAL 778 */ 779 ypresponse * 780 ypoldproc_first_1_svc(yprequest *argp, struct svc_req *rqstp) 781 { 782 static ypresponse result; 783 ypresp_key_val *v2_result; 784 785 result.yp_resptype = YPRESP_KEY_VAL; 786 result.ypresponse_u.yp_resp_key_valtype.val.valdat_val = 787 result.ypresponse_u.yp_resp_key_valtype.key.keydat_val = ""; 788 result.ypresponse_u.yp_resp_key_valtype.val.valdat_len = 789 result.ypresponse_u.yp_resp_key_valtype.key.keydat_len = 0; 790 791 if (argp->yp_reqtype != YPREQ_NOKEY) { 792 result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS; 793 return(&result); 794 } 795 796 v2_result = ypproc_first_2_svc(&argp->yprequest_u.yp_req_nokeytype, 797 rqstp); 798 if (v2_result == NULL) 799 return(NULL); 800 801 bcopy((char *)v2_result, 802 (char *)&result.ypresponse_u.yp_resp_key_valtype, 803 sizeof(ypresp_key_val)); 804 805 return (&result); 806 } 807 808 /* 809 * the 'next' procedure sends a response of type YPRESP_KEY_VAL 810 */ 811 ypresponse * 812 ypoldproc_next_1_svc(yprequest *argp, struct svc_req *rqstp) 813 { 814 static ypresponse result; 815 ypresp_key_val *v2_result; 816 817 result.yp_resptype = YPRESP_KEY_VAL; 818 result.ypresponse_u.yp_resp_key_valtype.val.valdat_val = 819 result.ypresponse_u.yp_resp_key_valtype.key.keydat_val = ""; 820 result.ypresponse_u.yp_resp_key_valtype.val.valdat_len = 821 result.ypresponse_u.yp_resp_key_valtype.key.keydat_len = 0; 822 823 if (argp->yp_reqtype != YPREQ_KEY) { 824 result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS; 825 return(&result); 826 } 827 828 v2_result = ypproc_next_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp); 829 if (v2_result == NULL) 830 return(NULL); 831 832 bcopy((char *)v2_result, 833 (char *)&result.ypresponse_u.yp_resp_key_valtype, 834 sizeof(ypresp_key_val)); 835 836 return (&result); 837 } 838 839 /* 840 * the 'poll' procedure sends a response of type YPRESP_MAP_PARMS 841 */ 842 ypresponse * 843 ypoldproc_poll_1_svc(yprequest *argp, struct svc_req *rqstp) 844 { 845 static ypresponse result; 846 ypresp_master *v2_result1; 847 ypresp_order *v2_result2; 848 849 result.yp_resptype = YPRESP_MAP_PARMS; 850 result.ypresponse_u.yp_resp_map_parmstype.domain = 851 argp->yprequest_u.yp_req_nokeytype.domain; 852 result.ypresponse_u.yp_resp_map_parmstype.map = 853 argp->yprequest_u.yp_req_nokeytype.map; 854 /* 855 * Hmm... there is no 'status' value in the 856 * yp_resp_map_parmstype structure, so I have to 857 * guess at what to do to indicate a failure. 858 * I hope this is right. 859 */ 860 result.ypresponse_u.yp_resp_map_parmstype.ordernum = 0; 861 result.ypresponse_u.yp_resp_map_parmstype.peer = ""; 862 863 if (argp->yp_reqtype != YPREQ_MAP_PARMS) { 864 return(&result); 865 } 866 867 v2_result1 = ypproc_master_2_svc(&argp->yprequest_u.yp_req_nokeytype, 868 rqstp); 869 if (v2_result1 == NULL) 870 return(NULL); 871 872 if (v2_result1->stat != YP_TRUE) { 873 return(&result); 874 } 875 876 v2_result2 = ypproc_order_2_svc(&argp->yprequest_u.yp_req_nokeytype, 877 rqstp); 878 if (v2_result2 == NULL) 879 return(NULL); 880 881 if (v2_result2->stat != YP_TRUE) { 882 return(&result); 883 } 884 885 result.ypresponse_u.yp_resp_map_parmstype.peer = 886 v2_result1->peer; 887 result.ypresponse_u.yp_resp_map_parmstype.ordernum = 888 v2_result2->ordernum; 889 890 return (&result); 891 } 892 893 ypresponse * 894 ypoldproc_push_1_svc(yprequest *argp, struct svc_req *rqstp) 895 { 896 static ypresponse result; 897 898 /* 899 * Not implemented. 900 */ 901 902 return (&result); 903 } 904 905 ypresponse * 906 ypoldproc_pull_1_svc(yprequest *argp, struct svc_req *rqstp) 907 { 908 static ypresponse result; 909 910 /* 911 * Not implemented. 912 */ 913 914 return (&result); 915 } 916 917 ypresponse * 918 ypoldproc_get_1_svc(yprequest *argp, struct svc_req *rqstp) 919 { 920 static ypresponse result; 921 922 /* 923 * Not implemented. 924 */ 925 926 return (&result); 927 } 928