thiscell-whitespace-20061120
[openafs.git] / src / auth / cellconfig.c
index e277325..a5f8b3a 100644 (file)
@@ -25,9 +25,6 @@ RCSID
 #include <sys/utime.h>
 #include <io.h>
 #include <WINNT/afssw.h>
-#ifdef AFS_AFSDB_ENV
-#include <cm_dns.h>
-#endif /* AFS_AFSDB_ENV */
 #else
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -36,6 +33,9 @@ RCSID
 #include <sys/time.h>
 #ifdef AFS_AFSDB_ENV
 #include <arpa/nameser.h>
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#include <arpa/nameser_compat.h>
+#endif
 #include <resolv.h>
 #endif /* AFS_AFSDB_ENV */
 #endif /* AFS_NT40_ENV */
@@ -61,7 +61,12 @@ RCSID
 #include <afs/afsutil.h>
 #include "cellconfig.h"
 #include "keys.h"
-
+#ifdef AFS_NT40_ENV
+#ifdef AFS_AFSDB_ENV
+/* cm_dns.h depends on cellconfig.h */
+#include <cm_dns.h>
+#endif /* AFS_AFSDB_ENV */
+#endif
 static struct afsconf_servPair serviceTable[] = {
     {"afs", 7000,},
     {"afscb", 7001,},
@@ -80,7 +85,7 @@ static struct afsconf_servPair serviceTable[] = {
 
 /* Prototypes */
 static afs_int32 afsconf_FindService(register const char *aname);
-static int TrimLine(char *abuffer);
+static int TrimLine(char *abuffer, int abufsize);
 #ifdef AFS_NT40_ENV
 static int IsClientConfigDirectory(const char *path);
 static int GetCellNT(struct afsconf_dir *adir);
@@ -109,6 +114,113 @@ static int SaveKeys(struct afsconf_dir *adir);
  * CellServDB changes.
  */
 
+#if defined(AFS_SUN5_ENV) && !defined(__sparcv9)
+/* Solaris through 10 in 32 bit mode will return EMFILE if fopen can't
+   get an fd <= 255. We allow the fileserver to claim more fds than that.
+   This has always been a problem since pr_Initialize would have the same
+   issue, but hpr_Initialize makes it more likely that we would see this. 
+   Work around it. This is not generic. It's coded with the needs of
+   afsconf_* in mind only.
+
+   http://www.opensolaris.org/os/community/onnv/flag-days/pages/2006042001/
+*/
+
+#define BUFFER 4096
+
+struct afsconf_iobuffer {
+    int _file;
+    char *buffer;
+    char *ptr;
+    char *endptr;
+};
+
+typedef struct afsconf_iobuffer afsconf_FILE;
+
+static afsconf_FILE *
+afsconf_fopen(const char *fname, const char *fmode)
+{
+    int fd;
+    afsconf_FILE *iop;
+    
+    if ((fd = open(fname, O_RDONLY)) == -1) {
+       return NULL;
+    }
+    
+    iop = malloc(sizeof(struct afsconf_iobuffer));
+    if (iop == NULL) {
+       (void) close(fd);
+       errno = ENOMEM;
+       return NULL;
+    }
+    iop->_file = fd;
+    iop->buffer = malloc(BUFFER);
+    if (iop->buffer == NULL) {
+       (void) close(fd);
+       free((void *) iop);
+       errno = ENOMEM;
+       return NULL;
+    }
+    iop->ptr = iop->buffer;
+    iop->endptr = iop->buffer;
+    return iop;
+}
+
+static int
+afsconf_fclose(afsconf_FILE *iop)
+{
+    if (iop == NULL) {
+       return 0;
+    }
+    close(iop->_file);
+    free((void *)iop->buffer);
+    free((void *)iop);
+    return 0;
+}
+
+static char *
+afsconf_fgets(char *s, int n, afsconf_FILE *iop)
+{
+    char *p;
+    
+    p = s;
+    for (;;) {
+       char c;
+       
+       if (iop->ptr == iop->endptr) {
+           ssize_t len;
+           
+           if ((len = read(iop->_file, (void *)iop->buffer, BUFFER)) == -1) {
+               return NULL;
+           }
+           if (len == 0) {
+               *p = 0;
+               if (s == p) {
+                   return NULL;
+               }
+               return s;
+           }
+           iop->ptr = iop->buffer;
+           iop->endptr = iop->buffer + len;
+       }
+       c = *iop->ptr++;
+       *p++ = c;
+       if ((p - s) == (n - 1)) {
+           *p = 0;
+           return s;
+       }
+       if (c == '\n') {
+           *p = 0;
+           return s;
+       }
+    }
+}
+#define fopen afsconf_fopen
+#define fclose afsconf_fclose
+#define fgets afsconf_fgets
+#else
+#define afsconf_FILE FILE
+#endif /* AFS_SUN5_ENV && ! __sparcv9 */
+
 /* return port number in network byte order in the low 16 bits of a long; return -1 if not found */
 static afs_int32
 afsconf_FindService(register const char *aname)
@@ -117,7 +229,7 @@ afsconf_FindService(register const char *aname)
     struct servent *ts;
     register struct afsconf_servPair *tsp;
 
-#if     defined(AFS_OSF_ENV) || defined(AFS_DEC_ENV)
+#if     defined(AFS_OSF_ENV) 
     ts = getservbyname(aname, "");
 #else
     ts = getservbyname(aname, NULL);
@@ -137,7 +249,7 @@ afsconf_FindService(register const char *aname)
 }
 
 static int
-TrimLine(char *abuffer)
+TrimLine(char *abuffer, int abufsize)
 {
     char tbuffer[256];
     register char *tp;
@@ -149,8 +261,8 @@ TrimLine(char *abuffer)
            break;
        tp++;
     }
-    strcpy(tbuffer, tp);
-    strcpy(abuffer, tbuffer);
+    strlcpy(tbuffer, tp, sizeof tbuffer);
+    strlcpy(abuffer, tbuffer, abufsize);
     return 0;
 }
 
