Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

smb: client: don't trust DFSREF_STORAGE_SERVER bit

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>

authored by

Paulo Alcantara and committed by
Steve French
77c2e45d 2014c95a

+16 -14
+16 -14
fs/smb/client/dfs.c
··· 150 150 if (rc) 151 151 continue; 152 152 153 - if (tgt.flags & DFSREF_STORAGE_SERVER) { 154 - rc = cifs_mount_get_tcon(mnt_ctx); 155 - if (!rc) 156 - rc = cifs_is_path_remote(mnt_ctx); 153 + rc = cifs_mount_get_tcon(mnt_ctx); 154 + if (rc) { 155 + if (tgt.server_type == DFS_TYPE_LINK && 156 + DFS_INTERLINK(tgt.flags)) 157 + rc = -EREMOTE; 158 + } else { 159 + rc = cifs_is_path_remote(mnt_ctx); 157 160 if (!rc) { 158 161 ref_walk_set_tgt_hint(rw); 159 162 break; 160 163 } 161 - if (rc != -EREMOTE) 162 - continue; 163 164 } 164 - 165 - rc = ref_walk_advance(rw); 166 - if (!rc) { 167 - rc = setup_dfs_ref(&tgt, rw); 168 - if (rc) 169 - break; 170 - ref_walk_mark_end(rw); 171 - goto again; 165 + if (rc == -EREMOTE) { 166 + rc = ref_walk_advance(rw); 167 + if (!rc) { 168 + rc = setup_dfs_ref(&tgt, rw); 169 + if (rc) 170 + break; 171 + ref_walk_mark_end(rw); 172 + goto again; 173 + } 172 174 } 173 175 } 174 176 } while (rc && ref_walk_descend(rw));