summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/statcache.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c
index 0d55c22f7a..593df745cc 100644
--- a/source3/smbd/statcache.c
+++ b/source3/smbd/statcache.c
@@ -198,6 +198,8 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
size_t namelen;
hash_element *hash_elem;
char *sp;
+ BOOL sizechanged = False;
+ unsigned int num_components = 0;
if (!lp_stat_cache())
return False;
@@ -217,8 +219,17 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
}
pstrcpy(chk_name, name);
- if(!case_sensitive)
+
+ if(!case_sensitive) {
strupper( chk_name );
+ /*
+ * In some language encodings the length changes
+ * if we uppercase. We need to treat this differently
+ * below.
+ */
+ if (strlen(chk_name) != namelen)
+ sizechanged = True;
+ }
while (1) {
hash_elem = hash_lookup(&stat_cache, chk_name);
@@ -229,6 +240,13 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
sp = strrchr_m(chk_name, '/');
if (sp) {
*sp = '\0';
+ /*
+ * Count the number of times we have done this,
+ * we'll need it when reconstructing the string.
+ */
+ if (sizechanged)
+ num_components++;
+
} else {
/*
* We reached the end of the name - no match.
@@ -249,7 +267,20 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
hash_remove(&stat_cache, hash_elem);
return False;
}
- memcpy(name, scp->translated_path, MIN(sizeof(pstring)-1, scp->translated_path_length));
+
+ if (!sizechanged) {
+ memcpy(name, scp->translated_path, MIN(sizeof(pstring)-1, scp->translated_path_length));
+ } else {
+ pstring last_component;
+ sp = strnrchr_m(name, '/', num_components);
+ if (!sp) {
+ /* Logic error. */
+ smb_panic("logic error in stat_cache_lookup\n");
+ }
+ pstrcpy(last_component, sp);
+ pstrcpy(name, scp->translated_path);
+ pstrcat(name, last_component);
+ }
/* set pointer for 'where to start' on fixing the rest of the name */
*start = &name[scp->translated_path_length];