windows-linked-cells-20081103
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 3 Nov 2008 19:55:38 +0000 (19:55 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 3 Nov 2008 19:55:38 +0000 (19:55 +0000)
LICENSE MIT
FIXES 123571

The Windows code base was implemented ignorant of linked cells as
defined in the src/auth/cellconfig.h struct afsconf_cell.  The code
that made use of the afsconf_cell objects would leak the memory from
the linkedCell field if is non-NULL.

Add cm_SearchCellFileEx which is an extended version of cm_SearchCellFile
capable of returning a linked cell obtained from the CellServDB file.

Update GetCellConfig to populate the linkedCell field of the afsconf_cell
structure.

Modify cm_cell_t to support a linked cell name.

Modify cm_GetCell_Gen() to populate the cm_cell_t linked cell and enforce
that two cells are linked to each other.

Modify cm_GetVolumeByID() and cm_GetVolumeByName() to perform fallback
to the linked cell if the response is CM_ERROR_NOSUCHVOLUME.

12 files changed:
src/WINNT/afsd/afskfw.c
src/WINNT/afsd/cm_cell.c
src/WINNT/afsd/cm_cell.h
src/WINNT/afsd/cm_config.c
src/WINNT/afsd/cm_config.h
src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_volume.c
src/WINNT/afsd/cm_volume.h
src/WINNT/afsd/fs.c
src/WINNT/afsd/libafsconf.def
src/WINNT/client_creds/ipaddrchg.c
src/WINNT/netidmgr_plugin/afsfuncs.c

index 8b53df9..f0b024f 100644 (file)
@@ -1341,6 +1341,8 @@ KFW_AFS_get_cred( char * username,
         OutputDebugString("\n");
     }
 
+    memset(&cellconfig, 0, sizeof(cellconfig));
+
     code = pkrb5_init_context(&ctx);
     if ( code ) goto cleanup;
 
@@ -1446,6 +1448,11 @@ KFW_AFS_get_cred( char * username,
                     sprintf(message,"found another cell for the same principal: %s\n",cell);
                     OutputDebugString(message);
                 }
+
+                if (cellconfig.linkedCell) {
+                    free(cellconfig.linkedCell);
+                    cellconfig.linkedCell = NULL;
+                }
                 code = KFW_AFS_get_cellconfig( cells[cell_count], (void*)&cellconfig, local_cell);
                 if ( code ) continue;
     
@@ -1476,6 +1483,8 @@ KFW_AFS_get_cred( char * username,
         free(pname);
     if ( cc )
         pkrb5_cc_close(ctx, cc);
+    if ( cellconfig.linkedCell )
+        free(cellconfig.linkedCell);
 
     if ( code && reasonP ) {
         *reasonP = (char *)perror_message(code);
@@ -1627,6 +1636,8 @@ KFW_AFS_renew_expiring_tokens(void)
         OutputDebugString("KFW_AFS_renew_expiring_tokens\n");
     }
 
+    memset(&cellconfig, 0, sizeof(cellconfig));
+
     code = pkrb5_init_context(&ctx);
     if (code) goto cleanup;
 
@@ -1668,6 +1679,10 @@ KFW_AFS_renew_expiring_tokens(void)
                         OutputDebugString(cells[cell_count]);
                         OutputDebugString("\n");
                     }
+                    if (cellconfig.linkedCell) {
+                        free(cellconfig.linkedCell);
+                        cellconfig.linkedCell = NULL;
+                    }
                     code = KFW_AFS_get_cellconfig( cells[cell_count], (void*)&cellconfig, local_cell);
                     if ( code ) continue;
                     realm = afs_realm_of_cell(ctx, &cellconfig);  // do not free
@@ -1700,6 +1715,8 @@ KFW_AFS_renew_expiring_tokens(void)
         pkrb5_cc_close(ctx,cc);
     if ( ctx )
         pkrb5_free_context(ctx);
+    if (cellconfig.linkedCell)
+        free(cellconfig.linkedCell);
 
     return 0;
 }
