| // 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; |
| |
| rc = dns_resolve_server_name_to_ip(path, (struct sockaddr *)&ctx->dstaddr, NULL); |
| |
| out: |
| kfree(path); |
| return rc; |
| } |