major cleanup by Chuck Cranor
authorchuck <chuck@openbsd.org>
Sat, 20 Jan 1996 00:47:01 +0000 (00:47 +0000)
committerchuck <chuck@openbsd.org>
Sat, 20 Jan 1996 00:47:01 +0000 (00:47 +0000)
 - use queue.h rather than do by hand
 - fix up logging to use new yplog
 - fix a few off by one errors
 - don't double malloc the DBM structure
 - avoid possible sprintf buffer overflows
 - random code cleanup

usr.sbin/ypserv/ypserv/ypserv_db.c

index 3b85e13..83a5255 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
+ * Copyright (c) 1996 Charles D. Cranor
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  */
 
 #ifndef LINT
-static char rcsid[] = "$Id: ypserv_db.c,v 1.1 1995/11/01 16:56:37 deraadt Exp $";
+static char rcsid[] = "$Id: ypserv_db.c,v 1.2 1996/01/20 00:47:01 chuck Exp $";
 #endif
 
+/*
+ * major revision/cleanup of Mats' version 
+ * done by Chuck Cranor <chuck@ccrc.wustl.edu>
+ * Jan 1996.
+ */
+
+
 #include <rpc/rpc.h>
 #include <rpcsvc/yp.h>
 #include <rpcsvc/ypclnt.h>
 #include <sys/stat.h>
+#include <sys/param.h>
 #include <fcntl.h>
 #include <string.h>
 #include <stdio.h>
@@ -42,38 +51,53 @@ static char rcsid[] = "$Id: ypserv_db.c,v 1.1 1995/11/01 16:56:37 deraadt Exp $"
 #include <netdb.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/queue.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include "yplog.h"
 #include "ypdb.h"
 #include "ypdef.h"
 
+LIST_HEAD(domainlist, opt_domain);     /* LIST of domains */
+LIST_HEAD(maplist, opt_map);           /* LIST of maps (in a domain) */
+CIRCLEQ_HEAD(mapq, opt_map);           /* CIRCLEQ of maps (LRU) */
+
 struct opt_map {
-       mapname map;
-       DBM     *db;
-       int     *dptr;
-       struct  opt_map *next;
-       struct  opt_map *prev;
-       struct  opt_map *rnext;
-       struct  opt_map *rprev;
-       int     host_lookup;
+       mapname map;                    /* map name (malloc'd) */
+       DBM     *db;                    /* database */
+       struct opt_domain *dom;         /* back ptr to our domain */
+       int     host_lookup;            /* host lookup */
+       CIRCLEQ_ENTRY(opt_map) mapsq;   /* map queue pointers */
+       LIST_ENTRY(opt_map) mapsl;      /* map list pointers */
 };
-typedef struct opt_map opt_map;
 
 struct opt_domain {
-       domainname      domain;
-       opt_map         *map_root;
-       struct          opt_domain *next;
+       domainname      domain;         /* domain name (malloc'd) */
+       struct maplist  dmaps;          /* the domain's active maps */
+       LIST_ENTRY(opt_domain) domsl;   /* global linked list of domains */
 };
-typedef struct opt_domain opt_domain;
 
-       opt_domain      *domain_root = NULL;
-       opt_map         *map_first = NULL;
-       opt_map         *map_last  = NULL;
+
+struct domainlist doms;                        /* global list of domains */
+struct mapq maps;                      /* global queue of maps (LRU) */
 
 extern int usedns;
 
 /*
+ * ypdb_init: init the queues and lists
+ */
+
+void
+ypdb_init()
+
+{
+       LIST_INIT(&doms);
+       CIRCLEQ_INIT(&maps);
+}
+
+
+/*
+ * yp_private:
  * Check if key is a YP private key. Return TRUE if it is and
  * ypprivate is FALSE.
  */
