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