[SCM] Samba Shared Repository - branch v4-14-test updated

Karolin Seeger kseeger at samba.org
Thu Jun 10 10:32:01 UTC 2021


The branch, v4-14-test has been updated
       via  42fa9f800fd smbd: fix pathref unlinking in create_file_unixpath()
       via  1c8ba016208 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from call_trans2findfirst()
       via  c8355298be5 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file()
       via  94fc3ac176a smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file()
       via  acd2c1fed8d smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from rename_internals()
       via  fc8becea75d smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from rename_internals()
       via  89851bdfb8a smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from reply_search()
       via  8dc1552ce2a smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from create_file_unixpath()
       via  b87ada0acd7 smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from open_streams_for_delete()
       via  12a375df83b smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from get_file_handle_for_metadata()
       via  15e52ebd028 net: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from openat_pathref_fsp()
       via  ec89546b9b2 smbd: don't return NT_STATUS_STOPPED_ON_SYMLINK in openat_pathref_fsp()
       via  4b1918ca9a7 smbd: simplify error codepath in openat_pathref_fsp()
       via  95183a05af1 smbd: expect valid stat info in openat_pathref_fsp()
       via  19fe725a117 smbd: stat path before calling openat_pathref_fsp() in smbd_dirptr_get_entry()
       via  445b97d3168 smbd: move smb_fname creation to earlier point in smbd_dirptr_get_entry()
       via  821992641c3 smbd: stat path before calling openat_pathref_fsp() in open_pathref_base_fsp()
       via  5505b9a6834 smbd: remove a redundant fstat()in create_file_unixpath()
       via  2dff00e034a smbd: call stat before openat_pathref_fsp() in create_file_unixpath()
       via  af4737c4011 smbd: fix a resource leak in create_file_unixpath()
       via  589c10e91b9 smbd: stat path before calling openat_pathref_fsp() in unlink_internals()
       via  40583d313c3 s3/libadouble: stat path before calling openat_pathref_fsp() in ad_unconvert_open_ad()
      from  cfccd7792e1 VERSION: Bump version up to 4.14.6...

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-14-test


- Log -----------------------------------------------------------------
commit 42fa9f800fd008881c70cf37e63954f5987d0c78
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jun 8 18:53:18 2021 +0200

    smbd: fix pathref unlinking in create_file_unixpath()
    
    This is really subtle. If someone passes in an smb_fname where smb_fname
    actually is taken from fsp->fsp_name, then the lifetime of these objects is
    meant to be the same.
    
    This is commonly the case from an SMB1 path-based call
    (eg call_trans2qfilepathinfo()) where we use the pathref fsp
    (smb_fname->fsp) as the handle. In this case we must not unlink smb_fname->fsp
    from it's owner.
    
    The asserts below:
    
      SMB_ASSERT(fsp->fsp_name->fsp != NULL);
      SMB_ASSERT(fsp->fsp_name->fsp == fsp);
    
    ensure the required invarients are met.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14732
    
    Pair-Programmed-With: Ralph Boehme <slow at samba.org>
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Signed-off-by: Ralph Boehme <slow at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Tue Jun  8 20:44:41 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 8a427783e5e780d3ffbe4f9710ac4a17c483ca33)
    
    Autobuild-User(v4-14-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-14-test): Thu Jun 10 10:31:11 UTC 2021 on sn-devel-184

commit 1c8ba016208458d97a78bc3a1d954c2df915cafd
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 16:01:19 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from call_trans2findfirst()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Fri Feb  5 07:26:44 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 1b3d70e9ae95892a70bd0f46ae5bf733c1bc9548)

commit c8355298be5c27c841725bcb08be462a922507c5
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 16:00:32 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 5898f5769e0b126cca33ba0002f1e4c3eb80d21a)

commit 94fc3ac176aa0f97cd98750197a7d5c5d0189002
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 15:58:57 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from copy_file()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 544767f72df366baf50be6d841e36dbcbe9f4065)