@@ -85,41 +109,31 @@ yp_private(key,ypprivate)
 {
         int    result;
 
-       if (ypprivate) {
-               return (FALSE);
-       }
+       if (ypprivate) return (FALSE);
 
-        result = FALSE;
-
-       if ((!result) && (key.dsize == YP_LAST_LEN)) {
-               result = (strcmp(key.dptr,YP_LAST_KEY) == 0);
-       }
-       
-       if ((!result) && (key.dsize == YP_INPUT_LEN)) {
-               result = (strcmp(key.dptr,YP_INPUT_KEY) == 0);
-       }
-       
-       if ((!result) && (key.dsize == YP_OUTPUT_LEN)) {
-               result = (strcmp(key.dptr,YP_OUTPUT_KEY) == 0);
-       }
-       
-       if ((!result) && (key.dsize == YP_MASTER_LEN)) {
-               result = (strcmp(key.dptr,YP_MASTER_KEY) == 0);
-       }
-       
-       if ((!result) && (key.dsize == YP_DOMAIN_LEN)) {
-               result = (strcmp(key.dptr,YP_DOMAIN_KEY) == 0);
-       }
-       
-       if ((!result) && (key.dsize == YP_INTERDOMAIN_LEN)) {
-               result = (strcmp(key.dptr,YP_INTERDOMAIN_KEY) == 0);
-       }
-       
-       if ((!result) && (key.dsize == YP_SECURE_LEN)) {
-               result = (strcmp(key.dptr,YP_SECURE_KEY) == 0);
-       }
+       if (key.dsize == YP_LAST_LEN &&
+                       strncmp(key.dptr,YP_LAST_KEY,YP_LAST_LEN) == 0)
+               return(TRUE);
+       if (key.dsize == YP_INPUT_LEN &&
+                       strncmp(key.dptr,YP_INPUT_KEY,YP_INPUT_LEN) == 0)
+               return(TRUE);
+       if (key.dsize == YP_OUTPUT_LEN &&
+                       strncmp(key.dptr,YP_OUTPUT_KEY,YP_OUTPUT_LEN) == 0)
+               return(TRUE);
+       if (key.dsize == YP_MASTER_LEN &&
+                       strncmp(key.dptr,YP_MASTER_KEY,YP_MASTER_LEN) == 0)
+               return(TRUE);
+       if (key.dsize == YP_DOMAIN_LEN &&
+                       strncmp(key.dptr,YP_DOMAIN_KEY,YP_DOMAIN_LEN) == 0)
+               return(TRUE);
+       if (key.dsize == YP_INTERDOMAIN_LEN &&
+               strncmp(key.dptr,YP_INTERDOMAIN_KEY,YP_INTERDOMAIN_LEN) == 0)
+               return(TRUE);
+       if (key.dsize == YP_SECURE_LEN &&
+                       strncmp(key.dptr,YP_SECURE_KEY,YP_SECURE_LEN) == 0)
+               return(TRUE);
        
-       return(result);
+       return(FALSE);
 }     
 
 /*
@@ -130,44 +144,25 @@ yp_private(key,ypprivate)
 void
 ypdb_close_last()
 {
-       opt_map         *m = NULL;
-       opt_domain      *d = NULL;
+       struct opt_map *last = maps.cqh_last;
 
-       m = map_last;
-       d = (opt_domain *) m->dptr;
-       
-       /* Close database */
-       ypdb_close(m->db);
-       free(m->db);
+       if (last == (void*)&maps) {
+               yplog("  ypdb_close_last: LRU list is empty!");
+               return;
+       }
+
+       CIRCLEQ_REMOVE(&maps, last, mapsq);     /* remove from LRU circleq */
+       LIST_REMOVE(last, mapsl);               /* remove from domain list */
 
 #ifdef DEBUG
-       yplog_cat("info: ypdb_close_last: close map ");
-       yplog_cat(m->map);
-       yplog_cat(" in domain ");
-       yplog_cat(d->domain);
-       yplog_cat("\n");
+       yplog("  ypdb_close_last: closing map %s in domain %s [db=0x%x]",
+               last->map, last->dom->domain, last->db);
 #endif
 
-       /* Deallocate space for map name */
-       free(m->map);
-       
-       /* Unlink record from recent used list */
-       if (m->rprev != NULL) {
-               m->rprev->rnext = m->rnext;
-       }
-       map_last = m->rprev;
+       ypdb_close(last->db);                   /* close DB */
+       free(last->map);                        /* free map name */
+       free(last);                             /* free map */
 
-       /* Unlink record from domain list */
-       if (m->prev == NULL) {
-               d->map_root = m->next;
-       } else {
-               m->prev->next = m->next;
-       }
-       if (m->next != NULL) {
-               m->next->prev = m->prev;
-       }
-         
-       free(m);
        
 }
 
