[SCM] Samba Shared Repository - branch v3-6-test updated

Karolin Seeger kseeger at samba.org
Wed Oct 26 11:27:26 MDT 2011


The branch, v3-6-test has been updated
       via  074b946 Third part of fix for bug #8541 - readlink() on Linux clients fails if the symlink target is outside of the share.
       via  6529ac5 Second part of fix for bug #8541 - readlink() on Linux clients fails if the symlink target is outside of the share.
       via  a7d2815 Fix bug #8541 - readlink() on Linux clients fails if the symlink target is outside of the share.
       via  99b4d69 Use existing ISDOT and ISDOTDOT macros.
      from  2970d44 s3-netapi: remove pointless use_memory_krb5_ccache.

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


- Log -----------------------------------------------------------------
commit 074b9462e4b7b2b6e474566016e93a87c77e1599
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Oct 21 18:35:15 2011 -0700

    Third part of fix for bug #8541 - readlink() on Linux clients fails if the symlink target is outside of the share.
    
    Missed passing ucf_flags instead of hard coded flags in findfirst call.
    (cherry picked from commit 49d2a796bed0273327d8919755023c4dbd6d8232)

commit 6529ac5424f75943b612daddaefb765b44aecdf7
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Oct 21 17:46:12 2011 -0700

    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 305d7d7f7d76e37d82ce6ac257f178ce654b26db)

commit a7d2815e97218c2b7eccbac25f78f2c2fae45a79
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Oct 21 14:12:41 2011 -0700

    Fix bug #8541 - readlink() on Linux clients fails if the symlink target is outside of the share.
    
    The key is to only allow the lookup to succeed if it's a UNIX level lookup or readlink,
    but disallow all other operations.
    (cherry picked from commit d2ec9d20858b8e5256bf8339395c6f47793e0975)

commit 99b4d6912570cc210035b2222ad57f4279792a2d
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Jul 25 16:12:45 2011 -0700

    Use existing ISDOT and ISDOTDOT macros.
    
    Autobuild-User: Jeremy Allison <jra at samba.org>
    Autobuild-Date: Thu Jul 28 02:09:20 CEST 2011 on sn-devel-104
    (cherry picked from commit d82256ca119eb8315cc69ba725ba71c386caa901)

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

Summary of changes:
 source3/include/smb.h    |    1 +
 source3/smbd/filename.c  |   39 +++++++++++++++++++++++++++++----------
 source3/smbd/proto.h     |    2 ++
 source3/smbd/statcache.c |   11 ++++++++++-
 source3/smbd/trans2.c    |   21 +++++++++++++++------
 5 files changed, 57 insertions(+), 17 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/smb.h b/source3/include/smb.h