@@ -1744,6 +1761,8 @@ KFW_AFS_renew_token_for_cell(char * cell)
         struct afsconf_cell cellconfig;
         char local_cell[CELL_MAXNAMELEN+1];
 
+        memset(&cellconfig, 0, sizeof(cellconfig));
+
         while ( count-- ) {
             code = pkrb5_parse_name(ctx, principals[count], &princ);
             if (code) goto loop_cleanup;
@@ -1751,6 +1770,10 @@ KFW_AFS_renew_token_for_cell(char * cell)
             code = KFW_get_ccache(ctx, princ, &cc);
             if (code) goto loop_cleanup;
 
+            if (cellconfig.linkedCell) {
+                free(cellconfig.linkedCell);
+                cellconfig.linkedCell = NULL;
+            }
             code = KFW_AFS_get_cellconfig( cell, (void*)&cellconfig, local_cell);
             if ( code ) goto loop_cleanup;
 
@@ -1814,6 +1837,10 @@ KFW_AFS_renew_token_for_cell(char * cell)
                 pkrb5_free_principal(ctx, service);
                 princ = 0;
             }
+            if (cellconfig.linkedCell) {
+                free(cellconfig.linkedCell);
+                cellconfig.linkedCell = NULL;
+            }
 
             KFW_AFS_update_cell_princ_map(ctx, cell, principals[count], code ? FALSE : TRUE);
             free(principals[count]);
@@ -1824,7 +1851,7 @@ KFW_AFS_renew_token_for_cell(char * cell)
 
   cleanup:
     if (ctx) 
-               pkrb5_free_context(ctx);
+        pkrb5_free_context(ctx);
     return (code ? FALSE : TRUE);
 
 }
