int get_real_filename(connection_struct *conn, const char *path, const char *name, TALLOC_CTX *mem_ctx, char **found_name) { int ret; bool mangled; mangled = mangle_is_mangled(name, conn->params); if (mangled) { return get_real_filename_full_scan(conn, path, name, mangled, mem_ctx, found_name); } /* Try the vfs first to take advantage of case-insensitive stat. */ ret = SMB_VFS_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name); /* * If the case-insensitive stat was successful, or returned an error * other than EOPNOTSUPP then there is no need to fall back on the * full directory scan. */ if (ret == 0 || (ret == -1 && errno != EOPNOTSUPP)) { return ret; } return get_real_filename_full_scan(conn, path, name, mangled, mem_ctx, found_name); }
static int get_real_filename_mangled(connection_struct *conn, const char *path, const char *name, TALLOC_CTX *mem_ctx, char **found_name) { bool mangled; char *unmangled_name = NULL; mangled = mangle_is_mangled(name, conn->params); /* handle null paths */ if ((path == NULL) || (*path == 0)) { path = "."; } /* If we have a case-sensitive filesystem, it doesn't do us any * good to search for a name. If a case variation of the name was * there, then the original stat(2) would have found it. */ if (!mangled && !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) { errno = ENOENT; return -1; } /* * The incoming name can be mangled, and if we de-mangle it * here it will not compare correctly against the filename (name2) * read from the directory and then mangled by the name_to_8_3() * call. We need to mangle both names or neither. * (JRA). * * Fix for bug found by Dina Fine. If in case sensitive mode then * the mangle cache is no good (3 letter extension could be wrong * case - so don't demangle in this case - leave as mangled and * allow the mangling of the directory entry read (which is done * case insensitively) to match instead. This will lead to more * false positive matches but we fail completely without it. JRA. */ if (mangled && !conn->case_sensitive) { mangled = !mangle_lookup_name_from_8_3(talloc_tos(), name, &unmangled_name, conn->params); if (!mangled) { /* Name is now unmangled. */ name = unmangled_name; } return get_real_filename(conn, path, name, mem_ctx, found_name); } return SMB_VFS_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name); }