2022-10-05 05:41:27 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2022 Paulo Alcantara <palcantara@suse.de>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "cifsproto.h"
|
|
|
|
#include "cifs_debug.h"
|
|
|
|
#include "dns_resolve.h"
|
|
|
|
#include "fs_context.h"
|
|
|
|
#include "dfs.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* dfs_parse_target_referral - set fs context for dfs target referral
|
|
|
|
*
|
|
|
|
* @full_path: full path in UNC format.
|
|
|
|
* @ref: dfs referral pointer.
|
|
|
|
* @ctx: smb3 fs context pointer.
|
|
|
|
*
|
|
|
|
* Return zero if dfs referral was parsed correctly, otherwise non-zero.
|
|
|
|
*/
|
|
|
|
int dfs_parse_target_referral(const char *full_path, const struct dfs_info3_param *ref,
|
|
|
|
struct smb3_fs_context *ctx)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
const char *prepath = NULL;
|
|
|
|
char *path;
|
|
|
|
|
|
|
|
if (!full_path || !*full_path || !ref || !ctx)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (WARN_ON_ONCE(!ref->node_name || ref->path_consumed < 0))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (strlen(full_path) - ref->path_consumed) {
|
|
|
|
prepath = full_path + ref->path_consumed;
|
|
|
|
/* skip initial delimiter */
|
|
|
|
if (*prepath == '/' || *prepath == '\\')
|
|
|
|
prepath++;
|
|
|
|
}
|
|
|
|
|
|
|
|
path = cifs_build_devname(ref->node_name, prepath);
|
|
|
|
if (IS_ERR(path))
|
|
|
|
return PTR_ERR(path);
|
|
|
|
|
|
|
|
rc = smb3_parse_devname(path, ctx);
|
|
|
|
if (rc)
|
|
|
|
goto out;
|
|
|
|
|
2022-10-05 05:41:36 +08:00
|
|
|
rc = dns_resolve_server_name_to_ip(path, (struct sockaddr *)&ctx->dstaddr, NULL);
|
2022-10-05 05:41:27 +08:00
|
|
|
|
|
|
|
out:
|
|
|
|
kfree(path);
|
|
|
|
return rc;
|
|
|
|
}
|