@@ -2810,6 +2837,7 @@ KFW_AFS_klog(
     if (!pkrb5_init_context)
         return 0;
 
+    memset(&ak_cellconfig, 0, sizeof(ak_cellconfig));
     memset(RealmName, '\0', sizeof(RealmName));
     memset(CellName, '\0', sizeof(CellName));
     memset(ServiceName, '\0', sizeof(ServiceName));
@@ -3318,6 +3346,8 @@ KFW_AFS_klog(
         pkrb5_cc_close(ctx, cc);
     if (ctx && (ctx != alt_ctx))
         pkrb5_free_context(ctx);
+    if (ak_cellconfig.linkedCell)
+        free(ak_cellconfig.linkedCell);
 
     return(rc? rc : code);
 }
@@ -3365,6 +3395,7 @@ KFW_AFS_get_cellconfig(char *cell, struct afsconf_cell *cellconfig, char *local_
 {
     int        rc;
     char newcell[CELL_MAXNAMELEN+1];
+    char linkedcell[CELL_MAXNAMELEN+1]="";
 
     local_cell[0] = (char)0;
     memset(cellconfig, 0, sizeof(*cellconfig));
@@ -3379,15 +3410,19 @@ KFW_AFS_get_cellconfig(char *cell, struct afsconf_cell *cellconfig, char *local_
         strcpy(cell, local_cell);
 
     /* WIN32: cm_SearchCellFile(cell, pcallback, pdata) */
-    strcpy(cellconfig->name, cell);
-
-    rc = cm_SearchCellFile(cell, newcell, get_cellconfig_callback, (void*)cellconfig);
+    rc = cm_SearchCellFileEx(cell, newcell, linkedcell, get_cellconfig_callback, (void*)cellconfig);
 #ifdef AFS_AFSDB_ENV
     if (rc != 0) {
         int ttl;
         rc = cm_SearchCellByDNS(cell, newcell, &ttl, get_cellconfig_callback, (void*)cellconfig);
     }
 #endif
+
+    if (rc == 0) {
+        strcpy(cellconfig->name, newcell);
+        if (linkedcell[0])
+            cellconfig->linkedCell = strdup(linkedcell);
+    }
     return rc;
 }
 
index 7047606..7bf3055 100644 (file)
@@ -99,7 +99,7 @@ cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags)
 
         rock.cellp = cp;
         rock.flags = flags;
-        code = cm_SearchCellFile(cp->name, NULL, cm_AddCellProc, &rock);
+        code = cm_SearchCellFileEx(cp->name, NULL, cp->linkedName, cm_AddCellProc, &rock);
         if (code == 0) {
             lock_ObtainMutex(&cp->mx);
            cp->timeout = time(0) + 7200;
@@ -158,6 +158,7 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
     cm_cell_t *cp, *cp2;
     long code;
     char fullname[CELL_MAXNAMELEN]="";
+    char linkedName[CELL_MAXNAMELEN]="";
     char name[CELL_MAXNAMELEN]="";
     int  hasWriteLock = 0;
     int  hasMutex = 0;
@@ -270,10 +271,11 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
 
         rock.cellp = cp;
         rock.flags = flags;
-        code = cm_SearchCellFile(namep, fullname, cm_AddCellProc, &rock);
+        code = cm_SearchCellFileEx(namep, fullname, linkedName, cm_AddCellProc, &rock);
         if (code) {
-            osi_Log3(afsd_logp,"in cm_GetCell_gen cm_SearchCellFile(%s) returns code= %d fullname= %s", 
-                      osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname));
+            osi_Log4(afsd_logp,"in cm_GetCell_gen cm_SearchCellFileEx(%s) returns code= %d fullname= %s linkedName= %s", 
+                      osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname),
+                      osi_LogSaveString(afsd_logp,linkedName));
 
 #ifdef AFS_AFSDB_ENV
             if (cm_dnsEnabled) {
@@ -338,6 +340,9 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
         strncpy(cp->name, fullname, CELL_MAXNAMELEN);
         cp->name[CELL_MAXNAMELEN-1] = '\0';
 
+        strncpy(cp->linkedName, linkedName, CELL_MAXNAMELEN);
+        cp->linkedName[CELL_MAXNAMELEN-1] = '\0';
+
         cm_AddCellToNameHashTable(cp);
         cm_AddCellToIDHashTable(cp);           
         lock_ReleaseMutex(&cp->mx);
@@ -371,6 +376,26 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
             newnamep[0] = '\0';
         }
     }
+
+    if (cp && cp->linkedName[0]) {
+        cm_cell_t * linkedCellp = NULL;
+        
+        if (!strcmp(cp->name, cp->linkedName)) {
+            cp->linkedName[0] = '\0'; 
+        } else if (!(flags & CM_FLAG_NOMOUNTCHASE)) {
+            linkedCellp = cm_GetCell(cp->linkedName, CM_FLAG_CREATE|CM_FLAG_NOPROBE|CM_FLAG_NOMOUNTCHASE);
+
+            lock_ObtainWrite(&cm_cellLock);
+            if (!linkedCellp || 
+                (linkedCellp->linkedName[0] && strcmp(cp->name, linkedCellp->linkedName))) {
+                cp->linkedName[0] = '\0';
+            } else {
+                strncpy(linkedCellp->linkedName, cp->name, CELL_MAXNAMELEN);
+                linkedCellp->linkedName[CELL_MAXNAMELEN-1]='\0';
+            }
+            lock_ReleaseWrite(&cm_cellLock);
+        }
+    }
     return cp;
 }
 
index a5249f0..56fcfdc 100644 (file)
@@ -27,6 +27,7 @@ typedef struct cm_cell {
     osi_mutex_t mx;                    /* mutex locking fields (flags) */
     long flags;                                /* locked by mx */
     time_t timeout;                     /* if dns, time at which the server addrs expire (mx) */
+    char linkedName[CELL_MAXNAMELEN];   /* linked cell name; cm_cellLock */
 } cm_cell_t;
 
 /* These are bit flag values */