commit acd2c1fed8db0e0acee5158c81fdf93952bcbbd0
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 15:58:42 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from rename_internals()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 8999c7d69c6312c7e7bef93417ecef93ddbdabf5)

commit fc8becea75db6e8123f36a3816f2707cc85739f7
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 15:58:30 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from rename_internals()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit f21eb28cb8737d3125e4c0c65545f93dd7ea863f)

commit 89851bdfb8a9f5acbffa03b239bb3b58f013f47b
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 15:57:26 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from reply_search()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 6c2dad2aaef5eab75f3fe14219e9eca6724d6c99)

commit 8dc1552ce2ac0ecb4630c1a791f205323e2f85f9
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 15:57:09 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from create_file_unixpath()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 300d851a89248ac9b220fbac55cd5daaebb7fbca)

commit b87ada0acd7293785ff300ed814dc29264c9f211
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 15:56:44 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from open_streams_for_delete()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit f121374514ed6957b9c6d022a17cc4e5c8aea9a6)

commit 12a375df83b4cbda0464482f64d3d03de8d54943
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 15:54:43 2021 +0100

    smbd: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from get_file_handle_for_metadata()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 0d454f34db52d2903c830e1f1acd56a9a1dca04b)

commit 15e52ebd028187017195933876bc248739535d38
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 15:54:02 2021 +0100

    net: remove NT_STATUS_STOPPED_ON_SYMLINK status code check from openat_pathref_fsp()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 6e7142ba6c79c9c6f3ce299b6c7dd476cc229e6b)

commit ec89546b9b20f4e3bfd43d18058b77a19e646376
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 11:18:54 2021 +0100

    smbd: don't return NT_STATUS_STOPPED_ON_SYMLINK in openat_pathref_fsp()
    
    NT_STATUS_STOPPED_ON_SYMLINK is returned when trying to open a symlink, most
    callers are not interested in this.
    
    Some callers that would want to know whether openat_pathref_fsp() failed
    specifically on a symlink are setup_close_full_information(),
    smbd_dirptr_get_entry(), unlink_internals() and filename_convert_internal(), so
    we fix those callers to handle the symlink case themselves.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 977f37643b223e164fbbf6c3ba1d37aa546ddb7d)

commit 4b1918ca9a715026eb3143e73af23112476aa9de
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Feb 2 13:49:56 2021 +0100

    smbd: simplify error codepath in openat_pathref_fsp()
    
    No change in behaviour: the cleanup code at the fail label does the same as the
    cleanup this patch removes. It has an extra fd_close() that is not existing in
    the removed cleanup, but as fsp->fd is -1, that's a noop.
    
    And when previously the
    
    		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    
    returns an an explicit status code, when now doing goto fail status will also be
    set to NT_STATUS_OBJECT_NAME_NOT_FOUND.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit cd3d970c84b340630745bc555a86ac2d1306baac)

commit 95183a05af1a5d90e349325a2540916afa2f602b
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Feb 1 10:17:13 2021 +0100

    smbd: expect valid stat info in openat_pathref_fsp()
    
    We're never creating files here, so instead of waiting for the underlying open()
    to return ENOENT, just check that we have valid stat info, expecting all callers
    to have called SMB_VFS_[L]STAT() on the smb_fname.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 48bc561d1a8bb5ce99663b58a2e5e9aa344af96a)

commit 19fe725a117757b35c7e2cd2eca9899e4fb36c78
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Feb 1 12:09:39 2021 +0100

    smbd: stat path before calling openat_pathref_fsp() in smbd_dirptr_get_entry()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 87e97e1b519159b5f4c5ed4ef684783855e79ac3)

commit 445b97d3168dbc6486463b39db73173b0a7b5215
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Feb 1 12:04:49 2021 +0100

    smbd: move smb_fname creation to earlier point in smbd_dirptr_get_entry()
    
    No change in behaviour. Makes way for the next commit adding additional logic.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit b3a0d6a128989b593f135c425dd59351d13b6120)

