auth: prevent uninitialized key list in AFS config
[openafs.git] / src / auth / cellconfig.c
index e4490e8..2509ec7 100644 (file)
@@ -138,7 +138,7 @@ afsconf_fopen(const char *fname, const char *fmode)
     iop->buffer = malloc(BUFFER);
     if (iop->buffer == NULL) {
        (void) close(fd);
-       free((void *) iop);
+       free(iop);
        errno = ENOMEM;
        return NULL;
     }
@@ -154,8 +154,8 @@ afsconf_fclose(afsconf_FILE *iop)
        return 0;
     }
     close(iop->_file);
-    free((void *)iop->buffer);
-    free((void *)iop);
+    free(iop->buffer);
+    free(iop);
     return 0;
 }
 
@@ -353,7 +353,7 @@ _afsconf_UpToDate(struct afsconf_dir *adir)
     int code;
     time_t now = time(0);
 
-    if (adir->timeCheck == now) {
+    if (adir->timeRead && (adir->timeCheck == now)) {
        return 1; /* stat no more than once a second */
     }
     adir->timeCheck = now;
@@ -435,8 +435,7 @@ afsconf_Open(const char *adir)
 
     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 = calloc(1, sizeof(struct afsconf_dir));
     tdir->name = strdup(adir);
 
     code = afsconf_OpenInternal(tdir, 0, 0);
@@ -454,36 +453,34 @@ afsconf_Open(const char *adir)
            if (!(home_dir = getenv("HOME"))) {
                /* Our last chance is the "/.AFSCONF" file */
                fp = fopen("/.AFSCONF", "r");
-               if (fp == 0) {
-                   free(tdir);
-                   UNLOCK_GLOBAL_MUTEX;
-                   return (struct afsconf_dir *)0;
-               }
+               if (fp == 0)
+                   goto fail;
+
                fgets(afs_confdir, 128, fp);
                fclose(fp);
            } else {
-               char pathname[256];
+               char *pathname = NULL;
+
+               asprintf(&pathname, "%s/%s", home_dir, ".AFSCONF");
+               if (pathname == NULL)
+                   goto fail;
 
-               sprintf(pathname, "%s/%s", home_dir, ".AFSCONF");
                fp = fopen(pathname, "r");
+               free(pathname);
+
                if (fp == 0) {
                    /* Our last chance is the "/.AFSCONF" file */
                    fp = fopen("/.AFSCONF", "r");
-                   if (fp == 0) {
-                       free(tdir);
-                       UNLOCK_GLOBAL_MUTEX;
-                       return (struct afsconf_dir *)0;
-                   }
+                   if (fp == 0)
+                       goto fail;
                }
                fgets(afs_confdir, 128, fp);
                fclose(fp);
            }
            len = strlen(afs_confdir);
-           if (len == 0) {
-               free(tdir);
-               UNLOCK_GLOBAL_MUTEX;
-               return (struct afsconf_dir *)0;
-           }
+           if (len == 0)
+               goto fail;
+
            if (afs_confdir[len - 1] == '\n') {
                afs_confdir[len - 1] = 0;
            }
@@ -493,13 +490,16 @@ afsconf_Open(const char *adir)
        code = afsconf_OpenInternal(tdir, 0, 0);
        if (code) {
            free(tdir->name);
-           free(tdir);
-           UNLOCK_GLOBAL_MUTEX;
-           return (struct afsconf_dir *)0;
+           goto fail;
        }
     }
     UNLOCK_GLOBAL_MUTEX;
     return tdir;
+
+fail:
+    free(tdir);
+    UNLOCK_GLOBAL_MUTEX;
+    return NULL;
 }
 
 static int
@@ -510,7 +510,8 @@ GetCellUnix(struct afsconf_dir *adir)
     char *start, *p;
     afsconf_FILE *fp;
 
-    strcompose(tbuffer, 256, adir->name, "/", AFSDIR_THISCELL_FILE, NULL);
+    strcompose(tbuffer, 256, adir->name, "/", AFSDIR_THISCELL_FILE,
+       (char *)NULL);
     fp = fopen(tbuffer, "r");
     if (fp == 0) {
        return -1;
@@ -631,6 +632,9 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
     cm_enumCellRegistry_t enumCellRegistry = {0, 0};
 #endif /* AFS_NT40_ENV */
 
+    /* init the keys queue before any call to afsconf_CloseInternal() */
+    _afsconf_InitKeys(adir);
+
     /* figure out the local cell name */
 #ifdef AFS_NT40_ENV
     i = GetCellNT(adir);
@@ -666,9 +670,6 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
        return -1;
     }
 