@@ -199,15 +311,28 @@ IsClientConfigDirectory(const char *path)
 static int
 afsconf_Check(register struct afsconf_dir *adir)
 {
-    char tbuffer[256];
+    char tbuffer[256], *p;
     struct stat tstat;
     register afs_int32 code;
 
 #ifdef AFS_NT40_ENV
     /* NT client CellServDB has different file name than NT server or Unix */
     if (IsClientConfigDirectory(adir->name)) {
-       strcompose(tbuffer, 256, adir->name, "/",
-                  AFSDIR_CELLSERVDB_FILE_NTCLIENT, NULL);
+       if (!afssw_GetClientCellServDBDir(&p)) {
+           strcompose(tbuffer, sizeof(tbuffer), p, "/",
+                      AFSDIR_CELLSERVDB_FILE_NTCLIENT, NULL);
+           free(p);
+       } else {
+           int len;
+           strncpy(tbuffer, adir->name, sizeof(tbuffer));
+           len = (int)strlen(tbuffer);
+           if (tbuffer[len - 1] != '\\' && tbuffer[len - 1] != '/') {
+               strncat(tbuffer, "\\", sizeof(tbuffer));
+           }
+           strncat(tbuffer, AFSDIR_CELLSERVDB_FILE_NTCLIENT,
+                   sizeof(tbuffer));
+           tbuffer[sizeof(tbuffer) - 1] = '\0';
+       }
     } else {
        strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLSERVDB_FILE,
                   NULL);
@@ -232,7 +357,7 @@ afsconf_Check(register struct afsconf_dir *adir)
 static int
 afsconf_Touch(register struct afsconf_dir *adir)
 {
-    char tbuffer[256];
+    char tbuffer[256], *p;
 #ifndef AFS_NT40_ENV
     struct timeval tvp[2];
 #endif
@@ -243,8 +368,19 @@ afsconf_Touch(register struct afsconf_dir *adir)
     /* NT client CellServDB has different file name than NT server or Unix */
 
     if (IsClientConfigDirectory(adir->name)) {
-       strcompose(tbuffer, 256, adir->name, "/",
-                  AFSDIR_CELLSERVDB_FILE_NTCLIENT, NULL);
+       if (!afssw_GetClientCellServDBDir(&p)) {
+           strcompose(tbuffer, sizeof(tbuffer), p, "/",
+                      AFSDIR_CELLSERVDB_FILE_NTCLIENT, NULL);
+           free(p);
+       } else {
+           int len = (int)strlen(tbuffer);
+           if (tbuffer[len - 1] != '\\' && tbuffer[len - 1] != '/') {
+               strncat(tbuffer, "\\", sizeof(tbuffer));
+           }
+           strncat(tbuffer, AFSDIR_CELLSERVDB_FILE_NTCLIENT,
+                   sizeof(tbuffer));
+           tbuffer[sizeof(tbuffer) - 1] = '\0';
+       }
     } else {
        strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLSERVDB_FILE,
                   NULL);
@@ -266,12 +402,11 @@ afsconf_Open(register const char *adir)
     register struct afsconf_dir *tdir;
     register afs_int32 code;
 
-    LOCK_GLOBAL_MUTEX
-       /* zero structure and fill in name; rest is done by internal routine */
-       tdir = (struct afsconf_dir *)malloc(sizeof(struct afsconf_dir));
+    LOCK_GLOBAL_MUTEX;
+    /* zero structure and fill in name; rest is done by internal routine */
+    tdir = (struct afsconf_dir *)malloc(sizeof(struct afsconf_dir));
     memset(tdir, 0, sizeof(struct afsconf_dir));
-    tdir->name = (char *)malloc(strlen(adir) + 1);
-    strcpy(tdir->name, adir);
+    tdir->name = strdup(adir);
 
     code = afsconf_OpenInternal(tdir, 0, 0);
     if (code) {
@@ -282,7 +417,7 @@ afsconf_Open(register const char *adir)
        if (!(afsconf_path = getenv("AFSCONF"))) {
            /* The "AFSCONF" environment (or contents of "/.AFSCONF") will be typically set to something like "/afs/<cell>/common/etc" where, by convention, the default files for "ThisCell" and "CellServDB" will reside; note that a major drawback is that a given afs client on that cell may NOT contain the same contents... */
            char *home_dir;
-           FILE *fp;
+           afsconf_FILE *fp;
            size_t len;
 
            if (!(home_dir = getenv("HOME"))) {
@@ -290,7 +425,8 @@ afsconf_Open(register const char *adir)
                fp = fopen("/.AFSCONF", "r");
                if (fp == 0) {
                    free(tdir);
-                   UNLOCK_GLOBAL_MUTEX return (struct afsconf_dir *)0;
+                   UNLOCK_GLOBAL_MUTEX;
+                   return (struct afsconf_dir *)0;
                }
                fgets(afs_confdir, 128, fp);
                fclose(fp);
@@ -304,10 +440,9 @@ afsconf_Open(register const char *adir)
                    fp = fopen("/.AFSCONF", "r");
                    if (fp == 0) {
                        free(tdir);
-                       UNLOCK_GLOBAL_MUTEX return (struct afsconf_dir *)0;
+                       UNLOCK_GLOBAL_MUTEX;
+                       return (struct afsconf_dir *)0;
                    }
-                   fgets(afs_confdir, 128, fp);
-                   fclose(fp);
                }
                fgets(afs_confdir, 128, fp);
                fclose(fp);
@@ -315,45 +450,56 @@ afsconf_Open(register const char *adir)
            len = strlen(afs_confdir);
            if (len == 0) {
                free(tdir);
-               UNLOCK_GLOBAL_MUTEX return (struct afsconf_dir *)0;
+               UNLOCK_GLOBAL_MUTEX;
+               return (struct afsconf_dir *)0;
            }
            if (afs_confdir[len - 1] == '\n') {
                afs_confdir[len - 1] = 0;
            }
            afsconf_path = afs_confdir;
        }
-       tdir->name = (char *)malloc(strlen(afsconf_path) + 1);
-       strcpy(tdir->name, afsconf_path);
+       tdir->name = strdup(afsconf_path);
        code = afsconf_OpenInternal(tdir, 0, 0);
        if (code) {
            free(tdir->name);
            free(tdir);
-           UNLOCK_GLOBAL_MUTEX return (struct afsconf_dir *)0;
+           UNLOCK_GLOBAL_MUTEX;
+           return (struct afsconf_dir *)0;
        }
     }
-    UNLOCK_GLOBAL_MUTEX return tdir;
+    UNLOCK_GLOBAL_MUTEX;
+    return tdir;
 }
 
-
 static int
 GetCellUnix(struct afsconf_dir *adir)
 {
-    int rc;
+    char *rc;
     char tbuffer[256];
-    FILE *tf;
-
+    char *start, *p;
+    afsconf_FILE *fp;
+    
     strcompose(tbuffer, 256, adir->name, "/", AFSDIR_THISCELL_FILE, NULL);
-    tf = fopen(tbuffer, "r");
-    if (tf) {
-       rc = fscanf(tf, "%s", tbuffer);
-       if (rc == 1) {
-           adir->cellName = (char *)malloc(strlen(tbuffer) + 1);
-           strcpy(adir->cellName, tbuffer);
-       }
-       fclose(tf);
-    } else {
+    fp = fopen(tbuffer, "r");
+    if (fp == 0) {
        return -1;
     }
+    rc = fgets(tbuffer, 256, fp);
+    fclose(fp);
+    if (rc == NULL)
+        return -1;
+
+    start = tbuffer;
+    while (*start != '\0' && isspace(*start))
+        start++;
+    p = start;
+    while (*p != '\0' && !isspace(*p))
+        p++;
+    *p = '\0';
+    if (*start == '\0')
+        return -1;
+
+    adir->cellName = strdup(start);
     return 0;
 }
 
@@ -377,7 +523,7 @@ static int
 afsconf_OpenInternal(register struct afsconf_dir *adir, char *cell,
                     char clones[])
 {
-    FILE *tf;
+    afsconf_FILE *tf;
     register char *tp, *bp;
     register struct afsconf_entry *curEntry;
     struct afsconf_aliasentry *curAlias;
@@ -408,8 +554,22 @@ afsconf_OpenInternal(register struct afsconf_dir *adir, char *cell,
      */
     if (IsClientConfigDirectory(adir->name)) {
        /* NT client config dir */
-       strcompose(tbuffer, 256, adir->name, "/",
-                  AFSDIR_CELLSERVDB_FILE_NTCLIENT, NULL);
+       char *p;
+       if (!afssw_GetClientCellServDBDir(&p)) {
+           strcompose(tbuffer, sizeof(tbuffer), p, "/",
+                      AFSDIR_CELLSERVDB_FILE_NTCLIENT, NULL);
+           free(p);
+       } else {
+           int len;
+           strncpy(tbuffer, adir->name, sizeof(tbuffer));
+           len = (int)strlen(tbuffer);
+           if (tbuffer[len - 1] != '\\' && tbuffer[len - 1] != '/') {
+               strncat(tbuffer, "\\", sizeof(tbuffer));
+           }
+           strncat(tbuffer, AFSDIR_CELLSERVDB_FILE_NTCLIENT,
+                   sizeof(tbuffer));
+           tbuffer[sizeof(tbuffer) - 1] = '\0';
+       }
     } else {
        /* NT server config dir */
        strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLSERVDB_FILE,
@@ -425,7 +585,7 @@ afsconf_OpenInternal(register struct afsconf_dir *adir, char *cell,
        adir->timeRead = 0;
     }
 
-    strcpy(tbuf1, tbuffer);
+    strlcpy(tbuf1, tbuffer, sizeof tbuf1);
     tf = fopen(tbuffer, "r");
     if (!tf) {
        return -1;
@@ -434,7 +594,7 @@ afsconf_OpenInternal(register struct afsconf_dir *adir, char *cell,
        tp = fgets(tbuffer, sizeof(tbuffer), tf);
        if (!tp)
            break;
-       TrimLine(tbuffer);      /* remove white space */
+       TrimLine(tbuffer, sizeof tbuffer);      /* remove white space */
        if (tbuffer[0] == 0 || tbuffer[0] == '\n')
            continue;           /* empty line */
        if (tbuffer[0] == '>') {
@@ -454,13 +614,11 @@ afsconf_OpenInternal(register struct afsconf_dir *adir, char *cell,
            if (code) {
                afsconf_CloseInternal(adir);
                fclose(tf);
+               free(curEntry);
                return -1;
            }
-           if (linkedcell[0] != '\0') {
-               curEntry->cellInfo.linkedCell =
-                   (char *)malloc(strlen(linkedcell) + 1);
-               strcpy(curEntry->cellInfo.linkedCell, linkedcell);
-           }
+           if (linkedcell[0] != '\0')
+               curEntry->cellInfo.linkedCell = strdup(linkedcell);
        } else {
            /* new host in the current cell */
            if (!curEntry) {
@@ -514,7 +672,7 @@ afsconf_OpenInternal(register struct afsconf_dir *adir, char *cell,
        tp = fgets(tbuffer, sizeof(tbuffer), tf);
        if (!tp)
            break;
-       TrimLine(tbuffer);      /* remove white space */
+       TrimLine(tbuffer, sizeof tbuffer);      /* remove white space */
 
        if (tbuffer[0] == '\0' || tbuffer[0] == '\n' || tbuffer[0] == '#')
            continue;           /* empty line */
@@ -539,8 +697,8 @@ afsconf_OpenInternal(register struct afsconf_dir *adir, char *cell,
        curAlias = malloc(sizeof(*curAlias));
        memset(curAlias, 0, sizeof(*curAlias));
 
-       strcpy(curAlias->aliasInfo.aliasName, aliasPtr);
-       strcpy(curAlias->aliasInfo.realName, tbuffer);
+       strlcpy(curAlias->aliasInfo.aliasName, aliasPtr, sizeof curAlias->aliasInfo.aliasName);
+       strlcpy(curAlias->aliasInfo.realName, tbuffer, sizeof curAlias->aliasInfo.realName);
 
        curAlias->next = adir->alias_entries;
        adir->alias_entries = curAlias;
@@ -571,10 +729,12 @@ ParseHostLine(char *aline, register struct sockaddr_in *addr, char *aname,
     if (*aline == '[') {
        if (aclone)
            *aclone = 1;
+       /* FIXME: length of aname unknown here */
        code = sscanf(aline, "[%d.%d.%d.%d] #%s", &c1, &c2, &c3, &c4, aname);
     } else {
        if (aclone)
            *aclone = 0;
+       /* FIXME: length of aname unknown here */
        code = sscanf(aline, "%d.%d.%d.%d #%s", &c1, &c2, &c3, &c4, aname);
     }
     if (code != 5)
@@ -601,6 +761,7 @@ ParseCellLine(register char *aline, register char *aname,
              register char *alname)
 {
     register int code;
+    /* FIXME: length of aname, alname unknown here */
     code = sscanf(aline, ">%s %s", aname, alname);
     if (code == 1)
        *alname = '\0';
@@ -620,13 +781,16 @@ afsconf_CellApply(struct afsconf_dir *adir,
 {
     register struct afsconf_entry *tde;
     register afs_int32 code;
-    LOCK_GLOBAL_MUTEX for (tde = adir->entries; tde; tde = tde->next) {
+    LOCK_GLOBAL_MUTEX;
+    for (tde = adir->entries; tde; tde = tde->next) {
        code = (*aproc) (&tde->cellInfo, arock, adir);
        if (code) {
-           UNLOCK_GLOBAL_MUTEX return code;
+           UNLOCK_GLOBAL_MUTEX;
+           return code;
        }
     }
-    UNLOCK_GLOBAL_MUTEX return 0;
+    UNLOCK_GLOBAL_MUTEX;
+    return 0;
 }
 
 /* call aproc(entry, arock, adir) for all cell aliases.
@@ -640,13 +804,16 @@ afsconf_CellAliasApply(struct afsconf_dir *adir,
 {
     register struct afsconf_aliasentry *tde;
     register afs_int32 code;
-    LOCK_GLOBAL_MUTEX for (tde = adir->alias_entries; tde; tde = tde->next) {
+    LOCK_GLOBAL_MUTEX;
+    for (tde = adir->alias_entries; tde; tde = tde->next) {
        code = (*aproc) (&tde->aliasInfo, arock, adir);
        if (code) {
-           UNLOCK_GLOBAL_MUTEX return code;
+           UNLOCK_GLOBAL_MUTEX;
+           return code;
        }
     }
-    UNLOCK_GLOBAL_MUTEX return 0;
+    UNLOCK_GLOBAL_MUTEX;
+    return 0;
 }
 
 afs_int32 afsconf_SawCell = 0;
@@ -679,10 +846,11 @@ afsconf_GetAfsdbInfo(char *acellName, char *aservice,
                     struct afsconf_cell *acellInfo)
 {
     afs_int32 code;
-    int tservice, i;
-    size_t len;
+    int tservice, i, len;
     unsigned char answer[1024];
     unsigned char *p;
+    char *dotcellname;
+    int cellnamelength;
     char realCellName[256];
     char host[256];
     int server_num = 0;
@@ -692,10 +860,27 @@ afsconf_GetAfsdbInfo(char *acellName, char *aservice,
      * replaced with a more fine-grained lock just for the resolver
      * operations.
      */
-    LOCK_GLOBAL_MUTEX len =
-       res_search(acellName, C_IN, T_AFSDB, answer, sizeof(answer));
-    UNLOCK_GLOBAL_MUTEX if (len < 0)
-         return AFSCONF_NOTFOUND;
+
+    if ( ! strchr(acellName,'.') ) {
+       cellnamelength=strlen(acellName);
+       dotcellname=malloc(cellnamelength+2);
+       memcpy(dotcellname,acellName,cellnamelength);
+       dotcellname[cellnamelength]='.';
+       dotcellname[cellnamelength+1]=0;
+       LOCK_GLOBAL_MUTEX;
+           len = res_search(dotcellname, C_IN, T_AFSDB, answer, sizeof(answer));
+       if ( len < 0 ) {
+          len = res_search(acellName, C_IN, T_AFSDB, answer, sizeof(answer));
+       }
+       UNLOCK_GLOBAL_MUTEX;
+       free(dotcellname);
+    } else {
+       LOCK_GLOBAL_MUTEX;
+           len = res_search(acellName, C_IN, T_AFSDB, answer, sizeof(answer));
+       UNLOCK_GLOBAL_MUTEX;
+    }
+    if (len < 0)
+       return AFSCONF_NOTFOUND;
 
     p = answer + sizeof(HEADER);       /* Skip header */
     code = dn_expand(answer, answer + len, p, host, sizeof(host));
@@ -730,7 +915,7 @@ afsconf_GetAfsdbInfo(char *acellName, char *aservice,
                 * right AFSDB type.  Write down the true cell name that
                 * the resolver gave us above.
                 */
-               strcpy(realCellName, host);
+               strlcpy(realCellName, host, sizeof realCellName);
            }
 
            code = dn_expand(answer, answer + len, p + 2, host, sizeof(host));
@@ -786,16 +971,16 @@ afsconf_GetAfsdbInfo(char *acellName, char *aservice,
     register afs_int32 i;
     int tservice;
     struct afsconf_entry DNSce;
-    char *DNStmpStrp;          /* a temp string pointer */
-    struct hostent *thp;
-    afs_int32 cellHosts[AFSMAXCELLHOSTS];
+    afs_int32 cellHostAddrs[AFSMAXCELLHOSTS];
+    char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
     int numServers;
     int rc;
-    int *ttl;
+    int ttl;
 
     DNSce.cellInfo.numServers = 0;
     DNSce.next = NULL;
-    rc = getAFSServer(acellName, cellHosts, &numServers, &ttl);
+    rc = getAFSServer(acellName, cellHostAddrs, cellHostNames, &numServers,
+                     &ttl);
     /* ignore the ttl here since this code is only called by transitory programs
      * like klog, etc. */
     if (rc < 0)
@@ -804,18 +989,21 @@ afsconf_GetAfsdbInfo(char *acellName, char *aservice,
        return -1;
 
     for (i = 0; i < numServers; i++) {
-       memcpy(&acellInfo->hostAddr[i].sin_addr.s_addr, &cellHosts[i],
+       memcpy(&acellInfo->hostAddr[i].sin_addr.s_addr, &cellHostAddrs[i],
               sizeof(long));
+       memcpy(acellInfo->hostName[i], cellHostNames[i], MAXHOSTCHARS);
        acellInfo->hostAddr[i].sin_family = AF_INET;
 
        /* sin_port supplied by connection code */
     }
 
     acellInfo->numServers = numServers;
-    strcpy(acellInfo->name, acellName);
+    strlcpy(acellInfo->name, acellName, sizeof acellInfo->name);
     if (aservice) {
-       LOCK_GLOBAL_MUTEX tservice = afsconf_FindService(aservice);
-       UNLOCK_GLOBAL_MUTEX if (tservice < 0) {
+       LOCK_GLOBAL_MUTEX;
+       tservice = afsconf_FindService(aservice);
+       UNLOCK_GLOBAL_MUTEX;
+       if (tservice < 0) {
            return AFSCONF_NOTFOUND;    /* service not found */
        }
        for (i = 0; i < acellInfo->numServers; i++) {
@@ -839,22 +1027,24 @@ afsconf_GetCellInfo(struct afsconf_dir *adir, char *acellName, char *aservice,
     register afs_int32 i;
     int tservice;
     char *tcell;
-    size_t cnLen;
+    int cnLen;
     int ambig;
     char tbuffer[64];
 
-    LOCK_GLOBAL_MUTEX if (adir)
-         afsconf_Check(adir);
+    LOCK_GLOBAL_MUTEX;
+    if (adir)
+       afsconf_Check(adir);
     if (acellName) {
        tcell = acellName;
-       cnLen = strlen(tcell) + 1;
+       cnLen = (int)(strlen(tcell) + 1);
        lcstring(tcell, tcell, cnLen);
        afsconf_SawCell = 1;    /* will ignore the AFSCELL switch on future */
        /* call to afsconf_GetLocalCell: like klog  */
     } else {
        i = afsconf_GetLocalCell(adir, tbuffer, sizeof(tbuffer));
        if (i) {
-           UNLOCK_GLOBAL_MUTEX return i;
+           UNLOCK_GLOBAL_MUTEX;
+           return i;
        }
        tcell = tbuffer;
     }
@@ -862,7 +1052,8 @@ afsconf_GetCellInfo(struct afsconf_dir *adir, char *acellName, char *aservice,
     bestce = (struct afsconf_entry *)0;
     ambig = 0;
     if (!adir) {
-       UNLOCK_GLOBAL_MUTEX return 0;
+       UNLOCK_GLOBAL_MUTEX;
+       return 0;
     }
 
     /* Look through the list of aliases */
@@ -893,20 +1084,22 @@ afsconf_GetCellInfo(struct afsconf_dir *adir, char *acellName, char *aservice,
        if (aservice) {
            tservice = afsconf_FindService(aservice);
            if (tservice < 0) {
-               UNLOCK_GLOBAL_MUTEX return AFSCONF_NOTFOUND;    /* service not found */
+               UNLOCK_GLOBAL_MUTEX;
+               return AFSCONF_NOTFOUND;        /* service not found */
            }
            for (i = 0; i < acellInfo->numServers; i++) {
                acellInfo->hostAddr[i].sin_port = tservice;
            }
        }
        acellInfo->timeout = 0;
-       UNLOCK_GLOBAL_MUTEX return 0;
+       UNLOCK_GLOBAL_MUTEX;
+       return 0;
     } else {
-       UNLOCK_GLOBAL_MUTEX
+       UNLOCK_GLOBAL_MUTEX;
 #ifdef AFS_AFSDB_ENV
-           return afsconf_GetAfsdbInfo(tcell, aservice, acellInfo);
+       return afsconf_GetAfsdbInfo(tcell, aservice, acellInfo);
 #else
-           return AFSCONF_NOTFOUND;
+       return AFSCONF_NOTFOUND;
 #endif /* AFS_AFSDB_ENV */
     }
 }
@@ -919,14 +1112,14 @@ afsconf_GetLocalCell(register struct afsconf_dir *adir, char *aname,
     char *afscell_path;
     afs_int32 code = 0;
 
-    LOCK_GLOBAL_MUTEX
-       /*
-        * If a cell switch was specified in a command, then it should override the 
-        * AFSCELL variable.  If a cell was specified, then the afsconf_SawCell flag
-        * is set and the cell name in the adir structure is used.
-        * Read the AFSCELL var each time: in case it changes (unsetenv AFSCELL).
-        */
-       if (!afsconf_SawCell && (afscell_path = getenv("AFSCELL"))) {
+    LOCK_GLOBAL_MUTEX;
+    /*
+     * If a cell switch was specified in a command, then it should override the 
+     * AFSCELL variable.  If a cell was specified, then the afsconf_SawCell flag
+     * is set and the cell name in the adir structure is used.
+     * Read the AFSCELL var each time: in case it changes (unsetenv AFSCELL).
+     */
+    if (!afsconf_SawCell && (afscell_path = getenv("AFSCELL"))) {
        if (!afsconf_showcell) {
            fprintf(stderr, "Note: Operation is performed on cell %s\n",
                    afscell_path);
@@ -941,17 +1134,20 @@ afsconf_GetLocalCell(register struct afsconf_dir *adir, char *aname,
            code = AFSCONF_UNKNOWN;
     }
 
-    UNLOCK_GLOBAL_MUTEX return (code);
+    UNLOCK_GLOBAL_MUTEX;
+    return (code);
 }
 
 int
 afsconf_Close(struct afsconf_dir *adir)
 {
-    LOCK_GLOBAL_MUTEX afsconf_CloseInternal(adir);
+    LOCK_GLOBAL_MUTEX;
+    afsconf_CloseInternal(adir);
     if (adir->name)
        free(adir->name);
     free(adir);
-    UNLOCK_GLOBAL_MUTEX return 0;
+    UNLOCK_GLOBAL_MUTEX;
+    return 0;
 }
 
 static int
@@ -1017,9 +1213,9 @@ afsconf_IntGetKeys(struct afsconf_dir *adir)
     }
 #endif /* AFS_NT40_ENV */
 
-    LOCK_GLOBAL_MUTEX
-       /* compute the key name and other setup */
-       strcompose(tbuffer, 256, adir->name, "/", AFSDIR_KEY_FILE, NULL);
+    LOCK_GLOBAL_MUTEX;
+    /* compute the key name and other setup */
+    strcompose(tbuffer, 256, adir->name, "/", AFSDIR_KEY_FILE, NULL);
     tstr = (struct afsconf_keys *)malloc(sizeof(struct afsconf_keys));
     adir->keystr = tstr;
 
@@ -1027,21 +1223,31 @@ afsconf_IntGetKeys(struct afsconf_dir *adir)
     fd = open(tbuffer, O_RDONLY);
     if (fd < 0) {
        tstr->nkeys = 0;
-       UNLOCK_GLOBAL_MUTEX return 0;
+       UNLOCK_GLOBAL_MUTEX;
+       return 0;
     }
     code = read(fd, tstr, sizeof(struct afsconf_keys));
     close(fd);
     if (code < sizeof(afs_int32)) {
        tstr->nkeys = 0;
-       UNLOCK_GLOBAL_MUTEX return 0;
+       UNLOCK_GLOBAL_MUTEX;
+       return 0;
     }
 
     /* convert key structure to host order */
     tstr->nkeys = ntohl(tstr->nkeys);
+
+    if (code < sizeof(afs_int32) + (tstr->nkeys*sizeof(struct afsconf_key))) {
+       tstr->nkeys = 0;
+       UNLOCK_GLOBAL_MUTEX;
+       return 0;
+    }
+
     for (fd = 0; fd < tstr->nkeys; fd++)
        tstr->key[fd].kvno = ntohl(tstr->key[fd].kvno);
 
-    UNLOCK_GLOBAL_MUTEX return 0;
+    UNLOCK_GLOBAL_MUTEX;
+    return 0;
 }
 
 /* get keys structure */
@@ -1050,12 +1256,15 @@ afsconf_GetKeys(struct afsconf_dir *adir, struct afsconf_keys *astr)
 {
     register afs_int32 code;
 
-    LOCK_GLOBAL_MUTEX code = afsconf_Check(adir);
+    LOCK_GLOBAL_MUTEX;
+    code = afsconf_Check(adir);
     if (code) {
-       UNLOCK_GLOBAL_MUTEX return AFSCONF_FAILURE;
+       UNLOCK_GLOBAL_MUTEX;
+       return AFSCONF_FAILURE;
     }
     memcpy(astr, adir->keystr, sizeof(struct afsconf_keys));
-    UNLOCK_GLOBAL_MUTEX return 0;
+    UNLOCK_GLOBAL_MUTEX;
+    return 0;
 }
 
 /* get latest key */
@@ -1069,9 +1278,11 @@ afsconf_GetLatestKey(struct afsconf_dir * adir, afs_int32 * avno, char *akey)
     struct afsconf_key *bestk;
     register afs_int32 code;
 
-    LOCK_GLOBAL_MUTEX code = afsconf_Check(adir);
+    LOCK_GLOBAL_MUTEX;
+    code = afsconf_Check(adir);
     if (code) {
-       UNLOCK_GLOBAL_MUTEX return AFSCONF_FAILURE;
+       UNLOCK_GLOBAL_MUTEX;
+       return AFSCONF_FAILURE;
     }
     maxa = adir->keystr->nkeys;
 
@@ -1090,9 +1301,11 @@ afsconf_GetLatestKey(struct afsconf_dir * adir, afs_int32 * avno, char *akey)
            memcpy(akey, bestk->key, 8);        /* copy out latest key */
        if (avno)
            *avno = bestk->kvno;        /* and kvno to caller */
-       UNLOCK_GLOBAL_MUTEX return 0;
+       UNLOCK_GLOBAL_MUTEX;
+       return 0;
     }
-    UNLOCK_GLOBAL_MUTEX return AFSCONF_NOTFOUND;       /* didn't find any keys */
+    UNLOCK_GLOBAL_MUTEX;
+    return AFSCONF_NOTFOUND;   /* didn't find any keys */
 }
 
 /* get a particular key */
@@ -1103,20 +1316,24 @@ afsconf_GetKey(struct afsconf_dir *adir, afs_int32 avno, char *akey)
     register struct afsconf_key *tk;
     register afs_int32 code;
 
-    LOCK_GLOBAL_MUTEX code = afsconf_Check(adir);
+    LOCK_GLOBAL_MUTEX;
+    code = afsconf_Check(adir);
     if (code) {
-       UNLOCK_GLOBAL_MUTEX return AFSCONF_FAILURE;
+       UNLOCK_GLOBAL_MUTEX;
+       return AFSCONF_FAILURE;
     }
     maxa = adir->keystr->nkeys;
 
     for (tk = adir->keystr->key, i = 0; i < maxa; i++, tk++) {
        if (tk->kvno == avno) {
            memcpy(akey, tk->key, 8);
-           UNLOCK_GLOBAL_MUTEX return 0;
+           UNLOCK_GLOBAL_MUTEX;
+           return 0;
        }
     }
 
-    UNLOCK_GLOBAL_MUTEX return AFSCONF_NOTFOUND;
+    UNLOCK_GLOBAL_MUTEX;
+    return AFSCONF_NOTFOUND;
 }
 
 /* save the key structure in the appropriate file */
@@ -1159,18 +1376,21 @@ afsconf_AddKey(struct afsconf_dir *adir, afs_int32 akvno, char akey[8],
     register afs_int32 i;
     int foundSlot;
 
-    LOCK_GLOBAL_MUTEX tk = adir->keystr;
+    LOCK_GLOBAL_MUTEX;
+    tk = adir->keystr;
 
     if (akvno != 999) {
        if (akvno < 0 || akvno > 255) {
-           UNLOCK_GLOBAL_MUTEX return ERANGE;
+           UNLOCK_GLOBAL_MUTEX;
+           return ERANGE;
        }
     }
     foundSlot = 0;
     for (i = 0, tkey = tk->key; i < tk->nkeys; i++, tkey++) {
        if (tkey->kvno == akvno) {
            if (!overwrite) {
-               UNLOCK_GLOBAL_MUTEX return AFSCONF_KEYINUSE;
+               UNLOCK_GLOBAL_MUTEX;
+               return AFSCONF_KEYINUSE;
            }
            foundSlot = 1;
            break;
@@ -1178,7 +1398,8 @@ afsconf_AddKey(struct afsconf_dir *adir, afs_int32 akvno, char akey[8],
     }
     if (!foundSlot) {
        if (tk->nkeys >= AFSCONF_MAXKEYS) {
-           UNLOCK_GLOBAL_MUTEX return AFSCONF_FULL;
+           UNLOCK_GLOBAL_MUTEX;
+           return AFSCONF_FULL;
        }
        tkey = &tk->key[tk->nkeys++];
     }
@@ -1186,7 +1407,8 @@ afsconf_AddKey(struct afsconf_dir *adir, afs_int32 akvno, char akey[8],
     memcpy(tkey->key, akey, 8);
     i = SaveKeys(adir);
     afsconf_Touch(adir);
-    UNLOCK_GLOBAL_MUTEX return i;
+    UNLOCK_GLOBAL_MUTEX;
+    return i;
 }
 
 /* this proc works by sliding the other guys down, rather than using a funny
@@ -1200,7 +1422,8 @@ afsconf_DeleteKey(struct afsconf_dir *adir, afs_int32 akvno)
     register int i;
     int foundFlag = 0;
 
-    LOCK_GLOBAL_MUTEX tk = adir->keystr;
+    LOCK_GLOBAL_MUTEX;
+    tk = adir->keystr;
 
     for (i = 0, tkey = tk->key; i < tk->nkeys; i++, tkey++) {
        if (tkey->kvno == akvno) {
@@ -1209,7 +1432,8 @@ afsconf_DeleteKey(struct afsconf_dir *adir, afs_int32 akvno)
        }
     }
     if (!foundFlag) {
-       UNLOCK_GLOBAL_MUTEX return AFSCONF_NOTFOUND;
+       UNLOCK_GLOBAL_MUTEX;
+       return AFSCONF_NOTFOUND;
     }
 
     /* otherwise slide the others down.  i and tkey point at the guy to delete */
@@ -1220,5 +1444,6 @@ afsconf_DeleteKey(struct afsconf_dir *adir, afs_int32 akvno)
     tk->nkeys--;
     i = SaveKeys(adir);
     afsconf_Touch(adir);
-    UNLOCK_GLOBAL_MUTEX return i;
+    UNLOCK_GLOBAL_MUTEX;
+    return i;
 }