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)
#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
}
#if !defined(DJGPP)
-long cm_FreelanceMountPointExists(char * filename)
+long cm_FreelanceMountPointExists(char * filename, int prefix_ok)
{
char* cp;
char line[512];
found = 1;
break;
}
+
+ if (prefix_ok && strlen(shortname) - strlen(filename) == 1 && !strncmp(shortname, filename, strlen(filename))) {
+ found = 1;
+ break;
+ }
}
RegCloseKey(hkFreelance);
}
return found;
}
-long cm_FreelanceSymlinkExists(char * filename)
+long cm_FreelanceSymlinkExists(char * filename, int prefix_ok)
{
char* cp;
char line[512];
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];
}
#if !defined(DJGPP)
- if ( cm_FreelanceMountPointExists(filename) ||
- cm_FreelanceSymlinkExists(filename) )
+ if ( cm_FreelanceMountPointExists(filename, 0) ||
+ cm_FreelanceSymlinkExists(filename, 0) )
return -1;
#endif
}
#if !defined(DJGPP)
- if ( cm_FreelanceMountPointExists(filename) ||
- cm_FreelanceSymlinkExists(filename) )
+ if ( cm_FreelanceMountPointExists(filename, 0) ||
+ cm_FreelanceSymlinkExists(filename, 0) )
return CM_ERROR_EXISTS;
#endif
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);
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 */
for (i=0;i<len;i++) {
if(!(i%16)) {
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);
}
buf[j] = (k>32 && 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);
}
/*
* 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. */