-    /* init the keys queue before any call to afsconf_CloseInternal() */
-    _afsconf_InitKeys(adir);
-
     /* The CellServDB file is now open.
      * The following code parses the contents of the
      * file and creates a list with the first cell entry
@@ -697,9 +698,7 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
                adir->entries = curEntry;
                curEntry = 0;
            }
-           curEntry =
-               (struct afsconf_entry *)malloc(sizeof(struct afsconf_entry));
-           memset(curEntry, 0, sizeof(struct afsconf_entry));
+           curEntry = calloc(1, sizeof(struct afsconf_entry));
            code =
                ParseCellLine(tbuffer, curEntry->cellInfo.name, linkedcell);
            if (code) {
@@ -777,7 +776,8 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
 #endif /* AFS_NT40_ENV */
 
     /* Read in the alias list */
-    strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLALIAS_FILE, NULL);
+    strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLALIAS_FILE,
+       (char *)NULL);
 
     tf = fopen(tbuffer, "r");
     while (tf) {
@@ -808,8 +808,7 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
            tp++;
        tp[0] = '\0';
 
-       curAlias = malloc(sizeof(*curAlias));
-       memset(curAlias, 0, sizeof(*curAlias));
+       curAlias = calloc(1, sizeof(*curAlias));
 
        strlcpy(curAlias->aliasInfo.aliasName, aliasPtr, sizeof curAlias->aliasInfo.aliasName);
        strlcpy(curAlias->aliasInfo.realName, tbuffer, sizeof curAlias->aliasInfo.realName);
@@ -823,6 +822,10 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
 
     /* now read the fs keys, if possible */
     code = _afsconf_LoadKeys(adir);
+    if (code) {
+        return code;
+    }
+    code = _afsconf_LoadRealms(adir);
 
     return code;
 }
@@ -963,11 +966,10 @@ afsconf_LookupServer(const char *service, const char *protocol,
 {
     int code = 0;
     int len;
-    unsigned char answer[1024];
+    unsigned char answer[4096];
     unsigned char *p;
-    char *dotcellname;
+    char *dotcellname = NULL;
     char *realCellName;
-    int cellnamelength, fullnamelength;
     char host[256];
     int server_num = 0;
     int minttl = 0;
@@ -987,12 +989,6 @@ afsconf_LookupServer(const char *service, const char *protocol,
     if (strchr(cellName,'.'))
        pass += 2;
 
-    cellnamelength=strlen(cellName); /* _ ._ . . \0 */
-    fullnamelength=cellnamelength+strlen(protocol)+strlen(IANAname)+6;
-    dotcellname=malloc(fullnamelength);
-    if (!dotcellname)
-       return AFSCONF_NOTFOUND;        /* service not found */
-
 #ifdef HAVE_RES_RETRANSRETRY
     if ((_res.options & RES_INIT) == 0 && res_init() == -1)
       return (0);
@@ -1009,31 +1005,33 @@ afsconf_LookupServer(const char *service, const char *protocol,
     switch (pass) {
     case 0:
        dnstype = T_SRV;
-       code = snprintf(dotcellname, fullnamelength, "_%s._%s.%s.",
-                IANAname, protocol, cellName);
+       asprintf(&dotcellname, "_%s._%s.%s.", IANAname, protocol, cellName);
        break;
     case 1:
        dnstype = T_AFSDB;
-       code = snprintf(dotcellname, fullnamelength, "%s.",
-                cellName);
+       asprintf(&dotcellname, "%s.", cellName);
        break;
     case 2:
        dnstype = T_SRV;
-       code = snprintf(dotcellname, fullnamelength, "_%s._%s.%s",
-                IANAname, protocol, cellName);
+       asprintf(&dotcellname, "_%s._%s.%s", IANAname, protocol, cellName);
        break;
     case 3:
        dnstype = T_AFSDB;
-       code = snprintf(dotcellname, fullnamelength, "%s",
-                cellName);
+       asprintf(&dotcellname, "%s", cellName);
        break;
     }
-    if ((code < 0) || (code >= fullnamelength))
+    if (dotcellname == NULL)
        goto findservererror;
+
     LOCK_GLOBAL_MUTEX;
     len = res_search(dotcellname, C_IN, dnstype, answer, sizeof(answer));
     UNLOCK_GLOBAL_MUTEX;
 
+    if (dotcellname != NULL) {
+       free(dotcellname);
+       dotcellname = NULL;
+    }
+
     if (len < 0) {
        if (try_init < 1) {
            try_init++;
@@ -1177,7 +1175,6 @@ afsconf_LookupServer(const char *service, const char *protocol,
 findservererror:
     if (code && realCellName)
        free(realCellName);
-    free(dotcellname);
     return code;
 }
 
@@ -1559,6 +1556,7 @@ afsconf_CloseInternal(struct afsconf_dir *adir)
     }
 
     _afsconf_FreeAllKeys(adir);
+    _afsconf_FreeRealms(adir);
 
     /* reinit */
     memset(adir, 0, sizeof(struct afsconf_dir));