1 /* 2 * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca> 3 * 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. The name of the author may not be used to endorse or promote 14 * products derived from this software without specific prior written 15 * permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #ifndef LINT 31 static char rcsid[] = "$Id: yplib.c,v 1.5 1993/07/24 18:29:16 deraadt Exp $"; 32 #endif 33 34 #include <sys/param.h> 35 #include <sys/types.h> 36 #include <sys/socket.h> 37 #include <sys/file.h> 38 #include <errno.h> 39 #include <stdio.h> 40 #include <string.h> 41 #include <rpc/rpc.h> 42 #include <rpc/xdr.h> 43 #include <rpcsvc/yp_prot.h> 44 #include <rpcsvc/ypclnt.h> 45 46 #ifndef BINDINGDIR 47 #define BINDINGDIR "/var/yp/binding" 48 #endif 49 #define YPMATCHCACHE 50 51 extern bool_t xdr_domainname(), xdr_ypbind_resp(); 52 extern bool_t xdr_ypreq_key(), xdr_ypresp_val(); 53 extern bool_t xdr_ypreq_nokey(), xdr_ypresp_key_val(); 54 extern bool_t xdr_ypresp_all(), xdr_ypresp_all_seq(); 55 extern bool_t xdr_ypresp_master(); 56 57 int (*ypresp_allfn)(); 58 void *ypresp_data; 59 60 struct dom_binding *_ypbindlist; 61 static char _yp_domain[MAXHOSTNAMELEN]; 62 int _yplib_timeout = 10; 63 64 #ifdef YPMATCHCACHE 65 int _yplib_cache = 5; 66 67 static struct ypmatch_ent { 68 struct ypmatch_ent *next; 69 char *map, *key, *val; 70 int keylen, vallen; 71 time_t expire_t; 72 } *ypmc; 73 74 static void 75 ypmatch_add(map, key, keylen, val, vallen) 76 char *map; 77 char *key; 78 int keylen; 79 char *val; 80 int vallen; 81 { 82 struct ypmatch_ent *ep; 83 time_t t; 84 85 time(&t); 86 87 for(ep=ypmc; ep; ep=ep->next) 88 if(ep->expire_t < t) 89 break; 90 if(ep==NULL) { 91 ep = (struct ypmatch_ent *)malloc(sizeof *ep); 92 bzero((char *)ep, sizeof *ep); 93 if(ypmc) 94 ep->next = ypmc; 95 ypmc = ep; 96 } 97 98 if(ep->key) 99 free(ep->key); 100 if(ep->val) 101 free(ep->val); 102 103 ep->key = NULL; 104 ep->val = NULL; 105 106 ep->key = (char *)malloc(keylen); 107 if(ep->key==NULL) 108 return; 109 110 ep->val = (char *)malloc(vallen); 111 if(ep->key==NULL) { 112 free(ep->key); 113 ep->key = NULL; 114 return; 115 } 116 ep->keylen = keylen; 117 ep->vallen = vallen; 118 119 bcopy(key, ep->key, ep->keylen); 120 bcopy(val, ep->val, ep->vallen); 121 122 if(ep->map) { 123 if( strcmp(ep->map, map) ) { 124 free(ep->map); 125 ep->map = strdup(map); 126 } 127 } else { 128 ep->map = strdup(map); 129 } 130 131 ep->expire_t = t + _yplib_cache; 132 } 133 134 static bool_t 135 ypmatch_find(map, key, keylen, val, vallen) 136 char *map; 137 char *key; 138 int keylen; 139 char **val; 140 int *vallen; 141 { 142 struct ypmatch_ent *ep; 143 time_t t; 144 145 if(ypmc==NULL) 146 return 0; 147 148 time(&t); 149 150 for(ep=ypmc; ep; ep=ep->next) { 151 if(ep->keylen != keylen) 152 continue; 153 if(strcmp(ep->map, map)) 154 continue; 155 if(bcmp(ep->key, key, keylen)) 156 continue; 157 if(t > ep->expire_t) 158 continue; 159 160 *val = ep->val; 161 *vallen = ep->vallen; 162 return 1; 163 } 164 return 0; 165 } 166 #endif 167 168 int 169 _yp_dobind(dom, ypdb) 170 char *dom; 171 struct dom_binding **ypdb; 172 { 173 static int pid = -1; 174 char path[MAXPATHLEN]; 175 struct dom_binding *ysd, *ysd2; 176 struct ypbind_resp ypbr; 177 struct timeval tv; 178 struct sockaddr_in clnt_sin; 179 int clnt_sock, fd, gpid; 180 CLIENT *client; 181 int new=0, r; 182 183 gpid = getpid(); 184 if( !(pid==-1 || pid==gpid) ) { 185 ysd = _ypbindlist; 186 while(ysd) { 187 if(ysd->dom_client) 188 clnt_destroy(ysd->dom_client); 189 ysd2 = ysd->dom_pnext; 190 free(ysd); 191 ysd = ysd2; 192 } 193 _ypbindlist = NULL; 194 } 195 pid = gpid; 196 197 if(ypdb!=NULL) 198 *ypdb = NULL; 199 200 if(dom==NULL || strlen(dom)==0) 201 return YPERR_BADARGS; 202 203 for(ysd = _ypbindlist; ysd; ysd = ysd->dom_pnext) 204 if( strcmp(dom, ysd->dom_domain) == 0) 205 break; 206 if(ysd==NULL) { 207 ysd = (struct dom_binding *)malloc(sizeof *ysd); 208 bzero((char *)ysd, sizeof *ysd); 209 ysd->dom_socket = -1; 210 ysd->dom_vers = 0; 211 new = 1; 212 } 213 again: 214 #ifdef BINDINGDIR 215 if(ysd->dom_vers==0) { 216 sprintf(path, "%s/%s.%d", BINDINGDIR, dom, 2); 217 if( (fd=open(path, O_RDONLY)) == -1) { 218 /* no binding file, YP is dead. */ 219 if(new) 220 free(ysd); 221 return YPERR_YPBIND; 222 } 223 if( flock(fd, LOCK_EX|LOCK_NB) == -1 && errno==EWOULDBLOCK) { 224 r = read(fd, &ysd->dom_server_addr, sizeof ysd->dom_server_addr); 225 if(r != sizeof ysd->dom_server_addr) { 226 close(fd); 227 ysd->dom_vers = -1; 228 goto again; 229 } 230 ysd->dom_server_port = ysd->dom_server_addr.sin_port; 231 close(fd); 232 goto gotit; 233 } else { 234 /* no lock on binding file, YP is dead. */ 235 close(fd); 236 if(new) 237 free(ysd); 238 return YPERR_YPBIND; 239 } 240 } 241 #endif 242 if(ysd->dom_vers==-1 || ysd->dom_vers==0) { 243 bzero((char *)&clnt_sin, sizeof clnt_sin); 244 clnt_sin.sin_family = AF_INET; 245 clnt_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 246 247 clnt_sock = RPC_ANYSOCK; 248 client = clnttcp_create(&clnt_sin, YPBINDPROG, YPBINDVERS, &clnt_sock, 249 0, 0); 250 if(client==NULL) { 251 clnt_pcreateerror("clnttcp_create"); 252 if(new) 253 free(ysd); 254 return YPERR_YPBIND; 255 } 256 257 tv.tv_sec = _yplib_timeout; 258 tv.tv_usec = 0; 259 r = clnt_call(client, YPBINDPROC_DOMAIN, 260 xdr_domainname, dom, xdr_ypbind_resp, &ypbr, tv); 261 if(r != RPC_SUCCESS) { 262 fprintf(stderr, 263 "YP: server for domain %s not responding, still trying\n", dom); 264 clnt_destroy(client); 265 ysd->dom_vers = -1; 266 goto again; 267 } 268 clnt_destroy(client); 269 270 bzero((char *)&ysd->dom_server_addr, sizeof ysd->dom_server_addr); 271 ysd->dom_server_addr.sin_family = AF_INET; 272 ysd->dom_server_addr.sin_port = 273 ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port; 274 ysd->dom_server_addr.sin_addr.s_addr = 275 ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr.s_addr; 276 ysd->dom_server_port = 277 ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port; 278 gotit: 279 ysd->dom_vers = YPVERS; 280 strcpy(ysd->dom_domain, dom); 281 } 282 283 tv.tv_sec = _yplib_timeout/2; 284 tv.tv_usec = 0; 285 if(ysd->dom_client) 286 clnt_destroy(ysd->dom_client); 287 ysd->dom_socket = RPC_ANYSOCK; 288 ysd->dom_client = clntudp_create(&ysd->dom_server_addr, 289 YPPROG, YPVERS, tv, &ysd->dom_socket); 290 if(ysd->dom_client==NULL) { 291 clnt_pcreateerror("clntudp_create"); 292 ysd->dom_vers = -1; 293 goto again; 294 } 295 if( fcntl(ysd->dom_socket, F_SETFD, 1) == -1) 296 perror("fcntl: F_SETFD"); 297 298 if(new) { 299 ysd->dom_pnext = _ypbindlist; 300 _ypbindlist = ysd; 301 } 302 303 if(ypdb!=NULL) 304 *ypdb = ysd; 305 return 0; 306 } 307 308 static void 309 _yp_unbind(ypb) 310 struct dom_binding *ypb; 311 { 312 clnt_destroy(ypb->dom_client); 313 ypb->dom_client = NULL; 314 ypb->dom_socket = -1; 315 } 316 317 int 318 yp_bind(dom) 319 char *dom; 320 { 321 return _yp_dobind(dom, NULL); 322 } 323 324 void 325 yp_unbind(dom) 326 char *dom; 327 { 328 struct dom_binding *ypb, *ypbp; 329 330 ypbp = NULL; 331 for(ypb=_ypbindlist; ypb; ypb=ypb->dom_pnext) { 332 if( strcmp(dom, ypb->dom_domain) == 0) { 333 clnt_destroy(ypb->dom_client); 334 if(ypbp) 335 ypbp->dom_pnext = ypb->dom_pnext; 336 else 337 _ypbindlist = ypb->dom_pnext; 338 free(ypb); 339 return; 340 } 341 ypbp = ypb; 342 } 343 return; 344 } 345 346 int 347 yp_match(indomain, inmap, inkey, inkeylen, outval, outvallen) 348 char *indomain; 349 char *inmap; 350 const char *inkey; 351 int inkeylen; 352 char **outval; 353 int *outvallen; 354 { 355 struct dom_binding *ysd; 356 struct ypresp_val yprv; 357 struct timeval tv; 358 struct ypreq_key yprk; 359 int r; 360 361 *outval = NULL; 362 *outvallen = 0; 363 364 again: 365 if( _yp_dobind(indomain, &ysd) != 0) 366 return YPERR_DOMAIN; 367 368 #ifdef YPMATCHCACHE 369 if( !strcmp(_yp_domain, indomain) && ypmatch_find(inmap, inkey, 370 inkeylen, &yprv.valdat.dptr, &yprv.valdat.dsize)) { 371 *outvallen = yprv.valdat.dsize; 372 *outval = (char *)malloc(*outvallen+1); 373 bcopy(yprv.valdat.dptr, *outval, *outvallen); 374 (*outval)[*outvallen] = '\0'; 375 return 0; 376 } 377 #endif 378 379 tv.tv_sec = _yplib_timeout; 380 tv.tv_usec = 0; 381 382 yprk.domain = indomain; 383 yprk.map = inmap; 384 yprk.keydat.dptr = inkey; 385 yprk.keydat.dsize = inkeylen; 386 387 bzero((char *)&yprv, sizeof yprv); 388 389 r = clnt_call(ysd->dom_client, YPPROC_MATCH, 390 xdr_ypreq_key, &yprk, xdr_ypresp_val, &yprv, tv); 391 if(r != RPC_SUCCESS) { 392 clnt_perror(ysd->dom_client, "yp_match: clnt_call"); 393 ysd->dom_vers = -1; 394 goto again; 395 } 396 if( !(r=ypprot_err(yprv.status)) ) { 397 *outvallen = yprv.valdat.dsize; 398 *outval = (char *)malloc(*outvallen+1); 399 bcopy(yprv.valdat.dptr, *outval, *outvallen); 400 (*outval)[*outvallen] = '\0'; 401 #ifdef YPMATCHCACHE 402 if( strcmp(_yp_domain, indomain)==0 ) 403 ypmatch_add(inmap, inkey, inkeylen, *outval, *outvallen); 404 #endif 405 } 406 xdr_free(xdr_ypresp_val, (char *)&yprv); 407 _yp_unbind(ysd); 408 return r; 409 } 410 411 int 412 yp_get_default_domain(domp) 413 char **domp; 414 { 415 *domp = NULL; 416 if(_yp_domain[0] == '\0') 417 if( getdomainname(_yp_domain, sizeof _yp_domain)) 418 return YPERR_NODOM; 419 *domp = _yp_domain; 420 return 0; 421 } 422 423 int 424 yp_first(indomain, inmap, outkey, outkeylen, outval, outvallen) 425 char *indomain; 426 char *inmap; 427 char **outkey; 428 int *outkeylen; 429 char **outval; 430 int *outvallen; 431 { 432 struct ypresp_key_val yprkv; 433 struct ypreq_nokey yprnk; 434 struct dom_binding *ysd; 435 struct timeval tv; 436 int r; 437 438 *outkey = *outval = NULL; 439 *outkeylen = *outvallen = 0; 440 441 again: 442 if( _yp_dobind(indomain, &ysd) != 0) 443 return YPERR_DOMAIN; 444 445 tv.tv_sec = _yplib_timeout; 446 tv.tv_usec = 0; 447 448 yprnk.domain = indomain; 449 yprnk.map = inmap; 450 bzero((char *)&yprkv, sizeof yprkv); 451 452 r = clnt_call(ysd->dom_client, YPPROC_FIRST, 453 xdr_ypreq_nokey, &yprnk, xdr_ypresp_key_val, &yprkv, tv); 454 if(r != RPC_SUCCESS) { 455 clnt_perror(ysd->dom_client, "yp_first: clnt_call"); 456 ysd->dom_vers = -1; 457 goto again; 458 } 459 if( !(r=ypprot_err(yprkv.status)) ) { 460 *outkeylen = yprkv.keydat.dsize; 461 *outkey = (char *)malloc(*outkeylen+1); 462 bcopy(yprkv.keydat.dptr, *outkey, *outkeylen); 463 (*outkey)[*outkeylen] = '\0'; 464 *outvallen = yprkv.valdat.dsize; 465 *outval = (char *)malloc(*outvallen+1); 466 bcopy(yprkv.valdat.dptr, *outval, *outvallen); 467 (*outval)[*outvallen] = '\0'; 468 } 469 xdr_free(xdr_ypresp_key_val, (char *)&yprkv); 470 _yp_unbind(ysd); 471 return r; 472 } 473 474 int 475 yp_next(indomain, inmap, inkey, inkeylen, outkey, outkeylen, outval, outvallen) 476 char *indomain; 477 char *inmap; 478 char *inkey; 479 int inkeylen; 480 char **outkey; 481 int *outkeylen; 482 char **outval; 483 int *outvallen; 484 { 485 struct ypresp_key_val yprkv; 486 struct ypreq_key yprk; 487 struct dom_binding *ysd; 488 struct timeval tv; 489 int r; 490 491 *outkey = *outval = NULL; 492 *outkeylen = *outvallen = 0; 493 494 again: 495 if( _yp_dobind(indomain, &ysd) != 0) 496 return YPERR_DOMAIN; 497 498 tv.tv_sec = _yplib_timeout; 499 tv.tv_usec = 0; 500 501 yprk.domain = indomain; 502 yprk.map = inmap; 503 yprk.keydat.dptr = inkey; 504 yprk.keydat.dsize = inkeylen; 505 bzero((char *)&yprkv, sizeof yprkv); 506 507 r = clnt_call(ysd->dom_client, YPPROC_NEXT, 508 xdr_ypreq_key, &yprk, xdr_ypresp_key_val, &yprkv, tv); 509 if(r != RPC_SUCCESS) { 510 clnt_perror(ysd->dom_client, "yp_next: clnt_call"); 511 ysd->dom_vers = -1; 512 goto again; 513 } 514 if( !(r=ypprot_err(yprkv.status)) ) { 515 *outkeylen = yprkv.keydat.dsize; 516 *outkey = (char *)malloc(*outkeylen+1); 517 bcopy(yprkv.keydat.dptr, *outkey, *outkeylen); 518 (*outkey)[*outkeylen] = '\0'; 519 *outvallen = yprkv.valdat.dsize; 520 *outval = (char *)malloc(*outvallen+1); 521 bcopy(yprkv.valdat.dptr, *outval, *outvallen); 522 (*outval)[*outvallen] = '\0'; 523 } 524 xdr_free(xdr_ypresp_key_val, (char *)&yprkv); 525 _yp_unbind(ysd); 526 return r; 527 } 528 529 int 530 yp_all(indomain, inmap, incallback) 531 char *indomain; 532 char *inmap; 533 struct ypall_callback *incallback; 534 { 535 struct ypreq_nokey yprnk; 536 struct dom_binding *ysd; 537 struct timeval tv; 538 struct sockaddr_in clnt_sin; 539 CLIENT *clnt; 540 u_long status; 541 int clnt_sock; 542 543 if( _yp_dobind(indomain, &ysd) != 0) 544 return YPERR_DOMAIN; 545 546 tv.tv_sec = _yplib_timeout; 547 tv.tv_usec = 0; 548 clnt_sock = RPC_ANYSOCK; 549 clnt_sin = ysd->dom_server_addr; 550 clnt_sin.sin_port = 0; 551 clnt = clnttcp_create(&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0); 552 if(clnt==NULL) { 553 printf("clnttcp_create failed\n"); 554 return YPERR_PMAP; 555 } 556 557 yprnk.domain = indomain; 558 yprnk.map = inmap; 559 ypresp_allfn = incallback->foreach; 560 ypresp_data = (void *)incallback->data; 561 562 (void) clnt_call(clnt, YPPROC_ALL, 563 xdr_ypreq_nokey, &yprnk, xdr_ypresp_all_seq, &status, tv); 564 clnt_destroy(clnt); 565 xdr_free(xdr_ypresp_all_seq, (char *)&status); /* not really needed... */ 566 _yp_unbind(ysd); 567 568 if(status != YP_FALSE) 569 return ypprot_err(status); 570 return 0; 571 } 572 573 int 574 yp_order(indomain, inmap, outorder) 575 char *indomain; 576 char *inmap; 577 int *outorder; 578 { 579 struct dom_binding *ysd; 580 struct ypresp_order ypro; 581 struct ypreq_nokey yprnk; 582 struct timeval tv; 583 int r; 584 585 again: 586 if( _yp_dobind(indomain, &ysd) != 0) 587 return YPERR_DOMAIN; 588 589 tv.tv_sec = _yplib_timeout; 590 tv.tv_usec = 0; 591 592 yprnk.domain = indomain; 593 yprnk.map = inmap; 594 595 bzero((char *)(char *)&ypro, sizeof ypro); 596 597 r = clnt_call(ysd->dom_client, YPPROC_ORDER, 598 xdr_ypreq_nokey, &yprnk, xdr_ypresp_order, &ypro, tv); 599 if(r != RPC_SUCCESS) { 600 clnt_perror(ysd->dom_client, "yp_order: clnt_call"); 601 ysd->dom_vers = -1; 602 goto again; 603 } 604 605 *outorder = ypro.ordernum; 606 xdr_free(xdr_ypresp_order, (char *)&ypro); 607 _yp_unbind(ysd); 608 return ypprot_err(ypro.status); 609 } 610 611 int 612 yp_master(indomain, inmap, outname) 613 char *indomain; 614 char *inmap; 615 char **outname; 616 { 617 struct dom_binding *ysd; 618 struct ypresp_master yprm; 619 struct ypreq_nokey yprnk; 620 struct timeval tv; 621 int r; 622 623 again: 624 if( _yp_dobind(indomain, &ysd) != 0) 625 return YPERR_DOMAIN; 626 627 tv.tv_sec = _yplib_timeout; 628 tv.tv_usec = 0; 629 630 yprnk.domain = indomain; 631 yprnk.map = inmap; 632 633 bzero((char *)&yprm, sizeof yprm); 634 635 r = clnt_call(ysd->dom_client, YPPROC_MASTER, 636 xdr_ypreq_nokey, &yprnk, xdr_ypresp_master, &yprm, tv); 637 if(r != RPC_SUCCESS) { 638 clnt_perror(ysd->dom_client, "yp_master: clnt_call"); 639 ysd->dom_vers = -1; 640 goto again; 641 } 642 if( !(r=ypprot_err(yprm.status)) ) { 643 *outname = (char *)strdup(yprm.master); 644 } 645 xdr_free(xdr_ypresp_master, (char *)&yprm); 646 _yp_unbind(ysd); 647 return r; 648 } 649 650 yp_maplist(indomain, outmaplist) 651 char *indomain; 652 struct ypmaplist **outmaplist; 653 { 654 struct dom_binding *ysd; 655 struct ypresp_maplist ypml; 656 struct timeval tv; 657 int r; 658 659 again: 660 if( _yp_dobind(indomain, &ysd) != 0) 661 return YPERR_DOMAIN; 662 663 tv.tv_sec = _yplib_timeout; 664 tv.tv_usec = 0; 665 666 bzero((char *)&ypml, sizeof ypml); 667 668 r = clnt_call(ysd->dom_client, YPPROC_MAPLIST, 669 xdr_domainname, indomain, xdr_ypresp_maplist, &ypml, tv); 670 if (r != RPC_SUCCESS) { 671 clnt_perror(ysd->dom_client, "yp_maplist: clnt_call"); 672 ysd->dom_vers = -1; 673 goto again; 674 } 675 *outmaplist = ypml.list; 676 /* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/ 677 _yp_unbind(ysd); 678 return ypprot_err(ypml.status); 679 } 680 681 char * 682 yperr_string(incode) 683 int incode; 684 { 685 static char err[80]; 686 687 switch(incode) { 688 case 0: 689 return "Success"; 690 case YPERR_BADARGS: 691 return "Request arguments bad"; 692 case YPERR_RPC: 693 return "RPC failure"; 694 case YPERR_DOMAIN: 695 return "Can't bind to server which serves this domain"; 696 case YPERR_MAP: 697 return "No such map in server's domain"; 698 case YPERR_KEY: 699 return "No such key in map"; 700 case YPERR_YPERR: 701 return "YP server error"; 702 case YPERR_RESRC: 703 return "Local resource allocation failure"; 704 case YPERR_NOMORE: 705 return "No more records in map database"; 706 case YPERR_PMAP: 707 return "Can't communicate with portmapper"; 708 case YPERR_YPBIND: 709 return "Can't communicate with ypbind"; 710 case YPERR_YPSERV: 711 return "Can't communicate with ypserv"; 712 case YPERR_NODOM: 713 return "Local domain name not set"; 714 case YPERR_BADDB: 715 return "Server data base is bad"; 716 case YPERR_VERS: 717 return "YP server version mismatch - server can't supply service."; 718 case YPERR_ACCESS: 719 return "Access violation"; 720 case YPERR_BUSY: 721 return "Database is busy"; 722 } 723 sprintf(err, "YP unknown error %d\n", incode); 724 return err; 725 } 726 727 int 728 ypprot_err(incode) 729 unsigned int incode; 730 { 731 switch(incode) { 732 case YP_TRUE: 733 return 0; 734 case YP_FALSE: 735 return YPERR_YPBIND; 736 case YP_NOMORE: 737 return YPERR_NOMORE; 738 case YP_NOMAP: 739 return YPERR_MAP; 740 case YP_NODOM: 741 return YPERR_NODOM; 742 case YP_NOKEY: 743 return YPERR_KEY; 744 case YP_BADOP: 745 return YPERR_YPERR; 746 case YP_BADDB: 747 return YPERR_BADDB; 748 case YP_YPERR: 749 return YPERR_YPERR; 750 case YP_BADARGS: 751 return YPERR_BADARGS; 752 case YP_VERS: 753 return YPERR_VERS; 754 } 755 return YPERR_YPERR; 756 } 757 758 int 759 _yp_check(dom) 760 char **dom; 761 { 762 int use_yp = 0; 763 char *unused; 764 765 if( _yp_domain[0]=='\0' ) 766 if( yp_get_default_domain(&unused) ) 767 return 0; 768 769 if(dom) 770 *dom = _yp_domain; 771 772 if( yp_bind(_yp_domain)==0 ) 773 return 1; 774 return 0; 775 } 776