1 /* $NetBSD: ypserv_db.c,v 1.14 2002/07/06 00:42:27 wiz Exp $ */ 2 3 /* 4 * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se> 5 * Copyright (c) 1996 Charles D. Cranor 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Mats O Jansson 19 * and Charles D. Cranor. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 24 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <sys/cdefs.h> 37 #ifndef lint 38 __RCSID("$NetBSD: ypserv_db.c,v 1.14 2002/07/06 00:42:27 wiz Exp $"); 39 #endif 40 41 /* 42 * major revision/cleanup of Mats' version done by 43 * Chuck Cranor <chuck@ccrc.wustl.edu> Jan 1996. 44 */ 45 46 #include <sys/types.h> 47 #include <sys/socket.h> 48 #include <sys/queue.h> 49 #include <sys/stat.h> 50 #include <sys/param.h> 51 52 #include <netinet/in.h> 53 #include <arpa/inet.h> 54 #include <arpa/nameser.h> 55 56 #include <errno.h> 57 #include <fcntl.h> 58 #include <string.h> 59 #include <stdio.h> 60 #include <stdlib.h> 61 #include <netdb.h> 62 #include <resolv.h> 63 #include <syslog.h> 64 #include <unistd.h> 65 66 #include <rpc/rpc.h> 67 #include <rpcsvc/yp_prot.h> 68 #include <rpcsvc/ypclnt.h> 69 70 #include "ypdb.h" 71 #include "ypdef.h" 72 #include "ypserv.h" 73 74 LIST_HEAD(domainlist, opt_domain); /* LIST of domains */ 75 LIST_HEAD(maplist, opt_map); /* LIST of maps (in a domain) */ 76 CIRCLEQ_HEAD(mapq, opt_map); /* CIRCLEQ of maps (LRU) */ 77 78 struct opt_map { 79 char *map; /* map name (malloc'd) */ 80 DBM *db; /* database */ 81 struct opt_domain *dom; /* back ptr to our domain */ 82 int host_lookup; /* host lookup */ 83 int secure; /* is this map secure? */ 84 dev_t dbdev; /* device db is on */ 85 ino_t dbino; /* inode of db */ 86 time_t dbmtime; /* time of last db modification */ 87 CIRCLEQ_ENTRY(opt_map) mapsq; /* map queue pointers */ 88 LIST_ENTRY(opt_map) mapsl; /* map list pointers */ 89 }; 90 91 struct opt_domain { 92 char *domain; /* domain name (malloc'd) */ 93 struct maplist dmaps; /* the domain's active maps */ 94 LIST_ENTRY(opt_domain) domsl; /* global linked list of domains */ 95 }; 96 97 struct domainlist doms; /* global list of domains */ 98 struct mapq maps; /* global queue of maps (LRU) */ 99 100 extern int usedns; 101 102 int yp_private(datum, int); 103 void ypdb_close_db(DBM *); 104 void ypdb_close_last(void); 105 void ypdb_close_map(struct opt_map *); 106 DBM *ypdb_open_db(const char *, const char *, int *, struct opt_map **); 107 int lookup_host(int, int, DBM *, char *, struct ypresp_val *); 108 109 /* 110 * ypdb_init: init the queues and lists 111 */ 112 void 113 ypdb_init(void) 114 { 115 116 LIST_INIT(&doms); 117 CIRCLEQ_INIT(&maps); 118 } 119 120 /* 121 * yp_private: 122 * Check if key is a YP private key. Return TRUE if it is and 123 * ypprivate is FALSE. 124 */ 125 int 126 yp_private(datum key, int ypprivate) 127 { 128 129 if (ypprivate) 130 return (FALSE); 131 132 if (key.dsize == 0 || key.dptr == NULL) 133 return (FALSE); 134 135 if (key.dsize == YP_LAST_LEN && 136 strncmp(key.dptr, YP_LAST_KEY, YP_LAST_LEN) == 0) 137 return (TRUE); 138 139 if (key.dsize == YP_INPUT_LEN && 140 strncmp(key.dptr, YP_INPUT_KEY, YP_INPUT_LEN) == 0) 141 return (TRUE); 142 143 if (key.dsize == YP_OUTPUT_LEN && 144 strncmp(key.dptr, YP_OUTPUT_KEY, YP_OUTPUT_LEN) == 0) 145 return (TRUE); 146 147 if (key.dsize == YP_MASTER_LEN && 148 strncmp(key.dptr, YP_MASTER_KEY, YP_MASTER_LEN) == 0) 149 return (TRUE); 150 151 if (key.dsize == YP_DOMAIN_LEN && 152 strncmp(key.dptr, YP_DOMAIN_KEY, YP_DOMAIN_LEN) == 0) 153 return (TRUE); 154 155 if (key.dsize == YP_INTERDOMAIN_LEN && 156 strncmp(key.dptr, YP_INTERDOMAIN_KEY, YP_INTERDOMAIN_LEN) == 0) 157 return (TRUE); 158 159 if (key.dsize == YP_SECURE_LEN && 160 strncmp(key.dptr, YP_SECURE_KEY, YP_SECURE_LEN) == 0) 161 return (TRUE); 162 163 return (FALSE); 164 } 165 166 /* 167 * Close specified map. 168 */ 169 void 170 ypdb_close_map(struct opt_map *map) 171 { 172 CIRCLEQ_REMOVE(&maps, map, mapsq); /* remove from LRU circleq */ 173 LIST_REMOVE(map, mapsl); /* remove from domain list */ 174 175 #ifdef DEBUG 176 syslog(LOG_DEBUG, 177 "ypdb_close_map: closing map %s in domain %s [db=%p]", 178 map->map, map->dom->domain, map->db); 179 #endif 180 181 ypdb_close(map->db); /* close DB */ 182 free(map->map); /* free map name */ 183 free(map); /* free map */ 184 } 185 186 /* 187 * Close least recently used map. This routine is called when we have 188 * no more file descriptors free, or we want to close all maps. 189 */ 190 void 191 ypdb_close_last(void) 192 { 193 struct opt_map *last = maps.cqh_last; 194 195 if (last == (void *) &maps) { 196 syslog(LOG_ERR, 197 "ypdb_close_last: LRU list is empty!"); 198 return; 199 } 200 ypdb_close_map(last); 201 } 202 203 /* 204 * Close all open maps. 205 */ 206 void 207 ypdb_close_all(void) 208 { 209 210 #ifdef DEBUG 211 syslog(LOG_DEBUG, "ypdb_close_all(): start"); 212 #endif 213 214 while (maps.cqh_first != (void *) &maps) 215 ypdb_close_last(); 216 217 #ifdef DEBUG 218 syslog(LOG_DEBUG, "ypdb_close_all(): done"); 219 #endif 220 } 221 222 /* 223 * Close Database if Open/Close Optimization isn't turned on. 224 */ 225 void 226 ypdb_close_db(DBM *db) 227 { 228 229 #ifdef DEBUG 230 syslog(LOG_DEBUG, "ypdb_close_db(%p)", db); 231 #endif 232 233 #ifndef OPTIMIZE_DB 234 ypdb_close_all(); 235 #endif /* not OPTIMIZE_DB */ 236 } 237 238 /* 239 * ypdb_open_db 240 */ 241 DBM * 242 ypdb_open_db(const char *domain, const char *map, int *status, 243 struct opt_map **map_info) 244 { 245 static char *domain_key = YP_INTERDOMAIN_KEY; 246 static char *secure_key = YP_SECURE_KEY; 247 char map_path[MAXPATHLEN]; 248 struct stat finfo; 249 struct opt_domain *d = NULL; 250 struct opt_map *m = NULL; 251 DBM *db; 252 datum k, v; 253 254 *status = YP_TRUE; /* defaults to true */ 255 256 /* 257 * check for illegal domain and map names 258 */ 259 if (_yp_invalid_domain(domain)) { 260 *status = YP_NODOM; 261 return (NULL); 262 } 263 if (_yp_invalid_map(map)) { 264 *status = YP_NOMAP; 265 return (NULL); 266 } 267 268 /* 269 * check for domain, file. 270 */ 271 snprintf(map_path, sizeof(map_path), "%s/%s", YP_DB_PATH, domain); 272 if (stat(map_path, &finfo) < 0 || S_ISDIR(finfo.st_mode) == 0) { 273 #ifdef DEBUG 274 syslog(LOG_DEBUG, 275 "ypdb_open_db: no domain %s (map=%s)", domain, map); 276 #endif 277 *status = YP_NODOM; 278 } else { 279 snprintf(map_path, sizeof(map_path), "%s/%s/%s%s", 280 YP_DB_PATH, domain, map, YPDB_SUFFIX); 281 if (stat(map_path, &finfo) < 0) { 282 #ifdef DEBUG 283 syslog(LOG_DEBUG, 284 "ypdb_open_db: no map %s (domain=%s)", map, 285 domain); 286 #endif 287 *status = YP_NOMAP; 288 } 289 } 290 291 /* 292 * check for preloaded domain, map 293 */ 294 for (d = doms.lh_first; d != NULL; d = d->domsl.le_next) 295 if (strcmp(domain, d->domain) == 0) 296 break; 297 298 if (d) 299 for (m = d->dmaps.lh_first; m != NULL; m = m->mapsl.le_next) 300 if (strcmp(map, m->map) == 0) 301 break; 302 303 /* 304 * map found open? 305 */ 306 if (m) { 307 #ifdef DEBUG 308 syslog(LOG_DEBUG, 309 "ypdb_open_db: cached open: domain=%s, map=%s, db=%p,", 310 domain, map, m->db); 311 syslog(LOG_DEBUG, 312 "\tdbdev %d new %d; dbino %d new %d; dbmtime %ld new %ld", 313 m->dbdev, finfo.st_dev, m->dbino, finfo.st_ino, 314 (long) m->dbmtime, (long) finfo.st_mtime); 315 #endif 316 /* 317 * if status != YP_TRUE, then this cached database is now 318 * non-existent 319 */ 320 if (*status != YP_TRUE) { 321 #ifdef DEBUG 322 syslog(LOG_DEBUG, 323 "ypdb_open_db: cached db is now unavailable - " 324 "closing: status %s", 325 yperr_string(ypprot_err(*status))); 326 #endif 327 ypdb_close_map(m); 328 return (NULL); 329 } 330 331 /* 332 * is this the same db? 333 */ 334 if (finfo.st_dev == m->dbdev && finfo.st_ino == m->dbino && 335 finfo.st_mtime == m->dbmtime) { 336 CIRCLEQ_REMOVE(&maps, m, mapsq); /* adjust LRU queue */ 337 CIRCLEQ_INSERT_HEAD(&maps, m, mapsq); 338 if (map_info) 339 *map_info = m; 340 return (m->db); 341 } else { 342 #ifdef DEBUG 343 syslog(LOG_DEBUG, 344 "ypdb_open_db: db changed; closing"); 345 #endif 346 ypdb_close_map(m); 347 m = NULL; 348 } 349 } 350 351 /* 352 * not cached and non-existent, return 353 */ 354 if (*status != YP_TRUE) 355 return (NULL); 356 357 /* 358 * open map 359 */ 360 snprintf(map_path, sizeof(map_path), "%s/%s/%s", 361 YP_DB_PATH, domain, map); 362 #ifdef OPTIMIZE_DB 363 retryopen: 364 #endif /* OPTIMIZE_DB */ 365 db = ypdb_open(map_path, O_RDONLY, 0444); 366 #ifdef OPTIMIZE_DB 367 if (db == NULL) { 368 #ifdef DEBUG 369 syslog(LOG_DEBUG, 370 "ypdb_open_db: errno %d (%s)", errno, strerror(errno)); 371 #endif /* DEBUG */ 372 if ((errno == ENFILE) || (errno == EMFILE)) { 373 ypdb_close_last(); 374 goto retryopen; 375 } 376 } 377 #endif /* OPTIMIZE_DB */ 378 379 *status = YP_NOMAP; /* see note below */ 380 381 if (db == NULL) { 382 #ifdef DEBUG 383 syslog(LOG_DEBUG, 384 "ypdb_open_db: ypdb_open FAILED: map %s (domain=%s)", 385 map, domain); 386 #endif 387 return (NULL); 388 } 389 390 /* 391 * note: status now YP_NOMAP 392 */ 393 if (d == NULL) { /* allocate new domain? */ 394 d = (struct opt_domain *) malloc(sizeof(*d)); 395 if (d) 396 d->domain = strdup(domain); 397 if (d == NULL || d->domain == NULL) { 398 syslog(LOG_ERR, 399 "ypdb_open_db: MALLOC failed"); 400 ypdb_close(db); 401 if (d) 402 free(d); 403 return (NULL); 404 } 405 LIST_INIT(&d->dmaps); 406 LIST_INSERT_HEAD(&doms, d, domsl); 407 #ifdef DEBUG 408 syslog(LOG_DEBUG, 409 "ypdb_open_db: NEW DOMAIN %s", domain); 410 #endif 411 } 412 413 /* 414 * m must be NULL since we couldn't find a map. allocate new one 415 */ 416 m = (struct opt_map *) malloc(sizeof(*m)); 417 if (m) 418 m->map = strdup(map); 419 420 if (m == NULL || m->map == NULL) { 421 if (m) 422 free(m); 423 syslog(LOG_ERR, "ypdb_open_db: MALLOC failed"); 424 ypdb_close(db); 425 return (NULL); 426 } 427 m->db = db; 428 m->dom = d; 429 m->host_lookup = FALSE; 430 m->dbdev = finfo.st_dev; 431 m->dbino = finfo.st_ino; 432 m->dbmtime = finfo.st_mtime; 433 CIRCLEQ_INSERT_HEAD(&maps, m, mapsq); 434 LIST_INSERT_HEAD(&d->dmaps, m, mapsl); 435 if (strcmp(map, YP_HOSTNAME) == 0 || strcmp(map, YP_HOSTADDR) == 0) { 436 if (!usedns) { 437 k.dptr = domain_key; 438 k.dsize = YP_INTERDOMAIN_LEN; 439 v = ypdb_fetch(db, k); 440 if (v.dptr) 441 m->host_lookup = TRUE; 442 } else 443 m->host_lookup = TRUE; 444 } 445 446 m->secure = FALSE; 447 k.dptr = secure_key; 448 k.dsize = YP_SECURE_LEN; 449 v = ypdb_fetch(db, k); 450 if (v.dptr != NULL) 451 m->secure = TRUE; 452 453 *status = YP_TRUE; 454 455 if (map_info) 456 *map_info = m; 457 458 #ifdef DEBUG 459 syslog(LOG_DEBUG, 460 "ypdb_open_db: NEW MAP domain=%s, map=%s, hl=%d, s=%d, db=%p", 461 domain, map, m->host_lookup, m->secure, m->db); 462 #endif 463 464 return (m->db); 465 } 466 467 /* 468 * lookup host 469 */ 470 int 471 lookup_host(int nametable, int host_lookup, DBM *db, char *keystr, 472 struct ypresp_val *result) 473 { 474 struct hostent *host; 475 struct in_addr *addr_name; 476 struct in_addr addr_addr; 477 static char val[BUFSIZ + 1]; /* match libc */ 478 static char hostname[MAXHOSTNAMELEN]; 479 char tmpbuf[MAXHOSTNAMELEN + 20]; 480 char *v, *ptr; 481 int l; 482 483 if (!host_lookup) 484 return (YP_NOKEY); 485 486 if ((_res.options & RES_INIT) == 0) 487 res_init(); 488 489 if (nametable) { 490 host = gethostbyname(keystr); 491 if (host == NULL || host->h_addrtype != AF_INET) 492 return (YP_NOKEY); 493 494 addr_name = (struct in_addr *)host->h_addr_list[0]; 495 496 v = val; 497 498 for (; host->h_addr_list[0] != NULL; host->h_addr_list++) { 499 addr_name = (struct in_addr *)host->h_addr_list[0]; 500 snprintf(tmpbuf, sizeof(tmpbuf), "%s %s\n", 501 inet_ntoa(*addr_name), host->h_name); 502 if (v - val + strlen(tmpbuf) + 1 > sizeof(val)) 503 break; 504 strcpy(v, tmpbuf); 505 v = v + strlen(tmpbuf); 506 } 507 result->valdat.dptr = val; 508 result->valdat.dsize = v - val; 509 return (YP_TRUE); 510 } 511 inet_aton(keystr, &addr_addr); 512 host = gethostbyaddr((char *)&addr_addr, sizeof(addr_addr), AF_INET); 513 if (host == NULL) 514 return (YP_NOKEY); 515 516 strncpy((char *) hostname, host->h_name, sizeof(hostname) - 1); 517 hostname[sizeof(hostname) - 1] = '\0'; 518 host = gethostbyname(hostname); 519 if (host == NULL) 520 return (YP_NOKEY); 521 522 l = 0; 523 for (; host->h_addr_list[0] != NULL; host->h_addr_list++) 524 if (!memcmp(host->h_addr_list[0], &addr_addr, 525 sizeof(addr_addr))) 526 l++; 527 528 if (l == 0) { 529 syslog(LOG_NOTICE, 530 "address %s not listed for host %s\n", 531 inet_ntoa(addr_addr), hostname); 532 return (YP_NOKEY); 533 } 534 535 snprintf(val, sizeof(val), "%s %s", keystr, host->h_name); 536 l = strlen(val); 537 v = val + l; 538 while ((ptr = *(host->h_aliases)) != NULL) { 539 l = strlen(ptr); 540 if ((v - val) + l + 1 > BUFSIZ) 541 break; 542 strcpy(v, " "); 543 v += 1; 544 strcpy(v, ptr); 545 v += l; 546 host->h_aliases++; 547 } 548 result->valdat.dptr = val; 549 result->valdat.dsize = v - val; 550 551 return (YP_TRUE); 552 } 553 554 struct ypresp_val 555 ypdb_get_record(const char *domain, const char *map, datum key, int ypprivate) 556 { 557 static struct ypresp_val res; 558 static char keystr[YPMAXRECORD + 1]; 559 DBM *db; 560 datum k, v; 561 int host_lookup, hn; 562 struct opt_map *map_info = NULL; 563 564 host_lookup = 0; /* XXX gcc -Wuninitialized */ 565 566 memset(&res, 0, sizeof(res)); 567 568 db = ypdb_open_db(domain, map, &res.status, &map_info); 569 if (db == NULL || res.status < 0) 570 return (res); 571 572 if (map_info) 573 host_lookup = map_info->host_lookup; 574 575 k.dptr = key.dptr; 576 k.dsize = key.dsize; 577 578 if (yp_private(k, ypprivate)) { 579 res.status = YP_NOKEY; 580 goto done; 581 } 582 v = ypdb_fetch(db, k); 583 584 if (v.dptr == NULL) { 585 res.status = YP_NOKEY; 586 if ((hn = strcmp(map, YP_HOSTNAME)) != 0 && 587 strcmp(map, YP_HOSTADDR) != 0) 588 return (res); 589 590 /* note: lookup_host needs null terminated string */ 591 strncpy(keystr, key.dptr, key.dsize); 592 keystr[key.dsize] = '\0'; 593 res.status = lookup_host((hn == 0) ? TRUE : FALSE, 594 host_lookup, db, keystr, &res); 595 } else { 596 res.valdat.dptr = v.dptr; 597 res.valdat.dsize = v.dsize; 598 } 599 600 done: 601 ypdb_close_db(db); 602 return (res); 603 } 604 605 struct ypresp_key_val 606 ypdb_get_first(const char *domain, const char *map, int ypprivate) 607 { 608 static struct ypresp_key_val res; 609 DBM *db; 610 datum k, v; 611 612 memset(&res, 0, sizeof(res)); 613 614 db = ypdb_open_db(domain, map, &res.status, NULL); 615 616 if (db != NULL && res.status >= 0) { 617 k = ypdb_firstkey(db); 618 619 while (yp_private(k, ypprivate)) 620 k = ypdb_nextkey(db); 621 622 if (k.dptr == NULL) 623 res.status = YP_NOKEY; 624 else { 625 res.keydat.dptr = k.dptr; 626 res.keydat.dsize = k.dsize; 627 v = ypdb_fetch(db, k); 628 if (v.dptr == NULL) 629 res.status = YP_NOKEY; 630 else { 631 res.valdat.dptr = v.dptr; 632 res.valdat.dsize = v.dsize; 633 } 634 } 635 } 636 637 if (db != NULL) 638 ypdb_close_db(db); 639 640 return (res); 641 } 642 643 struct ypresp_key_val 644 ypdb_get_next(const char *domain, const char *map, datum key, int ypprivate) 645 { 646 static struct ypresp_key_val res; 647 DBM *db; 648 datum k, v, n; 649 650 memset(&res, 0, sizeof(res)); 651 652 db = ypdb_open_db(domain, map, &res.status, NULL); 653 654 if (db != NULL && res.status >= 0) { 655 n.dptr = key.dptr; 656 n.dsize = key.dsize; 657 v.dptr = NULL; 658 v.dsize = 0; 659 k.dptr = NULL; 660 k.dsize = 0; 661 662 n = ypdb_setkey(db, n); 663 664 if (n.dptr != NULL) 665 k = ypdb_nextkey(db); 666 else 667 k.dptr = NULL; 668 669 if (k.dptr != NULL) 670 while (yp_private(k, ypprivate)) 671 k = ypdb_nextkey(db); 672 673 if (k.dptr == NULL) 674 res.status = YP_NOMORE; 675 else { 676 res.keydat.dptr = k.dptr; 677 res.keydat.dsize = k.dsize; 678 v = ypdb_fetch(db, k); 679 if (v.dptr == NULL) 680 res.status = YP_NOMORE; 681 else { 682 res.valdat.dptr = v.dptr; 683 res.valdat.dsize = v.dsize; 684 } 685 } 686 } 687 688 if (db != NULL) 689 ypdb_close_db(db); 690 691 return (res); 692 } 693 694 struct ypresp_order 695 ypdb_get_order(const char *domain, const char *map) 696 { 697 static struct ypresp_order res; 698 static char *order_key = YP_LAST_KEY; 699 char order[MAX_LAST_LEN + 1]; 700 DBM *db; 701 datum k, v; 702 703 memset(&res, 0, sizeof(res)); 704 705 db = ypdb_open_db(domain, map, &res.status, NULL); 706 707 if (db != NULL && res.status >= 0) { 708 k.dptr = order_key; 709 k.dsize = YP_LAST_LEN; 710 711 v = ypdb_fetch(db, k); 712 if (v.dptr == NULL) 713 res.status = YP_NOKEY; 714 else { 715 strncpy(order, v.dptr, v.dsize); 716 order[v.dsize] = '\0'; 717 res.ordernum = (u_int) atol(order); 718 } 719 } 720 721 if (db != NULL) 722 ypdb_close_db(db); 723 724 return (res); 725 } 726 727 struct ypresp_master 728 ypdb_get_master(const char *domain, const char *map) 729 { 730 static struct ypresp_master res; 731 static char *master_key = YP_MASTER_KEY; 732 static char master[MAX_MASTER_LEN + 1]; 733 DBM *db; 734 datum k, v; 735 736 memset(&res, 0, sizeof(res)); 737 738 db = ypdb_open_db(domain, map, &res.status, NULL); 739 740 if (db != NULL && res.status >= 0) { 741 k.dptr = master_key; 742 k.dsize = YP_MASTER_LEN; 743 744 v = ypdb_fetch(db, k); 745 if (v.dptr == NULL) 746 res.status = YP_NOKEY; 747 else { 748 strncpy(master, v.dptr, v.dsize); 749 master[v.dsize] = '\0'; 750 res.master = &master[0]; 751 } 752 } 753 754 if (db != NULL) 755 ypdb_close_db(db); 756 757 return (res); 758 } 759 760 bool_t 761 ypdb_xdr_get_all(XDR *xdrs, struct ypreq_nokey *req) 762 { 763 static struct ypresp_all resp; 764 DBM *db; 765 datum k, v; 766 767 memset(&resp, 0, sizeof(resp)); 768 769 /* 770 * open db, and advance past any private keys we may see 771 */ 772 db = ypdb_open_db(req->domain, req->map, 773 &resp.ypresp_all_u.val.status, NULL); 774 775 if (db == NULL || resp.ypresp_all_u.val.status < 0) 776 return (FALSE); 777 778 k = ypdb_firstkey(db); 779 while (yp_private(k, FALSE)) 780 k = ypdb_nextkey(db); 781 782 for (;;) { 783 if (k.dptr == NULL) 784 break; 785 786 v = ypdb_fetch(db, k); 787 788 if (v.dptr == NULL) 789 break; 790 791 resp.more = TRUE; 792 resp.ypresp_all_u.val.status = YP_TRUE; 793 resp.ypresp_all_u.val.keydat.dptr = k.dptr; 794 resp.ypresp_all_u.val.keydat.dsize = k.dsize; 795 resp.ypresp_all_u.val.valdat.dptr = v.dptr; 796 resp.ypresp_all_u.val.valdat.dsize = v.dsize; 797 798 if (!xdr_ypresp_all(xdrs, &resp)) { 799 #ifdef DEBUG 800 syslog(LOG_DEBUG, 801 "ypdb_xdr_get_all: xdr_ypresp_all failed"); 802 #endif 803 return (FALSE); 804 } 805 806 /* advance past private keys */ 807 k = ypdb_nextkey(db); 808 while (yp_private(k, FALSE)) 809 k = ypdb_nextkey(db); 810 } 811 812 memset(&resp, 0, sizeof(resp)); 813 resp.ypresp_all_u.val.status = YP_NOKEY; 814 resp.more = FALSE; 815 816 if (!xdr_ypresp_all(xdrs, &resp)) { 817 #ifdef DEBUG 818 syslog(LOG_DEBUG, 819 "ypdb_xdr_get_all: final xdr_ypresp_all failed"); 820 #endif 821 return (FALSE); 822 } 823 824 if (db != NULL) 825 ypdb_close_db(db); 826 827 return (TRUE); 828 } 829 830 int 831 ypdb_secure(const char *domain, const char *map) 832 { 833 DBM *db; 834 int secure, status; 835 struct opt_map *map_info = NULL; 836 837 secure = FALSE; 838 839 db = ypdb_open_db(domain, map, &status, &map_info); 840 if (db == NULL || status < 0) 841 return (secure); 842 if (map_info != NULL) 843 secure = map_info->secure; 844 845 ypdb_close_db(db); 846 return (secure); 847 } 848