/*
 *   fs/cifs/ioctl.c
 *
 *   vfs operations that deal with io control
 *
 *   Copyright (C) International Business Machines  Corp., 2005,2013
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *   the GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <linux/fs.h>
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsproto.h"
#include "cifs_debug.h"
#include "cifsfs.h"
#include "cifs_ioctl.h"
#include "smb2proto.h"
#include <linux/btrfs.h>

static long cifs_ioctl_query_info(unsigned int xid, struct file *filep,
				  unsigned long p)
{
	struct inode *inode = file_inode(filep);
	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
	struct dentry *dentry = filep->f_path.dentry;
	const unsigned char *path;
	void *page = alloc_dentry_path();
	__le16 *utf16_path = NULL, root_path;
	int rc = 0;

	path = build_path_from_dentry(dentry, page);
	if (IS_ERR(path)) {
		free_dentry_path(page);
		return PTR_ERR(path);
	}

	cifs_dbg(FYI, "%s %s\n", __func__, path);

	if (!path[0]) {
		root_path = 0;
		utf16_path = &root_path;
	} else {
		utf16_path = cifs_convert_path_to_utf16(path + 1, cifs_sb);
		if (!utf16_path) {
			rc = -ENOMEM;
			goto ici_exit;
		}
	}

	if (tcon->ses->server->ops->ioctl_query_info)
		rc = tcon->ses->server->ops->ioctl_query_info(
				xid, tcon, cifs_sb, utf16_path,
				filep->private_data ? 0 : 1, p);
	else
		rc = -EOPNOTSUPP;

 ici_exit:
	if (utf16_path != &root_path)
		kfree(utf16_path);
	free_dentry_path(page);
	return rc;
}

static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file,
			unsigned long srcfd)
{
	int rc;
	struct fd src_file;
	struct inode *src_inode;

	cifs_dbg(FYI, "ioctl copychunk range\n");
	/* the destination must be opened for writing */
	if (!(dst_file->f_mode & FMODE_WRITE)) {
		cifs_dbg(FYI, "file target not open for write\n");
		return -EINVAL;
	}

	/* check if target volume is readonly and take reference */
	rc = mnt_want_write_file(dst_file);
	if (rc) {
		cifs_dbg(FYI, "mnt_want_write failed with rc %d\n", rc);
		return rc;
	}

	src_file = fdget(srcfd);
	if (!src_file.file) {
		rc = -EBADF;
		goto out_drop_write;
	}

	if (src_file.file->f_op->unlocked_ioctl != cifs_ioctl) {
		rc = -EBADF;
		cifs_dbg(VFS, "src file seems to be from a different filesystem type\n");
		goto out_fput;
	}

	src_inode = file_inode(src_file.file);
	rc = -EINVAL;
	if (S_ISDIR(src_inode->i_mode))
		goto out_fput;

	rc = cifs_file_copychunk_range(xid, src_file.file, 0, dst_file, 0,
					src_inode->i_size, 0);
	if (rc > 0)
		rc = 0;
out_fput:
	fdput(src_file);
out_drop_write:
	mnt_drop_write_file(dst_file);
	return rc;
}

static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon,
				void __user *arg)
{
	int rc = 0;
	struct smb_mnt_fs_info *fsinf;

	fsinf = kzalloc(sizeof(struct smb_mnt_fs_info), GFP_KERNEL);
	if (fsinf == NULL)
		return -ENOMEM;

	fsinf->version = 1;
	fsinf->protocol_id = tcon->ses->server->vals->protocol_id;
	fsinf->device_characteristics =
			le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics);
	fsinf->device_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
	fsinf->fs_attributes = le32_to_cpu(tcon->fsAttrInfo.Attributes);
	fsinf->max_path_component =
		le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength);
	fsinf->vol_serial_number = tcon->vol_serial_number;
	fsinf->vol_create_time = le64_to_cpu(tcon->vol_create_time);
	fsinf->share_flags = tcon->share_flags;
	fsinf->share_caps = le32_to_cpu(tcon->capabilities);
	fsinf->sector_flags = tcon->ss_flags;
	fsinf->optimal_sector_size = tcon->perf_sector_size;
	fsinf->max_bytes_chunk = tcon->max_bytes_chunk;
	fsinf->maximal_access = tcon->maximal_access;
	fsinf->cifs_posix_caps = le64_to_cpu(tcon->fsUnixInfo.Capability);

	if (copy_to_user(arg, fsinf, sizeof(struct smb_mnt_fs_info)))
		rc = -EFAULT;

	kfree(fsinf);
	return rc;
}

