[SCM] Samba Shared Repository - branch v4-16-stable updated

Jule Anger janger at samba.org
Tue Feb 15 07:25:59 UTC 2022


The branch, v4-16-stable has been updated
       via  2517bca6b10 VERSION: Disable GIT_SNAPSHOT for the 4.16.0rc3 release.
       via  5f8796ea630 WHATSNEW: Add release notes for Samba 4.16.0rc3.
       via  1bbb3677ae5 smbd: Safeguards for getpwuid
       via  cdc5e9e4dbe smbd: Only file_free() a self-created fsp in create_file_unixpath()
       via  d44c45cbdbc smbd: Introduce close_file_smb()
       via  521178327e4 smbd: Factor out fsp_unbind_smb() from file_free()
       via  4cc60cbdb70 torture: Add a test to show that full_audit uses a ptr after free
       via  a61a91d427f smbd: Simplify the flow in close_file_free()
       via  e8d165da42a smbd: No base fsps to close_file_free() from file_close_user()
       via  9794341b29e smbd: Factor out close_file_in_loop() from file_close_conn_fn()
       via  c0e02d8e879 smbd: No base fsps to close_file_free() from file_close_conn()
       via  d088caa4002 smbd: NULL out "fsp" in close_file()
       via  4f9bada50af smbd: Call file_free() just once in close_file()
       via  b48431f4783 smbd: Move the call to file_free() out of close_fake_file()
       via  3500cb49764 smbd: Move the call to file_free() out of close_normal_file()
       via  692fb63a1ac smbd: Move the call to file_free() out of close_directory()
       via  a260463481a smbd: Slightly simplify create_file_unixpath()
       via  e1e2bae551e s3:modules: Fix virusfilter_vfs_openat
       via  63f6fac589e s3:selftest: Add test for virus scanner
       via  e95306ed8e3 selftest: Fix trailing whitespace in Samba3.pm
       via  db32ea07caa docs-xml:manpages: Document 'dummy' virusfilter and 'virusfilter:infected files'
       via  174fcd9f6b3 s3:modules: Implement dummy virus scanner that uses filename matching
       via  2fd16c0cbf6 selftest: Do not force -d0 for smbd/nmbd/winbindd
       via  bc72fb438fe s4:kdc: Translate HDB flags to SDB flags
       via  27c6ad1f9b6 s4:kdc: Remove trailing spaces in hdb-samba4.c
       via  6628357976b s4:kdc: Add a HDB to SDB mask
       via  fe8bf1d8aa6 libcli/smb: let smb2_signing_decrypt_pdu() cope with gnutls_aead_cipher_decrypt() ptext_len bug
       via  f400eef07a4 libcli/smb: fix error checking in smb2_signing_decrypt_pdu() invalid ptext_len
       via  8deee49cda0 selftest/quick: add smb2.session
       via  188b96164c5 s3/libads: ensure a sockaddr variable is correctly zero initialized
       via  8cbf38a1b2b s3/libads: simplify storing existing ads->ldap.ss
       via  cdcf23aac2f s3: libsmb: Call cli_dfs_target_check() from cli_smb2_rename_send().
       via  35a250f49ee s3: libsmb: Call cli_dfs_target_check() from cli_cifs_rename_send().
       via  1304041a4fd s3: libsmb: Call cli_dfs_target_check() from cli_smb1_rename_send().
       via  01b06586f19 s3: libsmb: Call cli_dfs_target_check() from cli_ntrename_internal_send().
       via  96122869594 s3: libsmb: Call cli_dfs_target_check() from cli_smb2_hardlink_send().
       via  62ce0c8f55b s3: libsmb: Add cli_dfs_target_check() function.
       via  738fbcca544 s3: tests: Add a new test test_msdfs_rename() that does simple renames on MSDFS root shares.
       via  95aca464c7c s3: tests: Add a new test test_msdfs_hardlink() that does simple hardlinks on MSDFS root shares.
       via  64aea70f9f8 lib: libsmbclient: Ensure cli_rename() always sets cli->raw_status.
       via  5c55418c25e s4: test: Add samba4.libsmbclient.rename test. Currently fails for SMB3.
       via  29355d0a2d4 VERSION: Bump version up to Samba 4.16.0rc3...
      from  a4763bd9d87 VERSION: Disable GIT_SNAPSHOT for the 4.16.0rc2 release.

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


- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 VERSION                                            |   2 +-
 WHATSNEW.txt                                       |  32 ++++-
 docs-xml/manpages/vfs_virusfilter.8.xml            |  12 ++
 libcli/smb/smb2_signing.c                          |  24 +++-
 selftest/knownfail.d/smb1-tests                    |   2 +
 selftest/quick                                     |   1 +
 selftest/target/Samba3.pm                          |  20 ++-
 source3/lib/adouble.c                              |  20 +--
 source3/libads/ldap.c                              |  14 +-
 source3/libsmb/cli_smb2_fnum.c                     |  14 ++
 source3/libsmb/clidfs.c                            |  57 ++++++++
 source3/libsmb/clifile.c                           |  53 ++++++++
 source3/libsmb/proto.h                             |   6 +
 source3/modules/vfs_fruit.c                        |  12 +-
 source3/modules/vfs_virusfilter.c                  |  18 ++-
 source3/modules/vfs_virusfilter_common.h           |   4 +
 source3/modules/vfs_virusfilter_dummy.c            |  58 ++++++++
 source3/modules/vfs_worm.c                         |   2 +-
 source3/modules/wscript_build                      |   1 +
 source3/passdb/pdb_interface.c                     |  14 +-
 source3/printing/nt_printing.c                     |  10 +-
 source3/rpc_server/srvsvc/srv_srvsvc_nt.c          |   4 +-
 source3/script/tests/full_audit_segfault/run.sh    |  23 ++++
 .../script/tests/full_audit_segfault/vfstest.cmd   |   3 +
 source3/script/tests/test_smbclient_s3.sh          |  99 ++++++++++++++
 source3/script/tests/test_virus_scanner.sh         | 124 +++++++++++++++++
 source3/selftest/tests.py                          |  17 +++
 source3/smbd/close.c                               | 104 ++++++--------
 source3/smbd/dir.c                                 |   9 +-
 source3/smbd/fake_file.c                           |   4 +-
 source3/smbd/files.c                               | 150 +++++++++++++++++----
 source3/smbd/nttrans.c                             |   6 +-
 source3/smbd/open.c                                |  75 +++++------
 source3/smbd/proto.h                               |   9 +-
 source3/smbd/reply.c                               |  62 ++++-----
 source3/smbd/smb2_close.c                          |   2 +-
 source3/smbd/smb2_create.c                         |   3 +-
 source3/smbd/trans2.c                              |  48 +++----
 source3/torture/cmd_vfs.c                          |  85 ++++++++++++
 source3/utils/net_vfs.c                            |   7 +-
 source4/kdc/hdb-samba4.c                           |  12 +-
 source4/kdc/sdb.h                                  |  12 ++
 source4/torture/libsmbclient/libsmbclient.c        | 112 +++++++++++++++
 wscript_configure_system_gnutls                    |   3 +
 44 files changed, 1094 insertions(+), 255 deletions(-)
 create mode 100644 source3/modules/vfs_virusfilter_dummy.c
 create mode 100755 source3/script/tests/full_audit_segfault/run.sh
 create mode 100644 source3/script/tests/full_audit_segfault/vfstest.cmd
 create mode 100755 source3/script/tests/test_virus_scanner.sh


Changeset truncated at 500 lines:

diff --git a/VERSION b/VERSION
index 3584323d925..7c79f3655c4 100644
--- a/VERSION
+++ b/VERSION
@@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE=
 # e.g. SAMBA_VERSION_RC_RELEASE=1                      #
 #  ->  "3.0.0rc1"                                      #
 ########################################################