commit 821992641c386f84adf056987535caff1035aa7e
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Feb 1 12:04:01 2021 +0100

    smbd: stat path before calling openat_pathref_fsp() in open_pathref_base_fsp()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit c31fe2f9e7d65409229b7ad73418793ab34d359d)

commit 5505b9a68344d03c903fa3dcbceb277ea41cac71
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Feb 1 12:03:08 2021 +0100

    smbd: remove a redundant fstat()in create_file_unixpath()
    
    openat_pathref_fsp() deep inside already calls fstat().
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 91edc50dc0aaa82d9ede7a7f8cf0f63312eb8503)

commit 2dff00e034acf98ec29d264032506a068f6addeb
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Feb 1 12:01:22 2021 +0100

    smbd: call stat before openat_pathref_fsp() in create_file_unixpath()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit aa0ef26d1e9dcef0bcb47974d7cf60db922d7d08)

commit af4737c4011bb6ab54d4ba4672719294e5a16ba2
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Feb 1 12:01:01 2021 +0100

    smbd: fix a resource leak in create_file_unixpath()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit e636e20f90d4ee221ce6e20cab15a3cecb03850f)

commit 589c10e91b9e6c981a2269588573376a505e73f5
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Feb 1 12:00:35 2021 +0100

    smbd: stat path before calling openat_pathref_fsp() in unlink_internals()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit ab82dbc5ae43cdb661bf49627a84926163bc8998)

commit 40583d313c3530e4b144e1e5a32856f65dd628ed
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Feb 1 11:59:37 2021 +0100

    s3/libadouble: stat path before calling openat_pathref_fsp() in ad_unconvert_open_ad()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14730
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 4f30c04462fb1536323606dd4216fe5e32458ba5)

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

Summary of changes:
 source3/lib/adouble.c     |  13 ++++--
 source3/smbd/dir.c        | 116 +++++++++++++++++++++-------------------------
 source3/smbd/dosmode.c    |   3 --
 source3/smbd/filename.c   |  15 ++----
 source3/smbd/files.c      |  47 ++++++++-----------
 source3/smbd/open.c       |  77 ++++++++++++++++++------------
 source3/smbd/reply.c      |  34 +++++++-------
 source3/smbd/smb2_close.c |   5 +-
 source3/smbd/trans2.c     |   3 --
 source3/utils/net_vfs.c   |   3 --
 10 files changed, 156 insertions(+), 160 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c
