// 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;
}

static int get_session(struct cifs_mount_ctx *mnt_ctx, const char *full_path)
{
	struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
	int rc;

	ctx->leaf_fullpath = (char *)full_path;
	rc = cifs_mount_get_session(mnt_ctx);
	ctx->leaf_fullpath = NULL;

	return rc;
}

/*
 * Get an active reference of @ses so that next call to cifs_put_tcon() won't
 * release it as any new DFS referrals must go through its IPC tcon.
 */
static void add_root_smb_session(struct cifs_mount_ctx *mnt_ctx)
{
	struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
	struct cifs_ses *ses = mnt_ctx->ses;

	if (ses) {
		spin_lock(&cifs_tcp_ses_lock);
		cifs_smb_ses_inc_refcount(ses);
		spin_unlock(&cifs_tcp_ses_lock);
	}
	ctx->dfs_root_ses = ses;
}

static inline int parse_dfs_target(struct smb3_fs_context *ctx,
				   struct dfs_ref_walk *rw,
				   struct dfs_info3_param *tgt)
{
	int rc;
	const char *fpath = ref_walk_fpath(rw) + 1;

	rc = ref_walk_get_tgt(rw, tgt);
	if (!rc)
		rc = dfs_parse_target_referral(fpath, tgt, ctx);
	return rc;
}

static int set_ref_paths(struct cifs_mount_ctx *mnt_ctx,
			 struct dfs_info3_param *tgt,
			 struct dfs_ref_walk *rw)
{
	struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
	struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
	char *ref_path, *full_path;
	int rc;

	full_path = smb3_fs_context_fullpath(ctx, CIFS_DIR_SEP(cifs_sb));
	if (IS_ERR(full_path))
		return PTR_ERR(full_path);

	if (!tgt || (tgt->server_type == DFS_TYPE_LINK &&
		     DFS_INTERLINK(tgt->flags)))
		ref_path = dfs_get_path(cifs_sb, ctx->UNC);
	else
		ref_path = dfs_get_path(cifs_sb, full_path);
	if (IS_ERR(ref_path)) {
		rc = PTR_ERR(ref_path);
		kfree(full_path);
		return rc;
	}
	ref_walk_path(rw) = ref_path;
	ref_walk_fpath(rw) = full_path;
	return 0;
}

static int __dfs_referral_walk(struct cifs_mount_ctx *mnt_ctx,
			       struct dfs_ref_walk *rw)
{
	struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
	struct dfs_info3_param tgt = {};
	bool is_refsrv;
	int rc = -ENOENT;

again:
	do {
		if (ref_walk_empty(rw)) {
			rc = dfs_get_referral(mnt_ctx, ref_walk_path(rw) + 1,
					      NULL, ref_walk_tl(rw));
			if (rc) {
				rc = cifs_mount_get_tcon(mnt_ctx);
				if (!rc)
					rc = cifs_is_path_remote(mnt_ctx);
				continue;
			}
			if (!ref_walk_num_tgts(rw)) {
				rc = -ENOENT;
				continue;
			}
		}

		while (ref_walk_next_tgt(rw)) {
			rc = parse_dfs_target(ctx, rw, &tgt);
			if (rc)
				continue;

			cifs_mount_put_conns(mnt_ctx);
			rc = get_session(mnt_ctx, ref_walk_path(rw));
			if (rc)
				continue;

			is_refsrv = tgt.server_type == DFS_TYPE_ROOT ||
				DFS_INTERLINK(tgt.flags);
			ref_walk_set_tgt_hint(rw);

			if (tgt.flags & DFSREF_STORAGE_SERVER) {
				rc = cifs_mount_get_tcon(mnt_ctx);
				if (!rc)
					rc = cifs_is_path_remote(mnt_ctx);
				if (!rc)
					break;
				if (rc != -EREMOTE)
					continue;
			}

			if (is_refsrv)
				add_root_smb_session(mnt_ctx);

			rc = ref_walk_advance(rw);
			if (!rc) {
				rc = set_ref_paths(mnt_ctx, &tgt, rw);
				if (!rc) {
					rc = -EREMOTE;
					goto again;
				}
			}
			if (rc != -ELOOP)
				goto out;
		}
	} while (rc && ref_walk_descend(rw));

out:
	free_dfs_info_param(&tgt);
	return rc;
}

