From c4b6e73b406c4d89e03cb5b49bca52ef4dcefd9c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Oct 2011 17:46:12 -0700 Subject: [PATCH] Second part of fix for bug #8541 - readlink() on Linux clients fails if the symlink target is outside of the share. The statcache has to do lstat instead of stat when returning cached posix pathnames. (cherry picked from commit 305d7d7f7d76e37d82ce6ac257f178ce654b26db) (cherry picked from commit 6529ac5424f75943b612daddaefb765b44aecdf7) --- source3/smbd/filename.c | 2 +- source3/smbd/proto.h | 1 + source3/smbd/statcache.c | 11 ++++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 691a779d8ca..b2ed2397269 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -383,7 +383,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, if((!conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) && - stat_cache_lookup(conn, &smb_fname->base_name, &dirpath, &start, + stat_cache_lookup(conn, posix_pathnames, &smb_fname->base_name, &dirpath, &start, &smb_fname->st)) { goto done; } diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 1e5d891e9f8..02b5e407029 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -1038,6 +1038,7 @@ void stat_cache_add( const char *full_orig_name, char *translated_path, bool case_sensitive); bool stat_cache_lookup(connection_struct *conn, + bool posix_paths, char **pp_name, char **pp_dirpath, char **pp_start, diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c index e2ccc74a87a..e910982b6c8 100644 --- a/source3/smbd/statcache.c +++ b/source3/smbd/statcache.c @@ -150,6 +150,7 @@ void stat_cache_add( const char *full_orig_name, * Look through the stat cache for an entry * * @param conn A connection struct to do the stat() with. + * @param posix_paths Whether to lookup using stat() or lstat() * @param name The path we are attempting to cache, modified by this routine * to be correct as far as the cache can tell us. We assume that * it is a talloc'ed string from top of stack, we free it if @@ -166,6 +167,7 @@ void stat_cache_add( const char *full_orig_name, */ bool stat_cache_lookup(connection_struct *conn, + bool posix_paths, char **pp_name, char **pp_dirpath, char **pp_start, @@ -181,6 +183,7 @@ bool stat_cache_lookup(connection_struct *conn, char *name; TALLOC_CTX *ctx = talloc_tos(); struct smb_filename smb_fname; + int ret; *pp_dirpath = NULL; *pp_start = *pp_name; @@ -283,7 +286,13 @@ bool stat_cache_lookup(connection_struct *conn, ZERO_STRUCT(smb_fname); smb_fname.base_name = translated_path; - if (SMB_VFS_STAT(conn, &smb_fname) != 0) { + if (posix_paths) { + ret = SMB_VFS_LSTAT(conn, &smb_fname); + } else { + ret = SMB_VFS_STAT(conn, &smb_fname); + } + + if (ret != 0) { /* Discard this entry - it doesn't exist in the filesystem. */ memcache_delete(smbd_memcache(), STAT_CACHE, data_blob_const(chk_name, strlen(chk_name))); -- 2.11.4.GIT