From: Jeremy Allison Date: Sat, 22 Oct 2011 00:46:12 +0000 (-0700) Subject: Second part of fix for bug #8541 - readlink() on Linux clients fails if the symlink... X-Git-Url: http://git.samba.org/?a=commitdiff_plain;ds=sidebyside;h=d1a4ee604ffaac4c6ddf6b8939e3d42688d2c73d;p=rusty%2Fsamba.git 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. --- diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 722da316594..835f3b40d17 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 9891c1e4035..343b0b916e5 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -1041,6 +1041,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 963b7c4bc13..92010c230dd 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)));