From: Jeffrey Altman Date: Mon, 28 Jan 2008 07:23:35 +0000 (+0000) Subject: DEVEL15-windows-freelance-improved-dfs-handling-20080127 X-Git-Tag: openafs-devel-1_5_31~63 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=baa645b73da08c587615ef3f319bb199dde6c415;hp=fad6f22197226bc71f5bc502f5f3e61acc9e6f06 DEVEL15-windows-freelance-improved-dfs-handling-20080127 LICENSE MIT Cell names are published as share names. As a result they are searched for as part of the Dfs Referral evaluation. If share "foo" can not be reached, the CIFS client will fallback to searching for "fo" as well. Since the freelance client automatically adds a symlink for prefixes of the cell name, this results in both "foo" and "fo" being added to the freelance root.afs volume. This patch prevents that negative side effect. (cherry picked from commit 36bdf1ccd859fb0039d8ae9abd04f9eea08d704d) --- diff --git a/src/WINNT/afsd/cm.h b/src/WINNT/afsd/cm.h index 65676fb..c17d987 100644 --- a/src/WINNT/afsd/cm.h +++ b/src/WINNT/afsd/cm.h @@ -246,6 +246,7 @@ int RXAFS_Lookup (struct rx_connection *, #define CM_FLAG_DIRSEARCH 0x40 /* for directory search */ #define CM_FLAG_CHECKPATH 0x80 /* Path instead of File */ #define CM_FLAG_NOPROBE 0x100 /* For use with cm_GetCellxxx - do not probe server status */ +#define CM_FLAG_DFS_REFERRAL 0x200 /* The request is a DFS Referral - the last char of the lookup name may be missing */ /* error codes */ #define CM_ERROR_BASE 0x66543200 diff --git a/src/WINNT/afsd/cm_freelance.c b/src/WINNT/afsd/cm_freelance.c index 3b2651c..507e4d1 100644 --- a/src/WINNT/afsd/cm_freelance.c +++ b/src/WINNT/afsd/cm_freelance.c @@ -821,7 +821,7 @@ int cm_getNoLocalMountPoints() { } #if !defined(DJGPP) -long cm_FreelanceMountPointExists(char * filename) +long cm_FreelanceMountPointExists(char * filename, int prefix_ok) { char* cp; char line[512]; @@ -889,6 +889,11 @@ long cm_FreelanceMountPointExists(char * filename) found = 1; break; } + + if (prefix_ok && strlen(shortname) - strlen(filename) == 1 && !strncmp(shortname, filename, strlen(filename))) { + found = 1; + break; + } } RegCloseKey(hkFreelance); } @@ -898,7 +903,7 @@ long cm_FreelanceMountPointExists(char * filename) return found; } -long cm_FreelanceSymlinkExists(char * filename) +long cm_FreelanceSymlinkExists(char * filename, int prefix_ok) { char* cp; char line[512]; @@ -946,6 +951,11 @@ long cm_FreelanceSymlinkExists(char * filename) found = 1; break; } + + if (prefix_ok && strlen(shortname) - strlen(filename) == 1 && !strncmp(shortname, filename, strlen(filename))) { + found = 1; + break; + } } for ( dwIndex = 0; dwIndex < dwSymlinks; dwIndex++ ) { TCHAR szValueName[16]; @@ -1009,8 +1019,8 @@ long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, } #if !defined(DJGPP) - if ( cm_FreelanceMountPointExists(filename) || - cm_FreelanceSymlinkExists(filename) ) + if ( cm_FreelanceMountPointExists(filename, 0) || + cm_FreelanceSymlinkExists(filename, 0) ) return -1; #endif @@ -1246,8 +1256,8 @@ long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp) } #if !defined(DJGPP) - if ( cm_FreelanceMountPointExists(filename) || - cm_FreelanceSymlinkExists(filename) ) + if ( cm_FreelanceMountPointExists(filename, 0) || + cm_FreelanceSymlinkExists(filename, 0) ) return CM_ERROR_EXISTS; #endif diff --git a/src/WINNT/afsd/cm_freelance.h b/src/WINNT/afsd/cm_freelance.h index 2cebe49..9f327fa 100644 --- a/src/WINNT/afsd/cm_freelance.h +++ b/src/WINNT/afsd/cm_freelance.h @@ -19,6 +19,8 @@ extern long cm_FreelanceRemoveMount(char *toremove); extern long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, cm_fid_t *fidp); extern long cm_FreelanceRemoveSymlink(char *toremove); extern long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp); +extern long cm_FreelanceMountPointExists(char * filename, int prefix_ok); +extern long cm_FreelanceSymlinkExists(char * filename, int prefix_ok); extern int cm_clearLocalMountPointChange(); extern int cm_FakeRootFid(cm_fid_t *fidp); diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 7bc7c56..136e0ba 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -1290,21 +1290,29 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us osi_Log1(afsd_logp,"cm_Lookup adding mount for non-existent directory: %s", osi_LogSaveString(afsd_logp,namep)); + + /* + * There is an ugly behavior where a share name "foo" will be searched + * for as "fo". If the searched for name differs by an already existing + * symlink or mount point in the Freelance directory, do not add the + * new value automatically. + */ + if (namep[0] == '.') { if (cm_GetCell_Gen(&namep[1], &fullname[1], CM_FLAG_CREATE)) { found = 1; - if ( stricmp(&namep[1], &fullname[1]) ) + if (!cm_FreelanceMountPointExists(fullname, 0)) + code = cm_FreelanceAddMount(fullname, &fullname[1], "root.cell.", 1, &rock.fid); + if ( stricmp(&namep[1], &fullname[1]) && !cm_FreelanceSymlinkExists(namep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0)) code = cm_FreelanceAddSymlink(namep, fullname, &rock.fid); - else - code = cm_FreelanceAddMount(namep, &fullname[1], "root.cell.", 1, &rock.fid); } } else { if (cm_GetCell_Gen(namep, fullname, CM_FLAG_CREATE)) { found = 1; - if ( stricmp(namep, fullname) ) + if (!cm_FreelanceMountPointExists(fullname, 0)) + code = cm_FreelanceAddMount(fullname, fullname, "root.cell.", 0, &rock.fid); + if ( stricmp(namep, fullname) && !cm_FreelanceSymlinkExists(namep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0)) code = cm_FreelanceAddSymlink(namep, fullname, &rock.fid); - else - code = cm_FreelanceAddMount(namep, fullname, "root.cell.", 0, &rock.fid); } } if (!found || code < 0) { /* add mount point failed, so give up */ diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 41a914f..3523aca 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -170,7 +170,7 @@ void OutputDebugHexDump(unsigned char * buffer, int len) { for (i=0;i32 && k<127)?k:'.'; } if(i) { - osi_Log0(smb_logp, "%s", osi_LogSaveString(smb_logp, buf)); + osi_Log1(smb_logp, "%s", osi_LogSaveString(smb_logp, buf)); strcat(buf,"\r\n"); OutputDebugString(buf); } @@ -3640,9 +3640,13 @@ smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* * We have a requested path. Check to see if it is something * we know about. + * + * But be careful because the name that we might be searching + * for might be a known name with the final character stripped + * off. If we */ code = cm_NameI(cm_data.rootSCachep, &requestFileName[nbnLen+2], - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD | CM_FLAG_DFS_REFERRAL, userp, NULL, &req, &scp); if (code == 0) { /* Yes it is. */