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

Jule Anger janger at samba.org
Mon Jan 16 10:50:02 UTC 2023


The branch, v4-17-test has been updated
       via  34a90840448 s3: smbd: Tweak openat_pathref_dirfsp_nosymlink() to NULL out fsp->fsp_name after calling fd_close() on intermediate directories, rather than before.
       via  669da62d636 selftest: Show vfs_virusscanner crashes when traversing a 2-level directory tree.
       via  02e63b6d336 s4: libcli: Ignore errors when getting A records after fetching AAAA records.
       via  580cfa72138 s3: smbd: In synthetic_pathref() change DBG_ERR -> DBG_NOTICE to avoid spamming the logs.
       via  1e94c94ae85 s3: smbd: Cause SMB2_OP_FLUSH to go synchronous in a compound anywhere but the last operation in the list.
       via  61babd9af83 s3: smbd: Add utility function smbd_smb2_is_last_in_compound().
       via  7b4652b8027 s4: torture: Add an async SMB2_OP_FLUSH + SMB2_OP_FLUSH test to smb2.compound_async.
       via  67d388c71f7 s4: torture: Add an async SMB2_OP_FLUSH + SMB2_OP_CLOSE test to smb2.compound_async.
       via  7b29d4077d8 nsswitch:libwbclient - fix leak in wbcCtxPingDc2
       via  50330f69a07 s3: libsmbclient: Fix smbc_getxattr() to return 0 on success.
       via  a92a0043493 s4: torture: Show return value for smbc_getxattr() is incorrect (returns >0 for success, should return zero).
      from  0bc115f7570 s3:smbstatus: go to cmdline_messaging_context_free

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


- Log -----------------------------------------------------------------
commit 34a9084044814868a2a8d7deca9b3c8df1767abd
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Jan 12 11:20:08 2023 -0800

    s3: smbd: Tweak openat_pathref_dirfsp_nosymlink() to NULL out fsp->fsp_name after calling fd_close() on intermediate directories, rather than before.
    
    vfs_virusfilter expects a non-NULL fsp->fsp_name to use for printing debugs
    (it always indirects fsp->fsp_name). vfs_fruit also does the same, so would
    also crash in fruit_close() with 'debug level = 10' and vfs_default:VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS = no
    set (we don't test with that which is why we haven't noticed
    this before).
    
    Remove knownfail.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15283
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Fri Jan 13 08:33:47 UTC 2023 on sn-devel-184
    
    (cherry picked from commit 3d3d01cda8d3a6d0d18d1b808aa9414e71d56062)
    
    Autobuild-User(v4-17-test): Jule Anger <janger at samba.org>
    Autobuild-Date(v4-17-test): Mon Jan 16 10:49:14 UTC 2023 on sn-devel-184

commit 669da62d636d8e2dada61e096b33b91dde6c9eeb
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Jan 12 10:22:09 2023 -0800

    selftest: Show vfs_virusscanner crashes when traversing a 2-level directory tree.
    
    Modify check_infected_read() test to use a 2-level deep
    directory.
    
    We must have vfs_default:VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS = no
    set on the virusscanner share as otherwise the openat flag
    shortcut defeats the test.
    
    Add knownfail.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15283
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    (cherry picked from commit c844bff3eca336547c6cedfeeb03adda4eed57c6)

commit 02e63b6d336f3f8ece424cfe0577d4aad5f1069b
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Nov 8 10:13:18 2022 -0800

    s4: libcli: Ignore errors when getting A records after fetching AAAA records.
    
    The target may only be available over IPv6.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15226
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Wed Nov  9 20:34:07 UTC 2022 on sn-devel-184
    
    (cherry picked from commit 10537a89bb0b461ba31d614b7c9ed56a842422e7)

commit 580cfa7213874087a042e77c6f82d7b513e1705e
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Nov 15 13:29:46 2022 -0800

    s3: smbd: In synthetic_pathref() change DBG_ERR -> DBG_NOTICE to avoid spamming the logs.
    
    Can easily be seen by doing make test TESTS=fruit
    and looking in st/nt4_dc/smbd_test.log.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15210
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Wed Nov 16 06:00:56 UTC 2022 on sn-devel-184
    
    (cherry picked from commit f0ca9546102acf09f1834c03f8907ed26bfc80f8)

