From e0959885005da56865c6f9c46831f3040295a978 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Oct 2011 15:34:27 -0700 Subject: 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 84ce5f1b96be650ad80fa1dc030539113a27c50d) --- source3/include/proto.h | 1 + source3/smbd/filename.c | 2 +- source3/smbd/statcache.c | 11 ++++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 8afc2e7161f..2e04ca11b3c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7055,6 +7055,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/filename.c b/source3/smbd/filename.c index 2ea9d24f873..0c34aa83dce 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -295,7 +295,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/statcache.c b/source3/smbd/statcache.c index db347b5b7e8..5f58d5e54db 100644 --- a/source3/smbd/statcache.c +++ b/source3/smbd/statcache.c @@ -145,6 +145,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 @@ -161,6 +162,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, @@ -176,6 +178,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; @@ -278,7 +281,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))); -- cgit