auth: fix afsconf_GetExtendedCellInfo memory leak
[openafs.git] / src / auth / cellconfig.c
index 20547aa..5ec97bf 100644 (file)
@@ -73,10 +73,9 @@ static int TrimLine(char *abuffer, int abufsize);
 static int GetCellNT(struct afsconf_dir *adir);
 #endif
 static int GetCellUnix(struct afsconf_dir *adir);
-static int afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
-                               char clones[]);
+static int afsconf_OpenInternal(struct afsconf_dir *adir);
 static int ParseHostLine(char *aline, struct sockaddr_in *addr,
-                        char *aname, char *aclone);
+                        char *aname, char *aclone /* boolean */);
 static int ParseCellLine(char *aline, char *aname,
                         char *alname);
 static int afsconf_CloseInternal(struct afsconf_dir *adir);
@@ -349,7 +348,6 @@ _afsconf_CellServDBPath(struct afsconf_dir *adir, char **path)
 int
 _afsconf_UpToDate(struct afsconf_dir *adir)
 {
-    char *cellservDB;
     struct stat tstat;
     int code;
     time_t now = time(0);
@@ -359,12 +357,10 @@ _afsconf_UpToDate(struct afsconf_dir *adir)
     }
     adir->timeCheck = now;
 
-    _afsconf_CellServDBPath(adir, &cellservDB);
-    if (cellservDB == NULL)
+    if (adir->cellservDB == NULL)
        return 0;
 
-    code = stat(cellservDB, &tstat);
-    free(cellservDB);
+    code = stat(adir->cellservDB, &tstat);
     if (code < 0)
        return 0; /* Can't throw the error, so just say we're not up to date */
 
@@ -403,7 +399,6 @@ _afsconf_Check(struct afsconf_dir *adir)
 int
 _afsconf_Touch(struct afsconf_dir *adir)
 {
-    char *cellservDB;
     int code;
 #ifndef AFS_NT40_ENV
     struct timeval tvp[2];
@@ -412,18 +407,16 @@ _afsconf_Touch(struct afsconf_dir *adir)
     adir->timeRead = 0;                /* just in case */
     adir->timeCheck = 0;
 
-    _afsconf_CellServDBPath(adir, &cellservDB);
-    if (cellservDB == NULL)
+    if (adir->cellservDB == NULL)
        return ENOMEM;
 
 #ifdef AFS_NT40_ENV
-    code = _utime(cellservDB, NULL);
+    code = _utime(adir->cellservDB, NULL);
 #else
     gettimeofday(&tvp[0], NULL);
     tvp[1] = tvp[0];
-    code = utimes(cellservDB, tvp);
+    code = utimes(adir->cellservDB, tvp);
 #endif /* AFS_NT40_ENV */
-    free(cellservDB);
 
     return code;
 }
@@ -439,7 +432,7 @@ afsconf_Open(const char *adir)
     tdir = calloc(1, sizeof(struct afsconf_dir));
     tdir->name = strdup(adir);
 
-    code = afsconf_OpenInternal(tdir, 0, 0);
+    code = afsconf_OpenInternal(tdir);
     if (code) {
        char *afsconf_path, afs_confdir[128];
 
@@ -487,7 +480,7 @@ afsconf_Open(const char *adir)
            afsconf_path = afs_confdir;
        }
        tdir->name = strdup(afsconf_path);
-       code = afsconf_OpenInternal(tdir, 0, 0);
+       code = afsconf_OpenInternal(tdir);
        if (code) {
            free(tdir->name);
            goto fail;
@@ -615,8 +608,7 @@ cm_enumCellRegistryProc(void *rockp, char * cellNamep)
 
 
 static int
-afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
-                    char clones[])
+afsconf_OpenInternal(struct afsconf_dir *adir)
 {
     afsconf_FILE *tf;
     char *tp, *bp;
@@ -626,7 +618,6 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
     afs_int32 i;
     char tbuffer[256];
     struct stat tstat;
-    char *cellservDB;
 
 #ifdef AFS_NT40_ENV
     cm_enumCellRegistry_t enumCellRegistry = {0, 0};
@@ -652,20 +643,20 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
     /* now parse the individual lines */
     curEntry = 0;
 
-    _afsconf_CellServDBPath(adir, &cellservDB);
+    _afsconf_CellServDBPath(adir, &adir->cellservDB);
 
 #ifdef AFS_NT40_ENV
     if (_afsconf_IsClientConfigDirectory(adir->name))
         enumCellRegistry.client = 1;
 #endif /* AFS_NT40_ENV */
 
-    if (!stat(cellservDB, &tstat)) {
+    if (!stat(adir->cellservDB, &tstat)) {
        adir->timeRead = tstat.st_mtime;
     } else {
        adir->timeRead = 0;
     }
 
-    tf = fopen(cellservDB, "r");
+    tf = fopen(adir->cellservDB, "r");
     if (!tf) {
        return -1;
     }
@@ -718,18 +709,10 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
            }
            i = curEntry->cellInfo.numServers;
            if (i < MAXHOSTSPERCELL) {
-               if (cell && !strcmp(cell, curEntry->cellInfo.name))
-                   code =
-                       ParseHostLine(tbuffer,
-                                     &curEntry->cellInfo.hostAddr[i],
-                                     curEntry->cellInfo.hostName[i],
-                                     &clones[i]);
-               else
-                   code =
-                       ParseHostLine(tbuffer,
-                                     &curEntry->cellInfo.hostAddr[i],
-                                     curEntry->cellInfo.hostName[i], 0);
-
+               code = ParseHostLine(tbuffer,
+                                    &curEntry->cellInfo.hostAddr[i],
+                                    curEntry->cellInfo.hostName[i],
+                                    &curEntry->cellInfo.clone[i]);
                if (code) {
                    if (code == AFSCONF_SYNTAX) {
                        for (bp = tbuffer; *bp != '\n'; bp++) { /* Take out the <cr> from the buffer */
@@ -739,7 +722,7 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
                        *bp = '\0';
                        fprintf(stderr,
                                "Can't properly parse host line \"%s\" in configuration file %s\n",
-                               tbuffer, cellservDB);
+                               tbuffer, adir->cellservDB);
                    }
                    free(curEntry);
                    fclose(tf);
@@ -750,12 +733,11 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
            } else {
                fprintf(stderr,
                        "Too many hosts for cell %s in configuration file %s\n",
-                       curEntry->cellInfo.name, cellservDB);
+                       curEntry->cellInfo.name, adir->cellservDB);
            }
        }
     }
     fclose(tf);                        /* close the file now */