commit 1e94c94ae8520dfc91f8462f70ace026c96584e9
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Oct 20 15:19:05 2022 -0700

    s3: smbd: Cause SMB2_OP_FLUSH to go synchronous in a compound anywhere but the last operation in the list.
    
    Async read and write go synchronous in the same case,
    so do the same here.
    
    Remove knownfail.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15172
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Thu Nov 17 05:55:42 UTC 2022 on sn-devel-184
    
    (cherry picked from commit 26adf3344337f4e8d5d2107e6ba42e5ea7656372)

commit 61babd9af831ee47731cfe062c884e974e74e2fd
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Oct 20 15:08:14 2022 -0700

    s3: smbd: Add utility function smbd_smb2_is_last_in_compound().
    
    Not yet used. Returns true if we're processing the last SMB2 request in a
    compound.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15172
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    (cherry picked from commit e668c3a82cd566b405c976d45659dd79786948de)

commit 7b4652b80278ef21fe0bb8709676038f31e71a05
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Oct 20 14:22:25 2022 -0700

    s4: torture: Add an async SMB2_OP_FLUSH + SMB2_OP_FLUSH test to smb2.compound_async.
    
    Shows we fail sending an SMB2_OP_FLUSH + SMB2_OP_FLUSH
    compound if we immediately close the file afterward.
    
    Internally the flushes go async and we free the req, then
    we process the close. When the flushes complete they try to access
    already freed data.
    
    Extra test which will allow me to test when the final
    component (flush) of the compound goes async and returns
    NT_STATUS_PENDING.
    
    Add knownfail.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15172
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    (cherry picked from commit 6f149dfd9d8d2619a9e18975ebcf5e69df2b7766)

commit 67d388c71f75aad94b3019b1dbbab261c01e6604
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Oct 18 16:22:33 2022 -0700

    s4: torture: Add an async SMB2_OP_FLUSH + SMB2_OP_CLOSE test to smb2.compound_async.
    
    Shows we fail sending an SMB2_OP_FLUSH + SMB2_OP_CLOSE
    compound. Internally the flush goes async and
    we free the req, then we process the close.
    When the flush completes it tries to access
    already freed data.
    
    Found using the Apple MacOSX client at SNIA SDC 2022.
    
    Add knownfail.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15172
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    (cherry picked from commit 17a110c1b58196eb8ecf3c76eb97e8508976c544)

commit 7b29d4077d80093c4493f8b40a0729bd8541ff6e
Author: Andrew Walker <awalker at ixsystems.com>
Date:   Fri Sep 2 16:31:32 2022 -0400

    nsswitch:libwbclient - fix leak in wbcCtxPingDc2
    
    Memory allocated for response is never freed.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15164
    
    Signed-off-by: Andrew Walker <awalker at ixsystems.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Christof Schmitt <cs at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Sep  6 20:10:17 UTC 2022 on sn-devel-184
    
    (cherry picked from commit aa9f3a2da97ae13cce3e50fe3d58f143200e9a17)

commit 50330f69a073915c604070a1889e92af0f0a2006
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Oct 28 15:31:39 2022 -0700

    s3: libsmbclient: Fix smbc_getxattr() to return 0 on success.
    
    Remove knownfail.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14808
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Mulder <dmulder at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Nov  1 18:31:22 UTC 2022 on sn-devel-184
    
    (cherry picked from commit bdbb38d16c8eaff33484bb747efa639c4d8e7f35)

commit a92a0043493f678338ecdefa49810e91f6bb2a1a
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Oct 28 15:28:41 2022 -0700

    s4: torture: Show return value for smbc_getxattr() is incorrect (returns >0 for success, should return zero).
    
    Add torture test to show smbc_getxattr() should return -1 on
    failure, 0 on success.
    
    Add knownfail.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14808
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Mulder <dmulder at samba.org>
    (cherry picked from commit 74636dfe24c15677261fc40c0a4ec62404898cf4)

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