static int dfs_referral_walk(struct cifs_mount_ctx *mnt_ctx)
{
	struct dfs_ref_walk *rw;
	int rc;

	rw = ref_walk_alloc();
	if (IS_ERR(rw))
		return PTR_ERR(rw);

	ref_walk_init(rw);
	rc = set_ref_paths(mnt_ctx, NULL, rw);
	if (!rc)
		rc = __dfs_referral_walk(mnt_ctx, rw);
	ref_walk_free(rw);
	return rc;
}

static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx)
{
	struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
	struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
	struct cifs_tcon *tcon;
	char *origin_fullpath;
	bool new_tcon = true;
	int rc;

	origin_fullpath = dfs_get_path(cifs_sb, ctx->source);
	if (IS_ERR(origin_fullpath))
		return PTR_ERR(origin_fullpath);

	rc = dfs_referral_walk(mnt_ctx);
	if (!rc) {
		/*
		 * Prevent superblock from being created with any missing
		 * connections.
		 */
		if (WARN_ON(!mnt_ctx->server))
			rc = -EHOSTDOWN;
		else if (WARN_ON(!mnt_ctx->ses))
			rc = -EACCES;
		else if (WARN_ON(!mnt_ctx->tcon))
			rc = -ENOENT;
	}
	if (rc)
		goto out;

	tcon = mnt_ctx->tcon;
	spin_lock(&tcon->tc_lock);
	if (!tcon->origin_fullpath) {
		tcon->origin_fullpath = origin_fullpath;
		origin_fullpath = NULL;
	} else {
		new_tcon = false;
	}
	spin_unlock(&tcon->tc_lock);

	if (new_tcon) {
		queue_delayed_work(dfscache_wq, &tcon->dfs_cache_work,
				   dfs_cache_get_ttl() * HZ);
	}

out:
	kfree(origin_fullpath);
	return rc;
}

/*
 * If @ctx->dfs_automount, then update @ctx->dstaddr earlier with the DFS root
 * server from where we'll start following any referrals.  Otherwise rely on the
 * value provided by mount(2) as the user might not have dns_resolver key set up
 * and therefore failing to upcall to resolve UNC hostname under @ctx->source.
 */
static int update_fs_context_dstaddr(struct smb3_fs_context *ctx)
{
	struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
	int rc = 0;

	if (!ctx->nodfs && ctx->dfs_automount) {
		rc = dns_resolve_server_name_to_ip(ctx->source, addr, NULL);
		if (!rc)
			cifs_set_port(addr, ctx->port);
		ctx->dfs_automount = false;
	}
	return rc;
}

int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
{
	struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
	bool nodfs = ctx->nodfs;
	int rc;

	rc = update_fs_context_dstaddr(ctx);
	if (rc)
		return rc;

	*isdfs = false;
	rc = get_session(mnt_ctx, NULL);
	if (rc)
		return rc;

	/*
	 * If called with 'nodfs' mount option, then skip DFS resolving.  Otherwise unconditionally
	 * try to get an DFS referral (even cached) to determine whether it is an DFS mount.
	 *
	 * Skip prefix path to provide support for DFS referrals from w2k8 servers which don't seem
	 * to respond with PATH_NOT_COVERED to requests that include the prefix.
	 */
	if (!nodfs) {
		rc = dfs_get_referral(mnt_ctx, ctx->UNC + 1, NULL, NULL);
		if (rc) {
			cifs_dbg(FYI, "%s: no dfs referral for %s: %d\n",
				 __func__, ctx->UNC + 1, rc);
			cifs_dbg(FYI, "%s: assuming non-dfs mount...\n", __func__);
			nodfs = true;
		}
	}
	if (nodfs) {
		rc = cifs_mount_get_tcon(mnt_ctx);
		if (!rc)
			rc = cifs_is_path_remote(mnt_ctx);
		return rc;
	}

	*isdfs = true;
	add_root_smb_session(mnt_ctx);
	rc = __dfs_mount_share(mnt_ctx);
	dfs_put_root_smb_sessions(mnt_ctx);
	return rc;
}

static int target_share_matches_server(struct TCP_Server_Info *server, char *share,
				       bool *target_match)
{
	int rc = 0;
	const char *dfs_host;
	size_t dfs_host_len;

	*target_match = true;
	extract_unc_hostname(share, &dfs_host, &dfs_host_len);

	/* Check if hostnames or addresses match */
	cifs_server_lock(server);
	if (dfs_host_len != strlen(server->hostname) ||
	    strncasecmp(dfs_host, server->hostname, dfs_host_len)) {
		cifs_dbg(FYI, "%s: %.*s doesn't match %s\n", __func__,
			 (int)dfs_host_len, dfs_host, server->hostname);
		rc = match_target_ip(server, dfs_host, dfs_host_len, target_match);
		if (rc)
			cifs_dbg(VFS, "%s: failed to match target ip: %d\n", __func__, rc);
	}
	cifs_server_unlock(server);
	return rc;
}

