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