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 <j...@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 <s...@samba.org>
+   * BUG 14674: net ads info shows LDAP Server: 0.0.0.0 depending on contacted
+     server.
+
+o  Pavel Filipenský <pfili...@redhat.com>
+   * BUG 14971: virusfilter_vfs_openat: Not scanned: Directory or special file.
+
+o  Volker Lendecke <v...@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 <me...@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 <a...@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

Reply via email to