@@ -179,9 +174,15 @@ void
 ypdb_close_all()
 {
        
-       while (map_last != NULL) {
+#ifdef DEBUG
+       yplog("  ypdb_close_all(): start");
+#endif
+       while (maps.cqh_first != (void *)&maps) {
                ypdb_close_last();
        }
+#ifdef DEBUG
+       yplog("  ypdb_close_all(): done");
+#endif
 }
 
 /*
@@ -192,238 +193,173 @@ void
 ypdb_close_db(db)
        DBM     *db;
 {
+#ifdef DEBUG
+       yplog("  ypdb_close_db(0x%x)", db);
+#endif
 #ifndef OPTDB
        ypdb_close_all();
 #endif
 }
 
-DBM *
-ypdb_open_db_std(domain, map, status, map_info)
-       domainname      domain;
-        mapname                map;
-       ypstat          *status;
-        opt_map                *map_info;
-{
-       static  char map_path[255];
-       struct  stat finfo;
-       DBM     *db;
-       
-       *status = YP_TRUE;                      /* Preset return value */
-
-       db = NULL;                              /* Database isn't opened */
-       
-       /* Check domain */
-       sprintf(map_path,"%s/%s",YP_DB_PATH,domain);
-       if (!((stat(map_path, &finfo) == 0) &&
-             ((finfo.st_mode & S_IFMT) == S_IFDIR))) {
-               *status = YP_NODOM;
-#ifdef DEBUG
-               yplog_cat("err: ypdb_open_db_std: domain not found\n");
-#endif
-       }
-               
-       if (*status >= 0) {
-               /* Check map */
-               sprintf(map_path,"%s/%s/%s%s",YP_DB_PATH,domain,map,YPDB_SUFFIX);
-               if (!(stat(map_path, &finfo) == 0)) {
-                       *status = YP_NOMAP;
-#ifdef DEBUG
-                       yplog_cat("err: ypdb_open_db: map not found\n");
-#endif
-               }
-       }
-               
-       /* Ok, if no error yet, open database */
-       if (*status >= 0) {
-               sprintf(map_path,"%s/%s/%s",YP_DB_PATH,domain,map);
-               db = ypdb_open(map_path, O_RDONLY, 0444);
-#ifdef DEBUG
-               yplog_cat("info: ypdb_open_db: open ");
-               yplog_cat(map_path);
-               yplog_cat("\n");
-#endif
-       }
-
-       return(db);
-}
+/*
+ * ypdb_open_db
+ */
 
 DBM *
 ypdb_open_db(domain, map, status, map_info)
        domainname      domain;
         mapname                map;
        ypstat          *status;