index 1c11f48..5fbaf70 100644 (file)
@@ -112,14 +112,24 @@ IsWindowsModule(const char * name)
  * newCellNamep.  Anomaly:  if cellNamep is ambiguous, we may modify
  * newCellNamep but return an error code.
  *
- * newCellNamep is required to be CELL_MAXNAMELEN in size.
+ * Linked Cells: the CellServDB format permits linked cells
+ *   >cell [linked-cell] #Description
+ *
+ * newCellNamep and linkedNamep are required to be CELL_MAXNAMELEN in size.
  */
 long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
                        cm_configProc_t *procp, void *rockp)
 {
+    return cm_SearchCellFileEx(cellNamep, newCellNamep, NULL, procp, rockp);
+}
+
+long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
+                         char *linkedNamep,
+                         cm_configProc_t *procp, void *rockp)
+{
     char wdir[MAX_PATH]="";
     FILE *tfilep = NULL, *bestp, *tempp;
-    char *tp;
+    char *tp, *linkp;
     char lineBuffer[257];
     struct hostent *thp;
     char *valuep;
@@ -147,6 +157,7 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
 #endif
     /* have we seen the cell line for the guy we're looking for? */
     while (1) {
+        linkp = NULL;
         tp = fgets(lineBuffer, sizeof(lineBuffer), tfilep);
         if (tracking)
            (void) fgets(lineBuffer, sizeof(lineBuffer), bestp);
@@ -182,6 +193,11 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
        /* skip blank lines */
         if (lineBuffer[0] == 0) continue;
 
+        /*
+         * The format is:
+         *   >[cell] [linked-cell] #[Description]
+         * where linked-cell and Description are optional
+         */
         if (lineBuffer[0] == '>') {
             if (inRightCell) {
                 fclose(tfilep);
@@ -189,13 +205,21 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
                 return(foundCell ? 0 : -6);
             }
 
-           /* trim off at white space or '#' chars */
-            tp = strchr(lineBuffer, ' ');
-            if (tp) *tp = 0;
-            tp = strchr(lineBuffer, '\t');
-            if (tp) *tp = 0;
-            tp = strchr(lineBuffer, '#');
-            if (tp) *tp = 0;
+            /* 
+             * terminate the cellname at the first white space
+             * leaving 'tp' pointing to the next string if any
+             */
+            for (tp = &lineBuffer[1]; tp && !isspace(*tp); tp++);
+            if (tp) {
+                *tp = '\0';
+                for (tp++ ;tp && isspace(*tp); tp++);
+                if (*tp != '#') {
+                    linkp = tp;
+                    for (; tp && !isspace(*tp); tp++);
+                    if (tp) 
+                        *tp = '\0';
+                }
+            }
 
            /* now see if this is the right cell */
             if (stricmp(lineBuffer+1, cellNamep) == 0) {
@@ -205,6 +229,11 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
                     newCellNamep[CELL_MAXNAMELEN-1] = '\0';
                     strlwr(newCellNamep);
                 }
+                if (linkedNamep) {
+                    strncpy(linkedNamep, linkp ? linkp : "", CELL_MAXNAMELEN);
+                    linkedNamep[CELL_MAXNAMELEN-1] = '\0';
+                    strlwr(linkedNamep);
+                }
                 inRightCell = 1;
                tracking = 0;
 #ifdef CELLSERV_DEBUG                
@@ -224,6 +253,11 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
                     newCellNamep[CELL_MAXNAMELEN-1] = '\0';
                     strlwr(newCellNamep);
                 }
+                if (linkedNamep) {
+                    strncpy(linkedNamep, linkp ? linkp : "", CELL_MAXNAMELEN);
+                    linkedNamep[CELL_MAXNAMELEN-1] = '\0';
+                    strlwr(linkedNamep);
+                }
                inRightCell = 0;
                tracking = 0;
                partial = 1;
index d640af7..c6fb5ab 100644 (file)
@@ -31,10 +31,14 @@ typedef long (cm_configProc_t)(void *rockp, struct sockaddr_in *addrp, char *nam
 extern long cm_GetRootCellName(char *namep);
 
 extern long cm_SearchCellFile(char *cellNamep, char *newCellNamep,
-       cm_configProc_t *procp, void *rockp);
+                              cm_configProc_t *procp, void *rockp);
+
+extern long cm_SearchCellFileEx(char *cellNamep, char *newCellNamep,
+                                char *linkedNamep,
+                                cm_configProc_t *procp, void *rockp);
 
 extern long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
-               cm_configProc_t *procp, void *rockp);
+                               cm_configProc_t *procp, void *rockp);
 
 extern long cm_WriteConfigString(char *labelp, char *valuep);
 