-SAMBA_VERSION_RC_RELEASE=2
+SAMBA_VERSION_RC_RELEASE=3
 
 ########################################################
 # To mark SVN snapshots this should be set to 'yes'    #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index acf91910706..cdd911d40b1 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,7 +1,7 @@
 Release Announcements
 =====================
 
-This is the second release candidate of Samba 4.16.  This is *not*
+This is the third release candidate of Samba 4.16.  This is *not*
 intended for production environments and is designed for testing
 purposes only.  Please report any defects via the Samba bug reporting
 system at https://bugzilla.samba.org/.
@@ -174,6 +174,36 @@ smb.conf changes
   rpc start on demand helpers             Added           true
 
 
+CHANGES SINCE 4.16.0rc2
+=======================
+
+o  Jeremy Allison <jra at samba.org>
+   * BUG 14169: Renaming file on DFS root fails with
+     NT_STATUS_OBJECT_PATH_NOT_FOUND.
+   * BUG 14938: NT error code is not set when overwriting a file during rename
+     in libsmbclient.
+
+o  Ralph Boehme <slow at samba.org>
+   * BUG 14674: net ads info shows LDAP Server: 0.0.0.0 depending on contacted
+     server.
+
+o  Pavel Filipenský <pfilipen at redhat.com>
+   * BUG 14971: virusfilter_vfs_openat: Not scanned: Directory or special file.
+
+o  Volker Lendecke <vl at samba.org>
+   * BUG 14900: Regression: Samba 4.15.2 on macOS segfaults intermittently
+     during strcpy in tdbsam_getsampwnam.
+   * BUG 14975: Fix a crash in vfs_full_audit - CREATE_FILE can free a used fsp.
+
+o  Stefan Metzmacher <metze at samba.org>
+   * BUG 14968: smb2_signing_decrypt_pdu() may not decrypt with
+     gnutls_aead_cipher_decrypt() from gnutls before 3.5.2.
+
+o  Andreas Schneider <asn at samba.org>
+   * BUG 14960: SDB uses HDB flags directly which can lead to unwanted side
+     effects.
+
+
 CHANGES SINCE 4.16.0rc1
 =======================
 
diff --git a/docs-xml/manpages/vfs_virusfilter.8.xml b/docs-xml/manpages/vfs_virusfilter.8.xml
index 329a35af68a..88f91d73a42 100644
--- a/docs-xml/manpages/vfs_virusfilter.8.xml
+++ b/docs-xml/manpages/vfs_virusfilter.8.xml
@@ -48,6 +48,10 @@
 		  scanner</para></listitem>
 		  <listitem><para><emphasis>clamav</emphasis>, the ClamAV
 		  scanner</para></listitem>
+		  <listitem><para><emphasis>dummy</emphasis>, dummy scanner used in
+		  tests. Checks against the <emphasis>infected files</emphasis>
+		  parameter and flags any name that matches as infected.
+		  </para></listitem>
 		</itemizedlist>
 		</listitem>
 		</varlistentry>
@@ -264,6 +268,14 @@
 		</listitem>
 		</varlistentry>
 
+		<varlistentry>
+		<term>virusfilter:infected files = empty</term>
+		<listitem>
+		<para>Files that virusfilter <emphasis>dummy</emphasis> flags as infected.</para>
+		<para>If this option is not set, the default is empty.</para>
+		</listitem>
+		</varlistentry>
+
 		<varlistentry>
 		<term>virusfilter:block access on error = false</term>
 		<listitem>
diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c
index 4a94b026ccc..6efb87801cb 100644
--- a/libcli/smb/smb2_signing.c
+++ b/libcli/smb/smb2_signing.c
@@ -1251,9 +1251,31 @@ NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key,
 						ctext_size,
 						ptext,
 						&ptext_size);