Summary of changes:
 nsswitch/libwbclient/wbc_pam.c              |   1 +
 selftest/target/Samba3.pm                   |   1 +
 source3/libsmb/libsmb_xattr.c               |   6 +-
 source3/script/tests/test_virus_scanner.sh  |  25 ++-
 source3/selftest/tests.py                   |   2 +
 source3/smbd/files.c                        |   6 +-
 source3/smbd/globals.h                      |   1 +
 source3/smbd/smb2_flush.c                   |  14 ++
 source3/smbd/smb2_server.c                  |   6 +
 source4/libcli/resolve/dns_ex.c             |  14 +-
 source4/torture/libsmbclient/libsmbclient.c |  94 +++++++++++
 source4/torture/smb2/compound.c             | 232 ++++++++++++++++++++++++++++
 source4/torture/smb2/smb2.c                 |   1 +
 13 files changed, 386 insertions(+), 17 deletions(-)


Changeset truncated at 500 lines:

diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c
index b4bb2678ad0..4df0ffe2eb5 100644
--- a/nsswitch/libwbclient/wbc_pam.c
+++ b/nsswitch/libwbclient/wbc_pam.c
@@ -731,6 +731,7 @@ wbcErr wbcCtxPingDc2(struct wbcContext *ctx, const char *domain,
 	BAIL_ON_WBC_ERROR(wbc_status);
 
  done:
+	winbindd_free_response(&response);
 	return wbc_status;
 }
 
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 72c8abac867..226cab316d2 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1970,6 +1970,7 @@ sub setup_fileserver
 	virusfilter:infected files = *infected*
 	virusfilter:infected file action = rename
 	virusfilter:scan on close = yes
+	vfs_default:VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS = no
 
 [volumeserialnumber]
 	path = $volume_serial_number_sharedir
diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c
index e0e328a9a69..c8aa0743f54 100644
--- a/source3/libsmb/libsmb_xattr.c
+++ b/source3/libsmb/libsmb_xattr.c
@@ -2180,7 +2180,11 @@ SMBC_getxattr_ctx(SMBCCTX *context,
                         errno = SMBC_errno(context, srv->cli);
                 }
 		TALLOC_FREE(frame);
-                return ret;
+		/*
+		 * static function cacl_get returns a value greater than zero
+		 * on success. Map this to zero meaning success.
+		 */
+                return ret < 0 ? -1 : 0;
         }
 
         /* Unsupported attribute name */