index 08eb06b..613dba5 100644 (file)
@@ -1404,7 +1404,7 @@ cm_IoctlNewCell(struct cm_ioctl *ioctlp, struct cm_user *userp)
 
         rock.cellp = cp;
         rock.flags = 0;
-        code = cm_SearchCellFile(cp->name, cp->name, cm_AddCellProc, &rock);
+        code = cm_SearchCellFileEx(cp->name, cp->name, cp->linkedName, cm_AddCellProc, &rock);
 #ifdef AFS_AFSDB_ENV
         if (code) {
             if (cm_dnsEnabled) {
@@ -2157,6 +2157,7 @@ cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
     int i;
     char * p, * r;
 
+    memset(&info, 0, sizeof(info));
     tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
     code = afsconf_GetCellInfo(tdir, ucellp->cellp->name, "afsprot", &info);
     afsconf_Close(tdir);
@@ -2182,6 +2183,8 @@ cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
 
     code = ubik_ClientInit(serverconns, &pruclient);
     if (code) {
+        if (info.linkedCell)
+            free(info.linkedCell);
        return code;
     }
 
@@ -2215,6 +2218,8 @@ cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
        pruclient = NULL;
     }
 
+    if (info.linkedCell)
+        free(info.linkedCell);
     return 0;
 }
 #endif /* QUERY_AFSID */
index 7d23c0a..dfee587 100644 (file)
@@ -750,7 +750,15 @@ long cm_FindVolumeByID(cm_cell_t *cellp, afs_uint32 volumeID, cm_user_t *userp,
     /* otherwise, we didn't find it so consult the VLDB */
     sprintf(volNameString, "%u", volumeID);
     code = cm_FindVolumeByName(cellp, volNameString, userp, reqp,
-                             flags, outVolpp);
+                             flags | CM_GETVOL_FLAG_IGNORE_LINKED_CELL, outVolpp);
+
+    if (code == CM_ERROR_NOSUCHVOLUME && cellp->linkedName[0] && 
+        !(flags & CM_GETVOL_FLAG_IGNORE_LINKED_CELL)) {
+        cm_cell_t *linkedCellp = cm_GetCell(cellp->linkedName, flags);
+
+        if (linkedCellp)
+            code = cm_FindVolumeByID(linkedCellp, volumeID, userp, reqp, flags, outVolpp);
+    }
     return code;
 }
 
@@ -920,6 +928,14 @@ long cm_FindVolumeByName(struct cm_cell *cellp, char *volumeNamep,
         cm_PutVolume(volp);
         lock_ReleaseRead(&cm_volumeLock);
     }
+
+    if (code == CM_ERROR_NOSUCHVOLUME && cellp->linkedName[0] && 
+        !(flags & CM_GETVOL_FLAG_IGNORE_LINKED_CELL)) {
+        cm_cell_t *linkedCellp = cm_GetCell(cellp->linkedName, flags);
+
+        if (linkedCellp)
+            code = cm_FindVolumeByName(linkedCellp, volumeNamep, userp, reqp, flags, outVolpp);
+    }
     return code;
 }      
 
