From e314167f11f289248704426fe65fea13a734a937 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 14 May 2015 18:29:45 -0400 Subject: [PATCH] Windows: cm_GetCell_Gen rework cell prefix matching The cm_GetCell_Gen() function permits cells to be searched for by prefix. The idea is to permit "cs.cmu.edu" to be abbreviated "cs" when at CMU. There are two problems with the current behavior: 1. the existing match rules will accept "cs.c" and "cs.cmu.ed" as valid prefix matches. By not restricting the prefix matching to full components the Freelance symlink list can become cluttered. 2. the existing match rules will accept the first cell that matches even if there are more than one cells that would match. this can result in unpredictable behavior since the ordering of the cells is not guaranteed. Instead, fail requests for cell prefixes that are not full component matches or that would be ambiguous. Change-Id: I59fb5ea9bba4cebdd71808fc9fae9662456943e0 Reviewed-on: http://gerrit.openafs.org/11886 Reviewed-by: Jeffrey Altman Tested-by: BuildBot --- src/WINNT/afsd/cm_cell.c | 81 ++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/src/WINNT/afsd/cm_cell.c b/src/WINNT/afsd/cm_cell.c index 7d37fedf5..149b46f9c 100644 --- a/src/WINNT/afsd/cm_cell.c +++ b/src/WINNT/afsd/cm_cell.c @@ -168,6 +168,7 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags) afs_uint32 hash; cm_cell_rock_t rock; size_t len; + size_t namelen; afs_int32 cellID; if (namep == NULL || !namep[0] || !strcmp(namep,CM_IOCTL_FILENAME_NOSLASH)) @@ -186,6 +187,7 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags) if (len == 0) return NULL; namep = name; + namelen = strlen(namep); hash = CM_CELL_NAME_HASH(namep); @@ -199,13 +201,32 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags) } if (!cp) { - for (cp = cm_data.allCellsp; cp; cp=cp->allNextp) { - if (strnicmp(namep, cp->name, strlen(namep)) == 0) { - strncpy(fullname, cp->name, CELL_MAXNAMELEN); - fullname[CELL_MAXNAMELEN-1] = '\0'; - break; - } - } + /* the name wasn't found but it might be a matching prefix */ + for (cp = cm_data.allCellsp, cp2 = NULL; cp; cp=cp->allNextp) { + if (strnicmp(namep, cp->name, namelen) == 0 + && (namelen == strlen(cp->name) || cp->name[namelen] == '.')) { + if (cp2 != NULL) { + osi_Log5(afsd_logp, + "cm_GetCell_gen ambiguous prefix match: prefix %s matches (%u) %s and (%u) %s", + osi_LogSaveString(afsd_logp,namep), + cp->cellID, + osi_LogSaveString(afsd_logp,cp->name), + cp2->cellID, + osi_LogSaveString(afsd_logp,cp2->name)); + cp = NULL; + lock_ReleaseRead(&cm_cellLock); + goto done; + } + cp2 = cp; + } + } + + if (cp2 != NULL) { + /* an unambiguous prefix match was found */ + cp = cp2; + strncpy(fullname, cp->name, CELL_MAXNAMELEN); + fullname[CELL_MAXNAMELEN-1] = '\0'; + } } if (cp) { @@ -222,30 +243,36 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags) if (cm_stricmp_utf8(namep, cp->name) == 0) { strncpy(fullname, cp->name, CELL_MAXNAMELEN); fullname[CELL_MAXNAMELEN-1] = '\0'; - break; + goto done; } } - if (cp) - goto done; - - for (cp = cm_data.allCellsp; cp; cp=cp->allNextp) { - if (strnicmp(namep, cp->name, strlen(namep)) == 0) { - strncpy(fullname, cp->name, CELL_MAXNAMELEN); - fullname[CELL_MAXNAMELEN-1] = '\0'; - break; - } - } + /* the name wasn't found but it might be a matching prefix */ + for (cp = cm_data.allCellsp, cp2 = NULL; cp; cp=cp->allNextp) { + if (strnicmp(namep, cp->name, namelen) == 0 + && (namelen == strlen(cp->name) || cp->name[namelen] == '.')) { + if (cp2 != NULL) { + osi_Log5(afsd_logp, + "cm_GetCell_gen ambiguous prefix match: prefix %s matches (%u) %s and (%u) %s", + osi_LogSaveString(afsd_logp,namep), + cp->cellID, + osi_LogSaveString(afsd_logp,cp->name), + cp2->cellID, + osi_LogSaveString(afsd_logp,cp2->name)); + cp = NULL; + goto done; + } + cp2 = cp; + } + } - if (cp) { - lock_ReleaseWrite(&cm_cellLock); - lock_ObtainMutex(&cp->mx); - lock_ObtainWrite(&cm_cellLock); - cm_AddCellToNameHashTable(cp); - cm_AddCellToIDHashTable(cp); - lock_ReleaseMutex(&cp->mx); - goto done; - } + if (cp2 != NULL) { + /* an unambiguous prefix match was found */ + cp = cp2; + strncpy(fullname, cp->name, CELL_MAXNAMELEN); + fullname[CELL_MAXNAMELEN-1] = '\0'; + goto done; + } if ( cm_data.freeCellsp != NULL ) { cp = cm_data.freeCellsp; -- 2.39.5