summaryrefslogtreecommitdiff
path: root/fs/smb/client/dfs.c
diff options
context:
space:
mode:
authorPaulo Alcantara <pc@manguebit.com>2025-01-03 16:58:12 -0300
committerSteve French <stfrench@microsoft.com>2025-01-19 19:34:00 -0600
commitad46faff1afcc8db72f9954a6ea2296d31259217 (patch)
tree7938327a62e8c35757874d52a965e84029f71c26 /fs/smb/client/dfs.c
parent0e8ae9b953bc2c12aebd21e1e552e5deb1a0ff1e (diff)
smb: client: fix DFS mount against old servers with NTLMSSP
Old Windows servers will return not fully qualified DFS targets by default as specified in MS-DFSC 3.2.5.5 Receiving a Root Referral Request or Link Referral Request | Servers SHOULD<30> return fully qualified DNS host names of | targets in responses to root referral requests and link referral | requests. | ... | <30> Section 3.2.5.5: By default, Windows Server 2003, Windows | Server 2008, Windows Server 2008 R2, Windows Server 2012, and | Windows Server 2012 R2 return DNS host names that are not fully | qualified for targets. Fix this by converting all NetBIOS host names from DFS targets to FQDNs and try resolving them first if DNS domain name was provided in NTLMSSP CHALLENGE_MESSAGE message from previous SMB2_SESSION_SETUP. This also prevents the client from translating the DFS target hostnames to another domain depending on the network domain search order. Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/smb/client/dfs.c')
-rw-r--r--fs/smb/client/dfs.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/fs/smb/client/dfs.c b/fs/smb/client/dfs.c
index 4647df9e1e3b..09d8808cd2e0 100644
--- a/fs/smb/client/dfs.c
+++ b/fs/smb/client/dfs.c
@@ -9,6 +9,8 @@
#include "fs_context.h"
#include "dfs.h"
+#define DFS_DOM(ctx) (ctx->dfs_root_ses ? ctx->dfs_root_ses->dns_dom : NULL)
+
/**
* dfs_parse_target_referral - set fs context for dfs target referral
*
@@ -46,8 +48,9 @@ int dfs_parse_target_referral(const char *full_path, const struct dfs_info3_para
if (rc)
goto out;
- rc = dns_resolve_server_name_to_ip(path, (struct sockaddr *)&ctx->dstaddr, NULL);
-
+ rc = dns_resolve_server_name_to_ip(DFS_DOM(ctx), path,
+ (struct sockaddr *)&ctx->dstaddr,
+ NULL);
out:
kfree(path);
return rc;
@@ -59,8 +62,9 @@ static int get_session(struct cifs_mount_ctx *mnt_ctx, const char *full_path)
int rc;
ctx->leaf_fullpath = (char *)full_path;
+ ctx->dns_dom = DFS_DOM(ctx);
rc = cifs_mount_get_session(mnt_ctx);
- ctx->leaf_fullpath = NULL;
+ ctx->leaf_fullpath = ctx->dns_dom = NULL;
return rc;
}
@@ -264,7 +268,8 @@ static int update_fs_context_dstaddr(struct smb3_fs_context *ctx)
int rc = 0;
if (!ctx->nodfs && ctx->dfs_automount) {
- rc = dns_resolve_server_name_to_ip(ctx->source, addr, NULL);
+ rc = dns_resolve_server_name_to_ip(NULL, ctx->source,
+ addr, NULL);
if (!rc)
cifs_set_port(addr, ctx->port);
ctx->dfs_automount = false;