diff --git a/source3/script/tests/test_virus_scanner.sh b/source3/script/tests/test_virus_scanner.sh
index 913c353028b..83b50df915f 100755
--- a/source3/script/tests/test_virus_scanner.sh
+++ b/source3/script/tests/test_virus_scanner.sh
@@ -26,25 +26,36 @@ check_infected_read()
 {
 	rm -rf "${sharedir:?}"/*
 
-	if ! touch "${sharedir}/infected.txt"; then
-		echo "ERROR: Cannot create ${sharedir}/infected.txt"
+	if ! mkdir "${sharedir}/read1"; then
+		echo "ERROR: Cannot create ${sharedir}/read1"
+		return 1
+	fi
+
+	if ! mkdir "${sharedir}/read1/read2"; then
+		echo "ERROR: Cannot create ${sharedir}/read1/read2"
 		return 1
 	fi
 
-	${SMBCLIENT} "//${SERVER_IP}/${SHARE}" -U"${USER}"%"${PASSWORD}" -c "get infected.txt ${sharedir}/infected.download.txt"
+	if ! touch "${sharedir}/read1/read2/infected.txt"; then
+		echo "ERROR: Cannot create ${sharedir}/read1/read2/infected.txt"
+		return 1
+	fi
+
+	${SMBCLIENT} "//${SERVER_IP}/${SHARE}" -U"${USER}"%"${PASSWORD}" -c "get read1/read2/infected.txt ${sharedir}/read1/read2/infected.download.txt"
 
 	# check that virusfilter:rename prefix/suffix was added
-	if [ ! -f "${sharedir}/virusfilter.infected.txt.infected" ]; then
-		echo "ERROR: ${sharedir}/virusfilter.infected.txt.infected is missing."
+	if [ ! -f "${sharedir}/read1/read2/virusfilter.infected.txt.infected" ]; then
+		echo "ERROR: ${sharedir}/read1/read2/virusfilter.infected.txt.infected is missing."
 		return 1
 	fi
 
 	# check that file was not downloaded
-	if [ -f "${sharedir}/infected.download.txt" ]; then
-		echo "ERROR: {sharedir}/infected.download.txt should not exist."
+	if [ -f "${sharedir}/read1/read2/infected.download.txt" ]; then
+		echo "ERROR: {sharedir}/read1/read2/infected.download.txt should not exist."
 		return 1
 	fi
 
+	rm -rf "${sharedir:?}"/*
 	return 0
 }
 
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 54c788fd441..ad0d4820449 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -1052,6 +1052,8 @@ for t in tests:
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/aio -U$USERNAME%$PASSWORD', 'aio')
         plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
+    elif t == "smb2.compound_async":
+        plansmbtorture4testsuite(t, "fileserver", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
     elif t == "smb2.ea":
         plansmbtorture4testsuite(t, "fileserver", '//$SERVER/ea_acl_xattr --option=torture:acl_xattr_name=hackme -U$USERNAME%$PASSWORD')
     elif t == "rpc.samba3.netlogon" or t == "rpc.samba3.sessionkey":
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 9b0c902c0d4..bfcda0dd8e1 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -1053,9 +1053,9 @@ next:
 	}
 
 	if (dirfsp != conn->cwd_fsp) {
-		dirfsp->fsp_name = NULL;
 		SMB_ASSERT(fsp_get_pathref_fd(dirfsp) != -1);
 		fd_close(dirfsp);
+		dirfsp->fsp_name = NULL;
 		file_free(NULL, dirfsp);
 		dirfsp = NULL;
 	}
@@ -1117,9 +1117,9 @@ fail:
 	}
 
 	if ((dirfsp != NULL) && (dirfsp != conn->cwd_fsp)) {
-		dirfsp->fsp_name = NULL;
 		SMB_ASSERT(fsp_get_pathref_fd(dirfsp) != -1);
 		fd_close(dirfsp);
+		dirfsp->fsp_name = NULL;
 		file_free(NULL, dirfsp);
 		dirfsp = NULL;
 	}
@@ -1196,7 +1196,7 @@ NTSTATUS synthetic_pathref(TALLOC_CTX *mem_ctx,
 
 	status = openat_pathref_fsp(dirfsp, smb_fname);
 	if (!NT_STATUS_IS_OK(status)) {
-		DBG_ERR("opening [%s] failed\n",
+		DBG_NOTICE("opening [%s] failed\n",
 			smb_fname_str_dbg(smb_fname));
 		TALLOC_FREE(smb_fname);
 		return status;
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index efcf02f0d24..125ef64f070 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -238,6 +238,7 @@ void smbd_server_disconnect_client_ex(struct smbXsrv_client *client,
 const char *smb2_opcode_name(uint16_t opcode);
 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size);
 bool smbd_smb2_is_compound(const struct smbd_smb2_request *req);
+bool smbd_smb2_is_last_in_compound(const struct smbd_smb2_request *req);
 
 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
 			     NTTIME now, struct smbXsrv_connection **_xconn);
diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c
index e73666f0afc..5c8c171e418 100644
--- a/source3/smbd/smb2_flush.c
+++ b/source3/smbd/smb2_flush.c
@@ -126,6 +126,8 @@ static struct tevent_req *smbd_smb2_flush_send(TALLOC_CTX *mem_ctx,
 	struct tevent_req *subreq;
 	struct smbd_smb2_flush_state *state;
 	struct smb_request *smbreq;
+	bool is_compound = false;
+	bool is_last_in_compound = false;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct smbd_smb2_flush_state);
@@ -195,6 +197,18 @@ static struct tevent_req *smbd_smb2_flush_send(TALLOC_CTX *mem_ctx,
 
 	tevent_req_set_callback(subreq, smbd_smb2_flush_done, req);
 
+	is_compound = smbd_smb2_is_compound(smb2req);
+	is_last_in_compound = smbd_smb2_is_last_in_compound(smb2req);
+
+	if (is_compound && !is_last_in_compound) {
+		/*
+		 * Can't go async if we're not the
+		 * last request in a compound request.
+		 * Cause this request to complete synchronously.
+		 */
+		smb2_request_set_async_internal(state->smb2req, true);
+	}
+
 	/* Ensure any close request knows about this outstanding IO. */
 	if (!aio_add_req_to_fsp(fsp, req)) {
 		tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 1cd5953f116..8e32a477947 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -229,6 +229,12 @@ bool smbd_smb2_is_compound(const struct smbd_smb2_request *req)
 	return req->in.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ);
 }
 