-		if (rc < 0 || ptext_size != m_total) {
+		if (rc < 0) {
+			TALLOC_FREE(ptext);
+			TALLOC_FREE(ctext);
+			status = gnutls_error_to_ntstatus(rc, NT_STATUS_INTERNAL_ERROR);
+			goto out;
+		}
+#ifdef HAVE_GNUTLS_AEAD_CIPHER_DECRYPT_PTEXT_LEN_BUG
+		/*
+		 * Note that gnutls before 3.5.2 had a bug and returned
+		 * *ptext_len = ctext_len, instead of
+		 * *ptext_len = ctext_len - tag_size
+		 */
+		if (ptext_size != ctext_size) {
+			TALLOC_FREE(ptext);
+			TALLOC_FREE(ctext);
+			rc = GNUTLS_E_SHORT_MEMORY_BUFFER;
+			status = gnutls_error_to_ntstatus(rc, NT_STATUS_INTERNAL_ERROR);
+			goto out;
+		}
+		ptext_size -= tag_size;
+#endif /* HAVE_GNUTLS_AEAD_CIPHER_DECRYPT_PTEXT_LEN_BUG */
+		if (ptext_size != m_total) {
 			TALLOC_FREE(ptext);
 			TALLOC_FREE(ctext);
+			rc = GNUTLS_E_SHORT_MEMORY_BUFFER;
 			status = gnutls_error_to_ntstatus(rc, NT_STATUS_INTERNAL_ERROR);
 			goto out;
 		}
diff --git a/selftest/knownfail.d/smb1-tests b/selftest/knownfail.d/smb1-tests
index 28a74863c6a..03d299ad7c7 100644
--- a/selftest/knownfail.d/smb1-tests
+++ b/selftest/knownfail.d/smb1-tests
@@ -29,6 +29,8 @@
 ^samba3.blackbox.smbclient_s3.NT1.(plain|sign).member_creds.volume\((ad_member|nt4_member)\)
 ^samba3.blackbox.smbclient_s3.NT1.(plain|sign).member_creds.delete a non empty directory\((ad_member|nt4_member)\)
 ^samba3.blackbox.smbclient_s3.NT1.(plain|sign).member_creds.Recursive ls across MS-DFS links\((ad_member|nt4_member)\)
+^samba3.blackbox.smbclient_s3.NT1.(plain|sign).member_creds.Hardlink on MS-DFS share\((ad_member|nt4_member)\)
+^samba3.blackbox.smbclient_s3.NT1.(plain|sign).member_creds.Rename on MS-DFS share\((ad_member|nt4_member)\)
 ^samba3.blackbox.smbclient_s3.*valid.users.nt4.*
 ^samba3.blackbox.smbclient_s3.NT1.*valid.users.*
 ^samba3.unix.whoami machine account.whoami\(ad_member:local\)
diff --git a/selftest/quick b/selftest/quick
index 0e79f1020bf..6700180c2c2 100644
--- a/selftest/quick
+++ b/selftest/quick
@@ -33,6 +33,7 @@ rpc.join
 rpc.handles
 rpc.echo
 smb.signing
+smb2.session
 drs.unit
 samba4.blackbox.dbcheck.dc
 # This needs to be here to get testing of crypt_r()
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 7bb007c959d..2cc2d13d9e0 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -199,7 +199,7 @@ sub getlog_env_app($$$)
 	close(LOG);
 
 	return "" if $out eq $title;
- 
+
 	return $out;
 }
 
@@ -1694,6 +1694,9 @@ sub setup_fileserver
 	my $veto_sharedir="$share_dir/veto";
 	push(@dirs,$veto_sharedir);
 
+	my $virusfilter_sharedir="$share_dir/virusfilter";
+	push(@dirs,$virusfilter_sharedir);
+
 	my $ip4 = Samba::get_ipv4_addr("FILESERVER");
 	my $fileserver_options = "
 	kernel change notify = yes
@@ -1818,6 +1821,15 @@ sub setup_fileserver
 	path = $veto_sharedir
 	delete veto files = yes
 
+[virusfilter]
+	path = $virusfilter_sharedir
+	vfs objects = acl_xattr virusfilter
+	virusfilter:scanner = dummy
+	virusfilter:min file size = 0
+	virusfilter:infected files = *infected*
+	virusfilter:infected file action = rename
+	virusfilter:scan on close = yes
+
 [homes]
 	comment = Home directories
 	browseable = No
