yp_server.c revision 14303
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.6 1996/02/26 02:34:26 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 result.peer = ""; 536 537 if (yp_access(NULL, (struct svc_req *)rqstp)) { 538 result.stat = YP_YPERR; 539 return(&result); 540 } 541 542 if (argp->domain == NULL) { 543 result.stat = YP_BADARGS; 544 return (&result); 545 } 546 547 if (yp_validdomain(argp->domain)) { 548 result.stat = YP_NODOM; 549 return (&result); 550 } 551 552 key.data = "YP_MASTER_NAME"; 553 key.size = sizeof("YP_MASTER_NAME") - 1; 554 555 result.stat = yp_get_record(argp->domain, argp->map, &key, &data, 1); 556 557 if (result.stat == YP_TRUE) { 558 result.peer = (char *)data.data; 559 result.peer[data.size] = '\0'; 560 } else 561 result.peer = ""; 562 563 return (&result); 564} 565 566ypresp_order * 567ypproc_order_2_svc(ypreq_nokey *argp, struct svc_req *rqstp) 568{ 569 static ypresp_order result; 570 DBT key,data; 571 572 if (yp_access(NULL, (struct svc_req *)rqstp)) { 573 result.stat = YP_YPERR; 574 return(&result); 575 } 576 577 if (argp->domain == NULL) { 578 result.stat = YP_BADARGS; 579 return (&result); 580 } 581 582 if (yp_validdomain(argp->domain)) { 583 result.stat = YP_NODOM; 584 return (&result); 585 } 586 587 /* 588 * We could just check the timestamp on the map file, 589 * but that's a hack: we'll only know the last time the file 590 * was touched, not the last time the database contents were 591 * updated. 592 */ 593 key.data = "YP_LAST_MODIFIED"; 594 key.size = sizeof("YP_LAST_MODIFIED") - 1; 595 596 result.stat = yp_get_record(argp->domain, argp->map, &key, &data, 1); 597 598 if (result.stat == YP_TRUE) 599 result.ordernum = atoi((char *)data.data); 600 else 601 result.ordernum = 0; 602 603 return (&result); 604} 605 606static void yp_maplist_free(yp_maplist) 607 struct ypmaplist *yp_maplist; 608{ 609 register struct ypmaplist *next; 610 611 while(yp_maplist) { 612 next = yp_maplist->next; 613 free(yp_maplist->map); 614 free(yp_maplist); 615 yp_maplist = next; 616 } 617 return; 618} 619 620static struct ypmaplist *yp_maplist_create(domain) 621 const char *domain; 622{ 623 char yp_mapdir[MAXPATHLEN + 2]; 624 char yp_mapname[MAXPATHLEN + 2]; 625 struct ypmaplist *cur = NULL; 626 struct ypmaplist *yp_maplist = NULL; 627 DIR *dird; 628 struct dirent *dirp; 629 struct stat statbuf; 630 631 snprintf(yp_mapdir, sizeof(yp_mapdir), "%s/%s", yp_dir, domain); 632 633 if ((dird = opendir(yp_mapdir)) == NULL) { 634 yp_error("opendir(%s) failed: %s", yp_mapdir, strerror(errno)); 635 return(NULL); 636 } 637 638 while ((dirp = readdir(dird)) != NULL) { 639 if (strcmp(dirp->d_name, ".") && strcmp(dirp->d_name, "..")) { 640 snprintf(yp_mapname, sizeof(yp_mapname), "%s/%s",yp_mapdir,dirp->d_name); 641 if (stat(yp_mapname, &statbuf) < 0 || !S_ISREG(statbuf.st_mode)) 642 continue; 643 if ((cur = (struct ypmaplist *)malloc(sizeof(struct ypmaplist))) < 0) { 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 666ypresp_maplist * 667ypproc_maplist_2_svc(domainname *argp, struct svc_req *rqstp) 668{ 669 static ypresp_maplist result; 670 671 if (yp_access(NULL, (struct svc_req *)rqstp)) { 672 result.stat = YP_YPERR; 673 return(&result); 674 } 675 676 if (argp == NULL) { 677 result.stat = YP_BADARGS; 678 return (&result); 679 } 680 681 if (yp_validdomain(*argp)) { 682 result.stat = YP_NODOM; 683 return (&result); 684 } 685 686 /* 687 * We have to construct a linked list for the ypproc_maplist 688 * procedure using dynamically allocated memory. Since the XDR 689 * layer won't free this list for us, we have to deal with it 690 * ourselves. We call yp_maplist_free() first to free any 691 * previously allocated data we may have accumulated to insure 692 * that we have only one linked list in memory at any given 693 * time. 694 */ 695 696 yp_maplist_free(result.maps); 697 698 if ((result.maps = yp_maplist_create(*argp)) == NULL) { 699 yp_error("yp_maplist_create failed"); 700 result.stat = YP_YPERR; 701 return(&result); 702 } else 703 result.stat = YP_TRUE; 704 705 return (&result); 706} 707 708/* 709 * NIS v1 support. The nullproc, domain and domain_nonack 710 * functions from v1 are identical to those in v2, so all 711 * we have to do is hand off to them. 712 * 713 * The other functions are mostly just wrappers around their v2 714 * counterparts. For example, for the v1 'match' procedure, we 715 * crack open the argument structure, make a request to the v2 716 * 'match' function, repackage the data into a v1 response and 717 * then send it on its way. 718 * 719 * Note that we don't support the pull, push and get procedures. 720 * There's little documentation available to show what they 721 * do, and I suspect they're meant largely for map transfers 722 * between master and slave servers. 723 */ 724 725void * 726ypoldproc_null_1_svc(void *argp, struct svc_req *rqstp) 727{ 728 return(ypproc_null_2_svc(argp, rqstp)); 729} 730 731bool_t * 732ypoldproc_domain_1_svc(domainname *argp, struct svc_req *rqstp) 733{ 734 return(ypproc_domain_2_svc(argp, rqstp)); 735} 736 737bool_t * 738ypoldproc_domain_nonack_1_svc(domainname *argp, struct svc_req *rqstp) 739{ 740 return (ypproc_domain_nonack_2_svc(argp, rqstp)); 741} 742 743ypresponse * 744ypoldproc_match_1_svc(yprequest *argp, struct svc_req *rqstp) 745{ 746 static ypresponse result; 747 ypresp_val *v2_result; 748 749 result.yp_resptype = YPRESP_VAL; 750 751 if (argp->yp_reqtype != YPREQ_KEY) { 752 result.ypresponse_u.yp_resp_valtype.stat = YP_BADARGS; 753 return(&result); 754 } 755 756 v2_result = ypproc_match_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp); 757 if (v2_result == NULL) 758 return(NULL); 759 760 bcopy((char *)v2_result, 761 (char *)&result.ypresponse_u.yp_resp_valtype, 762 sizeof(ypresp_val)); 763 764 return (&result); 765} 766 767ypresponse * 768ypoldproc_first_1_svc(yprequest *argp, struct svc_req *rqstp) 769{ 770 static ypresponse result; 771 ypresp_key_val *v2_result; 772 773 result.yp_resptype = YPRESP_KEY_VAL; 774 775 if (argp->yp_reqtype != YPREQ_NOKEY) { 776 result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS; 777 return(&result); 778 } 779 780 v2_result = ypproc_first_2_svc(&argp->yprequest_u.yp_req_nokeytype, 781 rqstp); 782 if (v2_result == NULL) 783 return(NULL); 784 785 bcopy((char *)v2_result, 786 (char *)&result.ypresponse_u.yp_resp_key_valtype, 787 sizeof(ypresp_key_val)); 788 789 return (&result); 790} 791 792ypresponse * 793ypoldproc_next_1_svc(yprequest *argp, struct svc_req *rqstp) 794{ 795 static ypresponse result; 796 ypresp_key_val *v2_result; 797 798 result.yp_resptype = YPRESP_KEY_VAL; 799 800 if (argp->yp_reqtype != YPREQ_KEY) { 801 result.ypresponse_u.yp_resp_key_valtype.stat = YP_BADARGS; 802 return(&result); 803 } 804 805 v2_result = ypproc_next_2_svc(&argp->yprequest_u.yp_req_keytype,rqstp); 806 if (v2_result == NULL) 807 return(NULL); 808 809 bcopy((char *)v2_result, 810 (char *)&result.ypresponse_u.yp_resp_key_valtype, 811 sizeof(ypresp_key_val)); 812 813 return (&result); 814} 815 816ypresponse * 817ypoldproc_poll_1_svc(yprequest *argp, struct svc_req *rqstp) 818{ 819 static ypresponse result; 820 ypresp_master *v2_result1; 821 ypresp_order *v2_result2; 822 823 result.yp_resptype = YPRESP_MAP_PARMS; 824 result.ypresponse_u.yp_resp_map_parmstype.domain = 825 argp->yprequest_u.yp_req_nokeytype.domain; 826 result.ypresponse_u.yp_resp_map_parmstype.map = 827 argp->yprequest_u.yp_req_nokeytype.map; 828 /* 829 * Hmm... there is no 'status' value in the 830 * yp_resp_map_parmstype structure, so I have to 831 * guess at what to do to indicate a failure. 832 * I hope this is right. 833 */ 834 result.ypresponse_u.yp_resp_map_parmstype.ordernum = 0; 835 result.ypresponse_u.yp_resp_map_parmstype.peer = ""; 836 837 if (argp->yp_reqtype != YPREQ_MAP_PARMS) { 838 return(&result); 839 } 840 841 v2_result1 = ypproc_master_2_svc(&argp->yprequest_u.yp_req_nokeytype, 842 rqstp); 843 if (v2_result1 == NULL) 844 return(NULL); 845 846 if (v2_result1->stat != YP_TRUE) { 847 return(&result); 848 } 849 850 v2_result2 = ypproc_order_2_svc(&argp->yprequest_u.yp_req_nokeytype, 851 rqstp); 852 if (v2_result2 == NULL) 853 return(NULL); 854 855 if (v2_result2->stat != YP_TRUE) { 856 return(&result); 857 } 858 859 result.ypresponse_u.yp_resp_map_parmstype.peer = 860 v2_result1->peer; 861 result.ypresponse_u.yp_resp_map_parmstype.ordernum = 862 v2_result2->ordernum; 863 864 return (&result); 865} 866 867ypresponse * 868ypoldproc_push_1_svc(yprequest *argp, struct svc_req *rqstp) 869{ 870 static ypresponse result; 871 872 /* 873 * Not implemented. 874 */ 875 876 return (&result); 877} 878 879ypresponse * 880ypoldproc_pull_1_svc(yprequest *argp, struct svc_req *rqstp) 881{ 882 static ypresponse result; 883 884 /* 885 * Not implemented. 886 */ 887 888 return (&result); 889} 890 891ypresponse * 892ypoldproc_get_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