Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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);
}