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