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