int get_real_filename(connection_struct *conn, const char *path, const char *name, TALLOC_CTX *mem_ctx, char **found_name) { struct smb_Dir *cur_dir; const char *dname; bool mangled; char *unmangled_name = NULL; long curpos; /* open the directory */ if (!(cur_dir = OpenDir(talloc_tos(), conn, path, NULL, 0))) { DEBUG(3,("scan dir didn't open dir [%s]\n",path)); TALLOC_FREE(unmangled_name); return -1; } /* now scan for matching names */ curpos = 0; while ((dname = ReadDirName(cur_dir, &curpos, NULL))) { /* Is it dot or dot dot. */ if (ISDOT(dname) || ISDOTDOT(dname)) { continue; } /* * At this point dname is the unmangled name. * name is either mangled or not, depending on the state * of the "mangled" variable. JRA. */ /* * Check mangled name against mangled name, or unmangled name * against unmangled name. */ if ((mangled && mangled_equal(name,dname,conn->params)) || fname_equal(name, dname, conn->case_sensitive)) { /* we've found the file, change it's name and return */ *found_name = talloc_strdup(mem_ctx, dname); TALLOC_FREE(unmangled_name); TALLOC_FREE(cur_dir); if (!*found_name) { errno = ENOMEM; return -1; } return 0; } } TALLOC_FREE(unmangled_name); TALLOC_FREE(cur_dir); errno = ENOENT; return -1; }
static int get_real_filename_full_scan(connection_struct *conn, const char *path, const char *name, bool mangled, TALLOC_CTX *mem_ctx, char **found_name) { struct smb_Dir *cur_dir; const char *dname = NULL; char *talloced = NULL; char *unmangled_name = NULL; long curpos; /* 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; } } /* open the directory */ if (!(cur_dir = OpenDir(talloc_tos(), conn, path, NULL, 0))) { DEBUG(3,("scan dir didn't open dir [%s]\n",path)); TALLOC_FREE(unmangled_name); return -1; } /* now scan for matching names */ curpos = 0; while ((dname = ReadDirName(cur_dir, &curpos, NULL, &talloced))) { /* Is it dot or dot dot. */ if (ISDOT(dname) || ISDOTDOT(dname)) { TALLOC_FREE(talloced); continue; } /* * At this point dname is the unmangled name. * name is either mangled or not, depending on the state * of the "mangled" variable. JRA. */ /* * Check mangled name against mangled name, or unmangled name * against unmangled name. */ if ((mangled && mangled_equal(name,dname,conn->params)) || fname_equal(name, dname, conn->case_sensitive)) { /* we've found the file, change it's name and return */ *found_name = talloc_strdup(mem_ctx, dname); TALLOC_FREE(unmangled_name); TALLOC_FREE(cur_dir); if (!*found_name) { errno = ENOMEM; TALLOC_FREE(talloced); return -1; } TALLOC_FREE(talloced); return 0; } TALLOC_FREE(talloced); } TALLOC_FREE(unmangled_name); TALLOC_FREE(cur_dir); errno = ENOENT; return -1; }
static BOOL scan_directory(connection_struct *conn, const char *path, char *name, size_t maxlength) { struct smb_Dir *cur_dir; const char *dname; BOOL mangled; long curpos; mangled = mangle_is_mangled(name, conn->params); /* handle null paths */ if (*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 (!(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) { errno = ENOENT; return False; } /* * 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 mangle_map() * 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_check_cache( name, maxlength, conn->params); } /* open the directory */ if (!(cur_dir = OpenDir(conn, path, NULL, 0))) { DEBUG(3,("scan dir didn't open dir [%s]\n",path)); return(False); } /* now scan for matching names */ curpos = 0; while ((dname = ReadDirName(cur_dir, &curpos))) { /* Is it dot or dot dot. */ if ((dname[0] == '.') && (!dname[1] || (dname[1] == '.' && !dname[2]))) { continue; } /* * At this point dname is the unmangled name. * name is either mangled or not, depending on the state of the "mangled" * variable. JRA. */ /* * Check mangled name against mangled name, or unmangled name * against unmangled name. */ if ((mangled && mangled_equal(name,dname,conn->params)) || fname_equal(name, dname, conn->case_sensitive)) { /* we've found the file, change it's name and return */ safe_strcpy(name, dname, maxlength); CloseDir(cur_dir); return(True); } } CloseDir(cur_dir); errno = ENOENT; return(False); }