static int cifs_shutdown(struct super_block *sb, unsigned long arg)
{
	struct cifs_sb_info *sbi = CIFS_SB(sb);
	__u32 flags;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (get_user(flags, (__u32 __user *)arg))
		return -EFAULT;

	if (flags > CIFS_GOING_FLAGS_NOLOGFLUSH)
		return -EINVAL;

	if (cifs_forced_shutdown(sbi))
		return 0;

	cifs_dbg(VFS, "shut down requested (%d)", flags);
/*	trace_cifs_shutdown(sb, flags);*/

	/*
	 * see:
	 *   https://man7.org/linux/man-pages/man2/ioctl_xfs_goingdown.2.html
	 * for more information and description of original intent of the flags
	 */
	switch (flags) {
	/*
	 * We could add support later for default flag which requires:
	 *     "Flush all dirty data and metadata to disk"
	 * would need to call syncfs or equivalent to flush page cache for
	 * the mount and then issue fsync to server (if nostrictsync not set)
	 */
	case CIFS_GOING_FLAGS_DEFAULT:
		cifs_dbg(FYI, "shutdown with default flag not supported\n");
		return -EINVAL;
	/*
	 * FLAGS_LOGFLUSH is easy since it asks to write out metadata (not
	 * data) but metadata writes are not cached on the client, so can treat
	 * it similarly to NOLOGFLUSH
	 */
	case CIFS_GOING_FLAGS_LOGFLUSH:
	case CIFS_GOING_FLAGS_NOLOGFLUSH:
		sbi->mnt_cifs_flags |= CIFS_MOUNT_SHUTDOWN;
		return 0;
	default:
		return -EINVAL;
	}
	return 0;
}

static int cifs_dump_full_key(struct cifs_tcon *tcon, unsigned long arg)
{
	struct smb3_full_key_debug_info pfull_key_inf;
	__u64 suid;
	struct list_head *tmp;
	struct cifs_ses *ses;
	bool found = false;

	if (!smb3_encryption_required(tcon))
		return -EOPNOTSUPP;

	ses = tcon->ses; /* default to user id for current user */
	if (get_user(suid, (__u64 __user *)arg))
		suid = 0;
	if (suid) {
		/* search to see if there is a session with a matching SMB UID */
		spin_lock(&cifs_tcp_ses_lock);
		list_for_each(tmp, &tcon->ses->server->smb_ses_list) {
			ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
			if (ses->Suid == suid) {
				found = true;
				break;
			}
		}
		spin_unlock(&cifs_tcp_ses_lock);
		if (found == false)
			return -EINVAL;
	} /* else uses default user's SMB UID (ie current user) */

	pfull_key_inf.cipher_type = le16_to_cpu(ses->server->cipher_type);
	pfull_key_inf.Suid = ses->Suid;
	memcpy(pfull_key_inf.auth_key, ses->auth_key.response,
	       16 /* SMB2_NTLMV2_SESSKEY_SIZE */);
	memcpy(pfull_key_inf.smb3decryptionkey, ses->smb3decryptionkey,
	       32 /* SMB3_ENC_DEC_KEY_SIZE */);
	memcpy(pfull_key_inf.smb3encryptionkey,
	       ses->smb3encryptionkey, 32 /* SMB3_ENC_DEC_KEY_SIZE */);
	if (copy_to_user((void __user *)arg, &pfull_key_inf,
			 sizeof(struct smb3_full_key_debug_info)))
		return -EFAULT;

	return 0;
}

