Windows 2008 CIFS servers do not always return PATH_NOT_COVERED when
attempting to access a DFS share.  Therefore, when checking for remote
shares, unconditionally ask for a DFS referral for the UNC (w/out prepath)
before continuing with previous behavior of attempting to access the UNC +
prepath and checking for PATH_NOT_COVERED.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=31092

Signed-off-by: Sean Finney <[email protected]>
---
 fs/cifs/connect.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 96544a4..7e4ca38 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2874,6 +2874,56 @@ try_mount_again:
                               (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
 
 remote_path_check:
+#ifdef CONFIG_CIFS_DFS_UPCALL
+       /*
+        * Perform an unconditional check for whether there are
+        * DFS referrals for this path (without prefix), to provide
+        * some limited support for domain DFS referrals on w2k8
+        */
+       if (referral_walks_count == 0) {
+               cFYI(1, "Getting referral for: %s", volume_info->UNC);
+               rc = get_dfs_path(xid, pSesInfo , volume_info->UNC + 1,
+                       cifs_sb->local_nls, &num_referrals, &referrals,
+                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+               if (!rc && num_referrals > 0) {
+                       char *fake_devname = NULL;
+
+                       full_path = build_unc_path_to_root(volume_info,
+                                                          cifs_sb);
+                       if (IS_ERR(full_path)) {
+                               rc = PTR_ERR(full_path);
+                               goto mount_fail_check;
+                       }
+
+                       if (mount_data != mount_data_global)
+                               kfree(mount_data);
+
+                       mount_data = cifs_compose_mount_options(
+                                       cifs_sb->mountdata, full_path + 1,
+                                       referrals, &fake_devname);
+
+                       free_dfs_info_array(referrals, num_referrals);
+                       kfree(fake_devname);
+
+                       if (IS_ERR(mount_data)) {
+                               rc = PTR_ERR(mount_data);
+                               mount_data = NULL;
+                               goto mount_fail_check;
+                       }
+
+                       if (tcon)
+                               cifs_put_tcon(tcon);
+                       else if (pSesInfo)
+                               cifs_put_smb_ses(pSesInfo);
+
+                       cleanup_volume_info(&volume_info);
+                       referral_walks_count++;
+                       FreeXid(xid);
+                       goto try_mount_again;
+               }
+       }
+#endif
+
        /* check if a whole path (including prepath) is not remote */
        if (!rc && tcon) {
                /* build_path_to_root works only when we have a valid tcon */
-- 
1.7.2.3

--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to