diff options
author | James Peach <jpeach@samba.org> | 2007-12-22 14:55:37 -0800 |
---|---|---|
committer | James Peach <jpeach@samba.org> | 2007-12-22 14:55:37 -0800 |
commit | 596018455af0d80add90215689a80d336157429c (patch) | |
tree | e57331a0b8e0737da5fe4efb6b7d171a029402cf /source3/smbd | |
parent | 4dc0c1b88be359cbf4e5273e1670ef0f87b9e36b (diff) | |
download | samba-596018455af0d80add90215689a80d336157429c.tar.gz samba-596018455af0d80add90215689a80d336157429c.tar.bz2 samba-596018455af0d80add90215689a80d336157429c.zip |
Use filesystem capabilities to support case-insensitive filesystems.
If we know the underlying filesystem is case-insensitive, then we
know that it won't help to search for case variations of the requested
name.
Jeremy, please review (and revert if you disagree).
(This used to be commit 9e8b8f8c16612d8a08b55802f4fd9afca5498a7c)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/dir.c | 38 | ||||
-rw-r--r-- | source3/smbd/filename.c | 9 |
2 files changed, 30 insertions, 17 deletions
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 05679ee0ee..ccf91fe57d 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -646,10 +646,13 @@ const char *dptr_ReadDirName(TALLOC_CTX *ctx, TALLOC_FREE(pathreal); - /* In case sensitive mode we don't search - we know if it doesn't exist - with a stat we will fail. */ + /* Stat failed. We know this is authoratiative if we are + * providing case sensitive semantics or the underlying + * filesystem is case sensitive. + */ - if (dptr->conn->case_sensitive) { + if (dptr->conn->case_sensitive || + !(dptr->conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) { /* We need to set the underlying dir_hnd offset to -1 also as this function is usually called with the output from TellDir. */ dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; @@ -924,12 +927,7 @@ static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S return True; } - /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) { - DEBUG(10,("user_can_read_file: SMB_VFS_STAT failed for file %s with error %s\n", - name, strerror(errno) )); - return False; - } + SMB_ASSERT(VALID_STAT(*pst)); /* Pseudo-open the file (note - no fd's created). */ @@ -987,10 +985,7 @@ static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ return True; } - /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) { - return False; - } + SMB_ASSERT(VALID_STAT(*pst)); /* Pseudo-open the file */ @@ -1039,9 +1034,7 @@ static bool file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT if (conn->admin_user) return False; - /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) - return True; + SMB_ASSERT(VALID_STAT(*pst)); if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode)) return False; @@ -1050,7 +1043,9 @@ static bool file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT } /******************************************************************* - Should the file be seen by the client ? + Should the file be seen by the client ? NOTE: A successful return + is no guarantee of the file's existence ... you also have to check + whether pst is valid. ********************************************************************/ bool is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, bool use_veto) @@ -1086,6 +1081,15 @@ bool is_visible_file(connection_struct *conn, const char *dir_path, const char * return True; } + /* If the file name does not exist, there's no point checking + * the configuration options. We succeed, on the basis that the + * checks *might* have passed if the file was present. + */ + if (SMB_VFS_STAT(conn, entry, pst) != 0) { + SAFE_FREE(entry); + return True; + } + /* Honour _hide unreadable_ option */ if (hide_unreadable && !user_can_read_file(conn, entry, pst)) { DEBUG(10,("is_visible_file: file %s is unreadable.\n", entry )); diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index dc733d4568..f0d036b82b 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -735,6 +735,15 @@ static bool scan_directory(connection_struct *conn, const char *path, 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 False; + } + /* * The incoming name can be mangled, and if we de-mangle it * here it will not compare correctly against the filename (name2) |