@@ -2158,7 +2170,7 @@ sub make_bin_cmd
 {
 	my ($self, $binary, $env_vars, $options, $valgrind, $dont_log_stdout) = @_;
 
-	my @optargs = ("-d0");
+	my @optargs = ();
 	if (defined($options)) {
 		@optargs = split(/ /, $options);
 	}
@@ -2467,7 +2479,7 @@ sub provision($$)
 	my $nmbdsockdir="$prefix_abs/nmbd";
 	unlink($nmbdsockdir);
 
-	## 
+	##
 	## create the test directory layout
 	##
 	die ("prefix_abs = ''") if $prefix_abs eq "";
@@ -3331,7 +3343,7 @@ sub provision($$)
 	unless (open(PASSWD, ">$nss_wrapper_passwd")) {
            warn("Unable to open $nss_wrapper_passwd");
            return undef;
-        } 
+        }
 	print PASSWD "nobody:x:$uid_nobody:$gid_nobody:nobody gecos:$prefix_abs:/bin/false
 $unix_name:x:$unix_uid:$unix_gids[0]:$unix_name gecos:$prefix_abs:/bin/false
 pdbtest:x:$uid_pdbtest:$gid_nogroup:pdbtest gecos:$prefix_abs:/bin/false
diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c
index 37fb686f17b..aa78007dadd 100644
--- a/source3/lib/adouble.c
+++ b/source3/lib/adouble.c
@@ -1254,13 +1254,13 @@ static bool ad_convert_xattr(vfs_handle_struct *handle,
 		if (nwritten == -1) {
 			DBG_ERR("SMB_VFS_PWRITE failed\n");
 			saved_errno = errno;
-			close_file(NULL, fsp, ERROR_CLOSE);
+			close_file_free(NULL, &fsp, ERROR_CLOSE);
 			errno = saved_errno;
 			ok = false;
 			goto fail;
 		}
 
-		status = close_file(NULL, fsp, NORMAL_CLOSE);
+		status = close_file_free(NULL, &fsp, NORMAL_CLOSE);
 		if (!NT_STATUS_IS_OK(status)) {
 			ok = false;
 			goto fail;
@@ -1395,12 +1395,12 @@ static bool ad_convert_finderinfo(vfs_handle_struct *handle,
 	if (nwritten == -1) {
 		DBG_ERR("SMB_VFS_PWRITE failed\n");
 		saved_errno = errno;
-		close_file(NULL, fsp, ERROR_CLOSE);
+		close_file_free(NULL, &fsp, ERROR_CLOSE);
 		errno = saved_errno;
 		return false;
 	}
 
-	status = close_file(NULL, fsp, NORMAL_CLOSE);
+	status = close_file_free(NULL, &fsp, NORMAL_CLOSE);
 	if (!NT_STATUS_IS_OK(status)) {
 		return false;
 	}
@@ -1652,7 +1652,7 @@ static bool ad_unconvert_open_ad(TALLOC_CTX *mem_ctx,
 		if (ret != 0) {
 			DBG_ERR("SMB_VFS_FCHOWN [%s] failed: %s\n",
 				fsp_str_dbg(fsp), nt_errstr(status));
-			close_file(NULL, fsp, NORMAL_CLOSE);
+			close_file_free(NULL, &fsp, NORMAL_CLOSE);
 			return false;
 		}
 	}
@@ -1710,14 +1710,14 @@ static bool ad_unconvert_get_streams(struct vfs_handle_struct *handle,
 				num_streams,
 				streams);
 	if (!NT_STATUS_IS_OK(status)) {
-		close_file(NULL, fsp, NORMAL_CLOSE);
+		close_file_free(NULL, &fsp, NORMAL_CLOSE);
 		DBG_ERR("streaminfo on [%s] failed: %s\n",
 			smb_fname_str_dbg(smb_fname),
 			nt_errstr(status));
 		return false;
 	}
 
-	status = close_file(NULL, fsp, NORMAL_CLOSE);
+	status = close_file_free(NULL, &fsp, NORMAL_CLOSE);
 	if (!NT_STATUS_IS_OK(status)) {
 		DBG_ERR("close_file [%s] failed: %s\n",
 			smb_fname_str_dbg(smb_fname),
@@ -1975,7 +1975,7 @@ static bool ad_collect_one_stream(struct vfs_handle_struct *handle,
 out:
 	TALLOC_FREE(sname);
 	if (fsp != NULL) {
-		status = close_file(NULL, fsp, NORMAL_CLOSE);
+		status = close_file_free(NULL, &fsp, NORMAL_CLOSE);
 		if (!NT_STATUS_IS_OK(status)) {
 			DBG_ERR("close_file [%s] failed: %s\n",
 				smb_fname_str_dbg(smb_fname),
@@ -2117,9 +2117,9 @@ bool ad_unconvert(TALLOC_CTX *mem_ctx,
 
 out:
 	if (fsp != NULL) {
-		status = close_file(NULL, fsp, NORMAL_CLOSE);
+		status = close_file_free(NULL, &fsp, NORMAL_CLOSE);
 		if (!NT_STATUS_IS_OK(status)) {
-			DBG_ERR("close_file [%s] failed: %s\n",
+			DBG_ERR("close_file_free() [%s] failed: %s\n",
 				smb_fname_str_dbg(smb_fname),
 				nt_errstr(status));
 			ok = false;
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 1bc271785e2..647cdbd0459 100755
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -605,7 +605,9 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
 	ADS_STATUS status;
 	NTSTATUS ntstatus;
 	char addr[INET6_ADDRSTRLEN];
-	struct samba_sockaddr existing_sa = {0};
+	struct sockaddr_storage existing_ss;
+
+	zero_sockaddr(&existing_ss);
 
 	/*
 	 * ads_connect can be passed in a reused ADS_STRUCT
@@ -627,11 +629,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
 	 */
 	if (ads->server.ldap_server == NULL && !is_zero_addr(&ads->ldap.ss)) {
 		/* Save off the address we previously found by ads_find_dc(). */
-		bool ok = sockaddr_storage_to_samba_sockaddr(&existing_sa,
-							     &ads->ldap.ss);
-		if (!ok) {
-			return ADS_ERROR_NT(NT_STATUS_INVALID_ADDRESS);
-		}
+		existing_ss = ads->ldap.ss;
 	}
 
 	ads_zero_ldap(ads);
@@ -679,11 +677,11 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
 		}
 	}
 
-	if (!is_zero_addr(&existing_sa.u.ss)) {
+	if (!is_zero_addr(&existing_ss)) {
 		/* We saved off who we should talk to. */
 		bool ok = ads_try_connect(ads,
 					  ads->server.gc,
-					  &existing_sa.u.ss);
+					  &existing_ss);
 		if (ok) {
 			goto got_connection;
 		}
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index 87c56b5564d..13d23ed6566 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -3215,12 +3215,26 @@ struct tevent_req *cli_smb2_rename_send(
 {
 	struct tevent_req *req = NULL, *subreq = NULL;
 	struct cli_smb2_rename_state *state = NULL;
+	NTSTATUS status;
 
 	req = tevent_req_create(
 		mem_ctx, &state, struct cli_smb2_rename_state);
 	if (req == NULL) {
 		return NULL;
 	}
+
+	/*
+	 * Strip a MSDFS path from fname_dst if we were given one.
+	 */
+	status = cli_dfs_target_check(state,
+				cli,
+				fname_src,
+				fname_dst,
+				&fname_dst);
+	if (tevent_req_nterror(req, status)) {
+		return tevent_req_post(req, ev);
+	}
+
 	state->ev = ev;
 	state->cli = cli;
 	state->fname_dst = fname_dst;
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 5b64858ca33..5288a7efc64 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -1274,3 +1274,60 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 
 	return true;
 }
+
+/********************************************************************
+ Windows and NetApp (and arguably the SMB1/2/3 specs) expect a non-DFS
+ path for the targets of rename and hardlink. If we have been given
+ a DFS path for these calls, convert it back into a local path by
+ stripping off the DFS prefix.
+********************************************************************/
+
+NTSTATUS cli_dfs_target_check(TALLOC_CTX *mem_ctx,
+			struct cli_state *cli,
+			const char *fname_src,
+			const char *fname_dst,
+			const char **fname_dst_out)
+{
+	char *dfs_prefix = NULL;
+	size_t prefix_len = 0;
+	struct smbXcli_tcon *tcon = NULL;
+
+	if (!smbXcli_conn_dfs_supported(cli->conn)) {
+		goto copy_fname_out;
+	}
+	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+		tcon = cli->smb2.tcon;
+	} else {
+		tcon = cli->smb1.tcon;
+	}
+	if (!smbXcli_tcon_is_dfs_share(tcon)) {
+		goto copy_fname_out;
+	}
+	dfs_prefix = cli_dfs_make_full_path(mem_ctx, cli, "");
+	if (dfs_prefix == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	prefix_len = strlen(dfs_prefix);
+	if (strncmp(fname_dst, dfs_prefix, prefix_len) != 0) {
+		/*
+		 * Prefix doesn't match. Assume it was
+		 * already stripped or not added in the
+		 * first place.
+		 */
+		goto copy_fname_out;
+	}
+	/* Return the trailing name after the prefix. */
+	*fname_dst_out = &fname_dst[prefix_len];
+	TALLOC_FREE(dfs_prefix);
+	return NT_STATUS_OK;
+
+  copy_fname_out:
+
+	/*
+	 * No change to the destination name. Just
+	 * point it at the incoming destination name.
+	 */
+	*fname_dst_out = fname_dst;
+	TALLOC_FREE(dfs_prefix);
+	return NT_STATUS_OK;
+}
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index f1d0a9483f6..5c570c68eac 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1234,6 +1234,18 @@ static struct tevent_req *cli_smb1_rename_send(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 
+	/*
+	 * Strip a MSDFS path from fname_dst if we were given one.
+	 */
+	status = cli_dfs_target_check(state,
+				cli,
+				fname_src,
+				fname_dst,
+				&fname_dst);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto fail;
+	}
+
 	if (!push_ucs2_talloc(talloc_tos(), &converted_str, fname_dst,
 			      &converted_size_bytes)) {
 		status = NT_STATUS_INVALID_PARAMETER;
@@ -1311,6 +1323,7 @@ static struct tevent_req *cli_cifs_rename_send(TALLOC_CTX *mem_ctx,
 	uint8_t additional_flags = 0;
 	uint16_t additional_flags2 = 0;
 	uint8_t *bytes = NULL;
+	NTSTATUS status;
 
 	req = tevent_req_create(mem_ctx, &state, struct cli_cifs_rename_state);
 	if (req == NULL) {
@@ -1325,6 +1338,18 @@ static struct tevent_req *cli_cifs_rename_send(TALLOC_CTX *mem_ctx,
 		return tevent_req_post(req, ev);
 	}
 
+	/*
+	 * Strip a MSDFS path from fname_dst if we were given one.
+	 */
+	status = cli_dfs_target_check(state,
+				cli,
+				fname_src,
+				fname_dst,
+				&fname_dst);
+	if (tevent_req_nterror(req, status)) {
+		return tevent_req_post(req, ev);
+	}
+
 	SSVAL(state->vwv+0, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY);
 
 	bytes = talloc_array(state, uint8_t, 1);
@@ -1489,6 +1514,7 @@ NTSTATUS cli_rename(struct cli_state *cli,
 	}
 
 	status = cli_rename_recv(req);
+	cli->raw_status = status; /* cli_smb2_rename_recv doesn't set this */
 
  fail:
 	TALLOC_FREE(frame);
@@ -1517,6 +1543,7 @@ static struct tevent_req *cli_ntrename_internal_send(TALLOC_CTX *mem_ctx,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list