index 3a64af7..549ebb2 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1714,6 +1714,7 @@ struct smb_file_time {
 #define UCF_ALWAYS_ALLOW_WCARD_LCOMP	0x00000002
 #define UCF_COND_ALLOW_WCARD_LCOMP	0x00000004
 #define UCF_POSIX_PATHNAMES		0x00000008
+#define UCF_UNIX_NAME_LOOKUP		0x00000010
 
 /*
  * smb_filename
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 25301e6..b2ed239 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;
 	}
@@ -977,26 +977,39 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 }
 
 /****************************************************************************
- Check a filename - possibly calling check_reduced_name.
- This is called by every routine before it allows an operation on a filename.
- It does any final confirmation necessary to ensure that the filename is
- a valid one for the user to access.
+ Ensure a path is not vetod.
 ****************************************************************************/
 
-NTSTATUS check_name(connection_struct *conn, const char *name)
+NTSTATUS check_veto_path(connection_struct *conn, const char *name)
 {
 	if (IS_VETO_PATH(conn, name))  {
 		/* Is it not dot or dot dot. */
-		if (!((name[0] == '.') && (!name[1] ||
-					(name[1] == '.' && !name[2])))) {
-			DEBUG(5,("check_name: file path name %s vetoed\n",
+		if (!(ISDOT(name) || ISDOTDOT(name))) {
+			DEBUG(5,("check_veto_path: file path name %s vetoed\n",
 						name));
 			return map_nt_error_from_unix(ENOENT);
 		}
 	}
+	return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Check a filename - possibly calling check_reduced_name.
+ This is called by every routine before it allows an operation on a filename.
+ It does any final confirmation necessary to ensure that the filename is
+ a valid one for the user to access.
+****************************************************************************/
+
+NTSTATUS check_name(connection_struct *conn, const char *name)
+{
+	NTSTATUS status = check_veto_path(conn, name);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
 
 	if (!lp_widelinks(SNUM(conn)) || !lp_symlinks(SNUM(conn))) {
-		NTSTATUS status = check_reduced_name(conn,name);
+		status = check_reduced_name(conn,name);
 		if (!NT_STATUS_IS_OK(status)) {
 			DEBUG(5,("check_name: name %s failed with %s\n",name,
 						nt_errstr(status)));
@@ -1314,6 +1327,12 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx,
 		return status;
 	}
 
+	if ((ucf_flags & UCF_UNIX_NAME_LOOKUP) &&
+			VALID_STAT((*pp_smb_fname)->st) &&
+			S_ISLNK((*pp_smb_fname)->st.st_ex_mode)) {
+		return check_veto_path(conn, (*pp_smb_fname)->base_name);
+	}
+
 	status = check_name(conn, (*pp_smb_fname)->base_name);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(3,("filename_convert: check_name failed "
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index c455ffe..02b5e40 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -336,6 +336,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 		      const char *orig_path,
 		      struct smb_filename **smb_fname,
 		      uint32_t ucf_flags);
+NTSTATUS check_veto_path(connection_struct *conn, const char *name);
 NTSTATUS check_name(connection_struct *conn, const char *name);
 int get_real_filename(connection_struct *conn, const char *path,
 		      const char *name, TALLOC_CTX *mem_ctx,
@@ -1037,6 +1038,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 e2ccc74..e910982 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)));
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 0931fff..129ab01 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -2271,6 +2271,7 @@ static void call_trans2findfirst(connection_struct *conn,
 	TALLOC_CTX *ctx = talloc_tos();
 	struct dptr_struct *dirptr = NULL;
 	struct smbd_server_connection *sconn = req->sconn;
+	uint32_t ucf_flags = (UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP);
 
 	if (total_params < 13) {
 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@@ -2314,6 +2315,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
 				reply_nterror(req, NT_STATUS_INVALID_LEVEL);
 				goto out;
 			}
+			ucf_flags |= UCF_UNIX_NAME_LOOKUP;
 			break;
 		default:
 			reply_nterror(req, NT_STATUS_INVALID_LEVEL);
@@ -2331,8 +2333,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
 	ntstatus = filename_convert(ctx, conn,
 				    req->flags2 & FLAGS2_DFS_PATHNAMES,
 				    directory,
-				    (UCF_SAVE_LCOMP |
-					UCF_ALWAYS_ALLOW_WCARD_LCOMP),
+				    ucf_flags,
 				    &mask_contains_wcard,
 				    &smb_dname);
 	if (!NT_STATUS_IS_OK(ntstatus)) {
@@ -5103,6 +5104,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
 	} else {
 		uint32_t name_hash;
 		char *fname = NULL;
+		uint32_t ucf_flags = 0;
 
 		/* qpathinfo */
 		if (total_params < 7) {
@@ -5114,9 +5116,16 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
 
 		DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
 
-		if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
-			reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-			return;
+		if (INFO_LEVEL_IS_UNIX(info_level)) {
+			if (!lp_unix_extensions()) {
+				reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+				return;
+			}
+			if (info_level == SMB_QUERY_FILE_UNIX_BASIC ||
+					info_level == SMB_QUERY_FILE_UNIX_INFO2 ||
+					info_level == SMB_QUERY_FILE_UNIX_LINK) {
+				ucf_flags |= UCF_UNIX_NAME_LOOKUP;
+			}
 		}
 
 		srvstr_get_path(req, params, req->flags2, &fname, &params[6],
@@ -5131,7 +5140,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
 					conn,
 					req->flags2 & FLAGS2_DFS_PATHNAMES,
 					fname,
-					0,
+					ucf_flags,
 					NULL,
 					&smb_fname);
 		if (!NT_STATUS_IS_OK(status)) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list