long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
{
	struct inode *inode = file_inode(filep);
	struct smb3_key_debug_info pkey_inf;
	int rc = -ENOTTY; /* strange error - but the precedent */
	unsigned int xid;
	struct cifsFileInfo *pSMBFile = filep->private_data;
	struct cifs_tcon *tcon;
	struct tcon_link *tlink;
	struct cifs_sb_info *cifs_sb;
	__u64	ExtAttrBits = 0;
	__u64   caps;

	xid = get_xid();

	cifs_dbg(FYI, "cifs ioctl 0x%x\n", command);
	switch (command) {
		case FS_IOC_GETFLAGS:
			if (pSMBFile == NULL)
				break;
			tcon = tlink_tcon(pSMBFile->tlink);
			caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
#ifdef CONFIG_CIFS_POSIX
			if (CIFS_UNIX_EXTATTR_CAP & caps) {
				__u64	ExtAttrMask = 0;
				rc = CIFSGetExtAttr(xid, tcon,
						    pSMBFile->fid.netfid,
						    &ExtAttrBits, &ExtAttrMask);
				if (rc == 0)
					rc = put_user(ExtAttrBits &
						FS_FL_USER_VISIBLE,
						(int __user *)arg);
				if (rc != EOPNOTSUPP)
					break;
			}
#endif /* CONFIG_CIFS_POSIX */
			rc = 0;
			if (CIFS_I(inode)->cifsAttrs & ATTR_COMPRESSED) {
				/* add in the compressed bit */
				ExtAttrBits = FS_COMPR_FL;
				rc = put_user(ExtAttrBits & FS_FL_USER_VISIBLE,
					      (int __user *)arg);
			}
			break;
		case FS_IOC_SETFLAGS:
			if (pSMBFile == NULL)
				break;
			tcon = tlink_tcon(pSMBFile->tlink);
			caps = le64_to_cpu(tcon->fsUnixInfo.Capability);

			if (get_user(ExtAttrBits, (int __user *)arg)) {
				rc = -EFAULT;
				break;
			}

			/*
			 * if (CIFS_UNIX_EXTATTR_CAP & caps)
			 *	rc = CIFSSetExtAttr(xid, tcon,
			 *		       pSMBFile->fid.netfid,
			 *		       extAttrBits,
			 *		       &ExtAttrMask);
			 * if (rc != EOPNOTSUPP)
			 *	break;
			 */

			/* Currently only flag we can set is compressed flag */
			if ((ExtAttrBits & FS_COMPR_FL) == 0)
				break;

			/* Try to set compress flag */
			if (tcon->ses->server->ops->set_compression) {
				rc = tcon->ses->server->ops->set_compression(
							xid, tcon, pSMBFile);
				cifs_dbg(FYI, "set compress flag rc %d\n", rc);
			}
			break;
		case CIFS_IOC_COPYCHUNK_FILE:
			rc = cifs_ioctl_copychunk(xid, filep, arg);
			break;
		case CIFS_QUERY_INFO:
			rc = cifs_ioctl_query_info(xid, filep, arg);
			break;
		case CIFS_IOC_SET_INTEGRITY:
			if (pSMBFile == NULL)
				break;
			tcon = tlink_tcon(pSMBFile->tlink);
			if (tcon->ses->server->ops->set_integrity)
				rc = tcon->ses->server->ops->set_integrity(xid,
						tcon, pSMBFile);
			else
				rc = -EOPNOTSUPP;
			break;
		case CIFS_IOC_GET_MNT_INFO:
			if (pSMBFile == NULL)
				break;
			tcon = tlink_tcon(pSMBFile->tlink);
			rc = smb_mnt_get_fsinfo(xid, tcon, (void __user *)arg);
			break;
		case CIFS_ENUMERATE_SNAPSHOTS:
			if (pSMBFile == NULL)
				break;
			if (arg == 0) {
				rc = -EINVAL;
				goto cifs_ioc_exit;
			}
			tcon = tlink_tcon(pSMBFile->tlink);
			if (tcon->ses->server->ops->enum_snapshots)
				rc = tcon->ses->server->ops->enum_snapshots(xid, tcon,
						pSMBFile, (void __user *)arg);
			else
				rc = -EOPNOTSUPP;
			break;
		case CIFS_DUMP_KEY:
			if (pSMBFile == NULL)
				break;
			if (!capable(CAP_SYS_ADMIN)) {
				rc = -EACCES;
				break;
			}

			tcon = tlink_tcon(pSMBFile->tlink);
			if (!smb3_encryption_required(tcon)) {
				rc = -EOPNOTSUPP;
				break;
			}
			pkey_inf.cipher_type =
				le16_to_cpu(tcon->ses->server->cipher_type);
			pkey_inf.Suid = tcon->ses->Suid;
			memcpy(pkey_inf.auth_key, tcon->ses->auth_key.response,
					16 /* SMB2_NTLMV2_SESSKEY_SIZE */);
			memcpy(pkey_inf.smb3decryptionkey,
			      tcon->ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
			memcpy(pkey_inf.smb3encryptionkey,
			      tcon->ses->smb3encryptionkey, SMB3_SIGN_KEY_SIZE);
			if (copy_to_user((void __user *)arg, &pkey_inf,
					sizeof(struct smb3_key_debug_info)))
				rc = -EFAULT;
			else
				rc = 0;
			break;
		/*
		 * Dump full key (32 bytes instead of 16 bytes) is
		 * needed if GCM256 (stronger encryption) negotiated
		 */
		case CIFS_DUMP_FULL_KEY:
			if (pSMBFile == NULL)
				break;
			if (!capable(CAP_SYS_ADMIN)) {
				rc = -EACCES;
				break;
			}
			tcon = tlink_tcon(pSMBFile->tlink);
			rc = cifs_dump_full_key(tcon, arg);

			break;
		case CIFS_IOC_NOTIFY:
			if (!S_ISDIR(inode->i_mode)) {
				/* Notify can only be done on directories */
				rc = -EOPNOTSUPP;
				break;
			}
			cifs_sb = CIFS_SB(inode->i_sb);
			tlink = cifs_sb_tlink(cifs_sb);
			if (IS_ERR(tlink)) {
				rc = PTR_ERR(tlink);
				break;
			}
			tcon = tlink_tcon(tlink);
			if (tcon && tcon->ses->server->ops->notify) {
				rc = tcon->ses->server->ops->notify(xid,
						filep, (void __user *)arg);
				cifs_dbg(FYI, "ioctl notify rc %d\n", rc);
			} else
				rc = -EOPNOTSUPP;
			cifs_put_tlink(tlink);
			break;
		case CIFS_IOC_SHUTDOWN:
			rc = cifs_shutdown(inode->i_sb, arg);
			break;
		default:
			cifs_dbg(FYI, "unsupported ioctl\n");
			break;
	}
cifs_ioc_exit:
	free_xid(xid);
	return rc;
}