index dffc0d5b7be..0ab9019cfb5 100644
--- a/source3/lib/adouble.c
+++ b/source3/lib/adouble.c
@@ -1492,13 +1492,18 @@ static bool ad_unconvert_open_ad(TALLOC_CTX *mem_ctx,
 	NTSTATUS status;
 	int ret;
 
-	status = openat_pathref_fsp(handle->conn->cwd_fsp, adpath);
-	if (!NT_STATUS_IS_OK(status) &&
-	    !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))
-	{
+	ret = vfs_stat(handle->conn, adpath);
+	if (ret == -1 && errno != ENOENT) {
 		return false;
 	}
 
+	if (VALID_STAT(adpath->st)) {
+		status = openat_pathref_fsp(handle->conn->cwd_fsp, adpath);
+		if (!NT_STATUS_IS_OK(status)) {
+			return false;
+		}
+	}
+
 	status = SMB_VFS_CREATE_FILE(
 		handle->conn,
 		NULL,				/* req */
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index ae92fa08161..6614b4d4c47 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -793,6 +793,7 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
 	const char *dpath = dirptr->smb_dname->base_name;
 	bool dirptr_path_is_dot = ISDOT(dpath);
 	NTSTATUS status;
+	int ret;
 
 	*_smb_fname = NULL;
 	*_mode = 0;
@@ -860,17 +861,60 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
 			return false;
 		}
 
+		/*
+		 * We don't want to pass ./xxx to modules below us so don't
+		 * add the path if it is just . by itself.
+		 */
+		if (dirptr_path_is_dot) {
+			memcpy(pathreal, dname, talloc_get_size(dname));
+		} else {
+			memcpy(pathreal, dpath, pathlen);
+			pathreal[pathlen] = '/';
+			memcpy(pathreal + slashlen + pathlen, dname,
+			       talloc_get_size(dname));
+		}
+
+		/* Create smb_fname with NULL stream_name. */
+		smb_fname = synthetic_smb_fname(talloc_tos(),
+						pathreal,
+						NULL,
+						&sbuf,
+						dirptr->smb_dname->twrp,
+						dirptr->smb_dname->flags);
+		TALLOC_FREE(pathreal);
+		if (smb_fname == NULL) {
+			TALLOC_FREE(dname);
+			TALLOC_FREE(fname);
+			return false;
+		}
+
+		if (!VALID_STAT(smb_fname->st)) {
+			/*
+			 * If stat() fails with ENOENT it might be a
+			 * msdfs-symlink in Windows context, this is checked
+			 * below, for now we just want to fill stat info as good
+			 * as we can.
+			 */
+			ret = vfs_stat(conn, smb_fname);
+			if (ret != 0 && errno != ENOENT) {
+				TALLOC_FREE(smb_fname);
+				TALLOC_FREE(dname);
+				TALLOC_FREE(fname);
+				continue;
+			}
+		}
+
 		/* Create smb_fname with NULL stream_name. */
 		atname = synthetic_smb_fname(talloc_tos(),
 					     dname,
 					     NULL,
-					     &sbuf,
+					     &smb_fname->st,
 					     dirptr->smb_dname->twrp,
 					     dirptr->smb_dname->flags);
 		if (atname == NULL) {
 			TALLOC_FREE(dname);
 			TALLOC_FREE(fname);
-			TALLOC_FREE(pathreal);
+			TALLOC_FREE(smb_fname);
 			return false;
 		}
 
@@ -887,72 +931,25 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
 		 */
 		status = openat_pathref_fsp(dirptr->dir_hnd->fsp, atname);
 		if (!NT_STATUS_IS_OK(status) &&
-		    !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
-		    !NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK))
+		    !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))
 		{
 			TALLOC_FREE(atname);
 			TALLOC_FREE(dname);
 			TALLOC_FREE(fname);
-			TALLOC_FREE(pathreal);
+			TALLOC_FREE(smb_fname);
 			continue;
-		} else if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
+		} else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
 			if (!(atname->flags & SMB_FILENAME_POSIX_PATH)) {
-				TALLOC_FREE(atname);
-				TALLOC_FREE(dname);
-				TALLOC_FREE(fname);
-				TALLOC_FREE(pathreal);
-				continue;
+				check_dfs_symlink = true;
 			}
 			/*
-			 * It's a symlink, disable getting dosmode in the
-			 * mode_fn() and prime the mode as
-			 * FILE_ATTRIBUTE_NORMAL.
+			 * Check if it's a symlink. We only want to return this
+			 * if it's a DFS symlink or in POSIX mode. Disable
+			 * getting dosmode in the mode_fn() and prime the mode
+			 * as FILE_ATTRIBUTE_NORMAL.
 			 */
 			mode = FILE_ATTRIBUTE_NORMAL;
 			get_dosmode = false;
