[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-848-g9e8b8f8

James Peach jpeach at samba.org
Sat Dec 22 22:56:36 GMT 2007


The branch, v3-2-test has been updated
       via  9e8b8f8c16612d8a08b55802f4fd9afca5498a7c (commit)
      from  22ac34a329c9be9cf7d1e6749ebcfb50215378e4 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit 9e8b8f8c16612d8a08b55802f4fd9afca5498a7c
Author: James Peach <jpeach at samba.org>
Date:   Sat Dec 22 14:55:37 2007 -0800

    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).

-----------------------------------------------------------------------

Summary of changes:
 source/smbd/dir.c      |   38 +++++++++++++++++++++-----------------
 source/smbd/filename.c |    9 +++++++++
 2 files changed, 30 insertions(+), 17 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index 05679ee..ccf91fe 100644
--- a/source/smbd/dir.c
+++ b/source/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/source/smbd/filename.c b/source/smbd/filename.c
index dc733d4..f0d036b 100644
--- a/source/smbd/filename.c
+++ b/source/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)


-- 
Samba Shared Repository


More information about the samba-cvs mailing list