+bool smbd_smb2_is_last_in_compound(const struct smbd_smb2_request *req)
+{
+	return (req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ ==
+		req->in.vector_count);
+}
+
 static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn,
 				     uint64_t expected_seq_low)
 {
diff --git a/source4/libcli/resolve/dns_ex.c b/source4/libcli/resolve/dns_ex.c
index 0bb3ba02287..b8447bec4de 100644
--- a/source4/libcli/resolve/dns_ex.c
+++ b/source4/libcli/resolve/dns_ex.c
@@ -245,13 +245,15 @@ static struct dns_records_container get_a_aaaa_records(TALLOC_CTX *mem_ctx,
 		* Most of the server do it, let's ask for A specificaly.
 		*/
 		err = dns_lookup(tmp_ctx, name, QTYPE_A, &reply);
-		if (!ERR_DNS_IS_OK(err)) {
-			goto done;
-		}
-
-		total = reply_to_addrs(tmp_ctx, &a_num, &addrs, total,
+		if (ERR_DNS_IS_OK(err)) {
+			/*
+			 * Ignore an error here and just return any AAAA
+			 * records we already got. This may be an IPv6-only
+			 * config.
+			 */
+			total = reply_to_addrs(tmp_ctx, &a_num, &addrs, total,
 					reply, port);
-
+		}
 	}
 
 	if (total) {
diff --git a/source4/torture/libsmbclient/libsmbclient.c b/source4/torture/libsmbclient/libsmbclient.c
index d335cad3a4e..55ea26f5bc8 100644
--- a/source4/torture/libsmbclient/libsmbclient.c
+++ b/source4/torture/libsmbclient/libsmbclient.c
@@ -1473,6 +1473,98 @@ static bool torture_libsmbclient_getatr(struct torture_context *tctx)
 	return true;
 }
 
+static bool torture_libsmbclient_getxattr(struct torture_context *tctx)
+{
+	const char *smburl = torture_setting_string(tctx, "smburl", NULL);
+	int fhandle = -1;
+	SMBCCTX *ctx = NULL;
+	char *getxattr_name = NULL;
+	char value[4096];
+	bool ok = false;
+	int ret = -1;
+
+	if (smburl == NULL) {
+		torture_fail(tctx,
+			     "option --option=torture:smburl="
+			     "smb://user:password@server missing\n");
+	}
+
+	ok = torture_libsmbclient_init_context(tctx, &ctx);
+	torture_assert(tctx, ok, "Failed to init context");
+	smbc_set_context(ctx);
+
+	getxattr_name = talloc_asprintf(tctx,
+			"%s/getxattr",
+			smburl);
+	if (getxattr_name == NULL) {
+		torture_result(tctx,
+			       TORTURE_FAIL,
+			       __location__": %s",
+			       "talloc fail\n");
+		return false;
+	}
+	/* Ensure the file doesn't exist. */
+	smbc_unlink(getxattr_name);
+
+	/* Create testfile. */
+	fhandle = smbc_creat(getxattr_name, 0666);
+	if (fhandle < 0) {
+		torture_fail_goto(tctx,
+			done,
+			talloc_asprintf(tctx,
+				"failed to create file '%s': %s",
+				getxattr_name,
+				strerror(errno)));
+	}
+	ret = smbc_close(fhandle);
+	torture_assert_int_equal_goto(tctx,
+		ret,
+		0,
+		ok,
+		done,
+		talloc_asprintf(tctx,
+			"failed to close handle for '%s'",
+			getxattr_name));
+
+	/*
+	 * Ensure getting a non-existent attribute returns -1.
+	 */
+	ret = smbc_getxattr(getxattr_name, "foobar", value, sizeof(value));
+	torture_assert_int_equal_goto(tctx,
+		ret,
+		-1,
+		ok,
+		done,
+		talloc_asprintf(tctx,
+			"smbc_getxattr(foobar) on '%s' should "
+			"get -1, got %d\n",
+			getxattr_name,
+			ret));
+
+	/*
+	 * Ensure getting a valid attribute returns 0.
+	 */
+	ret = smbc_getxattr(getxattr_name, "system.*", value, sizeof(value));
+	torture_assert_int_equal_goto(tctx,
+		ret,
+		0,
+		ok,
+		done,
+		talloc_asprintf(tctx,
+			"smbc_getxattr(foobar) on '%s' should "
+			"get -1, got %d\n",
+			getxattr_name,
+			ret));
+
+	ok = true;
+
+  done:
+
+	smbc_unlink(getxattr_name);
+	smbc_free_context(ctx, 1);
+	return ok;
+}
+
 NTSTATUS torture_libsmbclient_init(TALLOC_CTX *ctx)
 {
 	struct torture_suite *suite;
@@ -1501,6 +1593,8 @@ NTSTATUS torture_libsmbclient_init(TALLOC_CTX *ctx)
 					torture_libsmbclient_rename);
 	torture_suite_add_simple_test(suite, "getatr",
 		torture_libsmbclient_getatr);
+	torture_suite_add_simple_test(suite, "getxattr",
+		torture_libsmbclient_getxattr);
 
 	suite->description = talloc_strdup(suite, "libsmbclient interface tests");
 
diff --git a/source4/torture/smb2/compound.c b/source4/torture/smb2/compound.c
index cf19361130f..47a550f0873 100644
--- a/source4/torture/smb2/compound.c
+++ b/source4/torture/smb2/compound.c
@@ -2057,6 +2057,223 @@ done:
 	return ret;
 }
 
+static bool test_compound_async_flush_close(struct torture_context *tctx,
+					    struct smb2_tree *tree)
+{
+	struct smb2_handle fhandle = { .data = { 0, 0 } };
+	struct smb2_handle relhandle = { .data = { UINT64_MAX, UINT64_MAX } };
+	struct smb2_close cl;
+	struct smb2_flush fl;
+	const char *fname = "compound_async_flush_close";
+	struct smb2_request *req[2];
+	NTSTATUS status;
+	bool ret = false;
+
+	/* Start clean. */
+	smb2_util_unlink(tree, fname);
+
+	/* Create a file. */
+	status = torture_smb2_testfile_access(tree,
+					      fname,
+					      &fhandle,
+					      SEC_RIGHTS_FILE_ALL);
+	CHECK_STATUS(status, NT_STATUS_OK);
+
+	/* Now do a compound flush + close handle. */
+	smb2_transport_compound_start(tree->session->transport, 2);
+
+	ZERO_STRUCT(fl);
+	fl.in.file.handle = fhandle;
+
+	req[0] = smb2_flush_send(tree, &fl);
+	torture_assert_not_null_goto(tctx, req[0], ret, done,
+		"smb2_flush_send failed\n");
+
+	smb2_transport_compound_set_related(tree->session->transport, true);
+
+	ZERO_STRUCT(cl);
+	cl.in.file.handle = relhandle;
+	req[1] = smb2_close_send(tree, &cl);
+	torture_assert_not_null_goto(tctx, req[1], ret, done,
+		"smb2_close_send failed\n");
+
+	status = smb2_flush_recv(req[0], &fl);
+	/*
+	 * On Windows, this flush will usually
+	 * succeed as we have nothing to flush,
+	 * so allow NT_STATUS_OK. Once bug #15172
+	 * is fixed Samba will do the flush synchronously
+	 * so allow NT_STATUS_OK.
+	 */
+	if (!NT_STATUS_IS_OK(status)) {
+		/*
+		 * If we didn't get NT_STATUS_OK, we *must*
+		 * get NT_STATUS_INTERNAL_ERROR if the flush
+		 * goes async.
+		 *
+		 * For pre-bugfix #15172 Samba, the flush goes async and
+		 * we should get NT_STATUS_INTERNAL_ERROR.
+		 */
+		torture_assert_ntstatus_equal_goto(tctx,
+			status,
+			NT_STATUS_INTERNAL_ERROR,
+			ret,
+			done,
+			"smb2_flush_recv didn't return "
+			"NT_STATUS_INTERNAL_ERROR.\n");
+	}
+	status = smb2_close_recv(req[1], &cl);
+	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+			"smb2_close_recv failed.");
+
+	ZERO_STRUCT(fhandle);
+
+	/*
+	 * Do several more operations on the tree, spaced
+	 * out by 1 sec sleeps to make sure the server didn't
+	 * crash on the close. The sleeps are required to
+	 * make test test for a crash reliable, as we ensure
+	 * the pthread fsync internally finishes and accesses
+	 * freed memory. Without them the test occassionally
+	 * passes as we disconnect before the pthread fsync
+	 * finishes.
+	 */
+	status = smb2_util_unlink(tree, fname);
+	CHECK_STATUS(status, NT_STATUS_OK);
+
+	sleep(1);
+	status = smb2_util_unlink(tree, fname);
+	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+
+	sleep(1);
+	status = smb2_util_unlink(tree, fname);
+	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+
+	ret = true;
+
+  done:
+
+	if (fhandle.data[0] != 0) {
+		smb2_util_close(tree, fhandle);
+	}
+
+	smb2_util_unlink(tree, fname);
+	return ret;
+}
+
+static bool test_compound_async_flush_flush(struct torture_context *tctx,
+					    struct smb2_tree *tree)
+{
+	struct smb2_handle fhandle = { .data = { 0, 0 } };
+	struct smb2_handle relhandle = { .data = { UINT64_MAX, UINT64_MAX } };
+	struct smb2_flush fl1;
+	struct smb2_flush fl2;
+	const char *fname = "compound_async_flush_flush";
+	struct smb2_request *req[2];
+	NTSTATUS status;
+	bool ret = false;
+
+	/* Start clean. */
+	smb2_util_unlink(tree, fname);
+
+	/* Create a file. */
+	status = torture_smb2_testfile_access(tree,
+					      fname,
+					      &fhandle,
+					      SEC_RIGHTS_FILE_ALL);
+	CHECK_STATUS(status, NT_STATUS_OK);
+
+	/* Now do a compound flush + flush handle. */
+	smb2_transport_compound_start(tree->session->transport, 2);
+
+	ZERO_STRUCT(fl1);
+	fl1.in.file.handle = fhandle;
+
+	req[0] = smb2_flush_send(tree, &fl1);
+	torture_assert_not_null_goto(tctx, req[0], ret, done,
+		"smb2_flush_send (1) failed\n");
+
+	smb2_transport_compound_set_related(tree->session->transport, true);
+
+	ZERO_STRUCT(fl2);
+	fl2.in.file.handle = relhandle;
+
+	req[1] = smb2_flush_send(tree, &fl2);
+	torture_assert_not_null_goto(tctx, req[1], ret, done,
+		"smb2_flush_send (2) failed\n");
+
+	status = smb2_flush_recv(req[0], &fl1);
+	/*
+	 * On Windows, this flush will usually
+	 * succeed as we have nothing to flush,
+	 * so allow NT_STATUS_OK. Once bug #15172
+	 * is fixed Samba will do the flush synchronously
+	 * so allow NT_STATUS_OK.
+	 */
+	if (!NT_STATUS_IS_OK(status)) {
+		/*
+		 * If we didn't get NT_STATUS_OK, we *must*


-- 
Samba Shared Repository



More information about the samba-cvs mailing list