-		} else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-			if (atname->flags & SMB_FILENAME_POSIX_PATH) {
-				TALLOC_FREE(atname);
-				TALLOC_FREE(dname);
-				TALLOC_FREE(fname);
-				TALLOC_FREE(pathreal);
-				continue;
-			}
-			/*
-			 * Likely a dangling symlink. We only want to return
-			 * this if it's a DFS symlink, so we need to check for
-			 * that. Set get_dosmode to skip getting dosmode.
-			 */
-			get_dosmode = false;
-			check_dfs_symlink = true;
-		}
-
-		/*
-		 * We don't want to pass ./xxx to modules below us so don't
-		 * add the path if it is just . by itself.
-		 */
-		if (dirptr_path_is_dot) {
-			memcpy(pathreal, dname, talloc_get_size(dname));
-		} else {
-			memcpy(pathreal, dpath, pathlen);
-			pathreal[pathlen] = '/';
-			memcpy(pathreal + slashlen + pathlen, dname,
-			       talloc_get_size(dname));
-		}
-
-		/* Create smb_fname with NULL stream_name. */
-		smb_fname = synthetic_smb_fname(talloc_tos(),
-						pathreal,
-						NULL,
-						&sbuf,
-						dirptr->smb_dname->twrp,
-						dirptr->smb_dname->flags);
-		if (smb_fname == NULL) {
-			TALLOC_FREE(atname);
-			TALLOC_FREE(dname);
-			TALLOC_FREE(fname);
-			TALLOC_FREE(pathreal);
-			return false;
 		}
 
 		status = move_smb_fname_fsp_link(smb_fname, atname);
@@ -964,7 +961,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
 			TALLOC_FREE(smb_fname);
 			TALLOC_FREE(dname);
 			TALLOC_FREE(fname);
-			TALLOC_FREE(pathreal);
 			continue;
 		}
 
@@ -973,7 +969,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
 			TALLOC_FREE(smb_fname);
 			TALLOC_FREE(dname);
 			TALLOC_FREE(fname);
-			TALLOC_FREE(pathreal);
 			continue;
 		}
 
@@ -992,7 +987,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
 			TALLOC_FREE(smb_fname);
 			TALLOC_FREE(dname);
 			TALLOC_FREE(fname);
-			TALLOC_FREE(pathreal);
 			continue;
 		}
 
@@ -1002,7 +996,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
 			TALLOC_FREE(smb_fname);
 			TALLOC_FREE(dname);
 			TALLOC_FREE(fname);
-			TALLOC_FREE(pathreal);
 			continue;
 		}
 
@@ -1037,7 +1030,6 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
 		TALLOC_FREE(dname);
 
 		*_smb_fname = talloc_move(ctx, &smb_fname);
-		TALLOC_FREE(pathreal);
 		if (*_smb_fname == NULL) {
 			return false;
 		}
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index ccfeaca124d..ea225a9b1ef 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -1378,9 +1378,6 @@ static NTSTATUS get_file_handle_for_metadata(connection_struct *conn,
 	}
 
 	status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
-	if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
-		status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-	}
 	if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(smb_fname_cp);
 		return status;
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 184a293f205..9035c7e82c7 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -1982,14 +1982,9 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx,
 	}
 
 	status = openat_pathref_fsp(conn->cwd_fsp, smb_fname);
-	if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
+	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
 		/*
-		 * Don't leak NT_STATUS_STOPPED_ON_SYMLINK into the callers:
-		 * it's a special SMB2 error that needs an extended SMB2 error
-		 * response. We don't support that for SMB2 and it doesn't exist
-		 * at all in SMB1.
-		 *
-		 * So we deal with symlinks here as we do in
+		 * We deal with symlinks here as we do in
 		 * SMB_VFS_CREATE_FILE(): return success for POSIX clients with
 		 * the notable difference that there will be no fsp in
 		 * smb_fname->fsp.
@@ -1997,10 +1992,10 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx,
 		 * For Windows (non POSIX) clients fail with
 		 * NT_STATUS_OBJECT_NAME_NOT_FOUND.
 		 */