index b32d72e..aae0c3e 100644 (file)
@@ -69,6 +69,7 @@ extern long cm_FindVolumeByID(struct cm_cell *cellp, afs_uint32 volumeID,
 #define CM_GETVOL_FLAG_CREATE               1
 #define CM_GETVOL_FLAG_NO_LRU_UPDATE        2
 #define CM_GETVOL_FLAG_NO_RESET                    4
+#define CM_GETVOL_FLAG_IGNORE_LINKED_CELL   8
 
 /* hash define.  Must not include the cell, since the callback revocation code
  * doesn't necessarily know the cell in the case of a multihomed server
index ce24c51..0e78fb7 100644 (file)
@@ -2027,6 +2027,8 @@ MakeMountCmd(struct cmd_syndesc *as, void *arock)
     struct ViceIoctl blob;
     char * parent;
 
+    memset(&info, 0, sizeof(info));
+
     if (as->parms[2].items)    /* cell name specified */
        cellName = as->parms[2].items->data;
     else
@@ -2145,6 +2147,10 @@ MakeMountCmd(struct cmd_syndesc *as, void *arock)
 #else /* not WIN32 */
     code = symlink(space, path);
 #endif /* not WIN32 */
+
+    if (info.linkedCell)
+        free(info.linkedCell);
+
     if (code) {
        Die(errno, path);
        return 1;
@@ -2245,6 +2251,7 @@ CheckServersCmd(struct cmd_syndesc *as, void *arock)
     struct afsconf_cell info;
     struct chservinfo checkserv;
 
+    memset(&info, 0, sizeof(info));
     memset(&checkserv, 0, sizeof(struct chservinfo));
     blob.in_size=sizeof(struct chservinfo);
     blob.in=(caddr_t)&checkserv;
@@ -2271,6 +2278,8 @@ CheckServersCmd(struct cmd_syndesc *as, void *arock)
        }
        strcpy(checkserv.tbuffer,info.name);
        checkserv.tsize=(int)strlen(info.name)+1;
+        if (info.linkedCell)
+            free(info.linkedCell);
     } else {
         strcpy(checkserv.tbuffer,"\0");
         checkserv.tsize=0;
@@ -3077,6 +3086,7 @@ GetCellCmd(struct cmd_syndesc *as, void *arock)
     } args;
     int error = 0;
 
+    memset(&info, 0, sizeof(info));
     memset(&args, 0, sizeof(args));      /* avoid Purify UMR error */
     for(ti=as->parms[0].items; ti; ti=ti->next) {
        /* once per cell */
@@ -3087,6 +3097,8 @@ GetCellCmd(struct cmd_syndesc *as, void *arock)
             error = 1;
            continue;
        }
+        if (info.linkedCell)
+            free(info.linkedCell);
        blob.in_size = 1+(long)strlen(info.name);
        blob.in = info.name;
        code = pioctl_utf8(0, VIOC_GETCELLSTATUS, &blob, 1);
@@ -3127,6 +3139,8 @@ static int SetCellCmd(struct cmd_syndesc *as, void *arock)
     } args;
     int error = 0;
 
+    memset(&info, 0, sizeof(info));
+
     /* Check arguments. */
     if (as->parms[1].items && as->parms[2].items) {
         fprintf(stderr, "Cannot specify both -suid and -nosuid.\n");
@@ -3160,6 +3174,8 @@ static int SetCellCmd(struct cmd_syndesc *as, void *arock)
             error = 1;
            continue;
        }
+        if (info.linkedCell)
+            free(info.linkedCell);
        strcpy(args.cname, info.name);
        blob.in_size = sizeof(args);
        blob.in = (caddr_t) &args;
index 75590c9..e5d8b40 100644 (file)
@@ -24,3 +24,4 @@ EXPORTS
         afs_uuid_create                 @17
         afs_uuid_equal                  @18
         cm_GetCellServDB                @19
