77 lines
1.7 KiB
C
77 lines
1.7 KiB
C
|
// 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"
|
||
|
|
||
|
/* Resolve UNC server name and set destination ip address in fs context */
|
||
|
static int resolve_unc(const char *path, struct smb3_fs_context *ctx)
|
||
|
{
|
||
|
int rc;
|
||
|
char *ip = NULL;
|
||
|
|
||
|
rc = dns_resolve_server_name_to_ip(path, &ip, NULL);
|
||
|
if (rc < 0) {
|
||
|
cifs_dbg(FYI, "%s: failed to resolve UNC server name: %d\n", __func__, rc);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
if (!cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip, strlen(ip))) {
|
||
|
cifs_dbg(VFS, "%s: could not determinate destination address\n", __func__);
|
||
|
rc = -EHOSTUNREACH;
|
||
|
} else
|
||
|
rc = 0;
|
||
|
|
||
|
kfree(ip);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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;
|
||
|
|
||
|
rc = resolve_unc(path, ctx);
|
||
|
|
||
|
out:
|
||
|
kfree(path);
|
||
|
return rc;
|
||
|
}
|