]> www.infradead.org Git - users/hch/xfs.git/commitdiff
smb: client: don't trust DFSREF_STORAGE_SERVER bit
authorPaulo Alcantara <pc@manguebit.com>
Wed, 5 Feb 2025 16:03:33 +0000 (13:03 -0300)
committerSteve French <stfrench@microsoft.com>
Thu, 6 Feb 2025 03:09:00 +0000 (21:09 -0600)
Some servers don't respect the DFSREF_STORAGE_SERVER bit, so
unconditionally tree connect to DFS link target and then decide
whether or not continue chasing DFS referrals for DFS interlinks.
Otherwise the client would fail to mount such shares.

Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/dfs.c

index dad521336b5eebb3856dac1ab84244fc55bd4f2b..f65a8a90ba279ae200ed6a918c7136f7b7873de2 100644 (file)
@@ -150,25 +150,27 @@ again:
                        if (rc)
                                continue;
 
-                       if (tgt.flags & DFSREF_STORAGE_SERVER) {
-                               rc = cifs_mount_get_tcon(mnt_ctx);
-                               if (!rc)
-                                       rc = cifs_is_path_remote(mnt_ctx);
+                       rc = cifs_mount_get_tcon(mnt_ctx);
+                       if (rc) {
+                               if (tgt.server_type == DFS_TYPE_LINK &&
+                                   DFS_INTERLINK(tgt.flags))
+                                       rc = -EREMOTE;
+                       } else {
+                               rc = cifs_is_path_remote(mnt_ctx);
                                if (!rc) {
                                        ref_walk_set_tgt_hint(rw);
                                        break;
                                }
-                               if (rc != -EREMOTE)
-                                       continue;
                        }
-
-                       rc = ref_walk_advance(rw);
-                       if (!rc) {
-                               rc = setup_dfs_ref(&tgt, rw);
-                               if (rc)
-                                       break;
-                               ref_walk_mark_end(rw);
-                               goto again;
+                       if (rc == -EREMOTE) {
+                               rc = ref_walk_advance(rw);
+                               if (!rc) {
+                                       rc = setup_dfs_ref(&tgt, rw);
+                                       if (rc)
+                                               break;
+                                       ref_walk_mark_end(rw);
+                                       goto again;
+                               }
                        }
                }
        } while (rc && ref_walk_descend(rw));