static int tree_connect_dfs_target(const unsigned int xid,
				   struct cifs_tcon *tcon,
				   struct cifs_sb_info *cifs_sb,
				   char *tree, bool islink,
				   struct dfs_cache_tgt_list *tl)
{
	const struct smb_version_operations *ops = tcon->ses->server->ops;
	struct TCP_Server_Info *server = tcon->ses->server;
	struct dfs_cache_tgt_iterator *tit;
	char *share = NULL, *prefix = NULL;
	bool target_match;
	int rc = -ENOENT;

	/* Try to tree connect to all dfs targets */
	for (tit = dfs_cache_get_tgt_iterator(tl);
	     tit; tit = dfs_cache_get_next_tgt(tl, tit)) {
		kfree(share);
		kfree(prefix);
		share = prefix = NULL;

		/* Check if share matches with tcp ses */
		rc = dfs_cache_get_tgt_share(server->leaf_fullpath + 1, tit, &share, &prefix);
		if (rc) {
			cifs_dbg(VFS, "%s: failed to parse target share: %d\n", __func__, rc);
			break;
		}

		rc = target_share_matches_server(server, share, &target_match);
		if (rc)
			break;
		if (!target_match) {
			rc = -EHOSTUNREACH;
			continue;
		}

		dfs_cache_noreq_update_tgthint(server->leaf_fullpath + 1, tit);
		scnprintf(tree, MAX_TREE_SIZE, "\\%s", share);
		rc = ops->tree_connect(xid, tcon->ses, tree,
				       tcon, tcon->ses->local_nls);
		if (islink && !rc && cifs_sb)
			rc = cifs_update_super_prepath(cifs_sb, prefix);
		break;
	}

	kfree(share);
	kfree(prefix);
	dfs_cache_free_tgts(tl);
	return rc;
}

int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc)
{
	int rc;
	struct TCP_Server_Info *server = tcon->ses->server;
	const struct smb_version_operations *ops = server->ops;
	DFS_CACHE_TGT_LIST(tl);
	struct cifs_sb_info *cifs_sb = NULL;
	struct super_block *sb = NULL;
	struct dfs_info3_param ref = {0};
	char *tree;

	/* only send once per connect */
	spin_lock(&tcon->tc_lock);

	/* if tcon is marked for needing reconnect, update state */
	if (tcon->need_reconnect)
		tcon->status = TID_NEED_TCON;

	if (tcon->status == TID_GOOD) {
		spin_unlock(&tcon->tc_lock);
		return 0;
	}

	if (tcon->status != TID_NEW &&
	    tcon->status != TID_NEED_TCON) {
		spin_unlock(&tcon->tc_lock);
		return -EHOSTDOWN;
	}

	tcon->status = TID_IN_TCON;
	spin_unlock(&tcon->tc_lock);

	tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
	if (!tree) {
		rc = -ENOMEM;
		goto out;
	}

	if (tcon->ipc) {
		cifs_server_lock(server);
		scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname);
		cifs_server_unlock(server);
		rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc);
		goto out;
	}

	sb = cifs_get_dfs_tcon_super(tcon);
	if (!IS_ERR(sb))
		cifs_sb = CIFS_SB(sb);

	/* Tree connect to last share in @tcon->tree_name if no DFS referral */
	if (!server->leaf_fullpath ||
	    dfs_cache_noreq_find(server->leaf_fullpath + 1, &ref, &tl)) {
		rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name,
				       tcon, tcon->ses->local_nls);
		goto out;
	}

	rc = tree_connect_dfs_target(xid, tcon, cifs_sb, tree, ref.server_type == DFS_TYPE_LINK,
				     &tl);
	free_dfs_info_param(&ref);

out:
	kfree(tree);
	cifs_put_tcp_super(sb);

	if (rc) {
		spin_lock(&tcon->tc_lock);
		if (tcon->status == TID_IN_TCON)
			tcon->status = TID_NEED_TCON;
		spin_unlock(&tcon->tc_lock);
	} else {
		spin_lock(&tcon->tc_lock);
		if (tcon->status == TID_IN_TCON)
			tcon->status = TID_GOOD;
		tcon->need_reconnect = false;
		spin_unlock(&tcon->tc_lock);
	}

	return rc;
}