-        opt_map                *map_info;
+        struct opt_map **map_info;
 {
-       static  char map_path[255];
+       char map_path[MAXPATHLEN];
+       static char   *domain_key = YP_INTERDOMAIN_KEY;
        struct  stat finfo;
        DBM     *db;
-       static char   domain_key[YP_INTERDOMAIN_LEN] = YP_INTERDOMAIN_KEY;
-       FILE    *fd;
-       opt_domain *d = NULL;
-       opt_map *m = NULL;
+       int     fd;
+       struct opt_domain *d = NULL;
+       struct opt_map  *m = NULL;
        datum   k,v;
        
-       *status = YP_TRUE;                      /* Preset return value */
+       /*
+        * check for preloaded domain, map
+        */
 
-       db = NULL;                              /* Database isn't opened */
-
-       d = domain_root;                        /* Find domain in list */
-       while ((d != NULL) && (strcmp(d->domain,domain) != 0)) {
-               d = d->next;
+       for (d = doms.lh_first ; d != NULL ; d = d->domsl.le_next) {
+               if (strcmp(domain, d->domain) == 0) break;
        }
 
-       if (d != NULL) {                        /* Domain found ! */
-               m = d->map_root;                /* Find map in list */
-               while ((m != NULL) && (strcmp(m->map,map) != 0)) {
-                       m = m->next;
-               }
+       if (d) {
+               for (m = d->dmaps.lh_first ; m != NULL ; m = m->mapsl.le_next)
+                       if (strcmp(map, m->map) == 0) break;
        }
 
-       if (m != NULL) {                        /* Map found ! */
-               db = m->db;
-               if (m != map_first) {
-                       /* Move map to top of recent used list */
-                       m->rprev->rnext = m->rnext;
-                       if (m->rnext == NULL) {
-                               map_last = m->rprev;
-                       } else {
-                               m->rnext->rprev = m->rprev;
-                       }
-                       m->rprev = NULL;
-                       map_first->rprev = m;
-                       m->rnext = map_first;
-                       map_first = m;
-               }
+       /*
+        * map found open?
+        */
+
+       if (m) {
+#ifdef DEBUG
+               yplog("  ypdb_open_db: cached open: domain=%s, map=%s, db=0x%x",
+                       domain, map, m->db);
+#endif
+               CIRCLEQ_REMOVE(&maps, m, mapsq);        /* adjust LRU queue */
+               CIRCLEQ_INSERT_HEAD(&maps, m, mapsq);
+               *status = YP_TRUE;
+               return(m->db);
        }
 
-       if (db == NULL) {                       /* Database not opened */
+       /*
+        * database not open, first check for "out of fd" and close a db if
+        * out...
+        */
 
-               /* Make a dummy open, if it succeeds then it's OK */
-               /* to open a new database, else we must close one */
-               /* first. Close least recent used database        */
-         
-               fd = fopen("/dev/null","r");
-               if (fd != NULL) {
-                       fclose(fd);             /* All is OK */
-               } else {
-                       ypdb_close_last();      /* Not OK, close one */
-               }
+       fd = open("/", O_RDONLY);
+       if (fd < 0) 
+               ypdb_close_last();
+       else
+               close(fd);
 
-               /* Check domain */
-               sprintf(map_path,"%s/%s",YP_DB_PATH,domain);
-               if (!((stat(map_path, &finfo) == 0) &&
-                     ((finfo.st_mode & S_IFMT) == S_IFDIR))) {
-                       *status = YP_NODOM;
-#ifdef DEBUG
-                       yplog_cat("err: ypdb_open_db: domain not found\n");
-#endif
-               }
-               
-               if (*status >= 0) {
-                       /* Check map */
-                       sprintf(map_path,"%s/%s/%s%s",YP_DB_PATH,domain,map,YPDB_SUFFIX);
-                       if (!(stat(map_path, &finfo) == 0)) {
-                               *status = YP_NOMAP;
+       /*
+        * check for domain, file.   
+        */
+
+       snprintf(map_path, sizeof(map_path), "%s/%s", YP_DB_PATH, domain);
+       if (stat(map_path, &finfo) < 0 ||
+               (finfo.st_mode & S_IFMT) != S_IFDIR) {
 #ifdef DEBUG
-                               yplog_cat("err: ypdb_open_db: map not found\n");
+               yplog("  ypdb_open_db: no domain %s (map=%s)", domain, map);
 #endif
-                       }
-               }
-               
-               /* Ok, if no error yet, open database */
-               if (*status >= 0) {
-                       sprintf(map_path,"%s/%s/%s",YP_DB_PATH,domain,map);
-                       db = ypdb_open(map_path, O_RDONLY, 0444);
+               *status = YP_NODOM;
+               return(NULL);
+       }
+       snprintf(map_path, sizeof(map_path), "%s/%s/%s%s", YP_DB_PATH,
+               domain, map, YPDB_SUFFIX);
+       if (stat(map_path, &finfo) < 0) {
 #ifdef DEBUG
-                       yplog_cat("info: ypdb_open_db: open ");
-                       yplog_cat(map_path);
-                       yplog_cat("\n");
+               yplog("  ypdb_open_db: no map %s (domain=%s)", map, domain);
 #endif
-               }
+               *status = YP_NOMAP;
+               return(NULL);
+       }
 
-               if (*status >= 0) {
-                       
-                       if (d == NULL) {                /* Domain is new */
-                               /* Allocate a domain record */
-                               d = (opt_domain *)
-                                   malloc((unsigned) sizeof(opt_domain));
-
-                               /* Setup domain record */
-                               d->domain   = (domainname)
-                                             malloc(strlen(domain)+1);
-                               (void)strcpy(d->domain,domain);
-                               d->map_root = NULL;
-                               d->next     = domain_root;
-                               domain_root = d;
-                       }
-                       
-                       if (m == NULL) {                /* Map is new */
-                               /* Allocatr a map record */
-                               m = (opt_map *)
-                                   malloc((unsigned) sizeof(opt_map));
-                               
-                               /* Setup map record */
-                               m->map      = (mapname)
-                                             malloc(strlen(map)+1);
-                               (void)strcpy(m->map,map);
-                               m->db     = malloc((unsigned) sizeof(DBM));
-                               memcpy(m->db,db,sizeof(DBM));
-                               m->next     = d->map_root;
-                               if (m->next != NULL) {
-                                       m->next->prev = m;
-                               }
-                               m->prev     = NULL;
-                               m->dptr   = (int *) d;
-                               d->map_root = m;
-                               m->rnext    = map_first;
-                               m->rprev    = NULL;
-                               if (map_first != NULL) {
-                                       map_first->rprev = m;
-                               }
-                               if (map_last == NULL) {
-                                       map_last = m;
-                               }
-                               m->host_lookup = FALSE;
-                               /* Check if hosts. */
-                               if ((strcmp(map, YP_HOSTNAME) == 0) ||
-                                   (strcmp(map, YP_HOSTADDR) == 0)) {
-                                       if (!usedns) {
-                                               k.dptr = (char *) &domain_key;
-                                               k.dsize = YP_INTERDOMAIN_LEN;
-                                               v = ypdb_fetch(db,k);
-                                               if (v.dptr != NULL) {
-                                                       m->host_lookup = TRUE;
+       /*
+        * open map
+        */
+       snprintf(map_path, sizeof(map_path), "%s/%s/%s", YP_DB_PATH, 
+               domain, map);
+       db = ypdb_open(map_path, O_RDONLY, 0444);
+       *status = YP_NOMAP;             /* see note below */
+       if (db == NULL) {
 #ifdef DEBUG
-                       yplog_cat("info: ypdb_open_db: YP_INTERDOMAIN\n");
+               yplog("  ypdb_open_db: ypdb_open FAILED: map %s (domain=%s)", 
+                       map, domain);
 #endif
-                                               }
-                                       } else {
-                                               m->host_lookup = usedns;
+               return(NULL);
+       }
+       
+       /*
+        * note: status now YP_NOMAP
+        */
+
+       if (d == NULL) {                /* allocate new domain? */
+               d = (struct opt_domain *) malloc(sizeof(*d));
+               if (d) d->domain = strdup(domain);
+               if (d == NULL || d->domain == NULL) {
+                       yplog("  ypdb_open_db: MALLOC failed");
+                       ypdb_close(db);
+                       if (d) free(d);
+                       return(NULL);
+               }
+               LIST_INIT(&d->dmaps);
+               LIST_INSERT_HEAD(&doms, d, domsl);
 #ifdef DEBUG
-                       yplog_cat("info: ypdb_open_db: ypserv -d\n");
+               yplog("  ypdb_open_db: NEW DOMAIN %s", domain);
 #endif
-                                       }
-                               }
-                               map_first = m;
-                       }
-
-                       if (map_info != NULL) {
-                               map_info->map         = NULL;
-                               map_info->db          = NULL;
-                               map_info->dptr        = m->dptr;
-                               map_info->next        = m->next;
-                               map_info->prev        = m->prev;
-                               map_info->rnext       = m->rnext;
-                               map_info->rprev       = m->rprev;
-                               map_info->host_lookup = m->host_lookup;
-                       }
-               }
-               
        }
 
-       return(db);
+       /*
+        * m must be NULL since we couldn't find a map.  allocate new one
+        */
+
+       m = (struct opt_map *) malloc(sizeof(*m));
+       if (m) {
+               m->map = strdup(map);
+       }
+       if (m == NULL || m->map == NULL) {
+               if (m) free(m);
+               yplog("  ypdb_open_db: MALLOC failed");
+               ypdb_close(db);
+               return(NULL);
+       }
+       m->db = db;
+       m->dom = d;
+       m->host_lookup = FALSE;
+       CIRCLEQ_INSERT_HEAD(&maps, m, mapsq);
+       LIST_INSERT_HEAD(&d->dmaps, m, mapsl);
+       if (strcmp(map, YP_HOSTNAME) == 0 || strcmp(map, YP_HOSTADDR) == 0) {
+               if (!usedns) {
+                       k.dptr = domain_key;
+                       k.dsize = YP_INTERDOMAIN_LEN;
+                       v = ypdb_fetch(db,k);
+                       if (v.dptr) m->host_lookup = TRUE;
+               } else {
+                       m->host_lookup = TRUE;
+               }
+       }
+       *status = YP_TRUE;
+       if (map_info) *map_info = m;
+#ifdef DEBUG
+            yplog("  ypdb_open_db: NEW MAP domain=%s, map=%s, hl=%d, db=0x%x", 
+                       domain, map, m->host_lookup, m->db);
+#endif
+       return(m->db);
 }
 
+/*
+ * lookup host
+ */
+
 ypstat
 lookup_host(nametable, host_lookup, db, keystr, result)
        int     nametable;
@@ -435,49 +371,57 @@ lookup_host(nametable, host_lookup, db, keystr, result)
        struct  hostent *host;
        struct  in_addr *addr_name;
        struct  in_addr addr_addr;
-       static  char val[255];
-       ypstat  status;
+       static  char val[BUFSIZ+1]; /* match libc */
+       char *v;
+       int l;
        char    *ptr;
        
-       status = YP_NOKEY;
-
-       if (host_lookup) {
-               if (nametable) {
-                       host = gethostbyname(keystr);
-                       if ((host != NULL) &&
-                           (host->h_addrtype == AF_INET)) {
-                               addr_name = (struct in_addr *)
-                                 *host->h_addr_list;
-                               sprintf(val,"%s %s",
-                                       inet_ntoa(*addr_name), keystr);
-                               while ((ptr = *(host->h_aliases)) != NULL) {
-                                       strcat(val," ");
-                                       strcat(val,ptr);
-                                       host->h_aliases++;
-                               }
-                               result->val.valdat_val = val;
-                               result->val.valdat_len = strlen(val);
-                               status = YP_TRUE;
-                       }
-               } else {
-                       inet_aton(keystr, &addr_addr);
-                       host = gethostbyaddr((char *) &addr_addr,
-                                            sizeof(addr_addr), AF_INET);
-                       if (host != NULL) {
-                               sprintf(val,"%s %s",keystr,host->h_name);
-                               while ((ptr = *(host->h_aliases)) != NULL) {
-                                       strcat(val," ");
-                                       strcat(val,ptr);
-                                       host->h_aliases++;
-                               }
-                               result->val.valdat_val = val;
-                               result->val.valdat_len = strlen(val);
-                               status = YP_TRUE;
-                       }
+       if (!host_lookup) return(YP_NOKEY);
+
+       if (nametable) {
+               host = gethostbyname(keystr);
+               if (host == NULL || host->h_addrtype != AF_INET) 
+                       return(YP_NOKEY);
+               addr_name = (struct in_addr *) *host->h_addr_list;
+               snprintf(val,sizeof(val), "%s %s",
+                       inet_ntoa(*addr_name), keystr);
+               l = strlen(val);
+               v = val + l;
+               while ((ptr = *(host->h_aliases)) != NULL) {
+                       l = strlen(ptr);
+                       if ((v - val) + l + 1 > BUFSIZ)
+                               break;
+                       strcpy(v, " ");
+                       v += 1;
+                       strcpy(v, ptr);
+                       v += l;
+                       host->h_aliases++;
                }
+               result->val.valdat_val = val;
+               result->val.valdat_len = v - val;
+               return(YP_TRUE);
        }
-       
-       return(status);
+
+       inet_aton(keystr, &addr_addr);
+       host = gethostbyaddr((char *) &addr_addr, sizeof(addr_addr), AF_INET);
+       if (host == NULL) return(YP_NOKEY);
+       snprintf(val,sizeof(val),"%s %s",keystr,host->h_name);
+       l = strlen(val);
+       v = val + l;
+       while ((ptr = *(host->h_aliases)) != NULL) {
+               l = strlen(ptr);
+               if ((v - val) + l + 1 > BUFSIZ)
+                       break;
+               strcpy(v, " ");
+               v += 1;
+               strcpy(v, ptr);
+               v += l;
+               host->h_aliases++;
+       }
+       result->val.valdat_val = val;
+       result->val.valdat_len = v - val;
+
+       return(YP_TRUE);
 }
 
 ypresp_val
@@ -488,58 +432,48 @@ ypdb_get_record(domain, map, key, ypprivate)
         int            ypprivate;
 {
        static  ypresp_val res;
-       static  char keystr[255];
+       static  char keystr[YPMAXRECORD+1];
        DBM     *db;
        datum   k,v;
-       ypstat  status;
-       int     host_lookup;
-       opt_map map_info;
+       int     host_lookup, hn;
+       struct opt_map *map_info = NULL;
 
        bzero((char *)&res, sizeof(res));
        
-       db = ypdb_open_db(domain, map, &status, &map_info);
-       host_lookup = map_info.host_lookup;
+       db = ypdb_open_db(domain, map, &res.stat, &map_info);
+       if (!db || res.stat < 0) 
+               return(res);
+       if (map_info)
+               host_lookup = map_info->host_lookup;
+
+       k.dptr = key.keydat_val;
+       k.dsize = key.keydat_len;
        
-       if (status >= 0) {
-               
-               (void) strncpy(keystr, key.keydat_val, key.keydat_len);
-               keystr[key.keydat_len] = '\0';
-               
-               k.dptr = (char *) &keystr;
-               k.dsize = key.keydat_len + 1;
-               
-               if (yp_private(k,ypprivate)) {
-                       status = YP_NOKEY;
-               } else {
-                       
-                       v = ypdb_fetch(db,k);
-                       if (v.dptr == NULL) {
-                         
-                               status = YP_NOKEY;
-                               
-                               if (strcmp(map, YP_HOSTNAME) == 0) {
-                                       status = lookup_host(TRUE, host_lookup,
-                                                            db, &keystr,&res);
-                               }
-
-                               if (strcmp(map, YP_HOSTADDR) == 0) {
-                                       status = lookup_host(FALSE,host_lookup,
-                                                            db, &keystr,&res);
-                               }
-
-                       } else {
-                               res.val.valdat_val = v.dptr;
-                               res.val.valdat_len = v.dsize - 1;
-                       }
-                       
-               }
+       if (yp_private(k,ypprivate)) {
+               res.stat = YP_NOKEY;
+               goto done;
        }
-       
+
+       v = ypdb_fetch(db, k);
+
+       if (v.dptr == NULL) {
+               res.stat = YP_NOKEY;
+               if ((hn = strcmp(map, YP_HOSTNAME)) != 0 &&
+                               strcmp(map, YP_HOSTADDR) != 0) 
+                       return(res);
+               /* note: lookup_host needs null terminated string */
+               strncpy(keystr, key.keydat_val, key.keydat_len);
+               res.stat = lookup_host((hn == 0) ? TRUE : FALSE,
+                               host_lookup, db, keystr, &res);
+       } else {
+               res.val.valdat_val = v.dptr;
+               res.val.valdat_len = v.dsize;
+       }
+
+done:
        ypdb_close_db(db);
+       return(res);
        
-       res.stat = status;
-       
-       return (res);
 }
 
 ypresp_key_val
@@ -551,13 +485,12 @@ ypdb_get_first(domain, map, ypprivate)
        static ypresp_key_val res;
        DBM     *db;
        datum   k,v;
-       ypstat  status;
 
        bzero((char *)&res, sizeof(res));
        
-       db = ypdb_open_db(domain, map, &status, NULL);
+       db = ypdb_open_db(domain, map, &res.stat, NULL);
 
-       if (status >= 0) {
+       if (res.stat >= 0) {
 
          k = ypdb_firstkey(db);
          
@@ -566,24 +499,22 @@ ypdb_get_first(domain, map, ypprivate)
          };
          
          if (k.dptr == NULL) {
-           status = YP_NOKEY;
+           res.stat = YP_NOKEY;
          } else {
            res.key.keydat_val = k.dptr;
            res.key.keydat_len = k.dsize;
            v = ypdb_fetch(db,k);
            if (v.dptr == NULL) {
-             status = YP_NOKEY;
+             res.stat = YP_NOKEY;
            } else {
              res.val.valdat_val = v.dptr;
-             res.val.valdat_len = v.dsize - 1;
+             res.val.valdat_len = v.dsize;
            }
          }
        }
 
        ypdb_close_db(db);
        
-       res.stat = status;
-
        return (res);
 }
 
@@ -597,13 +528,12 @@ ypdb_get_next(domain, map, key, ypprivate)
        static ypresp_key_val res;
        DBM     *db;
        datum   k,v,n;
-       ypstat  status;
 
        bzero((char *)&res, sizeof(res));
        
-       db = ypdb_open_db(domain, map, &status, NULL);
+       db = ypdb_open_db(domain, map, &res.stat, NULL);
        
-       if (status >= 0) {
+       if (res.stat >= 0) {
 
          n.dptr = key.keydat_val;
          n.dsize = key.keydat_len;
@@ -627,24 +557,22 @@ ypdb_get_next(domain, map, key, ypprivate)
          };
 
          if (k.dptr == NULL) {
-           status = YP_NOMORE;
+           res.stat = YP_NOMORE;
          } else {
            res.key.keydat_val = k.dptr;
            res.key.keydat_len = k.dsize;
            v = ypdb_fetch(db,k);
            if (v.dptr == NULL) {
-             status = YP_NOMORE;
+             res.stat = YP_NOMORE;
            } else {
              res.val.valdat_val = v.dptr;
-             res.val.valdat_len = v.dsize - 1;
+             res.val.valdat_len = v.dsize;
            }
          }
        }
 
        ypdb_close_db(db);
        
-       res.stat = status;
-
        return (res);
 }
 
@@ -654,24 +582,23 @@ ypdb_get_order(domain, map)
         mapname map;
 {
        static ypresp_order res;
-       static char   order_key[YP_LAST_LEN] = YP_LAST_KEY;
-       static char   order[MAX_LAST_LEN+1];
+       static char   *order_key = YP_LAST_KEY;
+       char   order[MAX_LAST_LEN+1];
        DBM     *db;
        datum   k,v;
-       ypstat  status;
 
        bzero((char *)&res, sizeof(res));
        
-       db = ypdb_open_db(domain, map, &status, NULL);
+       db = ypdb_open_db(domain, map, &res.stat, NULL);
        
-       if (status >= 0) {
+       if (res.stat >= 0) {
 
-         k.dptr = (char *) &order_key;
+         k.dptr = order_key;
          k.dsize = YP_LAST_LEN;
 
          v = ypdb_fetch(db,k);
          if (v.dptr == NULL) {
-           status = YP_NOKEY;
+           res.stat = YP_NOKEY;
          } else {
            strncpy(order, v.dptr, v.dsize);
            order[v.dsize] = '\0';
@@ -681,8 +608,6 @@ ypdb_get_order(domain, map)
 
        ypdb_close_db(db);
        
-       res.stat = status;
-
        return (res);
 }
 
@@ -692,25 +617,23 @@ ypdb_get_master(domain, map)
         mapname map;
 {
        static ypresp_master res;
-       static char   master_key[YP_MASTER_LEN] = YP_MASTER_KEY;
+       static char   *master_key = YP_MASTER_KEY;
        static char   master[MAX_MASTER_LEN+1];
        DBM     *db;
        datum   k,v;
-       ypstat  status;
 
        bzero((char *)&res, sizeof(res));
        
-       db = ypdb_open_db(domain, map, &status, NULL);
+       db = ypdb_open_db(domain, map, &res.stat, NULL);
        
-       if (status >= 0) {
+       if (res.stat >= 0) {
 
-         k.dptr = (char *) &master_key;
-         master_key[YP_MASTER_LEN] = '\0';
+         k.dptr = master_key;
          k.dsize = YP_MASTER_LEN;
 
          v = ypdb_fetch(db,k);
          if (v.dptr == NULL) {
-           status = YP_NOKEY;
+           res.stat = YP_NOKEY;
          } else {
            strncpy(master, v.dptr, v.dsize);
            master[v.dsize] = '\0';
@@ -720,8 +643,6 @@ ypdb_get_master(domain, map)
 
        ypdb_close_db(db);
        
-       res.stat = status;
-
        return (res);
 }
 
@@ -731,99 +652,67 @@ ypdb_xdr_get_all(xdrs, req)
         ypreq_nokey *req;
 {
        static ypresp_all resp;
-       static bool_t more = TRUE;
        DBM     *db;
        datum   k,v;
-       ypstat  status;
-       extern  int     acl_access_ok;
 
        bzero((char *)&resp, sizeof(resp));
        
-       if(acl_access_ok) {
-               db = ypdb_open_db_std(req->domain, req->map, &status);
-       } else {
-               db = NULL;
-               resp.ypresp_all_u.val.stat = YP_NODOM;
-       }
-
-       if (resp.ypresp_all_u.val.stat < 0) {
-               resp.more = FALSE;
-               
-               if (!xdr_ypresp_all(xdrs, &resp)) {
-#ifdef DEBUG
-                       yplog_cat("xdr_ypresp_all: 1 failed\n");
-#endif                                 
-                       return(FALSE);
-               }
-
-               return(TRUE);
-               
-       }
+       /*
+        * open db, and advance past any private keys we may see
+        */
 
+       db = ypdb_open_db(req->domain, req->map, 
+                       &resp.ypresp_all_u.val.stat, NULL);
+       if (!db || resp.ypresp_all_u.val.stat < 0) 
+               return(FALSE);
        k = ypdb_firstkey(db);
-       
        while (yp_private(k,FALSE)) {
                k = ypdb_nextkey(db);
         };
        
-       while(resp.ypresp_all_u.val.stat >= 0) {
+       while(1) {
                
-               if (k.dptr == NULL) {
-                       v.dptr = NULL;
-               } else {
-                       v = ypdb_fetch(db,k);
-               }
+               if (k.dptr == NULL) 
+                       break;
 
-               if (v.dptr == NULL) {
+               v = ypdb_fetch(db,k);
 
-                       resp.ypresp_all_u.val.stat = YP_NOKEY;
-                       
-               } else {
-                 
-#ifdef DEBUG
-                       yplog_cat("key: ");
-                       yplog_cat(k.dptr);
-                       yplog_cat(" val: ");
-                       yplog_cat(v.dptr);
-                       yplog_cat("\n");
-#endif
-                       resp.more = more;
-                       resp.ypresp_all_u.val.stat = YP_TRUE;
-                       resp.ypresp_all_u.val.key.keydat_val = k.dptr;
-                       resp.ypresp_all_u.val.key.keydat_len = k.dsize - 1;
-                       resp.ypresp_all_u.val.val.valdat_val = v.dptr;
-                       resp.ypresp_all_u.val.val.valdat_len = v.dsize - 1;
+               if (v.dptr == NULL) 
+                       break;
+
+               resp.more = TRUE;
+               resp.ypresp_all_u.val.stat = YP_TRUE;
+               resp.ypresp_all_u.val.key.keydat_val = k.dptr;
+               resp.ypresp_all_u.val.key.keydat_len = k.dsize;
+               resp.ypresp_all_u.val.val.valdat_val = v.dptr;
+               resp.ypresp_all_u.val.val.valdat_len = v.dsize;
                        
-                       if (!xdr_ypresp_all(xdrs, &resp)) {
+               if (!xdr_ypresp_all(xdrs, &resp)) {
 #ifdef DEBUG
-                               yplog_cat("xdr_ypresp_all: 2 failed\n");
+                       yplog("  ypdb_xdr_get_all: xdr_ypresp_all failed");
 #endif                                 
-                               return(FALSE);
-                       }
+                       return(FALSE);
+               }
                        
+               /* advance past private keys */
+               k = ypdb_nextkey(db);
+               while (yp_private(k,FALSE)) {
                        k = ypdb_nextkey(db);
-                       while (yp_private(k,FALSE)) {
-                               k = ypdb_nextkey(db);
-                       };
-
-               };
-         
-       };
+               }
+       }
                
        bzero((char *)&resp, sizeof(resp));
-       
+       resp.ypresp_all_u.val.stat = YP_NOKEY;
        resp.more = FALSE;
-       resp.ypresp_all_u.val.stat = status;
        
        if (!xdr_ypresp_all(xdrs, &resp)) {
 #ifdef DEBUG
-               yplog_cat("xdr_ypresp_all: 3 failed\n");
+               yplog("  ypdb_xdr_get_all: final xdr_ypresp_all failed");
 #endif                                 
                return(FALSE);
        }
                
-       ypdb_close(db);
+       ypdb_close_db(db);
        
        return (TRUE);
 }
-