-		if (ucf_flags & UCF_POSIX_PATHNAMES) {
+		if (smb_fname->flags & SMB_FILENAME_POSIX_PATH &&
+		    S_ISLNK(smb_fname->st.st_ex_mode))
+		{
 			status = NT_STATUS_OK;
-		} else {
-			status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
 		}
 	}
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index d9fd2b8ea86..371af875d4b 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -395,6 +395,7 @@ static NTSTATUS open_pathref_base_fsp(const struct files_struct *dirfsp,
 {
 	struct smb_filename *smb_fname_base = NULL;
 	NTSTATUS status;
+	int ret;
 
 	smb_fname_base = synthetic_smb_fname(talloc_tos(),
 					     fsp->fsp_name->base_name,
@@ -406,6 +407,11 @@ static NTSTATUS open_pathref_base_fsp(const struct files_struct *dirfsp,
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	ret = vfs_stat(fsp->conn, smb_fname_base);
+	if (ret != 0) {
+		return map_nt_error_from_unix(errno);
+	}
+
 	status = openat_pathref_fsp(dirfsp, smb_fname_base);
 	if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(smb_fname_base);
@@ -435,7 +441,6 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp,
 {
 	connection_struct *conn = dirfsp->conn;
 	struct smb_filename *full_fname = NULL;
-	bool file_existed = VALID_STAT(smb_fname->st);
 	struct files_struct *fsp = NULL;
 	int open_flags = O_RDONLY;
 	NTSTATUS status;
@@ -449,8 +454,12 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp,
 		return NT_STATUS_OK;
 	}
 
-	if (file_existed && S_ISLNK(smb_fname->st.st_ex_mode)) {
-		return NT_STATUS_STOPPED_ON_SYMLINK;
+	if (!VALID_STAT(smb_fname->st)) {
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (S_ISLNK(smb_fname->st.st_ex_mode)) {
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 	}
 
 	status = fsp_new(conn, conn, &fsp);
@@ -496,23 +505,9 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp,
 
 	status = fd_openat(dirfsp, smb_fname, fsp, open_flags, 0);
 	if (!NT_STATUS_IS_OK(status)) {
-		DBG_DEBUG("Could not open fd for [%s]: %s\n",
-			  fsp_str_dbg(fsp),
-			  nt_errstr(status));
-
-		if (fsp->base_fsp != NULL) {
-			struct files_struct *tmp_base_fsp = fsp->base_fsp;
-
-			fsp_set_base_fsp(fsp, NULL);
-
-			fd_close(tmp_base_fsp);
-			file_free(NULL, tmp_base_fsp);
-		}
-		file_free(NULL, fsp);
-		fsp = NULL;
-
 		if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) ||
-		    NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
+		    NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
+		    NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK))
 		{
 			/*
 			 * streams_xattr return NT_STATUS_NOT_FOUND for
@@ -524,19 +519,17 @@ NTSTATUS openat_pathref_fsp(const struct files_struct *dirfsp,
 			 *
 			 * NT_STATUS_OBJECT_NAME_NOT_FOUND is the simple
 			 * ENOENT case.
+			 *
+			 * NT_STATUS_STOPPED_ON_SYMLINK is returned when trying
+			 * to open a symlink, our callers are not interested in
+			 * this.
 			 */
 			status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
 		}
-		if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-			goto fail;
-		}
-
-		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+		goto fail;
 	}
 
-	if (file_existed &&
-	    !check_same_dev_ino(&smb_fname->st, &fsp->fsp_name->st))
-	{
+	if (!check_same_dev_ino(&smb_fname->st, &fsp->fsp_name->st)) {
 		DBG_DEBUG("file [%s] - dev/ino mismatch. "
 			  "Old (dev=%ju, ino=%ju). "
 			  "New (dev=%ju, ino=%ju).\n",
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index acb248047bf..9a18088c929 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -4997,9 +4997,6 @@ static NTSTATUS open_streams_for_delete(connection_struct *conn,
 		}
 
 		status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
-		if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
-			status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-		}
 		if (!NT_STATUS_IS_OK(status)) {
 			DBG_DEBUG("Unable to open stream [%s]: %s\n",
 				  smb_fname_str_dbg(smb_fname_cp),
@@ -5587,6 +5584,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
 	files_struct *base_fsp = NULL;
 	files_struct *fsp = NULL;
 	NTSTATUS status;
+	int ret;
 
 	DBG_DEBUG("create_file_unixpath: access_mask = 0x%x "
 		  "file_attributes = 0x%x, share_access = 0x%x, "
@@ -5734,37 +5732,28 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
 			goto fail;
 		}
 
-		SET_STAT_INVALID(smb_fname_base->st);
-
 		/*
 		 * We may be creating the basefile as part of creating the
 		 * stream, so it's legal if the basefile doesn't exist at this
 		 * point, the create_file_unixpath() below will create it. But
 		 * if the basefile exists we want a handle so we can fstat() it.
 		 */
-		status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_base);
-		if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
-			status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-		}
-		if (!NT_STATUS_IS_OK(status) &&
-		    !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))
-		{
-			DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
-				smb_fname_str_dbg(smb_fname_base),
-				nt_errstr(status));
+
+		ret = vfs_stat(conn, smb_fname_base);
+		if (ret == -1 && errno != ENOENT) {
+			status = map_nt_error_from_unix(errno);
 			TALLOC_FREE(smb_fname_base);
 			goto fail;
 		}
-
-		if (smb_fname_base->fsp != NULL) {
-			int ret;
-
-			ret = SMB_VFS_FSTAT(smb_fname_base->fsp,
-					    &smb_fname_base->st);
-			if (ret != 0) {
-				DBG_DEBUG("Unable to stat stream [%s]: %s\n",
-					  smb_fname_str_dbg(smb_fname_base),
-					  strerror(errno));
+		if (ret == 0) {
+			status = openat_pathref_fsp(conn->cwd_fsp,
+						    smb_fname_base);
+			if (!NT_STATUS_IS_OK(status)) {
+				DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
+					smb_fname_str_dbg(smb_fname_base),
+					nt_errstr(status));
+				TALLOC_FREE(smb_fname_base);
+				goto fail;
 			}
 
 			/*
@@ -5783,6 +5772,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
 					"for base %s failed: "
 					"%s\n", smb_fname->base_name,
 					nt_errstr(status)));
+				TALLOC_FREE(smb_fname_base);
 				goto fail;
 			}
 		}
@@ -5824,13 +5814,39 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
 	 * request to create a file that doesn't exist.
 	 */
 	if (smb_fname->fsp != NULL) {
-		fsp = smb_fname->fsp;
+		bool need_fsp_unlink = true;
 
 		/*
-		 * Unlink the fsp from the smb_fname so the fsp is not
-		 * autoclosed by the smb_fname pathref fsp talloc destructor.
+		 * This is really subtle. If someone passes in an smb_fname
+		 * where smb_fname actually is taken from fsp->fsp_name, then
+		 * the lifetime of these objects is meant to be the same.
+		 *
+		 * This is commonly the case from an SMB1 path-based call,
+		 * (call_trans2qfilepathinfo) where we use the pathref fsp
+		 * (smb_fname->fsp) as the handle. In this case we must not
+		 * unlink smb_fname->fsp from it's owner.
+		 *
+		 * The asserts below:
+		 *
+		 * SMB_ASSERT(fsp->fsp_name->fsp != NULL);
+		 * SMB_ASSERT(fsp->fsp_name->fsp == fsp);
+		 *
+		 * ensure the required invarients are met.
 		 */
-		smb_fname_fsp_unlink(smb_fname);
+		if (smb_fname->fsp->fsp_name == smb_fname) {
+			need_fsp_unlink = false;
+		}
+
+		fsp = smb_fname->fsp;
+
+		if (need_fsp_unlink) {
+			/*
+			 * Unlink the fsp from the smb_fname so the fsp is not
+			 * autoclosed by the smb_fname pathref fsp talloc
+			 * destructor.
+			 */
+			smb_fname_fsp_unlink(smb_fname);
+		}
 
 		status = fsp_bind_smb(fsp, req);
 		if (!NT_STATUS_IS_OK(status)) {
@@ -5860,6 +5876,9 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
 		}
 	}
 


-- 
Samba Shared Repository



More information about the samba-cvs mailing list