summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJames Peach <jpeach@samba.org>2007-12-22 14:55:37 -0800
committerJames Peach <jpeach@samba.org>2007-12-22 14:55:37 -0800
commit596018455af0d80add90215689a80d336157429c (patch)
treee57331a0b8e0737da5fe4efb6b7d171a029402cf /source3
parent4dc0c1b88be359cbf4e5273e1670ef0f87b9e36b (diff)
downloadsamba-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')
-rw-r--r--source3/smbd/dir.c38
-rw-r--r--source3/smbd/filename.c9
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)