+       cm_SearchCellFileEx             @20
index 381c509..d9286c4 100644 (file)
@@ -177,7 +177,7 @@ pingCell(char *cell)
     pp.host.retry = 0;
     pp.verbose = 1;
 
-    /* WIN32: cm_SearchCellFile(cell, pcallback, pdata) */
+    /* WIN32: cm_SearchCellFile(cell, newcell, linkedCell, pcallback, pdata) */
     rc = pcm_SearchCellFile(cell, newcell, pingFS, (void *)&pp);
 }
 #endif /* USE_FSPROBE */
index 15abc69..c0b856c 100644 (file)
@@ -763,6 +763,7 @@ afs_klog(khm_handle identity,
     if ( !cell )    cell = "";
     if ( !service ) service = "";
 
+    memset(&ak_cellconfig, 0, sizeof(ak_cellconfig));
     memset(RealmName, '\0', sizeof(RealmName));
     memset(CellName, '\0', sizeof(CellName));
     memset(ServiceName, '\0', sizeof(ServiceName));
@@ -1061,7 +1062,8 @@ afs_klog(khm_handle identity,
 
             _reportf(L"Same token already exists");
             
-            return 0;
+            rc = 0;
+            goto cleanup;
         }
 
         // * Reset the "aclient" structure before we call ktc_SetToken.
@@ -1105,7 +1107,7 @@ afs_klog(khm_handle identity,
             if (context)
                 pkrb5_free_context(context);
             
-            return 0;
+            goto cleanup;
         }
 
         _reportf(L"SetToken returns code %d", rc);
@@ -1238,7 +1240,8 @@ afs_klog(khm_handle identity,
             !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen)) {
 
             /* success! */
-            return(0);
+            rc = 0;
+            goto cleanup;
         }
 
         // Reset the "aclient" structure before we call ktc_SetToken.
@@ -1263,7 +1266,7 @@ afs_klog(khm_handle identity,
 
         if (rc = ktc_SetToken(&aserver, &atoken, &aclient, 0)) {
             afs_report_error(rc, "ktc_SetToken()");
-            return(rc);
+            goto cleanup;
         }
     } else if (method == AFS_TOKEN_AUTO ||
                method >= AFS_TOKEN_USER) {
@@ -1293,6 +1296,10 @@ afs_klog(khm_handle identity,
         }
     }
 
+  cleanup:
+    if (ak_cellconfig.linkedCell)
+        free(ak_cellconfig.linkedCell);
+
     return rc;
 }
 
@@ -1384,7 +1391,7 @@ afs_get_cellconfig(char *cell, afs_conf_cell *cellconfig, char *local_cell)
     if (strlen(cell) == 0)
         StringCbCopyA(cell, (MAXCELLCHARS+1) * sizeof(char), local_cell);
 
-    /* WIN32: cm_SearchCellFile(cell, pcallback, pdata) */
+    /* WIN32: cm_SearchCellFile(cell, newcell, pcallback, pdata) */
     StringCbCopyA(cellconfig->name, (MAXCELLCHARS+1) * sizeof(char), cell);
 
     rc = cm_SearchCellFile(cell, NULL, afs_get_cellconfig_callback, 
@@ -1592,12 +1599,15 @@ afs_check_for_cell_realm_match(khm_handle identity, char * cell) {
     int rc;
 
     ZeroMemory(local_cell, sizeof(local_cell));
+    ZeroMemory(&cellconfig, sizeof(cellconfig));
 
     rc = afs_get_cellconfig(cell, &cellconfig, local_cell);
     if (rc)
         return FALSE;
 
     realm = afs_realm_of_cell(&cellconfig, FALSE);
+    if (cellconfig.linkedCell)
+        free(cellconfig.linkedCell);
     if (realm == NULL)
         return FALSE;