-    free(cellservDB);
 
     /* end the last partially-completed cell */
     if (curEntry) {
@@ -837,7 +819,7 @@ afsconf_OpenInternal(struct afsconf_dir *adir, char *cell,
  */
 static int
 ParseHostLine(char *aline, struct sockaddr_in *addr, char *aname,
-             char *aclone)
+             char *aclone /* boolean */)
 {
     int i;
     int c[4];
@@ -951,18 +933,15 @@ afsconf_GetExtendedCellInfo(struct afsconf_dir *adir, char *acellName,
                            char clones[])
 {
     afs_int32 code;
-    char *cell;
+    int i;
 
     code = afsconf_GetCellInfo(adir, acellName, aservice, acellInfo);
     if (code)
        return code;
 
-    if (acellName)
-       cell = acellName;
-    else
-       cell = (char *)&acellInfo->name;
-
-    code = afsconf_OpenInternal(adir, cell, clones);
+    for (i = 0; i < acellInfo->numServers; i++) {
+       clones[i] = acellInfo->clone[i];
+    }
     return code;
 }
 
@@ -1412,9 +1391,11 @@ afsconf_GetCellInfo(struct afsconf_dir *adir, char *acellName, char *aservice,
             short numServers=0;                                        /*Num active servers for the cell */
             struct sockaddr_in hostAddr[MAXHOSTSPERCELL];      /*IP addresses for cell's servers */
             char hostName[MAXHOSTSPERCELL][MAXHOSTCHARS];      /*Names for cell's servers */
+            char clone[MAXHOSTSPERCELL];                       /*Indicates which ones are clones. */
 
             memset(&hostAddr, 0, sizeof(hostAddr));
             memset(&hostName, 0, sizeof(hostName));
+            memset(&clone, 0, sizeof(clone));
 
             for ( j=0; j<acellInfo->numServers && numServers < MAXHOSTSPERCELL; j++ ) {
                 struct hostent *he = gethostbyname(acellInfo->hostName[j]);
@@ -1443,6 +1424,7 @@ afsconf_GetCellInfo(struct afsconf_dir *adir, char *acellName, char *aservice,
 #endif
                         memcpy(&hostAddr[numServers].sin_addr.s_addr, he->h_addr_list[i], sizeof(afs_uint32));
                         strcpy(hostName[numServers], acellInfo->hostName[j]);
+                        clone[numServers] = acellInfo->clone[j];
                         foundAddr = 1;
                         numServers++;
                     }
@@ -1450,6 +1432,7 @@ afsconf_GetCellInfo(struct afsconf_dir *adir, char *acellName, char *aservice,
                 if (!foundAddr) {
                     hostAddr[numServers] = acellInfo->hostAddr[j];
                     strcpy(hostName[numServers], acellInfo->hostName[j]);
+                    clone[numServers] = acellInfo->clone[j];
                     numServers++;
                 }
             }
@@ -1457,6 +1440,7 @@ afsconf_GetCellInfo(struct afsconf_dir *adir, char *acellName, char *aservice,
             for (i=0; i<numServers; i++) {
                 acellInfo->hostAddr[i] = hostAddr[i];
                 strcpy(acellInfo->hostName[i], hostName[i]);
+                acellInfo->clone[i] = clone[i];
             }
             acellInfo->numServers = numServers;
             acellInfo->flags |= AFSCONF_CELL_FLAG_DNS_QUERIED;
@@ -1567,6 +1551,8 @@ afsconf_CloseInternal(struct afsconf_dir *adir)
     /* free everything we can find */
     if (adir->cellName)
        free(adir->cellName);
+    if (adir->cellservDB)
+       free(adir->cellservDB);
     for (td = adir->entries; td; td = nd) {
        nd = td->next;
        if (td->cellInfo.linkedCell)
@@ -1594,6 +1580,6 @@ afsconf_Reopen(struct afsconf_dir *adir)
     code = afsconf_CloseInternal(adir);
     if (code)
        return code;
-    code = afsconf_OpenInternal(adir, 0, 0);
+    code = afsconf_OpenInternal(adir);
     return code;
 }