File Index
Files and directories
Sign in
FILE

smb2pdu.c

File preview with syntax highlighting.

linux-6.19.14/fs/smb/server/smb2pdu.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *   Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
   4 *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
   5 */
   6
   7#include <crypto/utils.h>
   8#include <linux/inetdevice.h>
   9#include <net/addrconf.h>
  10#include <linux/syscalls.h>
  11#include <linux/namei.h>
  12#include <linux/statfs.h>
  13#include <linux/ethtool.h>
  14#include <linux/falloc.h>
  15#include <linux/mount.h>
  16#include <linux/filelock.h>
  17
  18#include "glob.h"
  19#include "smbfsctl.h"
  20#include "oplock.h"
  21#include "smbacl.h"
  22
  23#include "auth.h"
  24#include "asn1.h"
  25#include "connection.h"
  26#include "transport_ipc.h"
  27#include "../common/smbdirect/smbdirect.h"
  28#include "transport_rdma.h"
  29#include "vfs.h"
  30#include "vfs_cache.h"
  31#include "misc.h"
  32
  33#include "server.h"
  34#include "smb_common.h"
  35#include "../common/smb2status.h"
  36#include "ksmbd_work.h"
  37#include "mgmt/user_config.h"
  38#include "mgmt/share_config.h"
  39#include "mgmt/tree_connect.h"
  40#include "mgmt/user_session.h"
  41#include "mgmt/ksmbd_ida.h"
  42#include "ndr.h"
  43#include "transport_tcp.h"
  44
  45static void __wbuf(struct ksmbd_work *work, void **req, void **rsp)
  46{
  47	if (work->next_smb2_rcv_hdr_off) {
  48		*req = ksmbd_req_buf_next(work);
  49		*rsp = ksmbd_resp_buf_next(work);
  50	} else {
  51		*req = smb_get_msg(work->request_buf);
  52		*rsp = smb_get_msg(work->response_buf);
  53	}
  54}
  55
  56#define WORK_BUFFERS(w, rq, rs)	__wbuf((w), (void **)&(rq), (void **)&(rs))
  57
  58/**
  59 * check_session_id() - check for valid session id in smb header
  60 * @conn:	connection instance
  61 * @id:		session id from smb header
  62 *
  63 * Return:      1 if valid session id, otherwise 0
  64 */
  65static inline bool check_session_id(struct ksmbd_conn *conn, u64 id)
  66{
  67	struct ksmbd_session *sess;
  68
  69	if (id == 0 || id == -1)
  70		return false;
  71
  72	sess = ksmbd_session_lookup_all(conn, id);
  73	if (sess) {
  74		ksmbd_user_session_put(sess);
  75		return true;
  76	}
  77	pr_err("Invalid user session id: %llu\n", id);
  78	return false;
  79}
  80
  81struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn *conn)
  82{
  83	struct channel *chann;
  84
  85	down_read(&sess->chann_lock);
  86	chann = xa_load(&sess->ksmbd_chann_list, (long)conn);
  87	up_read(&sess->chann_lock);
  88
  89	return chann;
  90}
  91
  92/**
  93 * smb2_get_ksmbd_tcon() - get tree connection information using a tree id.
  94 * @work:	smb work
  95 *
  96 * Return:	0 if there is a tree connection matched or these are
  97 *		skipable commands, otherwise error
  98 */
  99int smb2_get_ksmbd_tcon(struct ksmbd_work *work)
 100{
 101	struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work);
 102	unsigned int cmd = le16_to_cpu(req_hdr->Command);
 103	unsigned int tree_id;
 104
 105	if (cmd == SMB2_TREE_CONNECT_HE ||
 106	    cmd ==  SMB2_CANCEL_HE ||
 107	    cmd ==  SMB2_LOGOFF_HE) {
 108		ksmbd_debug(SMB, "skip to check tree connect request\n");
 109		return 0;
 110	}
 111
 112	if (xa_empty(&work->sess->tree_conns)) {
 113		ksmbd_debug(SMB, "NO tree connected\n");
 114		return -ENOENT;
 115	}
 116
 117	tree_id = le32_to_cpu(req_hdr->Id.SyncId.TreeId);
 118
 119	/*
 120	 * If request is not the first in Compound request,
 121	 * Just validate tree id in header with work->tcon->id.
 122	 */
 123	if (work->next_smb2_rcv_hdr_off) {
 124		if (!work->tcon) {
 125			pr_err("The first operation in the compound does not have tcon\n");
 126			return -EINVAL;
 127		}
 128		if (work->tcon->t_state != TREE_CONNECTED)
 129			return -ENOENT;
 130		if (tree_id != UINT_MAX && work->tcon->id != tree_id) {
 131			pr_err("tree id(%u) is different with id(%u) in first operation\n",
 132					tree_id, work->tcon->id);
 133			return -EINVAL;
 134		}
 135		return 1;
 136	}
 137
 138	work->tcon = ksmbd_tree_conn_lookup(work->sess, tree_id);
 139	if (!work->tcon) {
 140		pr_err("Invalid tid %d\n", tree_id);
 141		return -ENOENT;
 142	}
 143
 144	return 1;
 145}
 146
 147/**
 148 * smb2_set_err_rsp() - set error response code on smb response
 149 * @work:	smb work containing response buffer
 150 */
 151void smb2_set_err_rsp(struct ksmbd_work *work)
 152{
 153	struct smb2_err_rsp *err_rsp;
 154
 155	if (work->next_smb2_rcv_hdr_off)
 156		err_rsp = ksmbd_resp_buf_next(work);
 157	else
 158		err_rsp = smb_get_msg(work->response_buf);
 159
 160	if (err_rsp->hdr.Status != STATUS_STOPPED_ON_SYMLINK) {
 161		int err;
 162
 163		err_rsp->StructureSize = SMB2_ERROR_STRUCTURE_SIZE2_LE;
 164		err_rsp->ErrorContextCount = 0;
 165		err_rsp->Reserved = 0;
 166		err_rsp->ByteCount = 0;
 167		err_rsp->ErrorData[0] = 0;
 168		err = ksmbd_iov_pin_rsp(work, (void *)err_rsp,
 169					__SMB2_HEADER_STRUCTURE_SIZE +
 170						SMB2_ERROR_STRUCTURE_SIZE2);
 171		if (err)
 172			work->send_no_response = 1;
 173	}
 174}
 175
 176/**
 177 * is_smb2_neg_cmd() - is it smb2 negotiation command
 178 * @work:	smb work containing smb header
 179 *
 180 * Return:      true if smb2 negotiation command, otherwise false
 181 */
 182bool is_smb2_neg_cmd(struct ksmbd_work *work)
 183{
 184	struct smb2_hdr *hdr = smb_get_msg(work->request_buf);
 185
 186	/* is it SMB2 header ? */
 187	if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
 188		return false;
 189
 190	/* make sure it is request not response message */
 191	if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
 192		return false;
 193
 194	if (hdr->Command != SMB2_NEGOTIATE)
 195		return false;
 196
 197	return true;
 198}
 199
 200/**
 201 * is_smb2_rsp() - is it smb2 response
 202 * @work:	smb work containing smb response buffer
 203 *
 204 * Return:      true if smb2 response, otherwise false
 205 */
 206bool is_smb2_rsp(struct ksmbd_work *work)
 207{
 208	struct smb2_hdr *hdr = smb_get_msg(work->response_buf);
 209
 210	/* is it SMB2 header ? */
 211	if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
 212		return false;
 213
 214	/* make sure it is response not request message */
 215	if (!(hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR))
 216		return false;
 217
 218	return true;
 219}
 220
 221/**
 222 * get_smb2_cmd_val() - get smb command code from smb header
 223 * @work:	smb work containing smb request buffer
 224 *
 225 * Return:      smb2 request command value
 226 */
 227u16 get_smb2_cmd_val(struct ksmbd_work *work)
 228{
 229	struct smb2_hdr *rcv_hdr;
 230
 231	if (work->next_smb2_rcv_hdr_off)
 232		rcv_hdr = ksmbd_req_buf_next(work);
 233	else
 234		rcv_hdr = smb_get_msg(work->request_buf);
 235	return le16_to_cpu(rcv_hdr->Command);
 236}
 237
 238/**
 239 * set_smb2_rsp_status() - set error response code on smb2 header
 240 * @work:	smb work containing response buffer
 241 * @err:	error response code
 242 */
 243void set_smb2_rsp_status(struct ksmbd_work *work, __le32 err)
 244{
 245	struct smb2_hdr *rsp_hdr;
 246
 247	rsp_hdr = smb_get_msg(work->response_buf);
 248	rsp_hdr->Status = err;
 249
 250	work->iov_idx = 0;
 251	work->iov_cnt = 0;
 252	work->next_smb2_rcv_hdr_off = 0;
 253	smb2_set_err_rsp(work);
 254}
 255
 256/**
 257 * init_smb2_neg_rsp() - initialize smb2 response for negotiate command
 258 * @work:	smb work containing smb request buffer
 259 *
 260 * smb2 negotiate response is sent in reply of smb1 negotiate command for
 261 * dialect auto-negotiation.
 262 */
 263int init_smb2_neg_rsp(struct ksmbd_work *work)
 264{
 265	struct smb2_hdr *rsp_hdr;
 266	struct smb2_negotiate_rsp *rsp;
 267	struct ksmbd_conn *conn = work->conn;
 268	int err;
 269
 270	rsp_hdr = smb_get_msg(work->response_buf);
 271	memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
 272	rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER;
 273	rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE;
 274	rsp_hdr->CreditRequest = cpu_to_le16(2);
 275	rsp_hdr->Command = SMB2_NEGOTIATE;
 276	rsp_hdr->Flags = (SMB2_FLAGS_SERVER_TO_REDIR);
 277	rsp_hdr->NextCommand = 0;
 278	rsp_hdr->MessageId = 0;
 279	rsp_hdr->Id.SyncId.ProcessId = 0;
 280	rsp_hdr->Id.SyncId.TreeId = 0;
 281	rsp_hdr->SessionId = 0;
 282	memset(rsp_hdr->Signature, 0, 16);
 283
 284	rsp = smb_get_msg(work->response_buf);
 285
 286	WARN_ON(ksmbd_conn_good(conn));
 287
 288	rsp->StructureSize = cpu_to_le16(65);
 289	ksmbd_debug(SMB, "conn->dialect 0x%x\n", conn->dialect);
 290	rsp->DialectRevision = cpu_to_le16(conn->dialect);
 291	/* Not setting conn guid rsp->ServerGUID, as it
 292	 * not used by client for identifying connection
 293	 */
 294	rsp->Capabilities = cpu_to_le32(conn->vals->req_capabilities);
 295	/* Default Max Message Size till SMB2.0, 64K*/
 296	rsp->MaxTransactSize = cpu_to_le32(conn->vals->max_trans_size);
 297	rsp->MaxReadSize = cpu_to_le32(conn->vals->max_read_size);
 298	rsp->MaxWriteSize = cpu_to_le32(conn->vals->max_write_size);
 299
 300	rsp->SystemTime = cpu_to_le64(ksmbd_systime());
 301	rsp->ServerStartTime = 0;
 302
 303	rsp->SecurityBufferOffset = cpu_to_le16(128);
 304	rsp->SecurityBufferLength = cpu_to_le16(AUTH_GSS_LENGTH);
 305	ksmbd_copy_gss_neg_header((char *)(&rsp->hdr) +
 306		le16_to_cpu(rsp->SecurityBufferOffset));
 307	rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE;
 308	if (server_conf.signing == KSMBD_CONFIG_OPT_MANDATORY)
 309		rsp->SecurityMode |= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE;
 310	err = ksmbd_iov_pin_rsp(work, rsp,
 311				sizeof(struct smb2_negotiate_rsp) + AUTH_GSS_LENGTH);
 312	if (err)
 313		return err;
 314	conn->use_spnego = true;
 315
 316	ksmbd_conn_set_need_negotiate(conn);
 317	return 0;
 318}
 319
 320/**
 321 * smb2_set_rsp_credits() - set number of credits in response buffer
 322 * @work:	smb work containing smb response buffer
 323 */
 324int smb2_set_rsp_credits(struct ksmbd_work *work)
 325{
 326	struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work);
 327	struct smb2_hdr *hdr = ksmbd_resp_buf_next(work);
 328	struct ksmbd_conn *conn = work->conn;
 329	unsigned short credits_requested, aux_max;
 330	unsigned short credit_charge, credits_granted = 0;
 331
 332	if (work->send_no_response)
 333		return 0;
 334
 335	hdr->CreditCharge = req_hdr->CreditCharge;
 336
 337	if (conn->total_credits > conn->vals->max_credits) {
 338		hdr->CreditRequest = 0;
 339		pr_err("Total credits overflow: %d\n", conn->total_credits);
 340		return -EINVAL;
 341	}
 342
 343	credit_charge = max_t(unsigned short,
 344			      le16_to_cpu(req_hdr->CreditCharge), 1);
 345	if (credit_charge > conn->total_credits) {
 346		ksmbd_debug(SMB, "Insufficient credits granted, given: %u, granted: %u\n",
 347			    credit_charge, conn->total_credits);
 348		return -EINVAL;
 349	}
 350
 351	conn->total_credits -= credit_charge;
 352	conn->outstanding_credits -= credit_charge;
 353	credits_requested = max_t(unsigned short,
 354				  le16_to_cpu(req_hdr->CreditRequest), 1);
 355
 356	/* according to smb2.credits smbtorture, Windows server
 357	 * 2016 or later grant up to 8192 credits at once.
 358	 *
 359	 * TODO: Need to adjuct CreditRequest value according to
 360	 * current cpu load
 361	 */
 362	if (hdr->Command == SMB2_NEGOTIATE)
 363		aux_max = 1;
 364	else
 365		aux_max = conn->vals->max_credits - conn->total_credits;
 366	credits_granted = min_t(unsigned short, credits_requested, aux_max);
 367
 368	conn->total_credits += credits_granted;
 369	work->credits_granted += credits_granted;
 370
 371	if (!req_hdr->NextCommand) {
 372		/* Update CreditRequest in last request */
 373		hdr->CreditRequest = cpu_to_le16(work->credits_granted);
 374	}
 375	ksmbd_debug(SMB,
 376		    "credits: requested[%d] granted[%d] total_granted[%d]\n",
 377		    credits_requested, credits_granted,
 378		    conn->total_credits);
 379	return 0;
 380}
 381
 382/**
 383 * init_chained_smb2_rsp() - initialize smb2 chained response
 384 * @work:	smb work containing smb response buffer
 385 */
 386static void init_chained_smb2_rsp(struct ksmbd_work *work)
 387{
 388	struct smb2_hdr *req = ksmbd_req_buf_next(work);
 389	struct smb2_hdr *rsp = ksmbd_resp_buf_next(work);
 390	struct smb2_hdr *rsp_hdr;
 391	struct smb2_hdr *rcv_hdr;
 392	int next_hdr_offset = 0;
 393	int len, new_len;
 394
 395	/* Len of this response = updated RFC len - offset of previous cmd
 396	 * in the compound rsp
 397	 */
 398
 399	/* Storing the current local FID which may be needed by subsequent
 400	 * command in the compound request
 401	 */
 402	if (req->Command == SMB2_CREATE && rsp->Status == STATUS_SUCCESS) {
 403		work->compound_fid = ((struct smb2_create_rsp *)rsp)->VolatileFileId;
 404		work->compound_pfid = ((struct smb2_create_rsp *)rsp)->PersistentFileId;
 405		work->compound_sid = le64_to_cpu(rsp->SessionId);
 406	}
 407
 408	len = get_rfc1002_len(work->response_buf) - work->next_smb2_rsp_hdr_off;
 409	next_hdr_offset = le32_to_cpu(req->NextCommand);
 410
 411	new_len = ALIGN(len, 8);
 412	work->iov[work->iov_idx].iov_len += (new_len - len);
 413	inc_rfc1001_len(work->response_buf, new_len - len);
 414	rsp->NextCommand = cpu_to_le32(new_len);
 415
 416	work->next_smb2_rcv_hdr_off += next_hdr_offset;
 417	work->curr_smb2_rsp_hdr_off = work->next_smb2_rsp_hdr_off;
 418	work->next_smb2_rsp_hdr_off += new_len;
 419	ksmbd_debug(SMB,
 420		    "Compound req new_len = %d rcv off = %d rsp off = %d\n",
 421		    new_len, work->next_smb2_rcv_hdr_off,
 422		    work->next_smb2_rsp_hdr_off);
 423
 424	rsp_hdr = ksmbd_resp_buf_next(work);
 425	rcv_hdr = ksmbd_req_buf_next(work);
 426
 427	if (!(rcv_hdr->Flags & SMB2_FLAGS_RELATED_OPERATIONS)) {
 428		ksmbd_debug(SMB, "related flag should be set\n");
 429		work->compound_fid = KSMBD_NO_FID;
 430		work->compound_pfid = KSMBD_NO_FID;
 431	}
 432	memset((char *)rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
 433	rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER;
 434	rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE;
 435	rsp_hdr->Command = rcv_hdr->Command;
 436
 437	/*
 438	 * Message is response. We don't grant oplock yet.
 439	 */
 440	rsp_hdr->Flags = (SMB2_FLAGS_SERVER_TO_REDIR |
 441				SMB2_FLAGS_RELATED_OPERATIONS);
 442	rsp_hdr->NextCommand = 0;
 443	rsp_hdr->MessageId = rcv_hdr->MessageId;
 444	rsp_hdr->Id.SyncId.ProcessId = rcv_hdr->Id.SyncId.ProcessId;
 445	rsp_hdr->Id.SyncId.TreeId = rcv_hdr->Id.SyncId.TreeId;
 446	rsp_hdr->SessionId = rcv_hdr->SessionId;
 447	memcpy(rsp_hdr->Signature, rcv_hdr->Signature, 16);
 448}
 449
 450/**
 451 * is_chained_smb2_message() - check for chained command
 452 * @work:	smb work containing smb request buffer
 453 *
 454 * Return:      true if chained request, otherwise false
 455 */
 456bool is_chained_smb2_message(struct ksmbd_work *work)
 457{
 458	struct smb2_hdr *hdr = smb_get_msg(work->request_buf);
 459	unsigned int len, next_cmd;
 460
 461	if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
 462		return false;
 463
 464	hdr = ksmbd_req_buf_next(work);
 465	next_cmd = le32_to_cpu(hdr->NextCommand);
 466	if (next_cmd > 0) {
 467		if ((u64)work->next_smb2_rcv_hdr_off + next_cmd +
 468			__SMB2_HEADER_STRUCTURE_SIZE >
 469		    get_rfc1002_len(work->request_buf)) {
 470			pr_err("next command(%u) offset exceeds smb msg size\n",
 471			       next_cmd);
 472			return false;
 473		}
 474
 475		if ((u64)get_rfc1002_len(work->response_buf) + MAX_CIFS_SMALL_BUFFER_SIZE >
 476		    work->response_sz) {
 477			pr_err("next response offset exceeds response buffer size\n");
 478			return false;
 479		}
 480
 481		ksmbd_debug(SMB, "got SMB2 chained command\n");
 482		init_chained_smb2_rsp(work);
 483		return true;
 484	} else if (work->next_smb2_rcv_hdr_off) {
 485		/*
 486		 * This is last request in chained command,
 487		 * align response to 8 byte
 488		 */
 489		len = ALIGN(get_rfc1002_len(work->response_buf), 8);
 490		len = len - get_rfc1002_len(work->response_buf);
 491		if (len) {
 492			ksmbd_debug(SMB, "padding len %u\n", len);
 493			work->iov[work->iov_idx].iov_len += len;
 494			inc_rfc1001_len(work->response_buf, len);
 495		}
 496		work->curr_smb2_rsp_hdr_off = work->next_smb2_rsp_hdr_off;
 497	}
 498	return false;
 499}
 500
 501/**
 502 * init_smb2_rsp_hdr() - initialize smb2 response
 503 * @work:	smb work containing smb request buffer
 504 *
 505 * Return:      0
 506 */
 507int init_smb2_rsp_hdr(struct ksmbd_work *work)
 508{
 509	struct smb2_hdr *rsp_hdr = smb_get_msg(work->response_buf);
 510	struct smb2_hdr *rcv_hdr = smb_get_msg(work->request_buf);
 511
 512	memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
 513	rsp_hdr->ProtocolId = rcv_hdr->ProtocolId;
 514	rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE;
 515	rsp_hdr->Command = rcv_hdr->Command;
 516
 517	/*
 518	 * Message is response. We don't grant oplock yet.
 519	 */
 520	rsp_hdr->Flags = (SMB2_FLAGS_SERVER_TO_REDIR);
 521	rsp_hdr->NextCommand = 0;
 522	rsp_hdr->MessageId = rcv_hdr->MessageId;
 523	rsp_hdr->Id.SyncId.ProcessId = rcv_hdr->Id.SyncId.ProcessId;
 524	rsp_hdr->Id.SyncId.TreeId = rcv_hdr->Id.SyncId.TreeId;
 525	rsp_hdr->SessionId = rcv_hdr->SessionId;
 526	memcpy(rsp_hdr->Signature, rcv_hdr->Signature, 16);
 527
 528	return 0;
 529}
 530
 531/**
 532 * smb2_allocate_rsp_buf() - allocate smb2 response buffer
 533 * @work:	smb work containing smb request buffer
 534 *
 535 * Return:      0 on success, otherwise error
 536 */
 537int smb2_allocate_rsp_buf(struct ksmbd_work *work)
 538{
 539	struct smb2_hdr *hdr = smb_get_msg(work->request_buf);
 540	size_t small_sz = MAX_CIFS_SMALL_BUFFER_SIZE;
 541	size_t large_sz = small_sz + work->conn->vals->max_trans_size;
 542	size_t sz = small_sz;
 543	int cmd = le16_to_cpu(hdr->Command);
 544
 545	if (cmd == SMB2_IOCTL_HE || cmd == SMB2_QUERY_DIRECTORY_HE)
 546		sz = large_sz;
 547
 548	if (cmd == SMB2_QUERY_INFO_HE) {
 549		struct smb2_query_info_req *req;
 550
 551		if (get_rfc1002_len(work->request_buf) <
 552		    offsetof(struct smb2_query_info_req, OutputBufferLength))
 553			return -EINVAL;
 554
 555		req = smb_get_msg(work->request_buf);
 556		if ((req->InfoType == SMB2_O_INFO_FILE &&
 557		     (req->FileInfoClass == FILE_FULL_EA_INFORMATION ||
 558		     req->FileInfoClass == FILE_ALL_INFORMATION)) ||
 559		    req->InfoType == SMB2_O_INFO_SECURITY)
 560			sz = large_sz;
 561	}
 562
 563	/* allocate large response buf for chained commands */
 564	if (le32_to_cpu(hdr->NextCommand) > 0)
 565		sz = large_sz;
 566
 567	work->response_buf = kvzalloc(sz, KSMBD_DEFAULT_GFP);
 568	if (!work->response_buf)
 569		return -ENOMEM;
 570
 571	work->response_sz = sz;
 572	return 0;
 573}
 574
 575/**
 576 * smb2_check_user_session() - check for valid session for a user
 577 * @work:	smb work containing smb request buffer
 578 *
 579 * Return:      0 on success, otherwise error
 580 */
 581int smb2_check_user_session(struct ksmbd_work *work)
 582{
 583	struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work);
 584	struct ksmbd_conn *conn = work->conn;
 585	unsigned int cmd = le16_to_cpu(req_hdr->Command);
 586	unsigned long long sess_id;
 587
 588	/*
 589	 * SMB2_ECHO, SMB2_NEGOTIATE, SMB2_SESSION_SETUP command do not
 590	 * require a session id, so no need to validate user session's for
 591	 * these commands.
 592	 */
 593	if (cmd == SMB2_ECHO_HE || cmd == SMB2_NEGOTIATE_HE ||
 594	    cmd == SMB2_SESSION_SETUP_HE)
 595		return 0;
 596
 597	if (!ksmbd_conn_good(conn))
 598		return -EIO;
 599
 600	sess_id = le64_to_cpu(req_hdr->SessionId);
 601
 602	/*
 603	 * If request is not the first in Compound request,
 604	 * Just validate session id in header with work->sess->id.
 605	 */
 606	if (work->next_smb2_rcv_hdr_off) {
 607		if (!work->sess) {
 608			pr_err("The first operation in the compound does not have sess\n");
 609			return -EINVAL;
 610		}
 611		if (sess_id != ULLONG_MAX && work->sess->id != sess_id) {
 612			pr_err("session id(%llu) is different with the first operation(%lld)\n",
 613					sess_id, work->sess->id);
 614			return -EINVAL;
 615		}
 616		return 1;
 617	}
 618
 619	/* Check for validity of user session */
 620	work->sess = ksmbd_session_lookup_all(conn, sess_id);
 621	if (work->sess)
 622		return 1;
 623	ksmbd_debug(SMB, "Invalid user session, Uid %llu\n", sess_id);
 624	return -ENOENT;
 625}
 626
 627/**
 628 * smb2_get_name() - get filename string from on the wire smb format
 629 * @src:	source buffer
 630 * @maxlen:	maxlen of source string
 631 * @local_nls:	nls_table pointer
 632 *
 633 * Return:      matching converted filename on success, otherwise error ptr
 634 */
 635static char *
 636smb2_get_name(const char *src, const int maxlen, struct nls_table *local_nls)
 637{
 638	char *name;
 639
 640	name = smb_strndup_from_utf16(src, maxlen, 1, local_nls);
 641	if (IS_ERR(name)) {
 642		pr_err("failed to get name %ld\n", PTR_ERR(name));
 643		return name;
 644	}
 645
 646	if (*name == '\0') {
 647		kfree(name);
 648		return ERR_PTR(-EINVAL);
 649	}
 650
 651	if (*name == '\\') {
 652		pr_err("not allow directory name included leading slash\n");
 653		kfree(name);
 654		return ERR_PTR(-EINVAL);
 655	}
 656
 657	ksmbd_conv_path_to_unix(name);
 658	ksmbd_strip_last_slash(name);
 659	return name;
 660}
 661
 662int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg)
 663{
 664	struct ksmbd_conn *conn = work->conn;
 665	int id;
 666
 667	id = ksmbd_acquire_async_msg_id(&conn->async_ida);
 668	if (id < 0) {
 669		pr_err("Failed to alloc async message id\n");
 670		return id;
 671	}
 672	work->asynchronous = true;
 673	work->async_id = id;
 674
 675	ksmbd_debug(SMB,
 676		    "Send interim Response to inform async request id : %d\n",
 677		    work->async_id);
 678
 679	work->cancel_fn = fn;
 680	work->cancel_argv = arg;
 681
 682	if (list_empty(&work->async_request_entry)) {
 683		spin_lock(&conn->request_lock);
 684		list_add_tail(&work->async_request_entry, &conn->async_requests);
 685		spin_unlock(&conn->request_lock);
 686	}
 687
 688	return 0;
 689}
 690
 691void release_async_work(struct ksmbd_work *work)
 692{
 693	struct ksmbd_conn *conn = work->conn;
 694
 695	spin_lock(&conn->request_lock);
 696	list_del_init(&work->async_request_entry);
 697	spin_unlock(&conn->request_lock);
 698
 699	work->asynchronous = 0;
 700	work->cancel_fn = NULL;
 701	kfree(work->cancel_argv);
 702	work->cancel_argv = NULL;
 703	if (work->async_id) {
 704		ksmbd_release_id(&conn->async_ida, work->async_id);
 705		work->async_id = 0;
 706	}
 707}
 708
 709void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status)
 710{
 711	struct smb2_hdr *rsp_hdr;
 712	struct ksmbd_work *in_work = ksmbd_alloc_work_struct();
 713
 714	if (!in_work)
 715		return;
 716
 717	if (allocate_interim_rsp_buf(in_work)) {
 718		pr_err("smb_allocate_rsp_buf failed!\n");
 719		ksmbd_free_work_struct(in_work);
 720		return;
 721	}
 722
 723	in_work->conn = work->conn;
 724	memcpy(smb_get_msg(in_work->response_buf), ksmbd_resp_buf_next(work),
 725	       __SMB2_HEADER_STRUCTURE_SIZE);
 726
 727	rsp_hdr = smb_get_msg(in_work->response_buf);
 728	rsp_hdr->Flags |= SMB2_FLAGS_ASYNC_COMMAND;
 729	rsp_hdr->Id.AsyncId = cpu_to_le64(work->async_id);
 730	smb2_set_err_rsp(in_work);
 731	rsp_hdr->Status = status;
 732
 733	ksmbd_conn_write(in_work);
 734	ksmbd_free_work_struct(in_work);
 735}
 736
 737static __le32 smb2_get_reparse_tag_special_file(umode_t mode)
 738{
 739	if (S_ISDIR(mode) || S_ISREG(mode))
 740		return 0;
 741
 742	if (S_ISLNK(mode))
 743		return IO_REPARSE_TAG_LX_SYMLINK_LE;
 744	else if (S_ISFIFO(mode))
 745		return IO_REPARSE_TAG_LX_FIFO_LE;
 746	else if (S_ISSOCK(mode))
 747		return IO_REPARSE_TAG_AF_UNIX_LE;
 748	else if (S_ISCHR(mode))
 749		return IO_REPARSE_TAG_LX_CHR_LE;
 750	else if (S_ISBLK(mode))
 751		return IO_REPARSE_TAG_LX_BLK_LE;
 752
 753	return 0;
 754}
 755
 756/**
 757 * smb2_get_dos_mode() - get file mode in dos format from unix mode
 758 * @stat:	kstat containing file mode
 759 * @attribute:	attribute flags
 760 *
 761 * Return:      converted dos mode
 762 */
 763static int smb2_get_dos_mode(struct kstat *stat, int attribute)
 764{
 765	int attr = 0;
 766
 767	if (S_ISDIR(stat->mode)) {
 768		attr = FILE_ATTRIBUTE_DIRECTORY |
 769			(attribute & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM));
 770	} else {
 771		attr = (attribute & 0x00005137) | FILE_ATTRIBUTE_ARCHIVE;
 772		attr &= ~(FILE_ATTRIBUTE_DIRECTORY);
 773		if (S_ISREG(stat->mode) && (server_conf.share_fake_fscaps &
 774				FILE_SUPPORTS_SPARSE_FILES))
 775			attr |= FILE_ATTRIBUTE_SPARSE_FILE;
 776
 777		if (smb2_get_reparse_tag_special_file(stat->mode))
 778			attr |= FILE_ATTRIBUTE_REPARSE_POINT;
 779	}
 780
 781	return attr;
 782}
 783
 784static void build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt,
 785			       __le16 hash_id)
 786{
 787	pneg_ctxt->ContextType = SMB2_PREAUTH_INTEGRITY_CAPABILITIES;
 788	pneg_ctxt->DataLength = cpu_to_le16(38);
 789	pneg_ctxt->HashAlgorithmCount = cpu_to_le16(1);
 790	pneg_ctxt->Reserved = cpu_to_le32(0);
 791	pneg_ctxt->SaltLength = cpu_to_le16(SMB311_SALT_SIZE);
 792	get_random_bytes(pneg_ctxt->Salt, SMB311_SALT_SIZE);
 793	pneg_ctxt->HashAlgorithms = hash_id;
 794}
 795
 796static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt,
 797			       __le16 cipher_type)
 798{
 799	pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES;
 800	pneg_ctxt->DataLength = cpu_to_le16(4);
 801	pneg_ctxt->Reserved = cpu_to_le32(0);
 802	pneg_ctxt->CipherCount = cpu_to_le16(1);
 803	pneg_ctxt->Ciphers[0] = cipher_type;
 804}
 805
 806static void build_sign_cap_ctxt(struct smb2_signing_capabilities *pneg_ctxt,
 807				__le16 sign_algo)
 808{
 809	pneg_ctxt->ContextType = SMB2_SIGNING_CAPABILITIES;
 810	pneg_ctxt->DataLength =
 811		cpu_to_le16((sizeof(struct smb2_signing_capabilities) + 2)
 812			- sizeof(struct smb2_neg_context));
 813	pneg_ctxt->Reserved = cpu_to_le32(0);
 814	pneg_ctxt->SigningAlgorithmCount = cpu_to_le16(1);
 815	pneg_ctxt->SigningAlgorithms[0] = sign_algo;
 816}
 817
 818static void build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
 819{
 820	pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE;
 821	pneg_ctxt->DataLength = cpu_to_le16(POSIX_CTXT_DATA_LEN);
 822	/* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
 823	pneg_ctxt->Name[0] = 0x93;
 824	pneg_ctxt->Name[1] = 0xAD;
 825	pneg_ctxt->Name[2] = 0x25;
 826	pneg_ctxt->Name[3] = 0x50;
 827	pneg_ctxt->Name[4] = 0x9C;
 828	pneg_ctxt->Name[5] = 0xB4;
 829	pneg_ctxt->Name[6] = 0x11;
 830	pneg_ctxt->Name[7] = 0xE7;
 831	pneg_ctxt->Name[8] = 0xB4;
 832	pneg_ctxt->Name[9] = 0x23;
 833	pneg_ctxt->Name[10] = 0x83;
 834	pneg_ctxt->Name[11] = 0xDE;
 835	pneg_ctxt->Name[12] = 0x96;
 836	pneg_ctxt->Name[13] = 0x8B;
 837	pneg_ctxt->Name[14] = 0xCD;
 838	pneg_ctxt->Name[15] = 0x7C;
 839}
 840
 841static unsigned int assemble_neg_contexts(struct ksmbd_conn *conn,
 842				  struct smb2_negotiate_rsp *rsp)
 843{
 844	char * const pneg_ctxt = (char *)rsp +
 845			le32_to_cpu(rsp->NegotiateContextOffset);
 846	int neg_ctxt_cnt = 1;
 847	int ctxt_size;
 848
 849	ksmbd_debug(SMB,
 850		    "assemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n");
 851	build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt,
 852			   conn->preauth_info->Preauth_HashId);
 853	ctxt_size = sizeof(struct smb2_preauth_neg_context);
 854
 855	if (conn->cipher_type) {
 856		/* Round to 8 byte boundary */
 857		ctxt_size = round_up(ctxt_size, 8);
 858		ksmbd_debug(SMB,
 859			    "assemble SMB2_ENCRYPTION_CAPABILITIES context\n");
 860		build_encrypt_ctxt((struct smb2_encryption_neg_context *)
 861				   (pneg_ctxt + ctxt_size),
 862				   conn->cipher_type);
 863		neg_ctxt_cnt++;
 864		ctxt_size += sizeof(struct smb2_encryption_neg_context) + 2;
 865	}
 866
 867	/* compression context not yet supported */
 868	WARN_ON(conn->compress_algorithm != SMB3_COMPRESS_NONE);
 869
 870	if (conn->posix_ext_supported) {
 871		ctxt_size = round_up(ctxt_size, 8);
 872		ksmbd_debug(SMB,
 873			    "assemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n");
 874		build_posix_ctxt((struct smb2_posix_neg_context *)
 875				 (pneg_ctxt + ctxt_size));
 876		neg_ctxt_cnt++;
 877		ctxt_size += sizeof(struct smb2_posix_neg_context);
 878	}
 879
 880	if (conn->signing_negotiated) {
 881		ctxt_size = round_up(ctxt_size, 8);
 882		ksmbd_debug(SMB,
 883			    "assemble SMB2_SIGNING_CAPABILITIES context\n");
 884		build_sign_cap_ctxt((struct smb2_signing_capabilities *)
 885				    (pneg_ctxt + ctxt_size),
 886				    conn->signing_algorithm);
 887		neg_ctxt_cnt++;
 888		ctxt_size += sizeof(struct smb2_signing_capabilities) + 2;
 889	}
 890
 891	rsp->NegotiateContextCount = cpu_to_le16(neg_ctxt_cnt);
 892	return ctxt_size + AUTH_GSS_PADDING;
 893}
 894
 895static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn,
 896				  struct smb2_preauth_neg_context *pneg_ctxt,
 897				  int ctxt_len)
 898{
 899	/*
 900	 * sizeof(smb2_preauth_neg_context) assumes SMB311_SALT_SIZE Salt,
 901	 * which may not be present. Only check for used HashAlgorithms[1].
 902	 */
 903	if (ctxt_len <
 904	    sizeof(struct smb2_neg_context) + MIN_PREAUTH_CTXT_DATA_LEN)
 905		return STATUS_INVALID_PARAMETER;
 906
 907	if (pneg_ctxt->HashAlgorithms != SMB2_PREAUTH_INTEGRITY_SHA512)
 908		return STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP;
 909
 910	conn->preauth_info->Preauth_HashId = SMB2_PREAUTH_INTEGRITY_SHA512;
 911	return STATUS_SUCCESS;
 912}
 913
 914static void decode_encrypt_ctxt(struct ksmbd_conn *conn,
 915				struct smb2_encryption_neg_context *pneg_ctxt,
 916				int ctxt_len)
 917{
 918	int cph_cnt;
 919	int i, cphs_size;
 920
 921	if (sizeof(struct smb2_encryption_neg_context) > ctxt_len) {
 922		pr_err("Invalid SMB2_ENCRYPTION_CAPABILITIES context size\n");
 923		return;
 924	}
 925
 926	conn->cipher_type = 0;
 927
 928	cph_cnt = le16_to_cpu(pneg_ctxt->CipherCount);
 929	cphs_size = cph_cnt * sizeof(__le16);
 930
 931	if (sizeof(struct smb2_encryption_neg_context) + cphs_size >
 932	    ctxt_len) {
 933		pr_err("Invalid cipher count(%d)\n", cph_cnt);
 934		return;
 935	}
 936
 937	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF)
 938		return;
 939
 940	for (i = 0; i < cph_cnt; i++) {
 941		if (pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_GCM ||
 942		    pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_CCM ||
 943		    pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_CCM ||
 944		    pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_GCM) {
 945			ksmbd_debug(SMB, "Cipher ID = 0x%x\n",
 946				    pneg_ctxt->Ciphers[i]);
 947			conn->cipher_type = pneg_ctxt->Ciphers[i];
 948			break;
 949		}
 950	}
 951}
 952
 953/**
 954 * smb3_encryption_negotiated() - checks if server and client agreed on enabling encryption
 955 * @conn:	smb connection
 956 *
 957 * Return:	true if connection should be encrypted, else false
 958 */
 959bool smb3_encryption_negotiated(struct ksmbd_conn *conn)
 960{
 961	if (!conn->ops->generate_encryptionkey)
 962		return false;
 963
 964	/*
 965	 * SMB 3.0 and 3.0.2 dialects use the SMB2_GLOBAL_CAP_ENCRYPTION flag.
 966	 * SMB 3.1.1 uses the cipher_type field.
 967	 */
 968	return (conn->vals->req_capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) ||
 969	    conn->cipher_type;
 970}
 971
 972static void decode_compress_ctxt(struct ksmbd_conn *conn,
 973				 struct smb2_compression_capabilities_context *pneg_ctxt)
 974{
 975	conn->compress_algorithm = SMB3_COMPRESS_NONE;
 976}
 977
 978static void decode_sign_cap_ctxt(struct ksmbd_conn *conn,
 979				 struct smb2_signing_capabilities *pneg_ctxt,
 980				 int ctxt_len)
 981{
 982	int sign_algo_cnt;
 983	int i, sign_alos_size;
 984
 985	if (sizeof(struct smb2_signing_capabilities) > ctxt_len) {
 986		pr_err("Invalid SMB2_SIGNING_CAPABILITIES context length\n");
 987		return;
 988	}
 989
 990	conn->signing_negotiated = false;
 991	sign_algo_cnt = le16_to_cpu(pneg_ctxt->SigningAlgorithmCount);
 992	sign_alos_size = sign_algo_cnt * sizeof(__le16);
 993
 994	if (sizeof(struct smb2_signing_capabilities) + sign_alos_size >
 995	    ctxt_len) {
 996		pr_err("Invalid signing algorithm count(%d)\n", sign_algo_cnt);
 997		return;
 998	}
 999
1000	for (i = 0; i < sign_algo_cnt; i++) {
1001		if (pneg_ctxt->SigningAlgorithms[i] == SIGNING_ALG_HMAC_SHA256_LE ||
1002		    pneg_ctxt->SigningAlgorithms[i] == SIGNING_ALG_AES_CMAC_LE) {
1003			ksmbd_debug(SMB, "Signing Algorithm ID = 0x%x\n",
1004				    pneg_ctxt->SigningAlgorithms[i]);
1005			conn->signing_negotiated = true;
1006			conn->signing_algorithm =
1007				pneg_ctxt->SigningAlgorithms[i];
1008			break;
1009		}
1010	}
1011}
1012
1013static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
1014				      struct smb2_negotiate_req *req,
1015				      unsigned int len_of_smb)
1016{
1017	/* +4 is to account for the RFC1001 len field */
1018	struct smb2_neg_context *pctx = (struct smb2_neg_context *)req;
1019	int i = 0, len_of_ctxts;
1020	unsigned int offset = le32_to_cpu(req->NegotiateContextOffset);
1021	unsigned int neg_ctxt_cnt = le16_to_cpu(req->NegotiateContextCount);
1022	__le32 status = STATUS_INVALID_PARAMETER;
1023
1024	ksmbd_debug(SMB, "decoding %d negotiate contexts\n", neg_ctxt_cnt);
1025	if (len_of_smb <= offset) {
1026		ksmbd_debug(SMB, "Invalid response: negotiate context offset\n");
1027		return status;
1028	}
1029
1030	len_of_ctxts = len_of_smb - offset;
1031
1032	while (i++ < neg_ctxt_cnt) {
1033		int clen, ctxt_len;
1034
1035		if (len_of_ctxts < (int)sizeof(struct smb2_neg_context))
1036			break;
1037
1038		pctx = (struct smb2_neg_context *)((char *)pctx + offset);
1039		clen = le16_to_cpu(pctx->DataLength);
1040		ctxt_len = clen + sizeof(struct smb2_neg_context);
1041
1042		if (ctxt_len > len_of_ctxts)
1043			break;
1044
1045		if (pctx->ContextType == SMB2_PREAUTH_INTEGRITY_CAPABILITIES) {
1046			ksmbd_debug(SMB,
1047				    "deassemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n");
1048			if (conn->preauth_info->Preauth_HashId)
1049				break;
1050
1051			status = decode_preauth_ctxt(conn,
1052						     (struct smb2_preauth_neg_context *)pctx,
1053						     ctxt_len);
1054			if (status != STATUS_SUCCESS)
1055				break;
1056		} else if (pctx->ContextType == SMB2_ENCRYPTION_CAPABILITIES) {
1057			ksmbd_debug(SMB,
1058				    "deassemble SMB2_ENCRYPTION_CAPABILITIES context\n");
1059			if (conn->cipher_type)
1060				break;
1061
1062			decode_encrypt_ctxt(conn,
1063					    (struct smb2_encryption_neg_context *)pctx,
1064					    ctxt_len);
1065		} else if (pctx->ContextType == SMB2_COMPRESSION_CAPABILITIES) {
1066			ksmbd_debug(SMB,
1067				    "deassemble SMB2_COMPRESSION_CAPABILITIES context\n");
1068			if (conn->compress_algorithm)
1069				break;
1070
1071			decode_compress_ctxt(conn,
1072					     (struct smb2_compression_capabilities_context *)pctx);
1073		} else if (pctx->ContextType == SMB2_NETNAME_NEGOTIATE_CONTEXT_ID) {
1074			ksmbd_debug(SMB,
1075				    "deassemble SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context\n");
1076		} else if (pctx->ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) {
1077			ksmbd_debug(SMB,
1078				    "deassemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n");
1079			conn->posix_ext_supported = true;
1080		} else if (pctx->ContextType == SMB2_SIGNING_CAPABILITIES) {
1081			ksmbd_debug(SMB,
1082				    "deassemble SMB2_SIGNING_CAPABILITIES context\n");
1083
1084			decode_sign_cap_ctxt(conn,
1085					     (struct smb2_signing_capabilities *)pctx,
1086					     ctxt_len);
1087		}
1088
1089		/* offsets must be 8 byte aligned */
1090		offset = (ctxt_len + 7) & ~0x7;
1091		len_of_ctxts -= offset;
1092	}
1093	return status;
1094}
1095
1096/**
1097 * smb2_handle_negotiate() - handler for smb2 negotiate command
1098 * @work:	smb work containing smb request buffer
1099 *
1100 * Return:      0
1101 */
1102int smb2_handle_negotiate(struct ksmbd_work *work)
1103{
1104	struct ksmbd_conn *conn = work->conn;
1105	struct smb2_negotiate_req *req = smb_get_msg(work->request_buf);
1106	struct smb2_negotiate_rsp *rsp = smb_get_msg(work->response_buf);
1107	int rc = 0;
1108	unsigned int smb2_buf_len, smb2_neg_size, neg_ctxt_len = 0;
1109	__le32 status;
1110
1111	ksmbd_debug(SMB, "Received negotiate request\n");
1112	conn->need_neg = false;
1113	if (ksmbd_conn_good(conn)) {
1114		pr_err("conn->tcp_status is already in CifsGood State\n");
1115		work->send_no_response = 1;
1116		return rc;
1117	}
1118
1119	ksmbd_conn_lock(conn);
1120	smb2_buf_len = get_rfc1002_len(work->request_buf);
1121	smb2_neg_size = offsetof(struct smb2_negotiate_req, Dialects);
1122	if (smb2_neg_size > smb2_buf_len) {
1123		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1124		rc = -EINVAL;
1125		goto err_out;
1126	}
1127
1128	if (req->DialectCount == 0) {
1129		pr_err("malformed packet\n");
1130		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1131		rc = -EINVAL;
1132		goto err_out;
1133	}
1134
1135	if (conn->dialect == SMB311_PROT_ID) {
1136		unsigned int nego_ctxt_off = le32_to_cpu(req->NegotiateContextOffset);
1137
1138		if (smb2_buf_len < nego_ctxt_off) {
1139			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1140			rc = -EINVAL;
1141			goto err_out;
1142		}
1143
1144		if (smb2_neg_size > nego_ctxt_off) {
1145			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1146			rc = -EINVAL;
1147			goto err_out;
1148		}
1149
1150		if (smb2_neg_size + le16_to_cpu(req->DialectCount) * sizeof(__le16) >
1151		    nego_ctxt_off) {
1152			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1153			rc = -EINVAL;
1154			goto err_out;
1155		}
1156	} else {
1157		if (smb2_neg_size + le16_to_cpu(req->DialectCount) * sizeof(__le16) >
1158		    smb2_buf_len) {
1159			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1160			rc = -EINVAL;
1161			goto err_out;
1162		}
1163	}
1164
1165	conn->cli_cap = le32_to_cpu(req->Capabilities);
1166	switch (conn->dialect) {
1167	case SMB311_PROT_ID:
1168		conn->preauth_info =
1169			kzalloc(sizeof(struct preauth_integrity_info),
1170				KSMBD_DEFAULT_GFP);
1171		if (!conn->preauth_info) {
1172			rc = -ENOMEM;
1173			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1174			goto err_out;
1175		}
1176
1177		status = deassemble_neg_contexts(conn, req,
1178						 get_rfc1002_len(work->request_buf));
1179		if (status != STATUS_SUCCESS) {
1180			pr_err("deassemble_neg_contexts error(0x%x)\n",
1181			       status);
1182			rsp->hdr.Status = status;
1183			rc = -EINVAL;
1184			kfree(conn->preauth_info);
1185			conn->preauth_info = NULL;
1186			goto err_out;
1187		}
1188
1189		rc = init_smb3_11_server(conn);
1190		if (rc < 0) {
1191			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1192			kfree(conn->preauth_info);
1193			conn->preauth_info = NULL;
1194			goto err_out;
1195		}
1196
1197		ksmbd_gen_preauth_integrity_hash(conn,
1198						 work->request_buf,
1199						 conn->preauth_info->Preauth_HashValue);
1200		rsp->NegotiateContextOffset =
1201				cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
1202		neg_ctxt_len = assemble_neg_contexts(conn, rsp);
1203		break;
1204	case SMB302_PROT_ID:
1205		init_smb3_02_server(conn);
1206		break;
1207	case SMB30_PROT_ID:
1208		init_smb3_0_server(conn);
1209		break;
1210	case SMB21_PROT_ID:
1211		init_smb2_1_server(conn);
1212		break;
1213	case SMB2X_PROT_ID:
1214	case BAD_PROT_ID:
1215	default:
1216		ksmbd_debug(SMB, "Server dialect :0x%x not supported\n",
1217			    conn->dialect);
1218		rsp->hdr.Status = STATUS_NOT_SUPPORTED;
1219		rc = -EINVAL;
1220		goto err_out;
1221	}
1222	rsp->Capabilities = cpu_to_le32(conn->vals->req_capabilities);
1223
1224	/* For stats */
1225	conn->connection_type = conn->dialect;
1226
1227	rsp->MaxTransactSize = cpu_to_le32(conn->vals->max_trans_size);
1228	rsp->MaxReadSize = cpu_to_le32(conn->vals->max_read_size);
1229	rsp->MaxWriteSize = cpu_to_le32(conn->vals->max_write_size);
1230
1231	memcpy(conn->ClientGUID, req->ClientGUID,
1232			SMB2_CLIENT_GUID_SIZE);
1233	conn->cli_sec_mode = le16_to_cpu(req->SecurityMode);
1234
1235	rsp->StructureSize = cpu_to_le16(65);
1236	rsp->DialectRevision = cpu_to_le16(conn->dialect);
1237	/* Not setting conn guid rsp->ServerGUID, as it
1238	 * not used by client for identifying server
1239	 */
1240	memset(rsp->ServerGUID, 0, SMB2_CLIENT_GUID_SIZE);
1241
1242	rsp->SystemTime = cpu_to_le64(ksmbd_systime());
1243	rsp->ServerStartTime = 0;
1244	ksmbd_debug(SMB, "negotiate context offset %d, count %d\n",
1245		    le32_to_cpu(rsp->NegotiateContextOffset),
1246		    le16_to_cpu(rsp->NegotiateContextCount));
1247
1248	rsp->SecurityBufferOffset = cpu_to_le16(128);
1249	rsp->SecurityBufferLength = cpu_to_le16(AUTH_GSS_LENGTH);
1250	ksmbd_copy_gss_neg_header((char *)(&rsp->hdr) +
1251				  le16_to_cpu(rsp->SecurityBufferOffset));
1252
1253	rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE;
1254	conn->use_spnego = true;
1255
1256	if ((server_conf.signing == KSMBD_CONFIG_OPT_AUTO ||
1257	     server_conf.signing == KSMBD_CONFIG_OPT_DISABLED) &&
1258	    req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED_LE)
1259		conn->sign = true;
1260	else if (server_conf.signing == KSMBD_CONFIG_OPT_MANDATORY) {
1261		server_conf.enforced_signing = true;
1262		rsp->SecurityMode |= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE;
1263		conn->sign = true;
1264	}
1265
1266	conn->srv_sec_mode = le16_to_cpu(rsp->SecurityMode);
1267	ksmbd_conn_set_need_setup(conn);
1268
1269err_out:
1270	ksmbd_conn_unlock(conn);
1271	if (rc)
1272		rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
1273
1274	if (!rc)
1275		rc = ksmbd_iov_pin_rsp(work, rsp,
1276				       sizeof(struct smb2_negotiate_rsp) +
1277					AUTH_GSS_LENGTH + neg_ctxt_len);
1278	if (rc < 0)
1279		smb2_set_err_rsp(work);
1280	return rc;
1281}
1282
1283static int alloc_preauth_hash(struct ksmbd_session *sess,
1284			      struct ksmbd_conn *conn)
1285{
1286	if (sess->Preauth_HashValue)
1287		return 0;
1288
1289	if (!conn->preauth_info)
1290		return -ENOMEM;
1291
1292	sess->Preauth_HashValue = kmemdup(conn->preauth_info->Preauth_HashValue,
1293					  PREAUTH_HASHVALUE_SIZE, KSMBD_DEFAULT_GFP);
1294	if (!sess->Preauth_HashValue)
1295		return -ENOMEM;
1296
1297	return 0;
1298}
1299
1300static int generate_preauth_hash(struct ksmbd_work *work)
1301{
1302	struct ksmbd_conn *conn = work->conn;
1303	struct ksmbd_session *sess = work->sess;
1304	u8 *preauth_hash;
1305
1306	if (conn->dialect != SMB311_PROT_ID)
1307		return 0;
1308
1309	if (conn->binding) {
1310		struct preauth_session *preauth_sess;
1311
1312		preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
1313		if (!preauth_sess) {
1314			preauth_sess = ksmbd_preauth_session_alloc(conn, sess->id);
1315			if (!preauth_sess)
1316				return -ENOMEM;
1317		}
1318
1319		preauth_hash = preauth_sess->Preauth_HashValue;
1320	} else {
1321		if (!sess->Preauth_HashValue)
1322			if (alloc_preauth_hash(sess, conn))
1323				return -ENOMEM;
1324		preauth_hash = sess->Preauth_HashValue;
1325	}
1326
1327	ksmbd_gen_preauth_integrity_hash(conn, work->request_buf, preauth_hash);
1328	return 0;
1329}
1330
1331static int decode_negotiation_token(struct ksmbd_conn *conn,
1332				    struct negotiate_message *negblob,
1333				    size_t sz)
1334{
1335	if (!conn->use_spnego)
1336		return -EINVAL;
1337
1338	if (ksmbd_decode_negTokenInit((char *)negblob, sz, conn)) {
1339		if (ksmbd_decode_negTokenTarg((char *)negblob, sz, conn)) {
1340			conn->auth_mechs |= KSMBD_AUTH_NTLMSSP;
1341			conn->preferred_auth_mech = KSMBD_AUTH_NTLMSSP;
1342			conn->use_spnego = false;
1343		}
1344	}
1345	return 0;
1346}
1347
1348static int ntlm_negotiate(struct ksmbd_work *work,
1349			  struct negotiate_message *negblob,
1350			  size_t negblob_len, struct smb2_sess_setup_rsp *rsp)
1351{
1352	struct challenge_message *chgblob;
1353	unsigned char *spnego_blob = NULL;
1354	u16 spnego_blob_len;
1355	char *neg_blob;
1356	int sz, rc;
1357
1358	ksmbd_debug(SMB, "negotiate phase\n");
1359	rc = ksmbd_decode_ntlmssp_neg_blob(negblob, negblob_len, work->conn);
1360	if (rc)
1361		return rc;
1362
1363	sz = le16_to_cpu(rsp->SecurityBufferOffset);
1364	chgblob = (struct challenge_message *)rsp->Buffer;
1365	memset(chgblob, 0, sizeof(struct challenge_message));
1366
1367	if (!work->conn->use_spnego) {
1368		sz = ksmbd_build_ntlmssp_challenge_blob(chgblob, work->conn);
1369		if (sz < 0)
1370			return -ENOMEM;
1371
1372		rsp->SecurityBufferLength = cpu_to_le16(sz);
1373		return 0;
1374	}
1375
1376	sz = sizeof(struct challenge_message);
1377	sz += (strlen(ksmbd_netbios_name()) * 2 + 1 + 4) * 6;
1378
1379	neg_blob = kzalloc(sz, KSMBD_DEFAULT_GFP);
1380	if (!neg_blob)
1381		return -ENOMEM;
1382
1383	chgblob = (struct challenge_message *)neg_blob;
1384	sz = ksmbd_build_ntlmssp_challenge_blob(chgblob, work->conn);
1385	if (sz < 0) {
1386		rc = -ENOMEM;
1387		goto out;
1388	}
1389
1390	rc = build_spnego_ntlmssp_neg_blob(&spnego_blob, &spnego_blob_len,
1391					   neg_blob, sz);
1392	if (rc) {
1393		rc = -ENOMEM;
1394		goto out;
1395	}
1396
1397	memcpy(rsp->Buffer, spnego_blob, spnego_blob_len);
1398	rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len);
1399
1400out:
1401	kfree(spnego_blob);
1402	kfree(neg_blob);
1403	return rc;
1404}
1405
1406static struct authenticate_message *user_authblob(struct ksmbd_conn *conn,
1407						  struct smb2_sess_setup_req *req)
1408{
1409	int sz;
1410
1411	if (conn->use_spnego && conn->mechToken)
1412		return (struct authenticate_message *)conn->mechToken;
1413
1414	sz = le16_to_cpu(req->SecurityBufferOffset);
1415	return (struct authenticate_message *)((char *)&req->hdr.ProtocolId
1416					       + sz);
1417}
1418
1419static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
1420				       struct smb2_sess_setup_req *req)
1421{
1422	struct authenticate_message *authblob;
1423	struct ksmbd_user *user;
1424	char *name;
1425	unsigned int name_off, name_len, secbuf_len;
1426
1427	if (conn->use_spnego && conn->mechToken)
1428		secbuf_len = conn->mechTokenLen;
1429	else
1430		secbuf_len = le16_to_cpu(req->SecurityBufferLength);
1431	if (secbuf_len < sizeof(struct authenticate_message)) {
1432		ksmbd_debug(SMB, "blob len %d too small\n", secbuf_len);
1433		return NULL;
1434	}
1435	authblob = user_authblob(conn, req);
1436	name_off = le32_to_cpu(authblob->UserName.BufferOffset);
1437	name_len = le16_to_cpu(authblob->UserName.Length);
1438
1439	if (secbuf_len < (u64)name_off + name_len)
1440		return NULL;
1441
1442	name = smb_strndup_from_utf16((const char *)authblob + name_off,
1443				      name_len,
1444				      true,
1445				      conn->local_nls);
1446	if (IS_ERR(name)) {
1447		pr_err("cannot allocate memory\n");
1448		return NULL;
1449	}
1450
1451	ksmbd_debug(SMB, "session setup request for user %s\n", name);
1452	user = ksmbd_login_user(name);
1453	kfree(name);
1454	return user;
1455}
1456
1457static int ntlm_authenticate(struct ksmbd_work *work,
1458			     struct smb2_sess_setup_req *req,
1459			     struct smb2_sess_setup_rsp *rsp)
1460{
1461	struct ksmbd_conn *conn = work->conn;
1462	struct ksmbd_session *sess = work->sess;
1463	struct channel *chann = NULL, *old;
1464	struct ksmbd_user *user;
1465	u64 prev_id;
1466	int sz, rc;
1467
1468	ksmbd_debug(SMB, "authenticate phase\n");
1469	if (conn->use_spnego) {
1470		unsigned char *spnego_blob;
1471		u16 spnego_blob_len;
1472
1473		rc = build_spnego_ntlmssp_auth_blob(&spnego_blob,
1474						    &spnego_blob_len,
1475						    0);
1476		if (rc)
1477			return -ENOMEM;
1478
1479		memcpy(rsp->Buffer, spnego_blob, spnego_blob_len);
1480		rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len);
1481		kfree(spnego_blob);
1482	}
1483
1484	user = session_user(conn, req);
1485	if (!user) {
1486		ksmbd_debug(SMB, "Unknown user name or an error\n");
1487		return -EPERM;
1488	}
1489
1490	/* Check for previous session */
1491	prev_id = le64_to_cpu(req->PreviousSessionId);
1492	if (prev_id && prev_id != sess->id)
1493		destroy_previous_session(conn, user, prev_id);
1494
1495	if (sess->state == SMB2_SESSION_VALID) {
1496		/*
1497		 * Reuse session if anonymous try to connect
1498		 * on reauthetication.
1499		 */
1500		if (conn->binding == false && ksmbd_anonymous_user(user)) {
1501			ksmbd_free_user(user);
1502			return 0;
1503		}
1504
1505		if (!ksmbd_compare_user(sess->user, user)) {
1506			ksmbd_free_user(user);
1507			return -EPERM;
1508		}
1509		ksmbd_free_user(user);
1510	} else {
1511		sess->user = user;
1512	}
1513
1514	if (conn->binding == false && user_guest(sess->user)) {
1515		rsp->SessionFlags = SMB2_SESSION_FLAG_IS_GUEST_LE;
1516	} else {
1517		struct authenticate_message *authblob;
1518
1519		authblob = user_authblob(conn, req);
1520		if (conn->use_spnego && conn->mechToken)
1521			sz = conn->mechTokenLen;
1522		else
1523			sz = le16_to_cpu(req->SecurityBufferLength);
1524		rc = ksmbd_decode_ntlmssp_auth_blob(authblob, sz, conn, sess);
1525		if (rc) {
1526			set_user_flag(sess->user, KSMBD_USER_FLAG_BAD_PASSWORD);
1527			ksmbd_debug(SMB, "authentication failed\n");
1528			return -EPERM;
1529		}
1530	}
1531
1532	/*
1533	 * If session state is SMB2_SESSION_VALID, We can assume
1534	 * that it is reauthentication. And the user/password
1535	 * has been verified, so return it here.
1536	 */
1537	if (sess->state == SMB2_SESSION_VALID) {
1538		if (conn->binding)
1539			goto binding_session;
1540		return 0;
1541	}
1542
1543	if ((rsp->SessionFlags != SMB2_SESSION_FLAG_IS_GUEST_LE &&
1544	     (conn->sign || server_conf.enforced_signing)) ||
1545	    (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
1546		sess->sign = true;
1547
1548	if (smb3_encryption_negotiated(conn) &&
1549			!(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
1550		conn->ops->generate_encryptionkey(conn, sess);
1551		sess->enc = true;
1552		if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION)
1553			rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE;
1554		/*
1555		 * signing is disable if encryption is enable
1556		 * on this session
1557		 */
1558		sess->sign = false;
1559	}
1560
1561binding_session:
1562	if (conn->dialect >= SMB30_PROT_ID) {
1563		chann = lookup_chann_list(sess, conn);
1564		if (!chann) {
1565			chann = kmalloc(sizeof(struct channel), KSMBD_DEFAULT_GFP);
1566			if (!chann)
1567				return -ENOMEM;
1568
1569			chann->conn = conn;
1570			down_write(&sess->chann_lock);
1571			old = xa_store(&sess->ksmbd_chann_list, (long)conn, chann,
1572					KSMBD_DEFAULT_GFP);
1573			up_write(&sess->chann_lock);
1574			if (xa_is_err(old)) {
1575				kfree(chann);
1576				return xa_err(old);
1577			}
1578		}
1579	}
1580
1581	if (conn->ops->generate_signingkey) {
1582		rc = conn->ops->generate_signingkey(sess, conn);
1583		if (rc) {
1584			ksmbd_debug(SMB, "SMB3 signing key generation failed\n");
1585			return -EINVAL;
1586		}
1587	}
1588
1589	if (!ksmbd_conn_lookup_dialect(conn)) {
1590		pr_err("fail to verify the dialect\n");
1591		return -ENOENT;
1592	}
1593	return 0;
1594}
1595
1596#ifdef CONFIG_SMB_SERVER_KERBEROS5
1597static int krb5_authenticate(struct ksmbd_work *work,
1598			     struct smb2_sess_setup_req *req,
1599			     struct smb2_sess_setup_rsp *rsp)
1600{
1601	struct ksmbd_conn *conn = work->conn;
1602	struct ksmbd_session *sess = work->sess;
1603	char *in_blob, *out_blob;
1604	struct channel *chann = NULL, *old;
1605	u64 prev_sess_id;
1606	int in_len, out_len;
1607	int retval;
1608
1609	in_blob = (char *)&req->hdr.ProtocolId +
1610		le16_to_cpu(req->SecurityBufferOffset);
1611	in_len = le16_to_cpu(req->SecurityBufferLength);
1612	out_blob = (char *)&rsp->hdr.ProtocolId +
1613		le16_to_cpu(rsp->SecurityBufferOffset);
1614	out_len = work->response_sz -
1615		(le16_to_cpu(rsp->SecurityBufferOffset) + 4);
1616
1617	retval = ksmbd_krb5_authenticate(sess, in_blob, in_len,
1618					 out_blob, &out_len);
1619	if (retval) {
1620		ksmbd_debug(SMB, "krb5 authentication failed\n");
1621		return -EINVAL;
1622	}
1623
1624	/* Check previous session */
1625	prev_sess_id = le64_to_cpu(req->PreviousSessionId);
1626	if (prev_sess_id && prev_sess_id != sess->id)
1627		destroy_previous_session(conn, sess->user, prev_sess_id);
1628
1629	rsp->SecurityBufferLength = cpu_to_le16(out_len);
1630
1631	/*
1632	 * If session state is SMB2_SESSION_VALID, We can assume
1633	 * that it is reauthentication. And the user/password
1634	 * has been verified, so return it here.
1635	 */
1636	if (sess->state == SMB2_SESSION_VALID) {
1637		if (conn->binding)
1638			goto binding_session;
1639		return 0;
1640	}
1641
1642	if ((rsp->SessionFlags != SMB2_SESSION_FLAG_IS_GUEST_LE &&
1643	    (conn->sign || server_conf.enforced_signing)) ||
1644	    (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
1645		sess->sign = true;
1646
1647	if (smb3_encryption_negotiated(conn) &&
1648	    !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
1649		conn->ops->generate_encryptionkey(conn, sess);
1650		sess->enc = true;
1651		if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION)
1652			rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE;
1653		sess->sign = false;
1654	}
1655
1656binding_session:
1657	if (conn->dialect >= SMB30_PROT_ID) {
1658		chann = lookup_chann_list(sess, conn);
1659		if (!chann) {
1660			chann = kmalloc(sizeof(struct channel), KSMBD_DEFAULT_GFP);
1661			if (!chann)
1662				return -ENOMEM;
1663
1664			chann->conn = conn;
1665			down_write(&sess->chann_lock);
1666			old = xa_store(&sess->ksmbd_chann_list, (long)conn,
1667					chann, KSMBD_DEFAULT_GFP);
1668			up_write(&sess->chann_lock);
1669			if (xa_is_err(old)) {
1670				kfree(chann);
1671				return xa_err(old);
1672			}
1673		}
1674	}
1675
1676	if (conn->ops->generate_signingkey) {
1677		retval = conn->ops->generate_signingkey(sess, conn);
1678		if (retval) {
1679			ksmbd_debug(SMB, "SMB3 signing key generation failed\n");
1680			return -EINVAL;
1681		}
1682	}
1683
1684	if (!ksmbd_conn_lookup_dialect(conn)) {
1685		pr_err("fail to verify the dialect\n");
1686		return -ENOENT;
1687	}
1688	return 0;
1689}
1690#else
1691static int krb5_authenticate(struct ksmbd_work *work,
1692			     struct smb2_sess_setup_req *req,
1693			     struct smb2_sess_setup_rsp *rsp)
1694{
1695	return -EOPNOTSUPP;
1696}
1697#endif
1698
1699int smb2_sess_setup(struct ksmbd_work *work)
1700{
1701	struct ksmbd_conn *conn = work->conn;
1702	struct smb2_sess_setup_req *req;
1703	struct smb2_sess_setup_rsp *rsp;
1704	struct ksmbd_session *sess;
1705	struct negotiate_message *negblob;
1706	unsigned int negblob_len, negblob_off;
1707	int rc = 0;
1708
1709	ksmbd_debug(SMB, "Received smb2 session setup request\n");
1710
1711	if (!ksmbd_conn_need_setup(conn) && !ksmbd_conn_good(conn)) {
1712		work->send_no_response = 1;
1713		return rc;
1714	}
1715
1716	WORK_BUFFERS(work, req, rsp);
1717
1718	rsp->StructureSize = cpu_to_le16(9);
1719	rsp->SessionFlags = 0;
1720	rsp->SecurityBufferOffset = cpu_to_le16(72);
1721	rsp->SecurityBufferLength = 0;
1722
1723	ksmbd_conn_lock(conn);
1724	if (!req->hdr.SessionId) {
1725		sess = ksmbd_smb2_session_create();
1726		if (!sess) {
1727			rc = -ENOMEM;
1728			goto out_err;
1729		}
1730		rsp->hdr.SessionId = cpu_to_le64(sess->id);
1731		rc = ksmbd_session_register(conn, sess);
1732		if (rc)
1733			goto out_err;
1734
1735		conn->binding = false;
1736	} else if (conn->dialect >= SMB30_PROT_ID &&
1737		   (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) &&
1738		   req->Flags & SMB2_SESSION_REQ_FLAG_BINDING) {
1739		u64 sess_id = le64_to_cpu(req->hdr.SessionId);
1740
1741		sess = ksmbd_session_lookup_slowpath(sess_id);
1742		if (!sess) {
1743			rc = -ENOENT;
1744			goto out_err;
1745		}
1746
1747		if (conn->dialect != sess->dialect) {
1748			rc = -EINVAL;
1749			goto out_err;
1750		}
1751
1752		if (!(req->hdr.Flags & SMB2_FLAGS_SIGNED)) {
1753			rc = -EINVAL;
1754			goto out_err;
1755		}
1756
1757		if (strncmp(conn->ClientGUID, sess->ClientGUID,
1758			    SMB2_CLIENT_GUID_SIZE)) {
1759			rc = -ENOENT;
1760			goto out_err;
1761		}
1762
1763		if (sess->state == SMB2_SESSION_IN_PROGRESS) {
1764			rc = -EACCES;
1765			goto out_err;
1766		}
1767
1768		if (sess->state == SMB2_SESSION_EXPIRED) {
1769			rc = -EFAULT;
1770			goto out_err;
1771		}
1772
1773		if (ksmbd_conn_need_reconnect(conn)) {
1774			rc = -EFAULT;
1775			ksmbd_user_session_put(sess);
1776			sess = NULL;
1777			goto out_err;
1778		}
1779
1780		if (is_ksmbd_session_in_connection(conn, sess_id)) {
1781			rc = -EACCES;
1782			goto out_err;
1783		}
1784
1785		if (user_guest(sess->user)) {
1786			rc = -EOPNOTSUPP;
1787			goto out_err;
1788		}
1789
1790		conn->binding = true;
1791	} else if ((conn->dialect < SMB30_PROT_ID ||
1792		    server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) &&
1793		   (req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
1794		sess = NULL;
1795		rc = -EACCES;
1796		goto out_err;
1797	} else {
1798		sess = ksmbd_session_lookup(conn,
1799					    le64_to_cpu(req->hdr.SessionId));
1800		if (!sess) {
1801			rc = -ENOENT;
1802			goto out_err;
1803		}
1804
1805		if (sess->state == SMB2_SESSION_EXPIRED) {
1806			rc = -EFAULT;
1807			goto out_err;
1808		}
1809
1810		if (ksmbd_conn_need_reconnect(conn)) {
1811			rc = -EFAULT;
1812			ksmbd_user_session_put(sess);
1813			sess = NULL;
1814			goto out_err;
1815		}
1816
1817		conn->binding = false;
1818	}
1819	work->sess = sess;
1820
1821	negblob_off = le16_to_cpu(req->SecurityBufferOffset);
1822	negblob_len = le16_to_cpu(req->SecurityBufferLength);
1823	if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer)) {
1824		rc = -EINVAL;
1825		goto out_err;
1826	}
1827
1828	negblob = (struct negotiate_message *)((char *)&req->hdr.ProtocolId +
1829			negblob_off);
1830
1831	if (decode_negotiation_token(conn, negblob, negblob_len) == 0) {
1832		if (conn->mechToken) {
1833			negblob = (struct negotiate_message *)conn->mechToken;
1834			negblob_len = conn->mechTokenLen;
1835		}
1836	}
1837
1838	if (negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) {
1839		rc = -EINVAL;
1840		goto out_err;
1841	}
1842
1843	if (server_conf.auth_mechs & conn->auth_mechs) {
1844		rc = generate_preauth_hash(work);
1845		if (rc)
1846			goto out_err;
1847
1848		if (conn->preferred_auth_mech &
1849				(KSMBD_AUTH_KRB5 | KSMBD_AUTH_MSKRB5)) {
1850			rc = krb5_authenticate(work, req, rsp);
1851			if (rc) {
1852				rc = -EINVAL;
1853				goto out_err;
1854			}
1855
1856			if (!ksmbd_conn_need_reconnect(conn)) {
1857				ksmbd_conn_set_good(conn);
1858				sess->state = SMB2_SESSION_VALID;
1859			}
1860		} else if (conn->preferred_auth_mech == KSMBD_AUTH_NTLMSSP) {
1861			if (negblob->MessageType == NtLmNegotiate) {
1862				rc = ntlm_negotiate(work, negblob, negblob_len, rsp);
1863				if (rc)
1864					goto out_err;
1865				rsp->hdr.Status =
1866					STATUS_MORE_PROCESSING_REQUIRED;
1867			} else if (negblob->MessageType == NtLmAuthenticate) {
1868				rc = ntlm_authenticate(work, req, rsp);
1869				if (rc)
1870					goto out_err;
1871
1872				if (!ksmbd_conn_need_reconnect(conn)) {
1873					ksmbd_conn_set_good(conn);
1874					sess->state = SMB2_SESSION_VALID;
1875				}
1876				if (conn->binding) {
1877					struct preauth_session *preauth_sess;
1878
1879					preauth_sess =
1880						ksmbd_preauth_session_lookup(conn, sess->id);
1881					if (preauth_sess) {
1882						list_del(&preauth_sess->preauth_entry);
1883						kfree(preauth_sess);
1884					}
1885				}
1886			} else {
1887				pr_info_ratelimited("Unknown NTLMSSP message type : 0x%x\n",
1888						le32_to_cpu(negblob->MessageType));
1889				rc = -EINVAL;
1890			}
1891		} else {
1892			/* TODO: need one more negotiation */
1893			pr_err("Not support the preferred authentication\n");
1894			rc = -EINVAL;
1895		}
1896	} else {
1897		pr_err("Not support authentication\n");
1898		rc = -EINVAL;
1899	}
1900
1901out_err:
1902	if (rc == -EINVAL)
1903		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
1904	else if (rc == -ENOENT)
1905		rsp->hdr.Status = STATUS_USER_SESSION_DELETED;
1906	else if (rc == -EACCES)
1907		rsp->hdr.Status = STATUS_REQUEST_NOT_ACCEPTED;
1908	else if (rc == -EFAULT)
1909		rsp->hdr.Status = STATUS_NETWORK_SESSION_EXPIRED;
1910	else if (rc == -ENOMEM)
1911		rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
1912	else if (rc == -EOPNOTSUPP)
1913		rsp->hdr.Status = STATUS_NOT_SUPPORTED;
1914	else if (rc)
1915		rsp->hdr.Status = STATUS_LOGON_FAILURE;
1916
1917	if (conn->mechToken) {
1918		kfree(conn->mechToken);
1919		conn->mechToken = NULL;
1920	}
1921
1922	if (rc < 0) {
1923		/*
1924		 * SecurityBufferOffset should be set to zero
1925		 * in session setup error response.
1926		 */
1927		rsp->SecurityBufferOffset = 0;
1928
1929		if (sess) {
1930			bool try_delay = false;
1931
1932			/*
1933			 * To avoid dictionary attacks (repeated session setups rapidly sent) to
1934			 * connect to server, ksmbd make a delay of a 5 seconds on session setup
1935			 * failure to make it harder to send enough random connection requests
1936			 * to break into a server.
1937			 */
1938			if (sess->user && sess->user->flags & KSMBD_USER_FLAG_DELAY_SESSION)
1939				try_delay = true;
1940
1941			/*
1942			 * For binding requests, session belongs to another
1943			 * connection. Do not expire it.
1944			 */
1945			if (!(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
1946				sess->last_active = jiffies;
1947				sess->state = SMB2_SESSION_EXPIRED;
1948			}
1949			ksmbd_user_session_put(sess);
1950			work->sess = NULL;
1951			if (try_delay) {
1952				ksmbd_conn_set_need_reconnect(conn);
1953				ssleep(5);
1954				ksmbd_conn_set_need_setup(conn);
1955			}
1956		}
1957		smb2_set_err_rsp(work);
1958		conn->binding = false;
1959	} else {
1960		unsigned int iov_len;
1961
1962		if (rsp->SecurityBufferLength)
1963			iov_len = offsetof(struct smb2_sess_setup_rsp, Buffer) +
1964				le16_to_cpu(rsp->SecurityBufferLength);
1965		else
1966			iov_len = sizeof(struct smb2_sess_setup_rsp);
1967		rc = ksmbd_iov_pin_rsp(work, rsp, iov_len);
1968		if (rc)
1969			rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
1970	}
1971
1972	ksmbd_conn_unlock(conn);
1973	return rc;
1974}
1975
1976/**
1977 * smb2_tree_connect() - handler for smb2 tree connect command
1978 * @work:	smb work containing smb request buffer
1979 *
1980 * Return:      0 on success, otherwise error
1981 */
1982int smb2_tree_connect(struct ksmbd_work *work)
1983{
1984	struct ksmbd_conn *conn = work->conn;
1985	struct smb2_tree_connect_req *req;
1986	struct smb2_tree_connect_rsp *rsp;
1987	struct ksmbd_session *sess = work->sess;
1988	char *treename = NULL, *name = NULL;
1989	struct ksmbd_tree_conn_status status;
1990	struct ksmbd_share_config *share = NULL;
1991	int rc = -EINVAL;
1992
1993	ksmbd_debug(SMB, "Received smb2 tree connect request\n");
1994
1995	WORK_BUFFERS(work, req, rsp);
1996
1997	treename = smb_strndup_from_utf16((char *)req + le16_to_cpu(req->PathOffset),
1998					  le16_to_cpu(req->PathLength), true,
1999					  conn->local_nls);
2000	if (IS_ERR(treename)) {
2001		pr_err("treename is NULL\n");
2002		status.ret = KSMBD_TREE_CONN_STATUS_ERROR;
2003		goto out_err1;
2004	}
2005
2006	name = ksmbd_extract_sharename(conn->um, treename);
2007	if (IS_ERR(name)) {
2008		status.ret = KSMBD_TREE_CONN_STATUS_ERROR;
2009		goto out_err1;
2010	}
2011
2012	ksmbd_debug(SMB, "tree connect request for tree %s treename %s\n",
2013		    name, treename);
2014
2015	status = ksmbd_tree_conn_connect(work, name);
2016	if (status.ret == KSMBD_TREE_CONN_STATUS_OK)
2017		rsp->hdr.Id.SyncId.TreeId = cpu_to_le32(status.tree_conn->id);
2018	else
2019		goto out_err1;
2020
2021	share = status.tree_conn->share_conf;
2022	if (test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
2023		ksmbd_debug(SMB, "IPC share path request\n");
2024		rsp->ShareType = SMB2_SHARE_TYPE_PIPE;
2025		rsp->MaximalAccess = FILE_READ_DATA_LE | FILE_READ_EA_LE |
2026			FILE_EXECUTE_LE | FILE_READ_ATTRIBUTES_LE |
2027			FILE_DELETE_LE | FILE_READ_CONTROL_LE |
2028			FILE_WRITE_DAC_LE | FILE_WRITE_OWNER_LE |
2029			FILE_SYNCHRONIZE_LE;
2030	} else {
2031		rsp->ShareType = SMB2_SHARE_TYPE_DISK;
2032		rsp->MaximalAccess = FILE_READ_DATA_LE | FILE_READ_EA_LE |
2033			FILE_EXECUTE_LE | FILE_READ_ATTRIBUTES_LE;
2034		if (test_tree_conn_flag(status.tree_conn,
2035					KSMBD_TREE_CONN_FLAG_WRITABLE)) {
2036			rsp->MaximalAccess |= FILE_WRITE_DATA_LE |
2037				FILE_APPEND_DATA_LE | FILE_WRITE_EA_LE |
2038				FILE_DELETE_LE | FILE_WRITE_ATTRIBUTES_LE |
2039				FILE_DELETE_CHILD_LE | FILE_READ_CONTROL_LE |
2040				FILE_WRITE_DAC_LE | FILE_WRITE_OWNER_LE |
2041				FILE_SYNCHRONIZE_LE;
2042		}
2043	}
2044
2045	status.tree_conn->maximal_access = le32_to_cpu(rsp->MaximalAccess);
2046	if (conn->posix_ext_supported)
2047		status.tree_conn->posix_extensions = true;
2048
2049	write_lock(&sess->tree_conns_lock);
2050	status.tree_conn->t_state = TREE_CONNECTED;
2051	write_unlock(&sess->tree_conns_lock);
2052	rsp->StructureSize = cpu_to_le16(16);
2053out_err1:
2054	if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE && share &&
2055	    test_share_config_flag(share,
2056				   KSMBD_SHARE_FLAG_CONTINUOUS_AVAILABILITY))
2057		rsp->Capabilities = SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY;
2058	else
2059		rsp->Capabilities = 0;
2060	rsp->Reserved = 0;
2061	/* default manual caching */
2062	rsp->ShareFlags = SMB2_SHAREFLAG_MANUAL_CACHING;
2063
2064	rc = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_tree_connect_rsp));
2065	if (rc)
2066		status.ret = KSMBD_TREE_CONN_STATUS_NOMEM;
2067
2068	if (!IS_ERR(treename))
2069		kfree(treename);
2070	if (!IS_ERR(name))
2071		kfree(name);
2072
2073	switch (status.ret) {
2074	case KSMBD_TREE_CONN_STATUS_OK:
2075		rsp->hdr.Status = STATUS_SUCCESS;
2076		rc = 0;
2077		break;
2078	case -ESTALE:
2079	case -ENOENT:
2080	case KSMBD_TREE_CONN_STATUS_NO_SHARE:
2081		rsp->hdr.Status = STATUS_BAD_NETWORK_NAME;
2082		break;
2083	case -ENOMEM:
2084	case KSMBD_TREE_CONN_STATUS_NOMEM:
2085		rsp->hdr.Status = STATUS_NO_MEMORY;
2086		break;
2087	case KSMBD_TREE_CONN_STATUS_ERROR:
2088	case KSMBD_TREE_CONN_STATUS_TOO_MANY_CONNS:
2089	case KSMBD_TREE_CONN_STATUS_TOO_MANY_SESSIONS:
2090		rsp->hdr.Status = STATUS_ACCESS_DENIED;
2091		break;
2092	case -EINVAL:
2093		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
2094		break;
2095	default:
2096		rsp->hdr.Status = STATUS_ACCESS_DENIED;
2097	}
2098
2099	if (status.ret != KSMBD_TREE_CONN_STATUS_OK)
2100		smb2_set_err_rsp(work);
2101
2102	return rc;
2103}
2104
2105/**
2106 * smb2_create_open_flags() - convert smb open flags to unix open flags
2107 * @file_present:	is file already present
2108 * @access:		file access flags
2109 * @disposition:	file disposition flags
2110 * @may_flags:		set with MAY_ flags
2111 * @coptions:		file creation options
2112 * @mode:		file mode
2113 *
2114 * Return:      file open flags
2115 */
2116static int smb2_create_open_flags(bool file_present, __le32 access,
2117				  __le32 disposition,
2118				  int *may_flags,
2119				  __le32 coptions,
2120				  umode_t mode)
2121{
2122	int oflags = O_NONBLOCK | O_LARGEFILE;
2123
2124	if (coptions & FILE_DIRECTORY_FILE_LE || S_ISDIR(mode)) {
2125		access &= ~FILE_WRITE_DESIRE_ACCESS_LE;
2126		ksmbd_debug(SMB, "Discard write access to a directory\n");
2127	}
2128
2129	if (access & FILE_READ_DESIRED_ACCESS_LE &&
2130	    access & FILE_WRITE_DESIRE_ACCESS_LE) {
2131		oflags |= O_RDWR;
2132		*may_flags = MAY_OPEN | MAY_READ | MAY_WRITE;
2133	} else if (access & FILE_WRITE_DESIRE_ACCESS_LE) {
2134		oflags |= O_WRONLY;
2135		*may_flags = MAY_OPEN | MAY_WRITE;
2136	} else {
2137		oflags |= O_RDONLY;
2138		*may_flags = MAY_OPEN | MAY_READ;
2139	}
2140
2141	if (access == FILE_READ_ATTRIBUTES_LE || S_ISBLK(mode) || S_ISCHR(mode))
2142		oflags |= O_PATH;
2143
2144	if (file_present) {
2145		switch (disposition & FILE_CREATE_MASK_LE) {
2146		case FILE_OPEN_LE:
2147		case FILE_CREATE_LE:
2148			break;
2149		case FILE_SUPERSEDE_LE:
2150		case FILE_OVERWRITE_LE:
2151		case FILE_OVERWRITE_IF_LE:
2152			oflags |= O_TRUNC;
2153			break;
2154		default:
2155			break;
2156		}
2157	} else {
2158		switch (disposition & FILE_CREATE_MASK_LE) {
2159		case FILE_SUPERSEDE_LE:
2160		case FILE_CREATE_LE:
2161		case FILE_OPEN_IF_LE:
2162		case FILE_OVERWRITE_IF_LE:
2163			oflags |= O_CREAT;
2164			break;
2165		case FILE_OPEN_LE:
2166		case FILE_OVERWRITE_LE:
2167			oflags &= ~O_CREAT;
2168			break;
2169		default:
2170			break;
2171		}
2172	}
2173
2174	return oflags;
2175}
2176
2177/**
2178 * smb2_tree_disconnect() - handler for smb tree connect request
2179 * @work:	smb work containing request buffer
2180 *
2181 * Return:      0 on success, otherwise error
2182 */
2183int smb2_tree_disconnect(struct ksmbd_work *work)
2184{
2185	struct smb2_tree_disconnect_rsp *rsp;
2186	struct smb2_tree_disconnect_req *req;
2187	struct ksmbd_session *sess = work->sess;
2188	struct ksmbd_tree_connect *tcon = work->tcon;
2189	int err;
2190
2191	ksmbd_debug(SMB, "Received smb2 tree disconnect request\n");
2192
2193	WORK_BUFFERS(work, req, rsp);
2194
2195	if (!tcon) {
2196		ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId);
2197
2198		rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
2199		err = -ENOENT;
2200		goto err_out;
2201	}
2202
2203	ksmbd_close_tree_conn_fds(work);
2204
2205	write_lock(&sess->tree_conns_lock);
2206	if (tcon->t_state == TREE_DISCONNECTED) {
2207		write_unlock(&sess->tree_conns_lock);
2208		rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
2209		err = -ENOENT;
2210		goto err_out;
2211	}
2212
2213	tcon->t_state = TREE_DISCONNECTED;
2214	write_unlock(&sess->tree_conns_lock);
2215
2216	err = ksmbd_tree_conn_disconnect(sess, tcon);
2217	if (err) {
2218		rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
2219		goto err_out;
2220	}
2221
2222	rsp->StructureSize = cpu_to_le16(4);
2223	err = ksmbd_iov_pin_rsp(work, rsp,
2224				sizeof(struct smb2_tree_disconnect_rsp));
2225	if (err) {
2226		rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
2227		goto err_out;
2228	}
2229
2230	return 0;
2231
2232err_out:
2233	smb2_set_err_rsp(work);
2234	return err;
2235
2236}
2237
2238/**
2239 * smb2_session_logoff() - handler for session log off request
2240 * @work:	smb work containing request buffer
2241 *
2242 * Return:      0 on success, otherwise error
2243 */
2244int smb2_session_logoff(struct ksmbd_work *work)
2245{
2246	struct ksmbd_conn *conn = work->conn;
2247	struct ksmbd_session *sess = work->sess;
2248	struct smb2_logoff_req *req;
2249	struct smb2_logoff_rsp *rsp;
2250	u64 sess_id;
2251	int err;
2252
2253	WORK_BUFFERS(work, req, rsp);
2254
2255	ksmbd_debug(SMB, "Received smb2 session logoff request\n");
2256
2257	ksmbd_conn_lock(conn);
2258	if (!ksmbd_conn_good(conn)) {
2259		ksmbd_conn_unlock(conn);
2260		rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
2261		smb2_set_err_rsp(work);
2262		return -ENOENT;
2263	}
2264	sess_id = le64_to_cpu(req->hdr.SessionId);
2265	ksmbd_all_conn_set_status(sess_id, KSMBD_SESS_NEED_RECONNECT);
2266	ksmbd_conn_unlock(conn);
2267
2268	ksmbd_close_session_fds(work);
2269	ksmbd_conn_wait_idle(conn);
2270
2271	if (ksmbd_tree_conn_session_logoff(sess)) {
2272		ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId);
2273		rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
2274		smb2_set_err_rsp(work);
2275		return -ENOENT;
2276	}
2277
2278	down_write(&conn->session_lock);
2279	sess->state = SMB2_SESSION_EXPIRED;
2280	up_write(&conn->session_lock);
2281
2282	ksmbd_all_conn_set_status(sess_id, KSMBD_SESS_NEED_SETUP);
2283
2284	rsp->StructureSize = cpu_to_le16(4);
2285	err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_logoff_rsp));
2286	if (err) {
2287		rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
2288		smb2_set_err_rsp(work);
2289		return err;
2290	}
2291	return 0;
2292}
2293
2294/**
2295 * create_smb2_pipe() - create IPC pipe
2296 * @work:	smb work containing request buffer
2297 *
2298 * Return:      0 on success, otherwise error
2299 */
2300static noinline int create_smb2_pipe(struct ksmbd_work *work)
2301{
2302	struct smb2_create_rsp *rsp;
2303	struct smb2_create_req *req;
2304	int id = -1;
2305	int err;
2306	char *name;
2307
2308	WORK_BUFFERS(work, req, rsp);
2309
2310	name = smb_strndup_from_utf16(req->Buffer, le16_to_cpu(req->NameLength),
2311				      1, work->conn->local_nls);
2312	if (IS_ERR(name)) {
2313		rsp->hdr.Status = STATUS_NO_MEMORY;
2314		err = PTR_ERR(name);
2315		goto out;
2316	}
2317
2318	id = ksmbd_session_rpc_open(work->sess, name);
2319	if (id < 0) {
2320		pr_err("Unable to open RPC pipe: %d\n", id);
2321		err = id;
2322		goto out;
2323	}
2324
2325	rsp->hdr.Status = STATUS_SUCCESS;
2326	rsp->StructureSize = cpu_to_le16(89);
2327	rsp->OplockLevel = SMB2_OPLOCK_LEVEL_NONE;
2328	rsp->Flags = 0;
2329	rsp->CreateAction = cpu_to_le32(FILE_OPENED);
2330
2331	rsp->CreationTime = cpu_to_le64(0);
2332	rsp->LastAccessTime = cpu_to_le64(0);
2333	rsp->ChangeTime = cpu_to_le64(0);
2334	rsp->AllocationSize = cpu_to_le64(0);
2335	rsp->EndofFile = cpu_to_le64(0);
2336	rsp->FileAttributes = FILE_ATTRIBUTE_NORMAL_LE;
2337	rsp->Reserved2 = 0;
2338	rsp->VolatileFileId = id;
2339	rsp->PersistentFileId = 0;
2340	rsp->CreateContextsOffset = 0;
2341	rsp->CreateContextsLength = 0;
2342
2343	err = ksmbd_iov_pin_rsp(work, rsp, offsetof(struct smb2_create_rsp, Buffer));
2344	if (err)
2345		goto out;
2346
2347	kfree(name);
2348	return 0;
2349
2350out:
2351	switch (err) {
2352	case -EINVAL:
2353		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
2354		break;
2355	case -ENOSPC:
2356	case -ENOMEM:
2357		rsp->hdr.Status = STATUS_NO_MEMORY;
2358		break;
2359	}
2360
2361	if (id >= 0)
2362		ksmbd_session_rpc_close(work->sess, id);
2363
2364	if (!IS_ERR(name))
2365		kfree(name);
2366
2367	smb2_set_err_rsp(work);
2368	return err;
2369}
2370
2371/**
2372 * smb2_set_ea() - handler for setting extended attributes using set
2373 *		info command
2374 * @eabuf:	set info command buffer
2375 * @buf_len:	set info command buffer length
2376 * @path:	dentry path for get ea
2377 * @get_write:	get write access to a mount
2378 *
2379 * Return:	0 on success, otherwise error
2380 */
2381static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len,
2382		       const struct path *path, bool get_write)
2383{
2384	struct mnt_idmap *idmap = mnt_idmap(path->mnt);
2385	char *attr_name = NULL, *value;
2386	int rc = 0;
2387	unsigned int next = 0;
2388
2389	if (buf_len < sizeof(struct smb2_ea_info) + eabuf->EaNameLength + 1 +
2390			le16_to_cpu(eabuf->EaValueLength))
2391		return -EINVAL;
2392
2393	attr_name = kmalloc(XATTR_NAME_MAX + 1, KSMBD_DEFAULT_GFP);
2394	if (!attr_name)
2395		return -ENOMEM;
2396
2397	do {
2398		if (!eabuf->EaNameLength)
2399			goto next;
2400
2401		ksmbd_debug(SMB,
2402			    "name : <%s>, name_len : %u, value_len : %u, next : %u\n",
2403			    eabuf->name, eabuf->EaNameLength,
2404			    le16_to_cpu(eabuf->EaValueLength),
2405			    le32_to_cpu(eabuf->NextEntryOffset));
2406
2407		if (eabuf->EaNameLength >
2408		    (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
2409			rc = -EINVAL;
2410			break;
2411		}
2412
2413		memcpy(attr_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
2414		memcpy(&attr_name[XATTR_USER_PREFIX_LEN], eabuf->name,
2415		       eabuf->EaNameLength);
2416		attr_name[XATTR_USER_PREFIX_LEN + eabuf->EaNameLength] = '\0';
2417		value = (char *)&eabuf->name + eabuf->EaNameLength + 1;
2418
2419		if (!eabuf->EaValueLength) {
2420			rc = ksmbd_vfs_casexattr_len(idmap,
2421						     path->dentry,
2422						     attr_name,
2423						     XATTR_USER_PREFIX_LEN +
2424						     eabuf->EaNameLength);
2425
2426			/* delete the EA only when it exits */
2427			if (rc > 0) {
2428				rc = ksmbd_vfs_remove_xattr(idmap,
2429							    path,
2430							    attr_name,
2431							    get_write);
2432
2433				if (rc < 0) {
2434					ksmbd_debug(SMB,
2435						    "remove xattr failed(%d)\n",
2436						    rc);
2437					break;
2438				}
2439			}
2440
2441			/* if the EA doesn't exist, just do nothing. */
2442			rc = 0;
2443		} else {
2444			rc = ksmbd_vfs_setxattr(idmap, path, attr_name, value,
2445						le16_to_cpu(eabuf->EaValueLength),
2446						0, get_write);
2447			if (rc < 0) {
2448				ksmbd_debug(SMB,
2449					    "ksmbd_vfs_setxattr is failed(%d)\n",
2450					    rc);
2451				break;
2452			}
2453		}
2454
2455next:
2456		next = le32_to_cpu(eabuf->NextEntryOffset);
2457		if (next == 0 || buf_len < next)
2458			break;
2459		buf_len -= next;
2460		eabuf = (struct smb2_ea_info *)((char *)eabuf + next);
2461		if (buf_len < sizeof(struct smb2_ea_info)) {
2462			rc = -EINVAL;
2463			break;
2464		}
2465
2466		if (buf_len < sizeof(struct smb2_ea_info) + eabuf->EaNameLength + 1 +
2467				le16_to_cpu(eabuf->EaValueLength)) {
2468			rc = -EINVAL;
2469			break;
2470		}
2471	} while (next != 0);
2472
2473	kfree(attr_name);
2474	return rc;
2475}
2476
2477static noinline int smb2_set_stream_name_xattr(const struct path *path,
2478					       struct ksmbd_file *fp,
2479					       char *stream_name, int s_type)
2480{
2481	struct mnt_idmap *idmap = mnt_idmap(path->mnt);
2482	size_t xattr_stream_size;
2483	char *xattr_stream_name;
2484	int rc;
2485
2486	rc = ksmbd_vfs_xattr_stream_name(stream_name,
2487					 &xattr_stream_name,
2488					 &xattr_stream_size,
2489					 s_type);
2490	if (rc)
2491		return rc;
2492
2493	fp->stream.name = xattr_stream_name;
2494	fp->stream.size = xattr_stream_size;
2495
2496	/* Check if there is stream prefix in xattr space */
2497	rc = ksmbd_vfs_casexattr_len(idmap,
2498				     path->dentry,
2499				     xattr_stream_name,
2500				     xattr_stream_size);
2501	if (rc >= 0)
2502		return 0;
2503
2504	if (fp->cdoption == FILE_OPEN_LE) {
2505		ksmbd_debug(SMB, "XATTR stream name lookup failed: %d\n", rc);
2506		return -EBADF;
2507	}
2508
2509	rc = ksmbd_vfs_setxattr(idmap, path, xattr_stream_name, NULL, 0, 0, false);
2510	if (rc < 0)
2511		pr_err("Failed to store XATTR stream name :%d\n", rc);
2512	return 0;
2513}
2514
2515static int smb2_remove_smb_xattrs(const struct path *path)
2516{
2517	struct mnt_idmap *idmap = mnt_idmap(path->mnt);
2518	char *name, *xattr_list = NULL;
2519	ssize_t xattr_list_len;
2520	int err = 0;
2521
2522	xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
2523	if (xattr_list_len < 0) {
2524		goto out;
2525	} else if (!xattr_list_len) {
2526		ksmbd_debug(SMB, "empty xattr in the file\n");
2527		goto out;
2528	}
2529
2530	for (name = xattr_list; name - xattr_list < xattr_list_len;
2531			name += strlen(name) + 1) {
2532		ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
2533
2534		if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
2535		    !strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
2536			     STREAM_PREFIX_LEN)) {
2537			err = ksmbd_vfs_remove_xattr(idmap, path,
2538						     name, true);
2539			if (err)
2540				ksmbd_debug(SMB, "remove xattr failed : %s\n",
2541					    name);
2542		}
2543	}
2544out:
2545	kvfree(xattr_list);
2546	return err;
2547}
2548
2549static int smb2_create_truncate(const struct path *path)
2550{
2551	int rc = vfs_truncate(path, 0);
2552
2553	if (rc) {
2554		pr_err("vfs_truncate failed, rc %d\n", rc);
2555		return rc;
2556	}
2557
2558	rc = smb2_remove_smb_xattrs(path);
2559	if (rc == -EOPNOTSUPP)
2560		rc = 0;
2561	if (rc)
2562		ksmbd_debug(SMB,
2563			    "ksmbd_truncate_stream_name_xattr failed, rc %d\n",
2564			    rc);
2565	return rc;
2566}
2567
2568static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, const struct path *path,
2569			    struct ksmbd_file *fp)
2570{
2571	struct xattr_dos_attrib da = {0};
2572	int rc;
2573
2574	if (!test_share_config_flag(tcon->share_conf,
2575				    KSMBD_SHARE_FLAG_STORE_DOS_ATTRS))
2576		return;
2577
2578	da.version = 4;
2579	da.attr = le32_to_cpu(fp->f_ci->m_fattr);
2580	da.itime = da.create_time = fp->create_time;
2581	da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
2582		XATTR_DOSINFO_ITIME;
2583
2584	rc = ksmbd_vfs_set_dos_attrib_xattr(mnt_idmap(path->mnt), path, &da, true);
2585	if (rc)
2586		ksmbd_debug(SMB, "failed to store file attribute into xattr\n");
2587}
2588
2589static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon,
2590			       const struct path *path, struct ksmbd_file *fp)
2591{
2592	struct xattr_dos_attrib da;
2593	int rc;
2594
2595	fp->f_ci->m_fattr &= ~(FILE_ATTRIBUTE_HIDDEN_LE | FILE_ATTRIBUTE_SYSTEM_LE);
2596
2597	/* get FileAttributes from XATTR_NAME_DOS_ATTRIBUTE */
2598	if (!test_share_config_flag(tcon->share_conf,
2599				    KSMBD_SHARE_FLAG_STORE_DOS_ATTRS))
2600		return;
2601
2602	rc = ksmbd_vfs_get_dos_attrib_xattr(mnt_idmap(path->mnt),
2603					    path->dentry, &da);
2604	if (rc > 0) {
2605		fp->f_ci->m_fattr = cpu_to_le32(da.attr);
2606		fp->create_time = da.create_time;
2607		fp->itime = da.itime;
2608	}
2609}
2610
2611static int smb2_creat(struct ksmbd_work *work,
2612		      struct path *path, char *name, int open_flags,
2613		      umode_t posix_mode, bool is_dir)
2614{
2615	struct ksmbd_tree_connect *tcon = work->tcon;
2616	struct ksmbd_share_config *share = tcon->share_conf;
2617	umode_t mode;
2618	int rc;
2619
2620	if (!(open_flags & O_CREAT))
2621		return -EBADF;
2622
2623	ksmbd_debug(SMB, "file does not exist, so creating\n");
2624	if (is_dir == true) {
2625		ksmbd_debug(SMB, "creating directory\n");
2626
2627		mode = share_config_directory_mode(share, posix_mode);
2628		rc = ksmbd_vfs_mkdir(work, name, mode);
2629		if (rc)
2630			return rc;
2631	} else {
2632		ksmbd_debug(SMB, "creating regular file\n");
2633
2634		mode = share_config_create_mode(share, posix_mode);
2635		rc = ksmbd_vfs_create(work, name, mode);
2636		if (rc)
2637			return rc;
2638	}
2639
2640	rc = ksmbd_vfs_kern_path(work, name, 0, path, 0);
2641	if (rc) {
2642		pr_err("cannot get linux path (%s), err = %d\n",
2643		       name, rc);
2644		return rc;
2645	}
2646	return 0;
2647}
2648
2649static int smb2_create_sd_buffer(struct ksmbd_work *work,
2650				 struct smb2_create_req *req,
2651				 const struct path *path)
2652{
2653	struct create_context *context;
2654	struct create_sd_buf_req *sd_buf;
2655
2656	if (!req->CreateContextsOffset)
2657		return -ENOENT;
2658
2659	/* Parse SD BUFFER create contexts */
2660	context = smb2_find_context_vals(req, SMB2_CREATE_SD_BUFFER, 4);
2661	if (!context)
2662		return -ENOENT;
2663	else if (IS_ERR(context))
2664		return PTR_ERR(context);
2665
2666	ksmbd_debug(SMB,
2667		    "Set ACLs using SMB2_CREATE_SD_BUFFER context\n");
2668	sd_buf = (struct create_sd_buf_req *)context;
2669	if (le16_to_cpu(context->DataOffset) +
2670	    le32_to_cpu(context->DataLength) <
2671	    sizeof(struct create_sd_buf_req))
2672		return -EINVAL;
2673	return set_info_sec(work->conn, work->tcon, path, &sd_buf->ntsd,
2674			    le32_to_cpu(sd_buf->ccontext.DataLength), true, false);
2675}
2676
2677static void ksmbd_acls_fattr(struct smb_fattr *fattr,
2678			     struct mnt_idmap *idmap,
2679			     struct inode *inode)
2680{
2681	vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);
2682	vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, inode);
2683
2684	fattr->cf_uid = vfsuid_into_kuid(vfsuid);
2685	fattr->cf_gid = vfsgid_into_kgid(vfsgid);
2686	fattr->cf_mode = inode->i_mode;
2687	fattr->cf_acls = NULL;
2688	fattr->cf_dacls = NULL;
2689
2690	if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
2691		fattr->cf_acls = get_inode_acl(inode, ACL_TYPE_ACCESS);
2692		if (S_ISDIR(inode->i_mode))
2693			fattr->cf_dacls = get_inode_acl(inode, ACL_TYPE_DEFAULT);
2694	}
2695}
2696
2697enum {
2698	DURABLE_RECONN_V2 = 1,
2699	DURABLE_RECONN,
2700	DURABLE_REQ_V2,
2701	DURABLE_REQ,
2702};
2703
2704struct durable_info {
2705	struct ksmbd_file *fp;
2706	unsigned short int type;
2707	bool persistent;
2708	bool reconnected;
2709	unsigned int timeout;
2710	char *CreateGuid;
2711};
2712
2713static int parse_durable_handle_context(struct ksmbd_work *work,
2714					struct smb2_create_req *req,
2715					struct lease_ctx_info *lc,
2716					struct durable_info *dh_info)
2717{
2718	struct ksmbd_conn *conn = work->conn;
2719	struct create_context *context;
2720	int dh_idx, err = 0;
2721	u64 persistent_id = 0;
2722	int req_op_level;
2723	static const char * const durable_arr[] = {"DH2C", "DHnC", "DH2Q", "DHnQ"};
2724
2725	req_op_level = req->RequestedOplockLevel;
2726	for (dh_idx = DURABLE_RECONN_V2; dh_idx <= ARRAY_SIZE(durable_arr);
2727	     dh_idx++) {
2728		context = smb2_find_context_vals(req, durable_arr[dh_idx - 1], 4);
2729		if (IS_ERR(context)) {
2730			err = PTR_ERR(context);
2731			goto out;
2732		}
2733		if (!context)
2734			continue;
2735
2736		switch (dh_idx) {
2737		case DURABLE_RECONN_V2:
2738		{
2739			struct create_durable_handle_reconnect_v2 *recon_v2;
2740
2741			if (dh_info->type == DURABLE_RECONN ||
2742			    dh_info->type == DURABLE_REQ_V2) {
2743				err = -EINVAL;
2744				goto out;
2745			}
2746
2747			if (le16_to_cpu(context->DataOffset) +
2748				le32_to_cpu(context->DataLength) <
2749			    sizeof(struct create_durable_handle_reconnect_v2)) {
2750				err = -EINVAL;
2751				goto out;
2752			}
2753
2754			recon_v2 = (struct create_durable_handle_reconnect_v2 *)context;
2755			persistent_id = recon_v2->dcontext.Fid.PersistentFileId;
2756			dh_info->fp = ksmbd_lookup_durable_fd(persistent_id);
2757			if (!dh_info->fp) {
2758				ksmbd_debug(SMB, "Failed to get durable handle state\n");
2759				err = -EBADF;
2760				goto out;
2761			}
2762
2763			if (memcmp(dh_info->fp->create_guid, recon_v2->dcontext.CreateGuid,
2764				   SMB2_CREATE_GUID_SIZE)) {
2765				err = -EBADF;
2766				ksmbd_put_durable_fd(dh_info->fp);
2767				goto out;
2768			}
2769
2770			dh_info->type = dh_idx;
2771			dh_info->reconnected = true;
2772			ksmbd_debug(SMB,
2773				"reconnect v2 Persistent-id from reconnect = %llu\n",
2774					persistent_id);
2775			break;
2776		}
2777		case DURABLE_RECONN:
2778		{
2779			create_durable_reconn_t *recon;
2780
2781			if (dh_info->type == DURABLE_RECONN_V2 ||
2782			    dh_info->type == DURABLE_REQ_V2) {
2783				err = -EINVAL;
2784				goto out;
2785			}
2786
2787			if (le16_to_cpu(context->DataOffset) +
2788				le32_to_cpu(context->DataLength) <
2789			    sizeof(create_durable_reconn_t)) {
2790				err = -EINVAL;
2791				goto out;
2792			}
2793
2794			recon = (create_durable_reconn_t *)context;
2795			persistent_id = recon->Data.Fid.PersistentFileId;
2796			dh_info->fp = ksmbd_lookup_durable_fd(persistent_id);
2797			if (!dh_info->fp) {
2798				ksmbd_debug(SMB, "Failed to get durable handle state\n");
2799				err = -EBADF;
2800				goto out;
2801			}
2802
2803			dh_info->type = dh_idx;
2804			dh_info->reconnected = true;
2805			ksmbd_debug(SMB, "reconnect Persistent-id from reconnect = %llu\n",
2806				    persistent_id);
2807			break;
2808		}
2809		case DURABLE_REQ_V2:
2810		{
2811			struct create_durable_req_v2 *durable_v2_blob;
2812
2813			if (dh_info->type == DURABLE_RECONN ||
2814			    dh_info->type == DURABLE_RECONN_V2) {
2815				err = -EINVAL;
2816				goto out;
2817			}
2818
2819			if (le16_to_cpu(context->DataOffset) +
2820				le32_to_cpu(context->DataLength) <
2821			    sizeof(struct create_durable_req_v2)) {
2822				err = -EINVAL;
2823				goto out;
2824			}
2825
2826			durable_v2_blob =
2827				(struct create_durable_req_v2 *)context;
2828			ksmbd_debug(SMB, "Request for durable v2 open\n");
2829			dh_info->fp = ksmbd_lookup_fd_cguid(durable_v2_blob->dcontext.CreateGuid);
2830			if (dh_info->fp) {
2831				if (!memcmp(conn->ClientGUID, dh_info->fp->client_guid,
2832					    SMB2_CLIENT_GUID_SIZE)) {
2833					if (!(req->hdr.Flags & SMB2_FLAGS_REPLAY_OPERATION)) {
2834						err = -ENOEXEC;
2835						ksmbd_put_durable_fd(dh_info->fp);
2836						goto out;
2837					}
2838
2839					if (dh_info->fp->conn) {
2840						ksmbd_put_durable_fd(dh_info->fp);
2841						err = -EBADF;
2842						goto out;
2843					}
2844					dh_info->reconnected = true;
2845					goto out;
2846				}
2847			}
2848
2849			if ((lc && (lc->req_state & SMB2_LEASE_HANDLE_CACHING_LE)) ||
2850			    req_op_level == SMB2_OPLOCK_LEVEL_BATCH) {
2851				dh_info->CreateGuid =
2852					durable_v2_blob->dcontext.CreateGuid;
2853				dh_info->persistent =
2854					le32_to_cpu(durable_v2_blob->dcontext.Flags);
2855				dh_info->timeout =
2856					le32_to_cpu(durable_v2_blob->dcontext.Timeout);
2857				dh_info->type = dh_idx;
2858			}
2859			break;
2860		}
2861		case DURABLE_REQ:
2862			if (dh_info->type == DURABLE_RECONN)
2863				goto out;
2864			if (dh_info->type == DURABLE_RECONN_V2 ||
2865			    dh_info->type == DURABLE_REQ_V2) {
2866				err = -EINVAL;
2867				goto out;
2868			}
2869
2870			if ((lc && (lc->req_state & SMB2_LEASE_HANDLE_CACHING_LE)) ||
2871			    req_op_level == SMB2_OPLOCK_LEVEL_BATCH) {
2872				ksmbd_debug(SMB, "Request for durable open\n");
2873				dh_info->type = dh_idx;
2874			}
2875		}
2876	}
2877
2878out:
2879	return err;
2880}
2881
2882/**
2883 * smb2_open() - handler for smb file open request
2884 * @work:	smb work containing request buffer
2885 *
2886 * Return:      0 on success, otherwise error
2887 */
2888int smb2_open(struct ksmbd_work *work)
2889{
2890	struct ksmbd_conn *conn = work->conn;
2891	struct ksmbd_session *sess = work->sess;
2892	struct ksmbd_tree_connect *tcon = work->tcon;
2893	struct smb2_create_req *req;
2894	struct smb2_create_rsp *rsp;
2895	struct path path;
2896	struct ksmbd_share_config *share = tcon->share_conf;
2897	struct ksmbd_file *fp = NULL;
2898	struct file *filp = NULL;
2899	struct mnt_idmap *idmap = NULL;
2900	struct kstat stat;
2901	struct create_context *context;
2902	struct lease_ctx_info *lc = NULL;
2903	struct create_ea_buf_req *ea_buf = NULL;
2904	struct oplock_info *opinfo;
2905	struct durable_info dh_info = {0};
2906	__le32 *next_ptr = NULL;
2907	int req_op_level = 0, open_flags = 0, may_flags = 0, file_info = 0;
2908	int rc = 0;
2909	int contxt_cnt = 0, query_disk_id = 0;
2910	bool maximal_access_ctxt = false, posix_ctxt = false;
2911	int s_type = 0;
2912	int next_off = 0;
2913	char *name = NULL;
2914	char *stream_name = NULL;
2915	bool file_present = false, created = false, already_permitted = false;
2916	int share_ret, need_truncate = 0;
2917	u64 time;
2918	umode_t posix_mode = 0;
2919	__le32 daccess, maximal_access = 0;
2920	int iov_len = 0;
2921
2922	ksmbd_debug(SMB, "Received smb2 create request\n");
2923
2924	WORK_BUFFERS(work, req, rsp);
2925
2926	if (req->hdr.NextCommand && !work->next_smb2_rcv_hdr_off &&
2927	    (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)) {
2928		ksmbd_debug(SMB, "invalid flag in chained command\n");
2929		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
2930		smb2_set_err_rsp(work);
2931		return -EINVAL;
2932	}
2933
2934	if (test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
2935		ksmbd_debug(SMB, "IPC pipe create request\n");
2936		return create_smb2_pipe(work);
2937	}
2938
2939	if (req->CreateContextsOffset && tcon->posix_extensions) {
2940		context = smb2_find_context_vals(req, SMB2_CREATE_TAG_POSIX, 16);
2941		if (IS_ERR(context)) {
2942			rc = PTR_ERR(context);
2943			goto err_out2;
2944		} else if (context) {
2945			struct create_posix *posix = (struct create_posix *)context;
2946
2947			if (le16_to_cpu(context->DataOffset) +
2948				le32_to_cpu(context->DataLength) <
2949			    sizeof(struct create_posix) - 4) {
2950				rc = -EINVAL;
2951				goto err_out2;
2952			}
2953			ksmbd_debug(SMB, "get posix context\n");
2954
2955			posix_mode = le32_to_cpu(posix->Mode);
2956			posix_ctxt = true;
2957		}
2958	}
2959
2960	if (req->NameLength) {
2961		name = smb2_get_name((char *)req + le16_to_cpu(req->NameOffset),
2962				     le16_to_cpu(req->NameLength),
2963				     work->conn->local_nls);
2964		if (IS_ERR(name)) {
2965			rc = PTR_ERR(name);
2966			name = NULL;
2967			goto err_out2;
2968		}
2969
2970		ksmbd_debug(SMB, "converted name = %s\n", name);
2971
2972		if (posix_ctxt == false) {
2973			if (strchr(name, ':')) {
2974				if (!test_share_config_flag(work->tcon->share_conf,
2975							KSMBD_SHARE_FLAG_STREAMS)) {
2976					rc = -EBADF;
2977					goto err_out2;
2978				}
2979				rc = parse_stream_name(name, &stream_name, &s_type);
2980				if (rc < 0)
2981					goto err_out2;
2982			}
2983
2984			rc = ksmbd_validate_filename(name);
2985			if (rc < 0)
2986				goto err_out2;
2987		}
2988
2989		if (ksmbd_share_veto_filename(share, name)) {
2990			rc = -ENOENT;
2991			ksmbd_debug(SMB, "Reject open(), vetoed file: %s\n",
2992				    name);
2993			goto err_out2;
2994		}
2995	} else {
2996		name = kstrdup("", KSMBD_DEFAULT_GFP);
2997		if (!name) {
2998			rc = -ENOMEM;
2999			goto err_out2;
3000		}
3001	}
3002
3003	req_op_level = req->RequestedOplockLevel;
3004
3005	if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE &&
3006	    req->CreateContextsOffset) {
3007		lc = parse_lease_state(req);
3008		rc = parse_durable_handle_context(work, req, lc, &dh_info);
3009		if (rc) {
3010			ksmbd_debug(SMB, "error parsing durable handle context\n");
3011			goto err_out2;
3012		}
3013
3014		if (dh_info.reconnected == true) {
3015			rc = smb2_check_durable_oplock(conn, share, dh_info.fp, lc, name);
3016			if (rc) {
3017				ksmbd_put_durable_fd(dh_info.fp);
3018				goto err_out2;
3019			}
3020
3021			rc = ksmbd_reopen_durable_fd(work, dh_info.fp);
3022			if (rc) {
3023				ksmbd_put_durable_fd(dh_info.fp);
3024				goto err_out2;
3025			}
3026
3027			fp = dh_info.fp;
3028
3029			if (ksmbd_override_fsids(work)) {
3030				rc = -ENOMEM;
3031				ksmbd_put_durable_fd(dh_info.fp);
3032				goto err_out2;
3033			}
3034
3035			file_info = FILE_OPENED;
3036
3037			rc = ksmbd_vfs_getattr(&fp->filp->f_path, &stat);
3038			ksmbd_put_durable_fd(fp);
3039			if (rc)
3040				goto err_out2;
3041
3042			goto reconnected_fp;
3043		}
3044	} else if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE)
3045		lc = parse_lease_state(req);
3046
3047	if (le32_to_cpu(req->ImpersonationLevel) > le32_to_cpu(IL_DELEGATE)) {
3048		pr_err("Invalid impersonationlevel : 0x%x\n",
3049		       le32_to_cpu(req->ImpersonationLevel));
3050		rc = -EIO;
3051		rsp->hdr.Status = STATUS_BAD_IMPERSONATION_LEVEL;
3052		goto err_out2;
3053	}
3054
3055	if (req->CreateOptions && !(req->CreateOptions & CREATE_OPTIONS_MASK_LE)) {
3056		pr_err("Invalid create options : 0x%x\n",
3057		       le32_to_cpu(req->CreateOptions));
3058		rc = -EINVAL;
3059		goto err_out2;
3060	} else {
3061		if (req->CreateOptions & FILE_SEQUENTIAL_ONLY_LE &&
3062		    req->CreateOptions & FILE_RANDOM_ACCESS_LE)
3063			req->CreateOptions = ~(FILE_SEQUENTIAL_ONLY_LE);
3064
3065		if (req->CreateOptions &
3066		    (FILE_OPEN_BY_FILE_ID_LE | CREATE_TREE_CONNECTION |
3067		     FILE_RESERVE_OPFILTER_LE)) {
3068			rc = -EOPNOTSUPP;
3069			goto err_out2;
3070		}
3071
3072		if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) {
3073			if (req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE) {
3074				rc = -EINVAL;
3075				goto err_out2;
3076			} else if (req->CreateOptions & FILE_NO_COMPRESSION_LE) {
3077				req->CreateOptions = ~(FILE_NO_COMPRESSION_LE);
3078			}
3079		}
3080	}
3081
3082	if (le32_to_cpu(req->CreateDisposition) >
3083	    le32_to_cpu(FILE_OVERWRITE_IF_LE)) {
3084		pr_err("Invalid create disposition : 0x%x\n",
3085		       le32_to_cpu(req->CreateDisposition));
3086		rc = -EINVAL;
3087		goto err_out2;
3088	}
3089
3090	if (!(req->DesiredAccess & DESIRED_ACCESS_MASK)) {
3091		pr_err("Invalid desired access : 0x%x\n",
3092		       le32_to_cpu(req->DesiredAccess));
3093		rc = -EACCES;
3094		goto err_out2;
3095	}
3096
3097	if (req->FileAttributes && !(req->FileAttributes & FILE_ATTRIBUTE_MASK_LE)) {
3098		pr_err("Invalid file attribute : 0x%x\n",
3099		       le32_to_cpu(req->FileAttributes));
3100		rc = -EINVAL;
3101		goto err_out2;
3102	}
3103
3104	if (req->CreateContextsOffset) {
3105		/* Parse non-durable handle create contexts */
3106		context = smb2_find_context_vals(req, SMB2_CREATE_EA_BUFFER, 4);
3107		if (IS_ERR(context)) {
3108			rc = PTR_ERR(context);
3109			goto err_out2;
3110		} else if (context) {
3111			ea_buf = (struct create_ea_buf_req *)context;
3112			if (le16_to_cpu(context->DataOffset) +
3113			    le32_to_cpu(context->DataLength) <
3114			    sizeof(struct create_ea_buf_req)) {
3115				rc = -EINVAL;
3116				goto err_out2;
3117			}
3118			if (req->CreateOptions & FILE_NO_EA_KNOWLEDGE_LE) {
3119				rsp->hdr.Status = STATUS_ACCESS_DENIED;
3120				rc = -EACCES;
3121				goto err_out2;
3122			}
3123		}
3124
3125		context = smb2_find_context_vals(req,
3126						 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST, 4);
3127		if (IS_ERR(context)) {
3128			rc = PTR_ERR(context);
3129			goto err_out2;
3130		} else if (context) {
3131			ksmbd_debug(SMB,
3132				    "get query maximal access context\n");
3133			maximal_access_ctxt = 1;
3134		}
3135
3136		context = smb2_find_context_vals(req,
3137						 SMB2_CREATE_TIMEWARP_REQUEST, 4);
3138		if (IS_ERR(context)) {
3139			rc = PTR_ERR(context);
3140			goto err_out2;
3141		} else if (context) {
3142			ksmbd_debug(SMB, "get timewarp context\n");
3143			rc = -EBADF;
3144			goto err_out2;
3145		}
3146	}
3147
3148	if (ksmbd_override_fsids(work)) {
3149		rc = -ENOMEM;
3150		goto err_out2;
3151	}
3152
3153	rc = ksmbd_vfs_kern_path(work, name, LOOKUP_NO_SYMLINKS,
3154				 &path, 1);
3155	if (!rc) {
3156		file_present = true;
3157
3158		if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) {
3159			/*
3160			 * If file exists with under flags, return access
3161			 * denied error.
3162			 */
3163			if (req->CreateDisposition == FILE_OVERWRITE_IF_LE ||
3164			    req->CreateDisposition == FILE_OPEN_IF_LE) {
3165				rc = -EACCES;
3166				goto err_out;
3167			}
3168
3169			if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
3170				ksmbd_debug(SMB,
3171					    "User does not have write permission\n");
3172				rc = -EACCES;
3173				goto err_out;
3174			}
3175		} else if (d_is_symlink(path.dentry)) {
3176			rc = -EACCES;
3177			goto err_out;
3178		}
3179
3180		idmap = mnt_idmap(path.mnt);
3181	} else {
3182		if (rc != -ENOENT)
3183			goto err_out;
3184		ksmbd_debug(SMB, "can not get linux path for %s, rc = %d\n",
3185			    name, rc);
3186		rc = 0;
3187	}
3188
3189	if (stream_name) {
3190		if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) {
3191			if (s_type == DATA_STREAM) {
3192				rc = -EIO;
3193				rsp->hdr.Status = STATUS_NOT_A_DIRECTORY;
3194			}
3195		} else {
3196			if (file_present && S_ISDIR(d_inode(path.dentry)->i_mode) &&
3197			    s_type == DATA_STREAM) {
3198				rc = -EIO;
3199				rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY;
3200			}
3201		}
3202
3203		if (req->CreateOptions & FILE_DIRECTORY_FILE_LE &&
3204		    req->FileAttributes & FILE_ATTRIBUTE_NORMAL_LE) {
3205			rsp->hdr.Status = STATUS_NOT_A_DIRECTORY;
3206			rc = -EIO;
3207		}
3208
3209		if (rc < 0)
3210			goto err_out;
3211	}
3212
3213	if (file_present && req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE &&
3214	    S_ISDIR(d_inode(path.dentry)->i_mode) &&
3215	    !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
3216		ksmbd_debug(SMB, "open() argument is a directory: %s, %x\n",
3217			    name, req->CreateOptions);
3218		rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY;
3219		rc = -EIO;
3220		goto err_out;
3221	}
3222
3223	if (file_present && (req->CreateOptions & FILE_DIRECTORY_FILE_LE) &&
3224	    !(req->CreateDisposition == FILE_CREATE_LE) &&
3225	    !S_ISDIR(d_inode(path.dentry)->i_mode)) {
3226		rsp->hdr.Status = STATUS_NOT_A_DIRECTORY;
3227		rc = -EIO;
3228		goto err_out;
3229	}
3230
3231	if (!stream_name && file_present &&
3232	    req->CreateDisposition == FILE_CREATE_LE) {
3233		rc = -EEXIST;
3234		goto err_out;
3235	}
3236
3237	daccess = smb_map_generic_desired_access(req->DesiredAccess);
3238
3239	if (file_present && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
3240		rc = smb_check_perm_dacl(conn, &path, &daccess,
3241					 sess->user->uid);
3242		if (rc)
3243			goto err_out;
3244	}
3245
3246	if (daccess & FILE_MAXIMAL_ACCESS_LE) {
3247		if (!file_present) {
3248			daccess = cpu_to_le32(GENERIC_ALL_FLAGS);
3249		} else {
3250			ksmbd_vfs_query_maximal_access(idmap,
3251							    path.dentry,
3252							    &daccess);
3253			already_permitted = true;
3254		}
3255		maximal_access = daccess;
3256	}
3257
3258	open_flags = smb2_create_open_flags(file_present, daccess,
3259					    req->CreateDisposition,
3260					    &may_flags,
3261					    req->CreateOptions,
3262					    file_present ? d_inode(path.dentry)->i_mode : 0);
3263
3264	if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
3265		if (open_flags & (O_CREAT | O_TRUNC)) {
3266			ksmbd_debug(SMB,
3267				    "User does not have write permission\n");
3268			rc = -EACCES;
3269			goto err_out;
3270		}
3271	}
3272
3273	/*create file if not present */
3274	if (!file_present) {
3275		rc = smb2_creat(work, &path, name, open_flags,
3276				posix_mode,
3277				req->CreateOptions & FILE_DIRECTORY_FILE_LE);
3278		if (rc) {
3279			if (rc == -ENOENT) {
3280				rc = -EIO;
3281				rsp->hdr.Status = STATUS_OBJECT_PATH_NOT_FOUND;
3282			}
3283			goto err_out;
3284		}
3285
3286		created = true;
3287		idmap = mnt_idmap(path.mnt);
3288		if (ea_buf) {
3289			if (le32_to_cpu(ea_buf->ccontext.DataLength) <
3290			    sizeof(struct smb2_ea_info)) {
3291				rc = -EINVAL;
3292				goto err_out;
3293			}
3294
3295			rc = smb2_set_ea(&ea_buf->ea,
3296					 le32_to_cpu(ea_buf->ccontext.DataLength),
3297					 &path, false);
3298			if (rc == -EOPNOTSUPP)
3299				rc = 0;
3300			else if (rc)
3301				goto err_out;
3302		}
3303	} else if (!already_permitted) {
3304		/* FILE_READ_ATTRIBUTE is allowed without inode_permission,
3305		 * because execute(search) permission on a parent directory,
3306		 * is already granted.
3307		 */
3308		if (daccess & ~(FILE_READ_ATTRIBUTES_LE | FILE_READ_CONTROL_LE)) {
3309			rc = inode_permission(idmap,
3310					      d_inode(path.dentry),
3311					      may_flags);
3312			if (rc)
3313				goto err_out;
3314
3315			if ((daccess & FILE_DELETE_LE) ||
3316			    (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
3317				rc = inode_permission(idmap,
3318						      d_inode(path.dentry->d_parent),
3319						      MAY_EXEC | MAY_WRITE);
3320				if (rc)
3321					goto err_out;
3322			}
3323		}
3324	}
3325
3326	rc = ksmbd_query_inode_status(path.dentry->d_parent);
3327	if (rc == KSMBD_INODE_STATUS_PENDING_DELETE) {
3328		rc = -EBUSY;
3329		goto err_out;
3330	}
3331
3332	rc = 0;
3333	filp = dentry_open(&path, open_flags, current_cred());
3334	if (IS_ERR(filp)) {
3335		rc = PTR_ERR(filp);
3336		pr_err("dentry open for dir failed, rc %d\n", rc);
3337		goto err_out;
3338	}
3339
3340	if (file_present) {
3341		if (!(open_flags & O_TRUNC))
3342			file_info = FILE_OPENED;
3343		else
3344			file_info = FILE_OVERWRITTEN;
3345
3346		if ((req->CreateDisposition & FILE_CREATE_MASK_LE) ==
3347		    FILE_SUPERSEDE_LE)
3348			file_info = FILE_SUPERSEDED;
3349	} else if (open_flags & O_CREAT) {
3350		file_info = FILE_CREATED;
3351	}
3352
3353	ksmbd_vfs_set_fadvise(filp, req->CreateOptions);
3354
3355	/* Obtain Volatile-ID */
3356	fp = ksmbd_open_fd(work, filp);
3357	if (IS_ERR(fp)) {
3358		fput(filp);
3359		rc = PTR_ERR(fp);
3360		fp = NULL;
3361		goto err_out;
3362	}
3363
3364	/* Get Persistent-ID */
3365	ksmbd_open_durable_fd(fp);
3366	if (!has_file_id(fp->persistent_id)) {
3367		rc = -ENOMEM;
3368		goto err_out;
3369	}
3370
3371	fp->cdoption = req->CreateDisposition;
3372	fp->daccess = daccess;
3373	fp->saccess = req->ShareAccess;
3374	fp->coption = req->CreateOptions;
3375
3376	/* Set default windows and posix acls if creating new file */
3377	if (created) {
3378		int posix_acl_rc;
3379		struct inode *inode = d_inode(path.dentry);
3380
3381		posix_acl_rc = ksmbd_vfs_inherit_posix_acl(idmap,
3382							   &path,
3383							   d_inode(path.dentry->d_parent));
3384		if (posix_acl_rc)
3385			ksmbd_debug(SMB, "inherit posix acl failed : %d\n", posix_acl_rc);
3386
3387		if (test_share_config_flag(work->tcon->share_conf,
3388					   KSMBD_SHARE_FLAG_ACL_XATTR)) {
3389			rc = smb_inherit_dacl(conn, &path, sess->user->uid,
3390					      sess->user->gid);
3391		}
3392
3393		if (rc) {
3394			rc = smb2_create_sd_buffer(work, req, &path);
3395			if (rc) {
3396				if (posix_acl_rc)
3397					ksmbd_vfs_set_init_posix_acl(idmap,
3398								     &path);
3399
3400				if (test_share_config_flag(work->tcon->share_conf,
3401							   KSMBD_SHARE_FLAG_ACL_XATTR)) {
3402					struct smb_fattr fattr;
3403					struct smb_ntsd *pntsd;
3404					int pntsd_size;
3405					size_t scratch_len;
3406
3407					ksmbd_acls_fattr(&fattr, idmap, inode);
3408					scratch_len = smb_acl_sec_desc_scratch_len(&fattr,
3409							NULL, 0,
3410							OWNER_SECINFO | GROUP_SECINFO |
3411							DACL_SECINFO);
3412					if (!scratch_len || scratch_len == SIZE_MAX) {
3413						rc = -EFBIG;
3414						posix_acl_release(fattr.cf_acls);
3415						posix_acl_release(fattr.cf_dacls);
3416						goto err_out;
3417					}
3418
3419					pntsd = kvzalloc(scratch_len, KSMBD_DEFAULT_GFP);
3420					if (!pntsd) {
3421						rc = -ENOMEM;
3422						posix_acl_release(fattr.cf_acls);
3423						posix_acl_release(fattr.cf_dacls);
3424						goto err_out;
3425					}
3426
3427					rc = build_sec_desc(idmap,
3428							    pntsd, NULL, 0,
3429							    OWNER_SECINFO |
3430							    GROUP_SECINFO |
3431							    DACL_SECINFO,
3432							    &pntsd_size, &fattr);
3433					posix_acl_release(fattr.cf_acls);
3434					posix_acl_release(fattr.cf_dacls);
3435					if (rc) {
3436						kvfree(pntsd);
3437						goto err_out;
3438					}
3439
3440					rc = ksmbd_vfs_set_sd_xattr(conn,
3441								    idmap,
3442								    &path,
3443								    pntsd,
3444								    pntsd_size,
3445								    false);
3446					kvfree(pntsd);
3447					if (rc)
3448						pr_err("failed to store ntacl in xattr : %d\n",
3449						       rc);
3450				}
3451			}
3452		}
3453		rc = 0;
3454	}
3455
3456	if (stream_name) {
3457		rc = smb2_set_stream_name_xattr(&path,
3458						fp,
3459						stream_name,
3460						s_type);
3461		if (rc)
3462			goto err_out;
3463		file_info = FILE_CREATED;
3464	}
3465
3466	fp->attrib_only = !(req->DesiredAccess & ~(FILE_READ_ATTRIBUTES_LE |
3467			FILE_WRITE_ATTRIBUTES_LE | FILE_SYNCHRONIZE_LE));
3468
3469	fp->is_posix_ctxt = posix_ctxt;
3470
3471	/* fp should be searchable through ksmbd_inode.m_fp_list
3472	 * after daccess, saccess, attrib_only, and stream are
3473	 * initialized.
3474	 */
3475	down_write(&fp->f_ci->m_lock);
3476	list_add(&fp->node, &fp->f_ci->m_fp_list);
3477	up_write(&fp->f_ci->m_lock);
3478
3479	/* Check delete pending among previous fp before oplock break */
3480	if (ksmbd_inode_pending_delete(fp)) {
3481		rc = -EBUSY;
3482		goto err_out;
3483	}
3484
3485	if (file_present || created)
3486		path_put(&path);
3487
3488	if (!S_ISDIR(file_inode(filp)->i_mode) && open_flags & O_TRUNC &&
3489	    !fp->attrib_only && !stream_name) {
3490		smb_break_all_oplock(work, fp);
3491		need_truncate = 1;
3492	}
3493
3494	share_ret = ksmbd_smb_check_shared_mode(fp->filp, fp);
3495	if (!test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_OPLOCKS) ||
3496	    (req_op_level == SMB2_OPLOCK_LEVEL_LEASE &&
3497	     !(conn->vals->req_capabilities & SMB2_GLOBAL_CAP_LEASING))) {
3498		if (share_ret < 0 && !S_ISDIR(file_inode(fp->filp)->i_mode)) {
3499			rc = share_ret;
3500			goto err_out1;
3501		}
3502	} else {
3503		if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE && lc) {
3504			if (S_ISDIR(file_inode(filp)->i_mode)) {
3505				lc->req_state &= ~SMB2_LEASE_WRITE_CACHING_LE;
3506				lc->is_dir = true;
3507			}
3508
3509			/*
3510			 * Compare parent lease using parent key. If there is no
3511			 * a lease that has same parent key, Send lease break
3512			 * notification.
3513			 */
3514			smb_send_parent_lease_break_noti(fp, lc);
3515
3516			req_op_level = smb2_map_lease_to_oplock(lc->req_state);
3517			ksmbd_debug(SMB,
3518				    "lease req for(%s) req oplock state 0x%x, lease state 0x%x\n",
3519				    name, req_op_level, lc->req_state);
3520			rc = find_same_lease_key(sess, fp->f_ci, lc);
3521			if (rc)
3522				goto err_out1;
3523		} else if (open_flags == O_RDONLY &&
3524			   (req_op_level == SMB2_OPLOCK_LEVEL_BATCH ||
3525			    req_op_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE))
3526			req_op_level = SMB2_OPLOCK_LEVEL_II;
3527
3528		rc = smb_grant_oplock(work, req_op_level,
3529				      fp->persistent_id, fp,
3530				      le32_to_cpu(req->hdr.Id.SyncId.TreeId),
3531				      lc, share_ret);
3532		if (rc < 0)
3533			goto err_out1;
3534	}
3535
3536	if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)
3537		ksmbd_fd_set_delete_on_close(fp, file_info);
3538
3539	if (need_truncate) {
3540		rc = smb2_create_truncate(&fp->filp->f_path);
3541		if (rc)
3542			goto err_out1;
3543	}
3544
3545	if (req->CreateContextsOffset) {
3546		struct create_alloc_size_req *az_req;
3547
3548		az_req = (struct create_alloc_size_req *)smb2_find_context_vals(req,
3549					SMB2_CREATE_ALLOCATION_SIZE, 4);
3550		if (IS_ERR(az_req)) {
3551			rc = PTR_ERR(az_req);
3552			goto err_out1;
3553		} else if (az_req) {
3554			loff_t alloc_size;
3555			int err;
3556
3557			if (le16_to_cpu(az_req->ccontext.DataOffset) +
3558			    le32_to_cpu(az_req->ccontext.DataLength) <
3559			    sizeof(struct create_alloc_size_req)) {
3560				rc = -EINVAL;
3561				goto err_out1;
3562			}
3563			alloc_size = le64_to_cpu(az_req->AllocationSize);
3564			ksmbd_debug(SMB,
3565				    "request smb2 create allocate size : %llu\n",
3566				    alloc_size);
3567			smb_break_all_levII_oplock(work, fp, 1);
3568			err = vfs_fallocate(fp->filp, FALLOC_FL_KEEP_SIZE, 0,
3569					    alloc_size);
3570			if (err < 0)
3571				ksmbd_debug(SMB,
3572					    "vfs_fallocate is failed : %d\n",
3573					    err);
3574		}
3575
3576		context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID, 4);
3577		if (IS_ERR(context)) {
3578			rc = PTR_ERR(context);
3579			goto err_out1;
3580		} else if (context) {
3581			ksmbd_debug(SMB, "get query on disk id context\n");
3582			query_disk_id = 1;
3583		}
3584
3585		if (conn->is_aapl == false) {
3586			context = smb2_find_context_vals(req, SMB2_CREATE_AAPL, 4);
3587			if (IS_ERR(context)) {
3588				rc = PTR_ERR(context);
3589				goto err_out1;
3590			} else if (context)
3591				conn->is_aapl = true;
3592		}
3593	}
3594
3595	rc = ksmbd_vfs_getattr(&path, &stat);
3596	if (rc)
3597		goto err_out1;
3598
3599	if (stat.result_mask & STATX_BTIME)
3600		fp->create_time = ksmbd_UnixTimeToNT(stat.btime);
3601	else
3602		fp->create_time = ksmbd_UnixTimeToNT(stat.ctime);
3603	if (req->FileAttributes || fp->f_ci->m_fattr == 0)
3604		fp->f_ci->m_fattr =
3605			cpu_to_le32(smb2_get_dos_mode(&stat, le32_to_cpu(req->FileAttributes)));
3606
3607	if (!created)
3608		smb2_update_xattrs(tcon, &path, fp);
3609	else
3610		smb2_new_xattrs(tcon, &path, fp);
3611
3612	memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
3613
3614	if (dh_info.type == DURABLE_REQ_V2 || dh_info.type == DURABLE_REQ) {
3615		if (dh_info.type == DURABLE_REQ_V2 && dh_info.persistent &&
3616		    test_share_config_flag(work->tcon->share_conf,
3617					   KSMBD_SHARE_FLAG_CONTINUOUS_AVAILABILITY))
3618			fp->is_persistent = true;
3619		else
3620			fp->is_durable = true;
3621
3622		if (dh_info.type == DURABLE_REQ_V2) {
3623			memcpy(fp->create_guid, dh_info.CreateGuid,
3624					SMB2_CREATE_GUID_SIZE);
3625			if (dh_info.timeout)
3626				fp->durable_timeout =
3627					min_t(unsigned int, dh_info.timeout,
3628					      DURABLE_HANDLE_MAX_TIMEOUT);
3629			else
3630				fp->durable_timeout = 60;
3631		}
3632	}
3633
3634reconnected_fp:
3635	rsp->StructureSize = cpu_to_le16(89);
3636	opinfo = opinfo_get(fp);
3637	rsp->OplockLevel = opinfo != NULL ? opinfo->level : 0;
3638	rsp->Flags = 0;
3639	rsp->CreateAction = cpu_to_le32(file_info);
3640	rsp->CreationTime = cpu_to_le64(fp->create_time);
3641	time = ksmbd_UnixTimeToNT(stat.atime);
3642	rsp->LastAccessTime = cpu_to_le64(time);
3643	time = ksmbd_UnixTimeToNT(stat.mtime);
3644	rsp->LastWriteTime = cpu_to_le64(time);
3645	time = ksmbd_UnixTimeToNT(stat.ctime);
3646	rsp->ChangeTime = cpu_to_le64(time);
3647	rsp->AllocationSize = S_ISDIR(stat.mode) ? 0 :
3648		cpu_to_le64(stat.blocks << 9);
3649	rsp->EndofFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
3650	rsp->FileAttributes = fp->f_ci->m_fattr;
3651
3652	rsp->Reserved2 = 0;
3653
3654	rsp->PersistentFileId = fp->persistent_id;
3655	rsp->VolatileFileId = fp->volatile_id;
3656
3657	rsp->CreateContextsOffset = 0;
3658	rsp->CreateContextsLength = 0;
3659	iov_len = offsetof(struct smb2_create_rsp, Buffer);
3660
3661	/* If lease is request send lease context response */
3662	if (opinfo && opinfo->is_lease) {
3663		struct create_context *lease_ccontext;
3664
3665		ksmbd_debug(SMB, "lease granted on(%s) lease state 0x%x\n",
3666			    name, opinfo->o_lease->state);
3667		rsp->OplockLevel = SMB2_OPLOCK_LEVEL_LEASE;
3668
3669		lease_ccontext = (struct create_context *)rsp->Buffer;
3670		contxt_cnt++;
3671		create_lease_buf(rsp->Buffer, opinfo->o_lease);
3672		le32_add_cpu(&rsp->CreateContextsLength,
3673			     conn->vals->create_lease_size);
3674		iov_len += conn->vals->create_lease_size;
3675		next_ptr = &lease_ccontext->Next;
3676		next_off = conn->vals->create_lease_size;
3677	}
3678	opinfo_put(opinfo);
3679
3680	if (maximal_access_ctxt) {
3681		struct create_context *mxac_ccontext;
3682
3683		if (maximal_access == 0)
3684			ksmbd_vfs_query_maximal_access(idmap,
3685						       path.dentry,
3686						       &maximal_access);
3687		mxac_ccontext = (struct create_context *)(rsp->Buffer +
3688				le32_to_cpu(rsp->CreateContextsLength));
3689		contxt_cnt++;
3690		create_mxac_rsp_buf(rsp->Buffer +
3691				le32_to_cpu(rsp->CreateContextsLength),
3692				le32_to_cpu(maximal_access));
3693		le32_add_cpu(&rsp->CreateContextsLength,
3694			     conn->vals->create_mxac_size);
3695		iov_len += conn->vals->create_mxac_size;
3696		if (next_ptr)
3697			*next_ptr = cpu_to_le32(next_off);
3698		next_ptr = &mxac_ccontext->Next;
3699		next_off = conn->vals->create_mxac_size;
3700	}
3701
3702	if (query_disk_id) {
3703		struct create_context *disk_id_ccontext;
3704
3705		disk_id_ccontext = (struct create_context *)(rsp->Buffer +
3706				le32_to_cpu(rsp->CreateContextsLength));
3707		contxt_cnt++;
3708		create_disk_id_rsp_buf(rsp->Buffer +
3709				le32_to_cpu(rsp->CreateContextsLength),
3710				stat.ino, tcon->id);
3711		le32_add_cpu(&rsp->CreateContextsLength,
3712			     conn->vals->create_disk_id_size);
3713		iov_len += conn->vals->create_disk_id_size;
3714		if (next_ptr)
3715			*next_ptr = cpu_to_le32(next_off);
3716		next_ptr = &disk_id_ccontext->Next;
3717		next_off = conn->vals->create_disk_id_size;
3718	}
3719
3720	if (dh_info.type == DURABLE_REQ || dh_info.type == DURABLE_REQ_V2) {
3721		struct create_context *durable_ccontext;
3722
3723		durable_ccontext = (struct create_context *)(rsp->Buffer +
3724				le32_to_cpu(rsp->CreateContextsLength));
3725		contxt_cnt++;
3726		if (dh_info.type == DURABLE_REQ) {
3727			create_durable_rsp_buf(rsp->Buffer +
3728					le32_to_cpu(rsp->CreateContextsLength));
3729			le32_add_cpu(&rsp->CreateContextsLength,
3730					conn->vals->create_durable_size);
3731			iov_len += conn->vals->create_durable_size;
3732		} else {
3733			create_durable_v2_rsp_buf(rsp->Buffer +
3734					le32_to_cpu(rsp->CreateContextsLength),
3735					fp);
3736			le32_add_cpu(&rsp->CreateContextsLength,
3737					conn->vals->create_durable_v2_size);
3738			iov_len += conn->vals->create_durable_v2_size;
3739		}
3740
3741		if (next_ptr)
3742			*next_ptr = cpu_to_le32(next_off);
3743		next_ptr = &durable_ccontext->Next;
3744		next_off = conn->vals->create_durable_size;
3745	}
3746
3747	if (posix_ctxt) {
3748		contxt_cnt++;
3749		create_posix_rsp_buf(rsp->Buffer +
3750				le32_to_cpu(rsp->CreateContextsLength),
3751				fp);
3752		le32_add_cpu(&rsp->CreateContextsLength,
3753			     conn->vals->create_posix_size);
3754		iov_len += conn->vals->create_posix_size;
3755		if (next_ptr)
3756			*next_ptr = cpu_to_le32(next_off);
3757	}
3758
3759	if (contxt_cnt > 0) {
3760		rsp->CreateContextsOffset =
3761			cpu_to_le32(offsetof(struct smb2_create_rsp, Buffer));
3762	}
3763
3764err_out:
3765	if (rc && (file_present || created))
3766		path_put(&path);
3767
3768err_out1:
3769	ksmbd_revert_fsids(work);
3770
3771err_out2:
3772	if (!rc) {
3773		ksmbd_update_fstate(&work->sess->file_table, fp, FP_INITED);
3774		rc = ksmbd_iov_pin_rsp(work, (void *)rsp, iov_len);
3775	}
3776	if (rc) {
3777		if (rc == -EINVAL)
3778			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
3779		else if (rc == -EOPNOTSUPP)
3780			rsp->hdr.Status = STATUS_NOT_SUPPORTED;
3781		else if (rc == -EACCES || rc == -ESTALE || rc == -EXDEV)
3782			rsp->hdr.Status = STATUS_ACCESS_DENIED;
3783		else if (rc == -ENOENT)
3784			rsp->hdr.Status = STATUS_OBJECT_NAME_INVALID;
3785		else if (rc == -EPERM)
3786			rsp->hdr.Status = STATUS_SHARING_VIOLATION;
3787		else if (rc == -EBUSY)
3788			rsp->hdr.Status = STATUS_DELETE_PENDING;
3789		else if (rc == -EBADF)
3790			rsp->hdr.Status = STATUS_OBJECT_NAME_NOT_FOUND;
3791		else if (rc == -ENOEXEC)
3792			rsp->hdr.Status = STATUS_DUPLICATE_OBJECTID;
3793		else if (rc == -ENXIO)
3794			rsp->hdr.Status = STATUS_NO_SUCH_DEVICE;
3795		else if (rc == -EEXIST)
3796			rsp->hdr.Status = STATUS_OBJECT_NAME_COLLISION;
3797		else if (rc == -EMFILE)
3798			rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
3799		if (!rsp->hdr.Status)
3800			rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
3801
3802		if (fp)
3803			ksmbd_fd_put(work, fp);
3804		smb2_set_err_rsp(work);
3805		ksmbd_debug(SMB, "Error response: %x\n", rsp->hdr.Status);
3806	}
3807
3808	kfree(name);
3809	kfree(lc);
3810
3811	return rc;
3812}
3813
3814static int readdir_info_level_struct_sz(int info_level)
3815{
3816	switch (info_level) {
3817	case FILE_FULL_DIRECTORY_INFORMATION:
3818		return sizeof(FILE_FULL_DIRECTORY_INFO);
3819	case FILE_BOTH_DIRECTORY_INFORMATION:
3820		return sizeof(FILE_BOTH_DIRECTORY_INFO);
3821	case FILE_DIRECTORY_INFORMATION:
3822		return sizeof(FILE_DIRECTORY_INFO);
3823	case FILE_NAMES_INFORMATION:
3824		return sizeof(struct file_names_info);
3825	case FILEID_FULL_DIRECTORY_INFORMATION:
3826		return sizeof(FILE_ID_FULL_DIR_INFO);
3827	case FILEID_BOTH_DIRECTORY_INFORMATION:
3828		return sizeof(struct file_id_both_directory_info);
3829	case SMB_FIND_FILE_POSIX_INFO:
3830		return sizeof(struct smb2_posix_info);
3831	default:
3832		return -EOPNOTSUPP;
3833	}
3834}
3835
3836static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
3837{
3838	switch (info_level) {
3839	case FILE_FULL_DIRECTORY_INFORMATION:
3840	{
3841		FILE_FULL_DIRECTORY_INFO *ffdinfo;
3842
3843		ffdinfo = (FILE_FULL_DIRECTORY_INFO *)d_info->rptr;
3844		d_info->rptr += le32_to_cpu(ffdinfo->NextEntryOffset);
3845		d_info->name = ffdinfo->FileName;
3846		d_info->name_len = le32_to_cpu(ffdinfo->FileNameLength);
3847		return 0;
3848	}
3849	case FILE_BOTH_DIRECTORY_INFORMATION:
3850	{
3851		FILE_BOTH_DIRECTORY_INFO *fbdinfo;
3852
3853		fbdinfo = (FILE_BOTH_DIRECTORY_INFO *)d_info->rptr;
3854		d_info->rptr += le32_to_cpu(fbdinfo->NextEntryOffset);
3855		d_info->name = fbdinfo->FileName;
3856		d_info->name_len = le32_to_cpu(fbdinfo->FileNameLength);
3857		return 0;
3858	}
3859	case FILE_DIRECTORY_INFORMATION:
3860	{
3861		FILE_DIRECTORY_INFO *fdinfo;
3862
3863		fdinfo = (FILE_DIRECTORY_INFO *)d_info->rptr;
3864		d_info->rptr += le32_to_cpu(fdinfo->NextEntryOffset);
3865		d_info->name = fdinfo->FileName;
3866		d_info->name_len = le32_to_cpu(fdinfo->FileNameLength);
3867		return 0;
3868	}
3869	case FILE_NAMES_INFORMATION:
3870	{
3871		struct file_names_info *fninfo;
3872
3873		fninfo = (struct file_names_info *)d_info->rptr;
3874		d_info->rptr += le32_to_cpu(fninfo->NextEntryOffset);
3875		d_info->name = fninfo->FileName;
3876		d_info->name_len = le32_to_cpu(fninfo->FileNameLength);
3877		return 0;
3878	}
3879	case FILEID_FULL_DIRECTORY_INFORMATION:
3880	{
3881		FILE_ID_FULL_DIR_INFO *dinfo;
3882
3883		dinfo = (FILE_ID_FULL_DIR_INFO *)d_info->rptr;
3884		d_info->rptr += le32_to_cpu(dinfo->NextEntryOffset);
3885		d_info->name = dinfo->FileName;
3886		d_info->name_len = le32_to_cpu(dinfo->FileNameLength);
3887		return 0;
3888	}
3889	case FILEID_BOTH_DIRECTORY_INFORMATION:
3890	{
3891		struct file_id_both_directory_info *fibdinfo;
3892
3893		fibdinfo = (struct file_id_both_directory_info *)d_info->rptr;
3894		d_info->rptr += le32_to_cpu(fibdinfo->NextEntryOffset);
3895		d_info->name = fibdinfo->FileName;
3896		d_info->name_len = le32_to_cpu(fibdinfo->FileNameLength);
3897		return 0;
3898	}
3899	case SMB_FIND_FILE_POSIX_INFO:
3900	{
3901		struct smb2_posix_info *posix_info;
3902
3903		posix_info = (struct smb2_posix_info *)d_info->rptr;
3904		d_info->rptr += le32_to_cpu(posix_info->NextEntryOffset);
3905		d_info->name = posix_info->name;
3906		d_info->name_len = le32_to_cpu(posix_info->name_len);
3907		return 0;
3908	}
3909	default:
3910		return -EINVAL;
3911	}
3912}
3913
3914/**
3915 * smb2_populate_readdir_entry() - encode directory entry in smb2 response
3916 * buffer
3917 * @conn:	connection instance
3918 * @info_level:	smb information level
3919 * @d_info:	structure included variables for query dir
3920 * @ksmbd_kstat:	ksmbd wrapper of dirent stat information
3921 *
3922 * if directory has many entries, find first can't read it fully.
3923 * find next might be called multiple times to read remaining dir entries
3924 *
3925 * Return:	0 on success, otherwise error
3926 */
3927static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
3928				       struct ksmbd_dir_info *d_info,
3929				       struct ksmbd_kstat *ksmbd_kstat)
3930{
3931	int next_entry_offset = 0;
3932	char *conv_name;
3933	int conv_len;
3934	void *kstat;
3935	int struct_sz, rc = 0;
3936
3937	conv_name = ksmbd_convert_dir_info_name(d_info,
3938						conn->local_nls,
3939						&conv_len);
3940	if (!conv_name)
3941		return -ENOMEM;
3942
3943	/* Somehow the name has only terminating NULL bytes */
3944	if (conv_len < 0) {
3945		rc = -EINVAL;
3946		goto free_conv_name;
3947	}
3948
3949	struct_sz = readdir_info_level_struct_sz(info_level) + conv_len;
3950	next_entry_offset = ALIGN(struct_sz, KSMBD_DIR_INFO_ALIGNMENT);
3951	d_info->last_entry_off_align = next_entry_offset - struct_sz;
3952
3953	if (next_entry_offset > d_info->out_buf_len) {
3954		d_info->out_buf_len = 0;
3955		rc = -ENOSPC;
3956		goto free_conv_name;
3957	}
3958
3959	kstat = d_info->wptr;
3960	if (info_level != FILE_NAMES_INFORMATION)
3961		kstat = ksmbd_vfs_init_kstat(&d_info->wptr, ksmbd_kstat);
3962
3963	switch (info_level) {
3964	case FILE_FULL_DIRECTORY_INFORMATION:
3965	{
3966		FILE_FULL_DIRECTORY_INFO *ffdinfo;
3967
3968		ffdinfo = (FILE_FULL_DIRECTORY_INFO *)kstat;
3969		ffdinfo->FileNameLength = cpu_to_le32(conv_len);
3970		ffdinfo->EaSize =
3971			smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
3972		if (ffdinfo->EaSize)
3973			ffdinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE;
3974		if (d_info->hide_dot_file && d_info->name[0] == '.')
3975			ffdinfo->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
3976		memcpy(ffdinfo->FileName, conv_name, conv_len);
3977		ffdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3978		break;
3979	}
3980	case FILE_BOTH_DIRECTORY_INFORMATION:
3981	{
3982		FILE_BOTH_DIRECTORY_INFO *fbdinfo;
3983
3984		fbdinfo = (FILE_BOTH_DIRECTORY_INFO *)kstat;
3985		fbdinfo->FileNameLength = cpu_to_le32(conv_len);
3986		fbdinfo->EaSize =
3987			smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
3988		if (fbdinfo->EaSize)
3989			fbdinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE;
3990		fbdinfo->ShortNameLength = 0;
3991		fbdinfo->Reserved = 0;
3992		if (d_info->hide_dot_file && d_info->name[0] == '.')
3993			fbdinfo->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
3994		memcpy(fbdinfo->FileName, conv_name, conv_len);
3995		fbdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
3996		break;
3997	}
3998	case FILE_DIRECTORY_INFORMATION:
3999	{
4000		FILE_DIRECTORY_INFO *fdinfo;
4001
4002		fdinfo = (FILE_DIRECTORY_INFO *)kstat;
4003		fdinfo->FileNameLength = cpu_to_le32(conv_len);
4004		if (d_info->hide_dot_file && d_info->name[0] == '.')
4005			fdinfo->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
4006		memcpy(fdinfo->FileName, conv_name, conv_len);
4007		fdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
4008		break;
4009	}
4010	case FILE_NAMES_INFORMATION:
4011	{
4012		struct file_names_info *fninfo;
4013
4014		fninfo = (struct file_names_info *)kstat;
4015		fninfo->FileNameLength = cpu_to_le32(conv_len);
4016		memcpy(fninfo->FileName, conv_name, conv_len);
4017		fninfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
4018		break;
4019	}
4020	case FILEID_FULL_DIRECTORY_INFORMATION:
4021	{
4022		FILE_ID_FULL_DIR_INFO *dinfo;
4023
4024		dinfo = (FILE_ID_FULL_DIR_INFO *)kstat;
4025		dinfo->FileNameLength = cpu_to_le32(conv_len);
4026		dinfo->EaSize =
4027			smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
4028		if (dinfo->EaSize)
4029			dinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE;
4030		dinfo->Reserved = 0;
4031		if (conn->is_aapl)
4032			dinfo->UniqueId = 0;
4033		else
4034			dinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
4035		if (d_info->hide_dot_file && d_info->name[0] == '.')
4036			dinfo->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
4037		memcpy(dinfo->FileName, conv_name, conv_len);
4038		dinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
4039		break;
4040	}
4041	case FILEID_BOTH_DIRECTORY_INFORMATION:
4042	{
4043		struct file_id_both_directory_info *fibdinfo;
4044
4045		fibdinfo = (struct file_id_both_directory_info *)kstat;
4046		fibdinfo->FileNameLength = cpu_to_le32(conv_len);
4047		fibdinfo->EaSize =
4048			smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
4049		if (fibdinfo->EaSize)
4050			fibdinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE;
4051		if (conn->is_aapl)
4052			fibdinfo->UniqueId = 0;
4053		else
4054			fibdinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
4055		fibdinfo->ShortNameLength = 0;
4056		fibdinfo->Reserved = 0;
4057		fibdinfo->Reserved2 = cpu_to_le16(0);
4058		if (d_info->hide_dot_file && d_info->name[0] == '.')
4059			fibdinfo->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
4060		memcpy(fibdinfo->FileName, conv_name, conv_len);
4061		fibdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
4062		break;
4063	}
4064	case SMB_FIND_FILE_POSIX_INFO:
4065	{
4066		struct smb2_posix_info *posix_info;
4067		u64 time;
4068
4069		posix_info = (struct smb2_posix_info *)kstat;
4070		posix_info->Ignored = 0;
4071		posix_info->CreationTime = cpu_to_le64(ksmbd_kstat->create_time);
4072		time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->ctime);
4073		posix_info->ChangeTime = cpu_to_le64(time);
4074		time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->atime);
4075		posix_info->LastAccessTime = cpu_to_le64(time);
4076		time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->mtime);
4077		posix_info->LastWriteTime = cpu_to_le64(time);
4078		posix_info->EndOfFile = cpu_to_le64(ksmbd_kstat->kstat->size);
4079		posix_info->AllocationSize = cpu_to_le64(ksmbd_kstat->kstat->blocks << 9);
4080		posix_info->DeviceId = cpu_to_le32(ksmbd_kstat->kstat->rdev);
4081		posix_info->HardLinks = cpu_to_le32(ksmbd_kstat->kstat->nlink);
4082		posix_info->Mode = cpu_to_le32(ksmbd_kstat->kstat->mode & 0777);
4083		switch (ksmbd_kstat->kstat->mode & S_IFMT) {
4084		case S_IFDIR:
4085			posix_info->Mode |= cpu_to_le32(POSIX_TYPE_DIR << POSIX_FILETYPE_SHIFT);
4086			break;
4087		case S_IFLNK:
4088			posix_info->Mode |= cpu_to_le32(POSIX_TYPE_SYMLINK << POSIX_FILETYPE_SHIFT);
4089			break;
4090		case S_IFCHR:
4091			posix_info->Mode |= cpu_to_le32(POSIX_TYPE_CHARDEV << POSIX_FILETYPE_SHIFT);
4092			break;
4093		case S_IFBLK:
4094			posix_info->Mode |= cpu_to_le32(POSIX_TYPE_BLKDEV << POSIX_FILETYPE_SHIFT);
4095			break;
4096		case S_IFIFO:
4097			posix_info->Mode |= cpu_to_le32(POSIX_TYPE_FIFO << POSIX_FILETYPE_SHIFT);
4098			break;
4099		case S_IFSOCK:
4100			posix_info->Mode |= cpu_to_le32(POSIX_TYPE_SOCKET << POSIX_FILETYPE_SHIFT);
4101		}
4102
4103		posix_info->Inode = cpu_to_le64(ksmbd_kstat->kstat->ino);
4104		posix_info->DosAttributes =
4105			S_ISDIR(ksmbd_kstat->kstat->mode) ?
4106				FILE_ATTRIBUTE_DIRECTORY_LE : FILE_ATTRIBUTE_ARCHIVE_LE;
4107		if (d_info->hide_dot_file && d_info->name[0] == '.')
4108			posix_info->DosAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
4109		/*
4110		 * SidBuffer(32) contain two sids(Domain sid(16), UNIX group sid(16)).
4111		 * UNIX sid(16) = revision(1) + num_subauth(1) + authority(6) +
4112		 *		  sub_auth(4 * 1(num_subauth)) + RID(4).
4113		 */
4114		id_to_sid(from_kuid_munged(&init_user_ns, ksmbd_kstat->kstat->uid),
4115			  SIDUNIX_USER, (struct smb_sid *)&posix_info->SidBuffer[0]);
4116		id_to_sid(from_kgid_munged(&init_user_ns, ksmbd_kstat->kstat->gid),
4117			  SIDUNIX_GROUP, (struct smb_sid *)&posix_info->SidBuffer[16]);
4118		memcpy(posix_info->name, conv_name, conv_len);
4119		posix_info->name_len = cpu_to_le32(conv_len);
4120		posix_info->NextEntryOffset = cpu_to_le32(next_entry_offset);
4121		break;
4122	}
4123
4124	} /* switch (info_level) */
4125
4126	d_info->last_entry_offset = d_info->data_count;
4127	d_info->data_count += next_entry_offset;
4128	d_info->out_buf_len -= next_entry_offset;
4129	d_info->wptr += next_entry_offset;
4130
4131	ksmbd_debug(SMB,
4132		    "info_level : %d, buf_len :%d, next_offset : %d, data_count : %d\n",
4133		    info_level, d_info->out_buf_len,
4134		    next_entry_offset, d_info->data_count);
4135
4136free_conv_name:
4137	kfree(conv_name);
4138	return rc;
4139}
4140
4141struct smb2_query_dir_private {
4142	struct ksmbd_work	*work;
4143	char			*search_pattern;
4144	struct ksmbd_file	*dir_fp;
4145
4146	struct ksmbd_dir_info	*d_info;
4147	int			info_level;
4148};
4149
4150static int process_query_dir_entries(struct smb2_query_dir_private *priv)
4151{
4152	struct mnt_idmap	*idmap = file_mnt_idmap(priv->dir_fp->filp);
4153	struct kstat		kstat;
4154	struct ksmbd_kstat	ksmbd_kstat;
4155	int			rc;
4156	int			i;
4157
4158	for (i = 0; i < priv->d_info->num_entry; i++) {
4159		struct dentry *dent;
4160
4161		if (dentry_name(priv->d_info, priv->info_level))
4162			return -EINVAL;
4163
4164		dent = lookup_one_unlocked(idmap,
4165					   &QSTR_LEN(priv->d_info->name,
4166						     priv->d_info->name_len),
4167					   priv->dir_fp->filp->f_path.dentry);
4168
4169		if (IS_ERR(dent)) {
4170			ksmbd_debug(SMB, "Cannot lookup `%s' [%ld]\n",
4171				    priv->d_info->name,
4172				    PTR_ERR(dent));
4173			continue;
4174		}
4175		if (unlikely(d_is_negative(dent))) {
4176			dput(dent);
4177			ksmbd_debug(SMB, "Negative dentry `%s'\n",
4178				    priv->d_info->name);
4179			continue;
4180		}
4181
4182		ksmbd_kstat.kstat = &kstat;
4183		if (priv->info_level != FILE_NAMES_INFORMATION) {
4184			rc = ksmbd_vfs_fill_dentry_attrs(priv->work,
4185							 idmap,
4186							 dent,
4187							 &ksmbd_kstat);
4188			if (rc) {
4189				dput(dent);
4190				continue;
4191			}
4192		}
4193
4194		rc = smb2_populate_readdir_entry(priv->work->conn,
4195						 priv->info_level,
4196						 priv->d_info,
4197						 &ksmbd_kstat);
4198		dput(dent);
4199		if (rc)
4200			return rc;
4201	}
4202	return 0;
4203}
4204
4205static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
4206				   int info_level)
4207{
4208	int struct_sz;
4209	int conv_len;
4210	int next_entry_offset;
4211
4212	struct_sz = readdir_info_level_struct_sz(info_level);
4213	if (struct_sz == -EOPNOTSUPP)
4214		return -EOPNOTSUPP;
4215
4216	conv_len = (d_info->name_len + 1) * 2;
4217	next_entry_offset = ALIGN(struct_sz + conv_len,
4218				  KSMBD_DIR_INFO_ALIGNMENT);
4219
4220	if (next_entry_offset > d_info->out_buf_len) {
4221		d_info->out_buf_len = 0;
4222		return -ENOSPC;
4223	}
4224
4225	switch (info_level) {
4226	case FILE_FULL_DIRECTORY_INFORMATION:
4227	{
4228		FILE_FULL_DIRECTORY_INFO *ffdinfo;
4229
4230		ffdinfo = (FILE_FULL_DIRECTORY_INFO *)d_info->wptr;
4231		memcpy(ffdinfo->FileName, d_info->name, d_info->name_len);
4232		ffdinfo->FileName[d_info->name_len] = 0x00;
4233		ffdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
4234		ffdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
4235		break;
4236	}
4237	case FILE_BOTH_DIRECTORY_INFORMATION:
4238	{
4239		FILE_BOTH_DIRECTORY_INFO *fbdinfo;
4240
4241		fbdinfo = (FILE_BOTH_DIRECTORY_INFO *)d_info->wptr;
4242		memcpy(fbdinfo->FileName, d_info->name, d_info->name_len);
4243		fbdinfo->FileName[d_info->name_len] = 0x00;
4244		fbdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
4245		fbdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
4246		break;
4247	}
4248	case FILE_DIRECTORY_INFORMATION:
4249	{
4250		FILE_DIRECTORY_INFO *fdinfo;
4251
4252		fdinfo = (FILE_DIRECTORY_INFO *)d_info->wptr;
4253		memcpy(fdinfo->FileName, d_info->name, d_info->name_len);
4254		fdinfo->FileName[d_info->name_len] = 0x00;
4255		fdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
4256		fdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
4257		break;
4258	}
4259	case FILE_NAMES_INFORMATION:
4260	{
4261		struct file_names_info *fninfo;
4262
4263		fninfo = (struct file_names_info *)d_info->wptr;
4264		memcpy(fninfo->FileName, d_info->name, d_info->name_len);
4265		fninfo->FileName[d_info->name_len] = 0x00;
4266		fninfo->FileNameLength = cpu_to_le32(d_info->name_len);
4267		fninfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
4268		break;
4269	}
4270	case FILEID_FULL_DIRECTORY_INFORMATION:
4271	{
4272		FILE_ID_FULL_DIR_INFO *dinfo;
4273
4274		dinfo = (FILE_ID_FULL_DIR_INFO *)d_info->wptr;
4275		memcpy(dinfo->FileName, d_info->name, d_info->name_len);
4276		dinfo->FileName[d_info->name_len] = 0x00;
4277		dinfo->FileNameLength = cpu_to_le32(d_info->name_len);
4278		dinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
4279		break;
4280	}
4281	case FILEID_BOTH_DIRECTORY_INFORMATION:
4282	{
4283		struct file_id_both_directory_info *fibdinfo;
4284
4285		fibdinfo = (struct file_id_both_directory_info *)d_info->wptr;
4286		memcpy(fibdinfo->FileName, d_info->name, d_info->name_len);
4287		fibdinfo->FileName[d_info->name_len] = 0x00;
4288		fibdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
4289		fibdinfo->NextEntryOffset = cpu_to_le32(next_entry_offset);
4290		break;
4291	}
4292	case SMB_FIND_FILE_POSIX_INFO:
4293	{
4294		struct smb2_posix_info *posix_info;
4295
4296		posix_info = (struct smb2_posix_info *)d_info->wptr;
4297		memcpy(posix_info->name, d_info->name, d_info->name_len);
4298		posix_info->name[d_info->name_len] = 0x00;
4299		posix_info->name_len = cpu_to_le32(d_info->name_len);
4300		posix_info->NextEntryOffset =
4301			cpu_to_le32(next_entry_offset);
4302		break;
4303	}
4304	} /* switch (info_level) */
4305
4306	d_info->num_entry++;
4307	d_info->out_buf_len -= next_entry_offset;
4308	d_info->wptr += next_entry_offset;
4309	return 0;
4310}
4311
4312static bool __query_dir(struct dir_context *ctx, const char *name, int namlen,
4313		       loff_t offset, u64 ino, unsigned int d_type)
4314{
4315	struct ksmbd_readdir_data	*buf;
4316	struct smb2_query_dir_private	*priv;
4317	struct ksmbd_dir_info		*d_info;
4318	int				rc;
4319
4320	buf	= container_of(ctx, struct ksmbd_readdir_data, ctx);
4321	priv	= buf->private;
4322	d_info	= priv->d_info;
4323
4324	/* dot and dotdot entries are already reserved */
4325	if (!strcmp(".", name) || !strcmp("..", name))
4326		return true;
4327	d_info->num_scan++;
4328	if (ksmbd_share_veto_filename(priv->work->tcon->share_conf, name))
4329		return true;
4330	if (!match_pattern(name, namlen, priv->search_pattern))
4331		return true;
4332
4333	d_info->name		= name;
4334	d_info->name_len	= namlen;
4335	rc = reserve_populate_dentry(d_info, priv->info_level);
4336	if (rc)
4337		return false;
4338	if (d_info->flags & SMB2_RETURN_SINGLE_ENTRY)
4339		d_info->out_buf_len = 0;
4340	return true;
4341}
4342
4343static int verify_info_level(int info_level)
4344{
4345	switch (info_level) {
4346	case FILE_FULL_DIRECTORY_INFORMATION:
4347	case FILE_BOTH_DIRECTORY_INFORMATION:
4348	case FILE_DIRECTORY_INFORMATION:
4349	case FILE_NAMES_INFORMATION:
4350	case FILEID_FULL_DIRECTORY_INFORMATION:
4351	case FILEID_BOTH_DIRECTORY_INFORMATION:
4352	case SMB_FIND_FILE_POSIX_INFO:
4353		break;
4354	default:
4355		return -EOPNOTSUPP;
4356	}
4357
4358	return 0;
4359}
4360
4361static int smb2_resp_buf_len(struct ksmbd_work *work, unsigned short hdr2_len)
4362{
4363	int free_len;
4364
4365	free_len = (int)(work->response_sz -
4366		(get_rfc1002_len(work->response_buf) + 4)) - hdr2_len;
4367	return free_len;
4368}
4369
4370static int smb2_calc_max_out_buf_len(struct ksmbd_work *work,
4371				     unsigned short hdr2_len,
4372				     unsigned int out_buf_len)
4373{
4374	int free_len;
4375
4376	if (out_buf_len > work->conn->vals->max_trans_size)
4377		return -EINVAL;
4378
4379	free_len = smb2_resp_buf_len(work, hdr2_len);
4380	if (free_len < 0)
4381		return -EINVAL;
4382
4383	return min_t(int, out_buf_len, free_len);
4384}
4385
4386int smb2_query_dir(struct ksmbd_work *work)
4387{
4388	struct ksmbd_conn *conn = work->conn;
4389	struct smb2_query_directory_req *req;
4390	struct smb2_query_directory_rsp *rsp;
4391	struct ksmbd_share_config *share = work->tcon->share_conf;
4392	struct ksmbd_file *dir_fp = NULL;
4393	struct ksmbd_dir_info d_info;
4394	int rc = 0;
4395	char *srch_ptr = NULL;
4396	unsigned char srch_flag;
4397	int buffer_sz;
4398	struct smb2_query_dir_private query_dir_private = {NULL, };
4399
4400	ksmbd_debug(SMB, "Received smb2 query directory request\n");
4401
4402	WORK_BUFFERS(work, req, rsp);
4403
4404	if (ksmbd_override_fsids(work)) {
4405		rsp->hdr.Status = STATUS_NO_MEMORY;
4406		smb2_set_err_rsp(work);
4407		return -ENOMEM;
4408	}
4409
4410	rc = verify_info_level(req->FileInformationClass);
4411	if (rc) {
4412		rc = -EFAULT;
4413		goto err_out2;
4414	}
4415
4416	dir_fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
4417	if (!dir_fp) {
4418		rc = -EBADF;
4419		goto err_out2;
4420	}
4421
4422	if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) ||
4423	    inode_permission(file_mnt_idmap(dir_fp->filp),
4424			     file_inode(dir_fp->filp),
4425			     MAY_READ | MAY_EXEC)) {
4426		pr_err("no right to enumerate directory (%pD)\n", dir_fp->filp);
4427		rc = -EACCES;
4428		goto err_out2;
4429	}
4430
4431	if (!S_ISDIR(file_inode(dir_fp->filp)->i_mode)) {
4432		pr_err("can't do query dir for a file\n");
4433		rc = -EINVAL;
4434		goto err_out2;
4435	}
4436
4437	srch_flag = req->Flags;
4438	srch_ptr = smb_strndup_from_utf16((char *)req + le16_to_cpu(req->FileNameOffset),
4439					  le16_to_cpu(req->FileNameLength), 1,
4440					  conn->local_nls);
4441	if (IS_ERR(srch_ptr)) {
4442		ksmbd_debug(SMB, "Search Pattern not found\n");
4443		rc = -EINVAL;
4444		goto err_out2;
4445	} else {
4446		ksmbd_debug(SMB, "Search pattern is %s\n", srch_ptr);
4447	}
4448
4449	if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) {
4450		ksmbd_debug(SMB, "Restart directory scan\n");
4451		generic_file_llseek(dir_fp->filp, 0, SEEK_SET);
4452	}
4453
4454	memset(&d_info, 0, sizeof(struct ksmbd_dir_info));
4455	d_info.wptr = (char *)rsp->Buffer;
4456	d_info.rptr = (char *)rsp->Buffer;
4457	d_info.out_buf_len =
4458		smb2_calc_max_out_buf_len(work,
4459				offsetof(struct smb2_query_directory_rsp, Buffer),
4460				le32_to_cpu(req->OutputBufferLength));
4461	if (d_info.out_buf_len < 0) {
4462		rc = -EINVAL;
4463		goto err_out;
4464	}
4465	d_info.flags = srch_flag;
4466
4467	/*
4468	 * reserve dot and dotdot entries in head of buffer
4469	 * in first response
4470	 */
4471	rc = ksmbd_populate_dot_dotdot_entries(work, req->FileInformationClass,
4472					       dir_fp, &d_info, srch_ptr,
4473					       smb2_populate_readdir_entry);
4474	if (rc == -ENOSPC)
4475		rc = 0;
4476	else if (rc)
4477		goto err_out;
4478
4479	if (test_share_config_flag(share, KSMBD_SHARE_FLAG_HIDE_DOT_FILES))
4480		d_info.hide_dot_file = true;
4481
4482	buffer_sz				= d_info.out_buf_len;
4483	d_info.rptr				= d_info.wptr;
4484	query_dir_private.work			= work;
4485	query_dir_private.search_pattern	= srch_ptr;
4486	query_dir_private.dir_fp		= dir_fp;
4487	query_dir_private.d_info		= &d_info;
4488	query_dir_private.info_level		= req->FileInformationClass;
4489	dir_fp->readdir_data.private		= &query_dir_private;
4490	set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir);
4491again:
4492	d_info.num_scan = 0;
4493	rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx);
4494	/*
4495	 * num_entry can be 0 if the directory iteration stops before reaching
4496	 * the end of the directory and no file is matched with the search
4497	 * pattern.
4498	 */
4499	if (rc >= 0 && !d_info.num_entry && d_info.num_scan &&
4500	    d_info.out_buf_len > 0)
4501		goto again;
4502	/*
4503	 * req->OutputBufferLength is too small to contain even one entry.
4504	 * In this case, it immediately returns OutputBufferLength 0 to client.
4505	 */
4506	if (!d_info.out_buf_len && !d_info.num_entry)
4507		goto no_buf_len;
4508	if (rc > 0 || rc == -ENOSPC)
4509		rc = 0;
4510	else if (rc)
4511		goto err_out;
4512
4513	d_info.wptr = d_info.rptr;
4514	d_info.out_buf_len = buffer_sz;
4515	rc = process_query_dir_entries(&query_dir_private);
4516	if (rc)
4517		goto err_out;
4518
4519	if (!d_info.data_count && d_info.out_buf_len >= 0) {
4520		if (srch_flag & SMB2_RETURN_SINGLE_ENTRY && !is_asterisk(srch_ptr)) {
4521			rsp->hdr.Status = STATUS_NO_SUCH_FILE;
4522		} else {
4523			dir_fp->dot_dotdot[0] = dir_fp->dot_dotdot[1] = 0;
4524			rsp->hdr.Status = STATUS_NO_MORE_FILES;
4525		}
4526		rsp->StructureSize = cpu_to_le16(9);
4527		rsp->OutputBufferOffset = cpu_to_le16(0);
4528		rsp->OutputBufferLength = cpu_to_le32(0);
4529		rsp->Buffer[0] = 0;
4530		rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
4531				       offsetof(struct smb2_query_directory_rsp, Buffer)
4532				       + 1);
4533		if (rc)
4534			goto err_out;
4535	} else {
4536no_buf_len:
4537		((FILE_DIRECTORY_INFO *)
4538		((char *)rsp->Buffer + d_info.last_entry_offset))
4539		->NextEntryOffset = 0;
4540		if (d_info.data_count >= d_info.last_entry_off_align)
4541			d_info.data_count -= d_info.last_entry_off_align;
4542
4543		rsp->StructureSize = cpu_to_le16(9);
4544		rsp->OutputBufferOffset = cpu_to_le16(72);
4545		rsp->OutputBufferLength = cpu_to_le32(d_info.data_count);
4546		rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
4547				       offsetof(struct smb2_query_directory_rsp, Buffer) +
4548				       d_info.data_count);
4549		if (rc)
4550			goto err_out;
4551	}
4552
4553	kfree(srch_ptr);
4554	ksmbd_fd_put(work, dir_fp);
4555	ksmbd_revert_fsids(work);
4556	return 0;
4557
4558err_out:
4559	pr_err("error while processing smb2 query dir rc = %d\n", rc);
4560	kfree(srch_ptr);
4561
4562err_out2:
4563	if (rc == -EINVAL)
4564		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
4565	else if (rc == -EACCES)
4566		rsp->hdr.Status = STATUS_ACCESS_DENIED;
4567	else if (rc == -ENOENT)
4568		rsp->hdr.Status = STATUS_NO_SUCH_FILE;
4569	else if (rc == -EBADF)
4570		rsp->hdr.Status = STATUS_FILE_CLOSED;
4571	else if (rc == -ENOMEM)
4572		rsp->hdr.Status = STATUS_NO_MEMORY;
4573	else if (rc == -EFAULT)
4574		rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
4575	else if (rc == -EIO)
4576		rsp->hdr.Status = STATUS_FILE_CORRUPT_ERROR;
4577	if (!rsp->hdr.Status)
4578		rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
4579
4580	smb2_set_err_rsp(work);
4581	ksmbd_fd_put(work, dir_fp);
4582	ksmbd_revert_fsids(work);
4583	return rc;
4584}
4585
4586/**
4587 * buffer_check_err() - helper function to check buffer errors
4588 * @reqOutputBufferLength:	max buffer length expected in command response
4589 * @rsp:		query info response buffer contains output buffer length
4590 * @rsp_org:		base response buffer pointer in case of chained response
4591 *
4592 * Return:	0 on success, otherwise error
4593 */
4594static int buffer_check_err(int reqOutputBufferLength,
4595			    struct smb2_query_info_rsp *rsp,
4596			    void *rsp_org)
4597{
4598	if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) {
4599		pr_err("Invalid Buffer Size Requested\n");
4600		rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH;
4601		*(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr));
4602		return -EINVAL;
4603	}
4604	return 0;
4605}
4606
4607static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp,
4608				   void *rsp_org)
4609{
4610	struct smb2_file_standard_info *sinfo;
4611
4612	sinfo = (struct smb2_file_standard_info *)rsp->Buffer;
4613
4614	sinfo->AllocationSize = cpu_to_le64(4096);
4615	sinfo->EndOfFile = cpu_to_le64(0);
4616	sinfo->NumberOfLinks = cpu_to_le32(1);
4617	sinfo->DeletePending = 1;
4618	sinfo->Directory = 0;
4619	rsp->OutputBufferLength =
4620		cpu_to_le32(sizeof(struct smb2_file_standard_info));
4621}
4622
4623static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num,
4624				   void *rsp_org)
4625{
4626	struct smb2_file_internal_info *file_info;
4627
4628	file_info = (struct smb2_file_internal_info *)rsp->Buffer;
4629
4630	/* any unique number */
4631	file_info->IndexNumber = cpu_to_le64(num | (1ULL << 63));
4632	rsp->OutputBufferLength =
4633		cpu_to_le32(sizeof(struct smb2_file_internal_info));
4634}
4635
4636static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
4637				   struct smb2_query_info_req *req,
4638				   struct smb2_query_info_rsp *rsp,
4639				   void *rsp_org)
4640{
4641	u64 id;
4642	int rc;
4643
4644	/*
4645	 * Windows can sometime send query file info request on
4646	 * pipe without opening it, checking error condition here
4647	 */
4648	id = req->VolatileFileId;
4649
4650	lockdep_assert_not_held(&sess->rpc_lock);
4651
4652	down_read(&sess->rpc_lock);
4653	if (!ksmbd_session_rpc_method(sess, id)) {
4654		up_read(&sess->rpc_lock);
4655		return -ENOENT;
4656	}
4657	up_read(&sess->rpc_lock);
4658
4659	ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n",
4660		    req->FileInfoClass, req->VolatileFileId);
4661
4662	switch (req->FileInfoClass) {
4663	case FILE_STANDARD_INFORMATION:
4664		get_standard_info_pipe(rsp, rsp_org);
4665		rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
4666				      rsp, rsp_org);
4667		break;
4668	case FILE_INTERNAL_INFORMATION:
4669		get_internal_info_pipe(rsp, id, rsp_org);
4670		rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
4671				      rsp, rsp_org);
4672		break;
4673	default:
4674		ksmbd_debug(SMB, "smb2_info_file_pipe for %u not supported\n",
4675			    req->FileInfoClass);
4676		rc = -EOPNOTSUPP;
4677	}
4678	return rc;
4679}
4680
4681/**
4682 * smb2_get_ea() - handler for smb2 get extended attribute command
4683 * @work:	smb work containing query info command buffer
4684 * @fp:		ksmbd_file pointer
4685 * @req:	get extended attribute request
4686 * @rsp:	response buffer pointer
4687 * @rsp_org:	base response buffer pointer in case of chained response
4688 *
4689 * Return:	0 on success, otherwise error
4690 */
4691static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,
4692		       struct smb2_query_info_req *req,
4693		       struct smb2_query_info_rsp *rsp, void *rsp_org)
4694{
4695	struct smb2_ea_info *eainfo, *prev_eainfo;
4696	char *name, *ptr, *xattr_list = NULL, *buf;
4697	int rc, name_len, value_len, xattr_list_len, idx;
4698	ssize_t buf_free_len, alignment_bytes, next_offset, rsp_data_cnt = 0;
4699	struct smb2_ea_info_req *ea_req = NULL;
4700	const struct path *path;
4701	struct mnt_idmap *idmap = file_mnt_idmap(fp->filp);
4702
4703	if (!(fp->daccess & FILE_READ_EA_LE)) {
4704		pr_err("Not permitted to read ext attr : 0x%x\n",
4705		       fp->daccess);
4706		return -EACCES;
4707	}
4708
4709	path = &fp->filp->f_path;
4710	/* single EA entry is requested with given user.* name */
4711	if (req->InputBufferLength) {
4712		if (le32_to_cpu(req->InputBufferLength) <=
4713		    sizeof(struct smb2_ea_info_req))
4714			return -EINVAL;
4715
4716		ea_req = (struct smb2_ea_info_req *)((char *)req +
4717						     le16_to_cpu(req->InputBufferOffset));
4718
4719		if (le32_to_cpu(req->InputBufferLength) <
4720		    offsetof(struct smb2_ea_info_req, name) +
4721		    ea_req->EaNameLength)
4722			return -EINVAL;
4723	} else {
4724		/* need to send all EAs, if no specific EA is requested*/
4725		if (le32_to_cpu(req->Flags) & SL_RETURN_SINGLE_ENTRY)
4726			ksmbd_debug(SMB,
4727				    "All EAs are requested but need to send single EA entry in rsp flags 0x%x\n",
4728				    le32_to_cpu(req->Flags));
4729	}
4730
4731	buf_free_len =
4732		smb2_calc_max_out_buf_len(work,
4733				offsetof(struct smb2_query_info_rsp, Buffer),
4734				le32_to_cpu(req->OutputBufferLength));
4735	if (buf_free_len < 0)
4736		return -EINVAL;
4737
4738	rc = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
4739	if (rc < 0) {
4740		rsp->hdr.Status = STATUS_INVALID_HANDLE;
4741		goto out;
4742	} else if (!rc) { /* there is no EA in the file */
4743		ksmbd_debug(SMB, "no ea data in the file\n");
4744		goto done;
4745	}
4746	xattr_list_len = rc;
4747
4748	ptr = (char *)rsp->Buffer;
4749	eainfo = (struct smb2_ea_info *)ptr;
4750	prev_eainfo = eainfo;
4751	idx = 0;
4752
4753	while (idx < xattr_list_len) {
4754		name = xattr_list + idx;
4755		name_len = strlen(name);
4756
4757		ksmbd_debug(SMB, "%s, len %d\n", name, name_len);
4758		idx += name_len + 1;
4759
4760		/*
4761		 * CIFS does not support EA other than user.* namespace,
4762		 * still keep the framework generic, to list other attrs
4763		 * in future.
4764		 */
4765		if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
4766			continue;
4767
4768		if (!strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
4769			     STREAM_PREFIX_LEN))
4770			continue;
4771
4772		if (req->InputBufferLength &&
4773		    strncmp(&name[XATTR_USER_PREFIX_LEN], ea_req->name,
4774			    ea_req->EaNameLength))
4775			continue;
4776
4777		if (!strncmp(&name[XATTR_USER_PREFIX_LEN],
4778			     DOS_ATTRIBUTE_PREFIX, DOS_ATTRIBUTE_PREFIX_LEN))
4779			continue;
4780
4781		if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
4782			name_len -= XATTR_USER_PREFIX_LEN;
4783
4784		ptr = eainfo->name + name_len + 1;
4785		buf_free_len -= (offsetof(struct smb2_ea_info, name) +
4786				name_len + 1);
4787		/* bailout if xattr can't fit in buf_free_len */
4788		value_len = ksmbd_vfs_getxattr(idmap, path->dentry,
4789					       name, &buf);
4790		if (value_len <= 0) {
4791			rc = -ENOENT;
4792			rsp->hdr.Status = STATUS_INVALID_HANDLE;
4793			goto out;
4794		}
4795
4796		buf_free_len -= value_len;
4797		if (buf_free_len < 0) {
4798			kfree(buf);
4799			break;
4800		}
4801
4802		memcpy(ptr, buf, value_len);
4803		kfree(buf);
4804
4805		ptr += value_len;
4806		eainfo->Flags = 0;
4807		eainfo->EaNameLength = name_len;
4808
4809		if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
4810			memcpy(eainfo->name, &name[XATTR_USER_PREFIX_LEN],
4811			       name_len);
4812		else
4813			memcpy(eainfo->name, name, name_len);
4814
4815		eainfo->name[name_len] = '\0';
4816		eainfo->EaValueLength = cpu_to_le16(value_len);
4817		next_offset = offsetof(struct smb2_ea_info, name) +
4818			name_len + 1 + value_len;
4819
4820		/* align next xattr entry at 4 byte bundary */
4821		alignment_bytes = ((next_offset + 3) & ~3) - next_offset;
4822		if (alignment_bytes) {
4823			memset(ptr, '\0', alignment_bytes);
4824			ptr += alignment_bytes;
4825			next_offset += alignment_bytes;
4826			buf_free_len -= alignment_bytes;
4827		}
4828		eainfo->NextEntryOffset = cpu_to_le32(next_offset);
4829		prev_eainfo = eainfo;
4830		eainfo = (struct smb2_ea_info *)ptr;
4831		rsp_data_cnt += next_offset;
4832
4833		if (req->InputBufferLength) {
4834			ksmbd_debug(SMB, "single entry requested\n");
4835			break;
4836		}
4837	}
4838
4839	/* no more ea entries */
4840	prev_eainfo->NextEntryOffset = 0;
4841done:
4842	rc = 0;
4843	if (rsp_data_cnt == 0)
4844		rsp->hdr.Status = STATUS_NO_EAS_ON_FILE;
4845	rsp->OutputBufferLength = cpu_to_le32(rsp_data_cnt);
4846out:
4847	kvfree(xattr_list);
4848	return rc;
4849}
4850
4851static void get_file_access_info(struct smb2_query_info_rsp *rsp,
4852				 struct ksmbd_file *fp, void *rsp_org)
4853{
4854	struct smb2_file_access_info *file_info;
4855
4856	file_info = (struct smb2_file_access_info *)rsp->Buffer;
4857	file_info->AccessFlags = fp->daccess;
4858	rsp->OutputBufferLength =
4859		cpu_to_le32(sizeof(struct smb2_file_access_info));
4860}
4861
4862static int get_file_basic_info(struct smb2_query_info_rsp *rsp,
4863			       struct ksmbd_file *fp, void *rsp_org)
4864{
4865	struct smb2_file_basic_info *basic_info;
4866	struct kstat stat;
4867	u64 time;
4868	int ret;
4869
4870	if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
4871		pr_err("no right to read the attributes : 0x%x\n",
4872		       fp->daccess);
4873		return -EACCES;
4874	}
4875
4876	ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
4877			  AT_STATX_SYNC_AS_STAT);
4878	if (ret)
4879		return ret;
4880
4881	basic_info = (struct smb2_file_basic_info *)rsp->Buffer;
4882	basic_info->CreationTime = cpu_to_le64(fp->create_time);
4883	time = ksmbd_UnixTimeToNT(stat.atime);
4884	basic_info->LastAccessTime = cpu_to_le64(time);
4885	time = ksmbd_UnixTimeToNT(stat.mtime);
4886	basic_info->LastWriteTime = cpu_to_le64(time);
4887	time = ksmbd_UnixTimeToNT(stat.ctime);
4888	basic_info->ChangeTime = cpu_to_le64(time);
4889	basic_info->Attributes = fp->f_ci->m_fattr;
4890	basic_info->Pad1 = 0;
4891	rsp->OutputBufferLength =
4892		cpu_to_le32(sizeof(struct smb2_file_basic_info));
4893	return 0;
4894}
4895
4896static int get_file_standard_info(struct smb2_query_info_rsp *rsp,
4897				  struct ksmbd_file *fp, void *rsp_org)
4898{
4899	struct smb2_file_standard_info *sinfo;
4900	unsigned int delete_pending;
4901	struct kstat stat;
4902	int ret;
4903
4904	ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
4905			  AT_STATX_SYNC_AS_STAT);
4906	if (ret)
4907		return ret;
4908
4909	sinfo = (struct smb2_file_standard_info *)rsp->Buffer;
4910	delete_pending = ksmbd_inode_pending_delete(fp);
4911
4912	if (ksmbd_stream_fd(fp) == false) {
4913		sinfo->AllocationSize = cpu_to_le64(stat.blocks << 9);
4914		sinfo->EndOfFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
4915	} else {
4916		sinfo->AllocationSize = cpu_to_le64(fp->stream.size);
4917		sinfo->EndOfFile = cpu_to_le64(fp->stream.size);
4918	}
4919	sinfo->NumberOfLinks = cpu_to_le32(get_nlink(&stat) - delete_pending);
4920	sinfo->DeletePending = delete_pending;
4921	sinfo->Directory = S_ISDIR(stat.mode) ? 1 : 0;
4922	rsp->OutputBufferLength =
4923		cpu_to_le32(sizeof(struct smb2_file_standard_info));
4924
4925	return 0;
4926}
4927
4928static void get_file_alignment_info(struct smb2_query_info_rsp *rsp,
4929				    void *rsp_org)
4930{
4931	struct smb2_file_alignment_info *file_info;
4932
4933	file_info = (struct smb2_file_alignment_info *)rsp->Buffer;
4934	file_info->AlignmentRequirement = 0;
4935	rsp->OutputBufferLength =
4936		cpu_to_le32(sizeof(struct smb2_file_alignment_info));
4937}
4938
4939static int get_file_all_info(struct ksmbd_work *work,
4940			     struct smb2_query_info_rsp *rsp,
4941			     struct ksmbd_file *fp,
4942			     void *rsp_org)
4943{
4944	struct ksmbd_conn *conn = work->conn;
4945	struct smb2_file_all_info *file_info;
4946	unsigned int delete_pending;
4947	struct kstat stat;
4948	int conv_len;
4949	char *filename;
4950	u64 time;
4951	int ret, buf_free_len, filename_len;
4952	struct smb2_query_info_req *req = ksmbd_req_buf_next(work);
4953
4954	if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
4955		ksmbd_debug(SMB, "no right to read the attributes : 0x%x\n",
4956			    fp->daccess);
4957		return -EACCES;
4958	}
4959
4960	filename = convert_to_nt_pathname(work->tcon->share_conf, &fp->filp->f_path);
4961	if (IS_ERR(filename))
4962		return PTR_ERR(filename);
4963
4964	filename_len = strlen(filename);
4965	buf_free_len = smb2_calc_max_out_buf_len(work,
4966			offsetof(struct smb2_query_info_rsp, Buffer) +
4967			offsetof(struct smb2_file_all_info, FileName),
4968			le32_to_cpu(req->OutputBufferLength));
4969	if (buf_free_len < (filename_len + 1) * 2) {
4970		kfree(filename);
4971		return -EINVAL;
4972	}
4973
4974	ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
4975			  AT_STATX_SYNC_AS_STAT);
4976	if (ret) {
4977		kfree(filename);
4978		return ret;
4979	}
4980
4981	ksmbd_debug(SMB, "filename = %s\n", filename);
4982	delete_pending = ksmbd_inode_pending_delete(fp);
4983	file_info = (struct smb2_file_all_info *)rsp->Buffer;
4984
4985	file_info->CreationTime = cpu_to_le64(fp->create_time);
4986	time = ksmbd_UnixTimeToNT(stat.atime);
4987	file_info->LastAccessTime = cpu_to_le64(time);
4988	time = ksmbd_UnixTimeToNT(stat.mtime);
4989	file_info->LastWriteTime = cpu_to_le64(time);
4990	time = ksmbd_UnixTimeToNT(stat.ctime);
4991	file_info->ChangeTime = cpu_to_le64(time);
4992	file_info->Attributes = fp->f_ci->m_fattr;
4993	file_info->Pad1 = 0;
4994	if (ksmbd_stream_fd(fp) == false) {
4995		file_info->AllocationSize =
4996			cpu_to_le64(stat.blocks << 9);
4997		file_info->EndOfFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
4998	} else {
4999		file_info->AllocationSize = cpu_to_le64(fp->stream.size);
5000		file_info->EndOfFile = cpu_to_le64(fp->stream.size);
5001	}
5002	file_info->NumberOfLinks =
5003			cpu_to_le32(get_nlink(&stat) - delete_pending);
5004	file_info->DeletePending = delete_pending;
5005	file_info->Directory = S_ISDIR(stat.mode) ? 1 : 0;
5006	file_info->Pad2 = 0;
5007	file_info->IndexNumber = cpu_to_le64(stat.ino);
5008	file_info->EASize = 0;
5009	file_info->AccessFlags = fp->daccess;
5010	if (ksmbd_stream_fd(fp) == false)
5011		file_info->CurrentByteOffset = cpu_to_le64(fp->filp->f_pos);
5012	else
5013		file_info->CurrentByteOffset = cpu_to_le64(fp->stream.pos);
5014	file_info->Mode = fp->coption;
5015	file_info->AlignmentRequirement = 0;
5016	conv_len = smbConvertToUTF16((__le16 *)file_info->FileName, filename,
5017				     min(filename_len, PATH_MAX),
5018				     conn->local_nls, 0);
5019	conv_len *= 2;
5020	file_info->FileNameLength = cpu_to_le32(conv_len);
5021	rsp->OutputBufferLength =
5022		cpu_to_le32(sizeof(struct smb2_file_all_info) + conv_len - 1);
5023	kfree(filename);
5024	return 0;
5025}
5026
5027static void get_file_alternate_info(struct ksmbd_work *work,
5028				    struct smb2_query_info_rsp *rsp,
5029				    struct ksmbd_file *fp,
5030				    void *rsp_org)
5031{
5032	struct ksmbd_conn *conn = work->conn;
5033	struct smb2_file_alt_name_info *file_info;
5034	struct dentry *dentry = fp->filp->f_path.dentry;
5035	int conv_len;
5036
5037	spin_lock(&dentry->d_lock);
5038	file_info = (struct smb2_file_alt_name_info *)rsp->Buffer;
5039	conv_len = ksmbd_extract_shortname(conn,
5040					   dentry->d_name.name,
5041					   file_info->FileName);
5042	spin_unlock(&dentry->d_lock);
5043	file_info->FileNameLength = cpu_to_le32(conv_len);
5044	rsp->OutputBufferLength =
5045		cpu_to_le32(struct_size(file_info, FileName, conv_len));
5046}
5047
5048static int get_file_stream_info(struct ksmbd_work *work,
5049				struct smb2_query_info_rsp *rsp,
5050				struct ksmbd_file *fp,
5051				void *rsp_org)
5052{
5053	struct ksmbd_conn *conn = work->conn;
5054	struct smb2_file_stream_info *file_info;
5055	char *stream_name, *xattr_list = NULL, *stream_buf;
5056	struct kstat stat;
5057	const struct path *path = &fp->filp->f_path;
5058	ssize_t xattr_list_len;
5059	int nbytes = 0, streamlen, stream_name_len, next, idx = 0;
5060	int buf_free_len;
5061	struct smb2_query_info_req *req = ksmbd_req_buf_next(work);
5062	int ret;
5063
5064	ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
5065			  AT_STATX_SYNC_AS_STAT);
5066	if (ret)
5067		return ret;
5068
5069	file_info = (struct smb2_file_stream_info *)rsp->Buffer;
5070
5071	buf_free_len =
5072		smb2_calc_max_out_buf_len(work,
5073				offsetof(struct smb2_query_info_rsp, Buffer),
5074				le32_to_cpu(req->OutputBufferLength));
5075	if (buf_free_len < 0)
5076		goto out;
5077
5078	xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
5079	if (xattr_list_len < 0) {
5080		goto out;
5081	} else if (!xattr_list_len) {
5082		ksmbd_debug(SMB, "empty xattr in the file\n");
5083		goto out;
5084	}
5085
5086	while (idx < xattr_list_len) {
5087		stream_name = xattr_list + idx;
5088		streamlen = strlen(stream_name);
5089		idx += streamlen + 1;
5090
5091		ksmbd_debug(SMB, "%s, len %d\n", stream_name, streamlen);
5092
5093		if (strncmp(&stream_name[XATTR_USER_PREFIX_LEN],
5094			    STREAM_PREFIX, STREAM_PREFIX_LEN))
5095			continue;
5096
5097		stream_name_len = streamlen - (XATTR_USER_PREFIX_LEN +
5098				STREAM_PREFIX_LEN);
5099		streamlen = stream_name_len;
5100
5101		/* plus : size */
5102		streamlen += 1;
5103		stream_buf = kmalloc(streamlen + 1, KSMBD_DEFAULT_GFP);
5104		if (!stream_buf)
5105			break;
5106
5107		streamlen = snprintf(stream_buf, streamlen + 1,
5108				     ":%s", &stream_name[XATTR_NAME_STREAM_LEN]);
5109
5110		next = sizeof(struct smb2_file_stream_info) + streamlen * 2;
5111		if (next > buf_free_len) {
5112			kfree(stream_buf);
5113			break;
5114		}
5115
5116		file_info = (struct smb2_file_stream_info *)&rsp->Buffer[nbytes];
5117		streamlen  = smbConvertToUTF16((__le16 *)file_info->StreamName,
5118					       stream_buf, streamlen,
5119					       conn->local_nls, 0);
5120		streamlen *= 2;
5121		kfree(stream_buf);
5122		file_info->StreamNameLength = cpu_to_le32(streamlen);
5123		file_info->StreamSize = cpu_to_le64(stream_name_len);
5124		file_info->StreamAllocationSize = cpu_to_le64(stream_name_len);
5125
5126		nbytes += next;
5127		buf_free_len -= next;
5128		file_info->NextEntryOffset = cpu_to_le32(next);
5129	}
5130
5131out:
5132	if (!S_ISDIR(stat.mode) &&
5133	    buf_free_len >= sizeof(struct smb2_file_stream_info) + 7 * 2) {
5134		file_info = (struct smb2_file_stream_info *)
5135			&rsp->Buffer[nbytes];
5136		streamlen = smbConvertToUTF16((__le16 *)file_info->StreamName,
5137					      "::$DATA", 7, conn->local_nls, 0);
5138		streamlen *= 2;
5139		file_info->StreamNameLength = cpu_to_le32(streamlen);
5140		file_info->StreamSize = cpu_to_le64(stat.size);
5141		file_info->StreamAllocationSize = cpu_to_le64(stat.blocks << 9);
5142		nbytes += sizeof(struct smb2_file_stream_info) + streamlen;
5143	}
5144
5145	/* last entry offset should be 0 */
5146	file_info->NextEntryOffset = 0;
5147	kvfree(xattr_list);
5148
5149	rsp->OutputBufferLength = cpu_to_le32(nbytes);
5150
5151	return 0;
5152}
5153
5154static int get_file_internal_info(struct smb2_query_info_rsp *rsp,
5155				  struct ksmbd_file *fp, void *rsp_org)
5156{
5157	struct smb2_file_internal_info *file_info;
5158	struct kstat stat;
5159	int ret;
5160
5161	ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
5162			  AT_STATX_SYNC_AS_STAT);
5163	if (ret)
5164		return ret;
5165
5166	file_info = (struct smb2_file_internal_info *)rsp->Buffer;
5167	file_info->IndexNumber = cpu_to_le64(stat.ino);
5168	rsp->OutputBufferLength =
5169		cpu_to_le32(sizeof(struct smb2_file_internal_info));
5170
5171	return 0;
5172}
5173
5174static int get_file_network_open_info(struct smb2_query_info_rsp *rsp,
5175				      struct ksmbd_file *fp, void *rsp_org)
5176{
5177	struct smb2_file_network_open_info *file_info;
5178	struct kstat stat;
5179	u64 time;
5180	int ret;
5181
5182	if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
5183		pr_err("no right to read the attributes : 0x%x\n",
5184		       fp->daccess);
5185		return -EACCES;
5186	}
5187
5188	ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
5189			  AT_STATX_SYNC_AS_STAT);
5190	if (ret)
5191		return ret;
5192
5193	file_info = (struct smb2_file_network_open_info *)rsp->Buffer;
5194
5195	file_info->CreationTime = cpu_to_le64(fp->create_time);
5196	time = ksmbd_UnixTimeToNT(stat.atime);
5197	file_info->LastAccessTime = cpu_to_le64(time);
5198	time = ksmbd_UnixTimeToNT(stat.mtime);
5199	file_info->LastWriteTime = cpu_to_le64(time);
5200	time = ksmbd_UnixTimeToNT(stat.ctime);
5201	file_info->ChangeTime = cpu_to_le64(time);
5202	file_info->Attributes = fp->f_ci->m_fattr;
5203	if (ksmbd_stream_fd(fp) == false) {
5204		file_info->AllocationSize = cpu_to_le64(stat.blocks << 9);
5205		file_info->EndOfFile = S_ISDIR(stat.mode) ? 0 : cpu_to_le64(stat.size);
5206	} else {
5207		file_info->AllocationSize = cpu_to_le64(fp->stream.size);
5208		file_info->EndOfFile = cpu_to_le64(fp->stream.size);
5209	}
5210	file_info->Reserved = cpu_to_le32(0);
5211	rsp->OutputBufferLength =
5212		cpu_to_le32(sizeof(struct smb2_file_network_open_info));
5213	return 0;
5214}
5215
5216static void get_file_ea_info(struct smb2_query_info_rsp *rsp, void *rsp_org)
5217{
5218	struct smb2_file_ea_info *file_info;
5219
5220	file_info = (struct smb2_file_ea_info *)rsp->Buffer;
5221	file_info->EASize = 0;
5222	rsp->OutputBufferLength =
5223		cpu_to_le32(sizeof(struct smb2_file_ea_info));
5224}
5225
5226static void get_file_position_info(struct smb2_query_info_rsp *rsp,
5227				   struct ksmbd_file *fp, void *rsp_org)
5228{
5229	struct smb2_file_pos_info *file_info;
5230
5231	file_info = (struct smb2_file_pos_info *)rsp->Buffer;
5232	if (ksmbd_stream_fd(fp) == false)
5233		file_info->CurrentByteOffset = cpu_to_le64(fp->filp->f_pos);
5234	else
5235		file_info->CurrentByteOffset = cpu_to_le64(fp->stream.pos);
5236
5237	rsp->OutputBufferLength =
5238		cpu_to_le32(sizeof(struct smb2_file_pos_info));
5239}
5240
5241static void get_file_mode_info(struct smb2_query_info_rsp *rsp,
5242			       struct ksmbd_file *fp, void *rsp_org)
5243{
5244	struct smb2_file_mode_info *file_info;
5245
5246	file_info = (struct smb2_file_mode_info *)rsp->Buffer;
5247	file_info->Mode = fp->coption & FILE_MODE_INFO_MASK;
5248	rsp->OutputBufferLength =
5249		cpu_to_le32(sizeof(struct smb2_file_mode_info));
5250}
5251
5252static int get_file_compression_info(struct smb2_query_info_rsp *rsp,
5253				     struct ksmbd_file *fp, void *rsp_org)
5254{
5255	struct smb2_file_comp_info *file_info;
5256	struct kstat stat;
5257	int ret;
5258
5259	ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
5260			  AT_STATX_SYNC_AS_STAT);
5261	if (ret)
5262		return ret;
5263
5264	file_info = (struct smb2_file_comp_info *)rsp->Buffer;
5265	file_info->CompressedFileSize = cpu_to_le64(stat.blocks << 9);
5266	file_info->CompressionFormat = COMPRESSION_FORMAT_NONE;
5267	file_info->CompressionUnitShift = 0;
5268	file_info->ChunkShift = 0;
5269	file_info->ClusterShift = 0;
5270	memset(&file_info->Reserved[0], 0, 3);
5271
5272	rsp->OutputBufferLength =
5273		cpu_to_le32(sizeof(struct smb2_file_comp_info));
5274
5275	return 0;
5276}
5277
5278static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp,
5279				       struct ksmbd_file *fp, void *rsp_org)
5280{
5281	struct smb2_file_attr_tag_info *file_info;
5282
5283	if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
5284		pr_err("no right to read the attributes : 0x%x\n",
5285		       fp->daccess);
5286		return -EACCES;
5287	}
5288
5289	file_info = (struct smb2_file_attr_tag_info *)rsp->Buffer;
5290	file_info->FileAttributes = fp->f_ci->m_fattr;
5291	file_info->ReparseTag = 0;
5292	rsp->OutputBufferLength =
5293		cpu_to_le32(sizeof(struct smb2_file_attr_tag_info));
5294	return 0;
5295}
5296
5297static int find_file_posix_info(struct smb2_query_info_rsp *rsp,
5298				struct ksmbd_file *fp, void *rsp_org)
5299{
5300	struct smb311_posix_qinfo *file_info;
5301	struct inode *inode = file_inode(fp->filp);
5302	struct mnt_idmap *idmap = file_mnt_idmap(fp->filp);
5303	vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);
5304	vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, inode);
5305	struct kstat stat;
5306	u64 time;
5307	int out_buf_len = sizeof(struct smb311_posix_qinfo) + 32;
5308	int ret;
5309
5310	ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
5311			  AT_STATX_SYNC_AS_STAT);
5312	if (ret)
5313		return ret;
5314
5315	file_info = (struct smb311_posix_qinfo *)rsp->Buffer;
5316	file_info->CreationTime = cpu_to_le64(fp->create_time);
5317	time = ksmbd_UnixTimeToNT(stat.atime);
5318	file_info->LastAccessTime = cpu_to_le64(time);
5319	time = ksmbd_UnixTimeToNT(stat.mtime);
5320	file_info->LastWriteTime = cpu_to_le64(time);
5321	time = ksmbd_UnixTimeToNT(stat.ctime);
5322	file_info->ChangeTime = cpu_to_le64(time);
5323	file_info->DosAttributes = fp->f_ci->m_fattr;
5324	file_info->Inode = cpu_to_le64(stat.ino);
5325	if (ksmbd_stream_fd(fp) == false) {
5326		file_info->EndOfFile = cpu_to_le64(stat.size);
5327		file_info->AllocationSize = cpu_to_le64(stat.blocks << 9);
5328	} else {
5329		file_info->EndOfFile = cpu_to_le64(fp->stream.size);
5330		file_info->AllocationSize = cpu_to_le64(fp->stream.size);
5331	}
5332	file_info->HardLinks = cpu_to_le32(stat.nlink);
5333	file_info->Mode = cpu_to_le32(stat.mode & 0777);
5334	switch (stat.mode & S_IFMT) {
5335	case S_IFDIR:
5336		file_info->Mode |= cpu_to_le32(POSIX_TYPE_DIR << POSIX_FILETYPE_SHIFT);
5337		break;
5338	case S_IFLNK:
5339		file_info->Mode |= cpu_to_le32(POSIX_TYPE_SYMLINK << POSIX_FILETYPE_SHIFT);
5340		break;
5341	case S_IFCHR:
5342		file_info->Mode |= cpu_to_le32(POSIX_TYPE_CHARDEV << POSIX_FILETYPE_SHIFT);
5343		break;
5344	case S_IFBLK:
5345		file_info->Mode |= cpu_to_le32(POSIX_TYPE_BLKDEV << POSIX_FILETYPE_SHIFT);
5346		break;
5347	case S_IFIFO:
5348		file_info->Mode |= cpu_to_le32(POSIX_TYPE_FIFO << POSIX_FILETYPE_SHIFT);
5349		break;
5350	case S_IFSOCK:
5351		file_info->Mode |= cpu_to_le32(POSIX_TYPE_SOCKET << POSIX_FILETYPE_SHIFT);
5352	}
5353
5354	file_info->DeviceId = cpu_to_le32(stat.rdev);
5355
5356	/*
5357	 * Sids(32) contain two sids(Domain sid(16), UNIX group sid(16)).
5358	 * UNIX sid(16) = revision(1) + num_subauth(1) + authority(6) +
5359	 *		  sub_auth(4 * 1(num_subauth)) + RID(4).
5360	 */
5361	id_to_sid(from_kuid_munged(&init_user_ns, vfsuid_into_kuid(vfsuid)),
5362		  SIDUNIX_USER, (struct smb_sid *)&file_info->Sids[0]);
5363	id_to_sid(from_kgid_munged(&init_user_ns, vfsgid_into_kgid(vfsgid)),
5364		  SIDUNIX_GROUP, (struct smb_sid *)&file_info->Sids[16]);
5365
5366	rsp->OutputBufferLength = cpu_to_le32(out_buf_len);
5367
5368	return 0;
5369}
5370
5371static int smb2_get_info_file(struct ksmbd_work *work,
5372			      struct smb2_query_info_req *req,
5373			      struct smb2_query_info_rsp *rsp)
5374{
5375	struct ksmbd_file *fp;
5376	int fileinfoclass = 0;
5377	int rc = 0;
5378	unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
5379
5380	if (test_share_config_flag(work->tcon->share_conf,
5381				   KSMBD_SHARE_FLAG_PIPE)) {
5382		/* smb2 info file called for pipe */
5383		rc = smb2_get_info_file_pipe(work->sess, req, rsp,
5384					       work->response_buf);
5385		goto iov_pin_out;
5386	}
5387
5388	if (work->next_smb2_rcv_hdr_off) {
5389		if (!has_file_id(req->VolatileFileId)) {
5390			ksmbd_debug(SMB, "Compound request set FID = %llu\n",
5391				    work->compound_fid);
5392			id = work->compound_fid;
5393			pid = work->compound_pfid;
5394		}
5395	}
5396
5397	if (!has_file_id(id)) {
5398		id = req->VolatileFileId;
5399		pid = req->PersistentFileId;
5400	}
5401
5402	fp = ksmbd_lookup_fd_slow(work, id, pid);
5403	if (!fp)
5404		return -ENOENT;
5405
5406	fileinfoclass = req->FileInfoClass;
5407
5408	switch (fileinfoclass) {
5409	case FILE_ACCESS_INFORMATION:
5410		get_file_access_info(rsp, fp, work->response_buf);
5411		break;
5412
5413	case FILE_BASIC_INFORMATION:
5414		rc = get_file_basic_info(rsp, fp, work->response_buf);
5415		break;
5416
5417	case FILE_STANDARD_INFORMATION:
5418		rc = get_file_standard_info(rsp, fp, work->response_buf);
5419		break;
5420
5421	case FILE_ALIGNMENT_INFORMATION:
5422		get_file_alignment_info(rsp, work->response_buf);
5423		break;
5424
5425	case FILE_ALL_INFORMATION:
5426		rc = get_file_all_info(work, rsp, fp, work->response_buf);
5427		break;
5428
5429	case FILE_ALTERNATE_NAME_INFORMATION:
5430		get_file_alternate_info(work, rsp, fp, work->response_buf);
5431		break;
5432
5433	case FILE_STREAM_INFORMATION:
5434		rc = get_file_stream_info(work, rsp, fp, work->response_buf);
5435		break;
5436
5437	case FILE_INTERNAL_INFORMATION:
5438		rc = get_file_internal_info(rsp, fp, work->response_buf);
5439		break;
5440
5441	case FILE_NETWORK_OPEN_INFORMATION:
5442		rc = get_file_network_open_info(rsp, fp, work->response_buf);
5443		break;
5444
5445	case FILE_EA_INFORMATION:
5446		get_file_ea_info(rsp, work->response_buf);
5447		break;
5448
5449	case FILE_FULL_EA_INFORMATION:
5450		rc = smb2_get_ea(work, fp, req, rsp, work->response_buf);
5451		break;
5452
5453	case FILE_POSITION_INFORMATION:
5454		get_file_position_info(rsp, fp, work->response_buf);
5455		break;
5456
5457	case FILE_MODE_INFORMATION:
5458		get_file_mode_info(rsp, fp, work->response_buf);
5459		break;
5460
5461	case FILE_COMPRESSION_INFORMATION:
5462		rc = get_file_compression_info(rsp, fp, work->response_buf);
5463		break;
5464
5465	case FILE_ATTRIBUTE_TAG_INFORMATION:
5466		rc = get_file_attribute_tag_info(rsp, fp, work->response_buf);
5467		break;
5468	case SMB_FIND_FILE_POSIX_INFO:
5469		if (!work->tcon->posix_extensions) {
5470			pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n");
5471			rc = -EOPNOTSUPP;
5472		} else {
5473			rc = find_file_posix_info(rsp, fp, work->response_buf);
5474		}
5475		break;
5476	default:
5477		ksmbd_debug(SMB, "fileinfoclass %d not supported yet\n",
5478			    fileinfoclass);
5479		rc = -EOPNOTSUPP;
5480	}
5481	if (!rc)
5482		rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
5483				      rsp, work->response_buf);
5484	ksmbd_fd_put(work, fp);
5485
5486iov_pin_out:
5487	if (!rc)
5488		rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
5489				offsetof(struct smb2_query_info_rsp, Buffer) +
5490				le32_to_cpu(rsp->OutputBufferLength));
5491	return rc;
5492}
5493
5494static int smb2_get_info_filesystem(struct ksmbd_work *work,
5495				    struct smb2_query_info_req *req,
5496				    struct smb2_query_info_rsp *rsp)
5497{
5498	struct ksmbd_conn *conn = work->conn;
5499	struct ksmbd_share_config *share = work->tcon->share_conf;
5500	int fsinfoclass = 0;
5501	struct kstatfs stfs;
5502	struct path path;
5503	int rc = 0, len;
5504
5505	if (!share->path)
5506		return -EIO;
5507
5508	rc = kern_path(share->path, LOOKUP_NO_SYMLINKS, &path);
5509	if (rc) {
5510		pr_err("cannot create vfs path\n");
5511		return -EIO;
5512	}
5513
5514	rc = vfs_statfs(&path, &stfs);
5515	if (rc) {
5516		pr_err("cannot do stat of path %s\n", share->path);
5517		path_put(&path);
5518		return -EIO;
5519	}
5520
5521	fsinfoclass = req->FileInfoClass;
5522
5523	switch (fsinfoclass) {
5524	case FS_DEVICE_INFORMATION:
5525	{
5526		FILE_SYSTEM_DEVICE_INFO *info;
5527
5528		info = (FILE_SYSTEM_DEVICE_INFO *)rsp->Buffer;
5529
5530		info->DeviceType = cpu_to_le32(FILE_DEVICE_DISK);
5531		info->DeviceCharacteristics =
5532			cpu_to_le32(FILE_DEVICE_IS_MOUNTED);
5533		if (!test_tree_conn_flag(work->tcon,
5534					 KSMBD_TREE_CONN_FLAG_WRITABLE))
5535			info->DeviceCharacteristics |=
5536				cpu_to_le32(FILE_READ_ONLY_DEVICE);
5537		rsp->OutputBufferLength = cpu_to_le32(8);
5538		break;
5539	}
5540	case FS_ATTRIBUTE_INFORMATION:
5541	{
5542		FILE_SYSTEM_ATTRIBUTE_INFO *info;
5543		size_t sz;
5544
5545		info = (FILE_SYSTEM_ATTRIBUTE_INFO *)rsp->Buffer;
5546		info->Attributes = cpu_to_le32(FILE_SUPPORTS_OBJECT_IDS |
5547					       FILE_PERSISTENT_ACLS |
5548					       FILE_UNICODE_ON_DISK |
5549					       FILE_CASE_PRESERVED_NAMES |
5550					       FILE_CASE_SENSITIVE_SEARCH |
5551					       FILE_SUPPORTS_BLOCK_REFCOUNTING);
5552
5553		info->Attributes |= cpu_to_le32(server_conf.share_fake_fscaps);
5554
5555		if (test_share_config_flag(work->tcon->share_conf,
5556		    KSMBD_SHARE_FLAG_STREAMS))
5557			info->Attributes |= cpu_to_le32(FILE_NAMED_STREAMS);
5558
5559		info->MaxPathNameComponentLength = cpu_to_le32(stfs.f_namelen);
5560		/*
5561		 * some application(potableapp) can not run on ksmbd share
5562		 * because only NTFS handle security setting on windows.
5563		 * So Although local fs(EXT4 or F2fs, etc) is not NTFS,
5564		 * ksmbd should show share as NTFS. Later, If needed, we can add
5565		 * fs type(s) parameter to change fs type user wanted.
5566		 */
5567		len = smbConvertToUTF16((__le16 *)info->FileSystemName,
5568					"NTFS", PATH_MAX, conn->local_nls, 0);
5569		len = len * 2;
5570		info->FileSystemNameLen = cpu_to_le32(len);
5571		sz = sizeof(FILE_SYSTEM_ATTRIBUTE_INFO) + len;
5572		rsp->OutputBufferLength = cpu_to_le32(sz);
5573		break;
5574	}
5575	case FS_VOLUME_INFORMATION:
5576	{
5577		struct filesystem_vol_info *info;
5578		size_t sz;
5579		unsigned int serial_crc = 0;
5580
5581		info = (struct filesystem_vol_info *)(rsp->Buffer);
5582		info->VolumeCreationTime = 0;
5583		serial_crc = crc32_le(serial_crc, share->name,
5584				      strlen(share->name));
5585		serial_crc = crc32_le(serial_crc, share->path,
5586				      strlen(share->path));
5587		serial_crc = crc32_le(serial_crc, ksmbd_netbios_name(),
5588				      strlen(ksmbd_netbios_name()));
5589		/* Taking dummy value of serial number*/
5590		info->SerialNumber = cpu_to_le32(serial_crc);
5591		len = smbConvertToUTF16((__le16 *)info->VolumeLabel,
5592					share->name, PATH_MAX,
5593					conn->local_nls, 0);
5594		len = len * 2;
5595		info->VolumeLabelSize = cpu_to_le32(len);
5596		info->Reserved = 0;
5597		sz = sizeof(struct filesystem_vol_info) + len;
5598		rsp->OutputBufferLength = cpu_to_le32(sz);
5599		break;
5600	}
5601	case FS_SIZE_INFORMATION:
5602	{
5603		FILE_SYSTEM_SIZE_INFO *info;
5604
5605		info = (FILE_SYSTEM_SIZE_INFO *)(rsp->Buffer);
5606		info->TotalAllocationUnits = cpu_to_le64(stfs.f_blocks);
5607		info->AvailableAllocationUnits = cpu_to_le64(stfs.f_bfree);
5608		info->SectorsPerAllocationUnit = cpu_to_le32(1);
5609		info->BytesPerSector = cpu_to_le32(stfs.f_bsize);
5610		rsp->OutputBufferLength = cpu_to_le32(24);
5611		break;
5612	}
5613	case FS_FULL_SIZE_INFORMATION:
5614	{
5615		struct smb2_fs_full_size_info *info;
5616
5617		info = (struct smb2_fs_full_size_info *)(rsp->Buffer);
5618		info->TotalAllocationUnits = cpu_to_le64(stfs.f_blocks);
5619		info->CallerAvailableAllocationUnits =
5620					cpu_to_le64(stfs.f_bavail);
5621		info->ActualAvailableAllocationUnits =
5622					cpu_to_le64(stfs.f_bfree);
5623		info->SectorsPerAllocationUnit = cpu_to_le32(1);
5624		info->BytesPerSector = cpu_to_le32(stfs.f_bsize);
5625		rsp->OutputBufferLength = cpu_to_le32(32);
5626		break;
5627	}
5628	case FS_OBJECT_ID_INFORMATION:
5629	{
5630		struct object_id_info *info;
5631
5632		info = (struct object_id_info *)(rsp->Buffer);
5633
5634		if (path.mnt->mnt_sb->s_uuid_len == 16)
5635			memcpy(info->objid, path.mnt->mnt_sb->s_uuid.b,
5636					path.mnt->mnt_sb->s_uuid_len);
5637		else
5638			memcpy(info->objid, &stfs.f_fsid, sizeof(stfs.f_fsid));
5639
5640		info->extended_info.magic = cpu_to_le32(EXTENDED_INFO_MAGIC);
5641		info->extended_info.version = cpu_to_le32(1);
5642		info->extended_info.release = cpu_to_le32(1);
5643		info->extended_info.rel_date = 0;
5644		memcpy(info->extended_info.version_string, "1.1.0", strlen("1.1.0"));
5645		rsp->OutputBufferLength = cpu_to_le32(64);
5646		break;
5647	}
5648	case FS_SECTOR_SIZE_INFORMATION:
5649	{
5650		struct smb3_fs_ss_info *info;
5651		unsigned int sector_size =
5652			min_t(unsigned int, path.mnt->mnt_sb->s_blocksize, 4096);
5653
5654		info = (struct smb3_fs_ss_info *)(rsp->Buffer);
5655
5656		info->LogicalBytesPerSector = cpu_to_le32(sector_size);
5657		info->PhysicalBytesPerSectorForAtomicity =
5658				cpu_to_le32(sector_size);
5659		info->PhysicalBytesPerSectorForPerf = cpu_to_le32(sector_size);
5660		info->FSEffPhysicalBytesPerSectorForAtomicity =
5661				cpu_to_le32(sector_size);
5662		info->Flags = cpu_to_le32(SSINFO_FLAGS_ALIGNED_DEVICE |
5663				    SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE);
5664		info->ByteOffsetForSectorAlignment = 0;
5665		info->ByteOffsetForPartitionAlignment = 0;
5666		rsp->OutputBufferLength = cpu_to_le32(28);
5667		break;
5668	}
5669	case FS_CONTROL_INFORMATION:
5670	{
5671		/*
5672		 * TODO : The current implementation is based on
5673		 * test result with win7(NTFS) server. It's need to
5674		 * modify this to get valid Quota values
5675		 * from Linux kernel
5676		 */
5677		struct smb2_fs_control_info *info;
5678
5679		info = (struct smb2_fs_control_info *)(rsp->Buffer);
5680		info->FreeSpaceStartFiltering = 0;
5681		info->FreeSpaceThreshold = 0;
5682		info->FreeSpaceStopFiltering = 0;
5683		info->DefaultQuotaThreshold = cpu_to_le64(SMB2_NO_FID);
5684		info->DefaultQuotaLimit = cpu_to_le64(SMB2_NO_FID);
5685		info->Padding = 0;
5686		rsp->OutputBufferLength = cpu_to_le32(48);
5687		break;
5688	}
5689	case FS_POSIX_INFORMATION:
5690	{
5691		FILE_SYSTEM_POSIX_INFO *info;
5692
5693		if (!work->tcon->posix_extensions) {
5694			pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n");
5695			path_put(&path);
5696			return -EOPNOTSUPP;
5697		} else {
5698			info = (FILE_SYSTEM_POSIX_INFO *)(rsp->Buffer);
5699			info->OptimalTransferSize = cpu_to_le32(stfs.f_bsize);
5700			info->BlockSize = cpu_to_le32(stfs.f_bsize);
5701			info->TotalBlocks = cpu_to_le64(stfs.f_blocks);
5702			info->BlocksAvail = cpu_to_le64(stfs.f_bfree);
5703			info->UserBlocksAvail = cpu_to_le64(stfs.f_bavail);
5704			info->TotalFileNodes = cpu_to_le64(stfs.f_files);
5705			info->FreeFileNodes = cpu_to_le64(stfs.f_ffree);
5706			rsp->OutputBufferLength = cpu_to_le32(56);
5707		}
5708		break;
5709	}
5710	default:
5711		path_put(&path);
5712		return -EOPNOTSUPP;
5713	}
5714	rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
5715			      rsp, work->response_buf);
5716	path_put(&path);
5717
5718	if (!rc)
5719		rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
5720				offsetof(struct smb2_query_info_rsp, Buffer) +
5721				le32_to_cpu(rsp->OutputBufferLength));
5722	return rc;
5723}
5724
5725static int smb2_get_info_sec(struct ksmbd_work *work,
5726			     struct smb2_query_info_req *req,
5727			     struct smb2_query_info_rsp *rsp)
5728{
5729	struct ksmbd_file *fp;
5730	struct mnt_idmap *idmap;
5731	struct smb_ntsd *pntsd = NULL, *ppntsd = NULL;
5732	struct smb_fattr fattr = {{0}};
5733	struct inode *inode;
5734	__u32 secdesclen = 0;
5735	unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
5736	int addition_info = le32_to_cpu(req->AdditionalInformation);
5737	int rc = 0, ppntsd_size = 0, max_len;
5738	size_t scratch_len = 0;
5739
5740	if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO |
5741			      PROTECTED_DACL_SECINFO |
5742			      UNPROTECTED_DACL_SECINFO)) {
5743		ksmbd_debug(SMB, "Unsupported addition info: 0x%x)\n",
5744		       addition_info);
5745
5746		pntsd = kzalloc(ALIGN(sizeof(struct smb_ntsd), 8),
5747				KSMBD_DEFAULT_GFP);
5748		if (!pntsd)
5749			return -ENOMEM;
5750
5751		pntsd->revision = cpu_to_le16(1);
5752		pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PROTECTED);
5753		pntsd->osidoffset = 0;
5754		pntsd->gsidoffset = 0;
5755		pntsd->sacloffset = 0;
5756		pntsd->dacloffset = 0;
5757
5758		secdesclen = sizeof(struct smb_ntsd);
5759		goto iov_pin;
5760	}
5761
5762	if (work->next_smb2_rcv_hdr_off) {
5763		if (!has_file_id(req->VolatileFileId)) {
5764			ksmbd_debug(SMB, "Compound request set FID = %llu\n",
5765				    work->compound_fid);
5766			id = work->compound_fid;
5767			pid = work->compound_pfid;
5768		}
5769	}
5770
5771	if (!has_file_id(id)) {
5772		id = req->VolatileFileId;
5773		pid = req->PersistentFileId;
5774	}
5775
5776	fp = ksmbd_lookup_fd_slow(work, id, pid);
5777	if (!fp)
5778		return -ENOENT;
5779
5780	idmap = file_mnt_idmap(fp->filp);
5781	inode = file_inode(fp->filp);
5782	ksmbd_acls_fattr(&fattr, idmap, inode);
5783
5784	if (test_share_config_flag(work->tcon->share_conf,
5785				   KSMBD_SHARE_FLAG_ACL_XATTR))
5786		ppntsd_size = ksmbd_vfs_get_sd_xattr(work->conn, idmap,
5787						     fp->filp->f_path.dentry,
5788						     &ppntsd);
5789
5790	/* Check if sd buffer size exceeds response buffer size */
5791	max_len = smb2_calc_max_out_buf_len(work,
5792			offsetof(struct smb2_query_info_rsp, Buffer),
5793			le32_to_cpu(req->OutputBufferLength));
5794	if (max_len < 0) {
5795		rc = -EINVAL;
5796		goto release_acl;
5797	}
5798
5799	scratch_len = smb_acl_sec_desc_scratch_len(&fattr, ppntsd,
5800			ppntsd_size, addition_info);
5801	if (!scratch_len || scratch_len == SIZE_MAX) {
5802		rc = -EFBIG;
5803		goto release_acl;
5804	}
5805
5806	pntsd = kvzalloc(scratch_len, KSMBD_DEFAULT_GFP);
5807	if (!pntsd) {
5808		rc = -ENOMEM;
5809		goto release_acl;
5810	}
5811
5812	rc = build_sec_desc(idmap, pntsd, ppntsd, ppntsd_size,
5813			addition_info, &secdesclen, &fattr);
5814
5815release_acl:
5816	posix_acl_release(fattr.cf_acls);
5817	posix_acl_release(fattr.cf_dacls);
5818	kfree(ppntsd);
5819	ksmbd_fd_put(work, fp);
5820
5821	if (!rc && ALIGN(secdesclen, 8) > scratch_len)
5822		rc = -EFBIG;
5823	if (rc)
5824		goto err_out;
5825
5826iov_pin:
5827	rsp->OutputBufferLength = cpu_to_le32(secdesclen);
5828	rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
5829			      rsp, work->response_buf);
5830	if (rc)
5831		goto err_out;
5832
5833	rc = ksmbd_iov_pin_rsp_read(work, (void *)rsp,
5834			offsetof(struct smb2_query_info_rsp, Buffer),
5835			pntsd, secdesclen);
5836err_out:
5837	if (rc) {
5838		rsp->OutputBufferLength = 0;
5839		kvfree(pntsd);
5840	}
5841
5842	return rc;
5843}
5844
5845/**
5846 * smb2_query_info() - handler for smb2 query info command
5847 * @work:	smb work containing query info request buffer
5848 *
5849 * Return:	0 on success, otherwise error
5850 */
5851int smb2_query_info(struct ksmbd_work *work)
5852{
5853	struct smb2_query_info_req *req;
5854	struct smb2_query_info_rsp *rsp;
5855	int rc = 0;
5856
5857	ksmbd_debug(SMB, "Received request smb2 query info request\n");
5858
5859	WORK_BUFFERS(work, req, rsp);
5860
5861	if (ksmbd_override_fsids(work)) {
5862		rc = -ENOMEM;
5863		goto err_out;
5864	}
5865
5866	rsp->StructureSize = cpu_to_le16(9);
5867	rsp->OutputBufferOffset = cpu_to_le16(72);
5868
5869	switch (req->InfoType) {
5870	case SMB2_O_INFO_FILE:
5871		ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILE\n");
5872		rc = smb2_get_info_file(work, req, rsp);
5873		break;
5874	case SMB2_O_INFO_FILESYSTEM:
5875		ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILESYSTEM\n");
5876		rc = smb2_get_info_filesystem(work, req, rsp);
5877		break;
5878	case SMB2_O_INFO_SECURITY:
5879		ksmbd_debug(SMB, "GOT SMB2_O_INFO_SECURITY\n");
5880		rc = smb2_get_info_sec(work, req, rsp);
5881		break;
5882	default:
5883		ksmbd_debug(SMB, "InfoType %d not supported yet\n",
5884			    req->InfoType);
5885		rc = -EOPNOTSUPP;
5886	}
5887	ksmbd_revert_fsids(work);
5888
5889err_out:
5890	if (rc < 0) {
5891		if (rc == -EACCES)
5892			rsp->hdr.Status = STATUS_ACCESS_DENIED;
5893		else if (rc == -ENOENT)
5894			rsp->hdr.Status = STATUS_FILE_CLOSED;
5895		else if (rc == -EIO)
5896			rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
5897		else if (rc == -ENOMEM)
5898			rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
5899		else if (rc == -EINVAL && rsp->hdr.Status == 0)
5900			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
5901		else if (rc == -EOPNOTSUPP || rsp->hdr.Status == 0)
5902			rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
5903		smb2_set_err_rsp(work);
5904
5905		ksmbd_debug(SMB, "error while processing smb2 query rc = %d\n",
5906			    rc);
5907		return rc;
5908	}
5909	return 0;
5910}
5911
5912/**
5913 * smb2_close_pipe() - handler for closing IPC pipe
5914 * @work:	smb work containing close request buffer
5915 *
5916 * Return:	0
5917 */
5918static noinline int smb2_close_pipe(struct ksmbd_work *work)
5919{
5920	u64 id;
5921	struct smb2_close_req *req;
5922	struct smb2_close_rsp *rsp;
5923
5924	WORK_BUFFERS(work, req, rsp);
5925
5926	id = req->VolatileFileId;
5927	ksmbd_session_rpc_close(work->sess, id);
5928
5929	rsp->StructureSize = cpu_to_le16(60);
5930	rsp->Flags = 0;
5931	rsp->Reserved = 0;
5932	rsp->CreationTime = 0;
5933	rsp->LastAccessTime = 0;
5934	rsp->LastWriteTime = 0;
5935	rsp->ChangeTime = 0;
5936	rsp->AllocationSize = 0;
5937	rsp->EndOfFile = 0;
5938	rsp->Attributes = 0;
5939
5940	return ksmbd_iov_pin_rsp(work, (void *)rsp,
5941				 sizeof(struct smb2_close_rsp));
5942}
5943
5944/**
5945 * smb2_close() - handler for smb2 close file command
5946 * @work:	smb work containing close request buffer
5947 *
5948 * Return:	0 on success, otherwise error
5949 */
5950int smb2_close(struct ksmbd_work *work)
5951{
5952	u64 volatile_id = KSMBD_NO_FID;
5953	u64 sess_id;
5954	struct smb2_close_req *req;
5955	struct smb2_close_rsp *rsp;
5956	struct ksmbd_conn *conn = work->conn;
5957	struct ksmbd_file *fp;
5958	u64 time;
5959	int err = 0;
5960
5961	ksmbd_debug(SMB, "Received smb2 close request\n");
5962
5963	WORK_BUFFERS(work, req, rsp);
5964
5965	if (test_share_config_flag(work->tcon->share_conf,
5966				   KSMBD_SHARE_FLAG_PIPE)) {
5967		ksmbd_debug(SMB, "IPC pipe close request\n");
5968		return smb2_close_pipe(work);
5969	}
5970
5971	sess_id = le64_to_cpu(req->hdr.SessionId);
5972	if (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)
5973		sess_id = work->compound_sid;
5974
5975	work->compound_sid = 0;
5976	if (check_session_id(conn, sess_id)) {
5977		work->compound_sid = sess_id;
5978	} else {
5979		rsp->hdr.Status = STATUS_USER_SESSION_DELETED;
5980		if (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)
5981			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
5982		err = -EBADF;
5983		goto out;
5984	}
5985
5986	if (work->next_smb2_rcv_hdr_off &&
5987	    !has_file_id(req->VolatileFileId)) {
5988		if (!has_file_id(work->compound_fid)) {
5989			/* file already closed, return FILE_CLOSED */
5990			ksmbd_debug(SMB, "file already closed\n");
5991			rsp->hdr.Status = STATUS_FILE_CLOSED;
5992			err = -EBADF;
5993			goto out;
5994		} else {
5995			ksmbd_debug(SMB,
5996				    "Compound request set FID = %llu:%llu\n",
5997				    work->compound_fid,
5998				    work->compound_pfid);
5999			volatile_id = work->compound_fid;
6000
6001			/* file closed, stored id is not valid anymore */
6002			work->compound_fid = KSMBD_NO_FID;
6003			work->compound_pfid = KSMBD_NO_FID;
6004		}
6005	} else {
6006		volatile_id = req->VolatileFileId;
6007	}
6008	ksmbd_debug(SMB, "volatile_id = %llu\n", volatile_id);
6009
6010	rsp->StructureSize = cpu_to_le16(60);
6011	rsp->Reserved = 0;
6012
6013	if (req->Flags == SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB) {
6014		struct kstat stat;
6015		int ret;
6016
6017		fp = ksmbd_lookup_fd_fast(work, volatile_id);
6018		if (!fp) {
6019			err = -ENOENT;
6020			goto out;
6021		}
6022
6023		ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
6024				  AT_STATX_SYNC_AS_STAT);
6025		if (ret) {
6026			ksmbd_fd_put(work, fp);
6027			goto out;
6028		}
6029
6030		rsp->Flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
6031		rsp->AllocationSize = S_ISDIR(stat.mode) ? 0 :
6032			cpu_to_le64(stat.blocks << 9);
6033		rsp->EndOfFile = cpu_to_le64(stat.size);
6034		rsp->Attributes = fp->f_ci->m_fattr;
6035		rsp->CreationTime = cpu_to_le64(fp->create_time);
6036		time = ksmbd_UnixTimeToNT(stat.atime);
6037		rsp->LastAccessTime = cpu_to_le64(time);
6038		time = ksmbd_UnixTimeToNT(stat.mtime);
6039		rsp->LastWriteTime = cpu_to_le64(time);
6040		time = ksmbd_UnixTimeToNT(stat.ctime);
6041		rsp->ChangeTime = cpu_to_le64(time);
6042		ksmbd_fd_put(work, fp);
6043	} else {
6044		rsp->Flags = 0;
6045		rsp->AllocationSize = 0;
6046		rsp->EndOfFile = 0;
6047		rsp->Attributes = 0;
6048		rsp->CreationTime = 0;
6049		rsp->LastAccessTime = 0;
6050		rsp->LastWriteTime = 0;
6051		rsp->ChangeTime = 0;
6052	}
6053
6054	err = ksmbd_close_fd(work, volatile_id);
6055out:
6056	if (!err)
6057		err = ksmbd_iov_pin_rsp(work, (void *)rsp,
6058					sizeof(struct smb2_close_rsp));
6059
6060	if (err) {
6061		if (rsp->hdr.Status == 0)
6062			rsp->hdr.Status = STATUS_FILE_CLOSED;
6063		smb2_set_err_rsp(work);
6064	}
6065
6066	return err;
6067}
6068
6069/**
6070 * smb2_echo() - handler for smb2 echo(ping) command
6071 * @work:	smb work containing echo request buffer
6072 *
6073 * Return:	0 on success, otherwise error
6074 */
6075int smb2_echo(struct ksmbd_work *work)
6076{
6077	struct smb2_echo_rsp *rsp = smb_get_msg(work->response_buf);
6078
6079	ksmbd_debug(SMB, "Received smb2 echo request\n");
6080
6081	if (work->next_smb2_rcv_hdr_off)
6082		rsp = ksmbd_resp_buf_next(work);
6083
6084	rsp->StructureSize = cpu_to_le16(4);
6085	rsp->Reserved = 0;
6086	return ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_echo_rsp));
6087}
6088
6089static int smb2_rename(struct ksmbd_work *work,
6090		       struct ksmbd_file *fp,
6091		       struct smb2_file_rename_info *file_info,
6092		       struct nls_table *local_nls)
6093{
6094	struct ksmbd_share_config *share = fp->tcon->share_conf;
6095	char *new_name = NULL;
6096	int rc, flags = 0;
6097
6098	ksmbd_debug(SMB, "setting FILE_RENAME_INFO\n");
6099	new_name = smb2_get_name(file_info->FileName,
6100				 le32_to_cpu(file_info->FileNameLength),
6101				 local_nls);
6102	if (IS_ERR(new_name))
6103		return PTR_ERR(new_name);
6104
6105	if (fp->is_posix_ctxt == false && strchr(new_name, ':')) {
6106		int s_type;
6107		char *xattr_stream_name, *stream_name = NULL;
6108		size_t xattr_stream_size;
6109		int len;
6110
6111		rc = parse_stream_name(new_name, &stream_name, &s_type);
6112		if (rc < 0)
6113			goto out;
6114
6115		len = strlen(new_name);
6116		if (len > 0 && new_name[len - 1] != '/') {
6117			pr_err("not allow base filename in rename\n");
6118			rc = -ESHARE;
6119			goto out;
6120		}
6121
6122		rc = ksmbd_vfs_xattr_stream_name(stream_name,
6123						 &xattr_stream_name,
6124						 &xattr_stream_size,
6125						 s_type);
6126		if (rc)
6127			goto out;
6128
6129		rc = ksmbd_vfs_setxattr(file_mnt_idmap(fp->filp),
6130					&fp->filp->f_path,
6131					xattr_stream_name,
6132					NULL, 0, 0, true);
6133		if (rc < 0) {
6134			pr_err("failed to store stream name in xattr: %d\n",
6135			       rc);
6136			rc = -EINVAL;
6137			goto out;
6138		}
6139
6140		goto out;
6141	}
6142
6143	ksmbd_debug(SMB, "new name %s\n", new_name);
6144	if (ksmbd_share_veto_filename(share, new_name)) {
6145		rc = -ENOENT;
6146		ksmbd_debug(SMB, "Can't rename vetoed file: %s\n", new_name);
6147		goto out;
6148	}
6149
6150	if (!file_info->ReplaceIfExists)
6151		flags = RENAME_NOREPLACE;
6152
6153	rc = ksmbd_vfs_rename(work, &fp->filp->f_path, new_name, flags);
6154	if (!rc)
6155		smb_break_all_levII_oplock(work, fp, 0);
6156out:
6157	kfree(new_name);
6158	return rc;
6159}
6160
6161static int smb2_create_link(struct ksmbd_work *work,
6162			    struct ksmbd_share_config *share,
6163			    struct smb2_file_link_info *file_info,
6164			    unsigned int buf_len, struct file *filp,
6165			    struct nls_table *local_nls)
6166{
6167	char *link_name = NULL, *target_name = NULL, *pathname = NULL;
6168	struct path path;
6169	int rc;
6170
6171	if (buf_len < (u64)sizeof(struct smb2_file_link_info) +
6172			le32_to_cpu(file_info->FileNameLength))
6173		return -EINVAL;
6174
6175	ksmbd_debug(SMB, "setting FILE_LINK_INFORMATION\n");
6176	pathname = kmalloc(PATH_MAX, KSMBD_DEFAULT_GFP);
6177	if (!pathname)
6178		return -ENOMEM;
6179
6180	link_name = smb2_get_name(file_info->FileName,
6181				  le32_to_cpu(file_info->FileNameLength),
6182				  local_nls);
6183	if (IS_ERR(link_name) || S_ISDIR(file_inode(filp)->i_mode)) {
6184		rc = -EINVAL;
6185		goto out;
6186	}
6187
6188	ksmbd_debug(SMB, "link name is %s\n", link_name);
6189	target_name = file_path(filp, pathname, PATH_MAX);
6190	if (IS_ERR(target_name)) {
6191		rc = -EINVAL;
6192		goto out;
6193	}
6194
6195	ksmbd_debug(SMB, "target name is %s\n", target_name);
6196	rc = ksmbd_vfs_kern_path_start_removing(work, link_name, LOOKUP_NO_SYMLINKS,
6197						&path, 0);
6198	if (rc) {
6199		if (rc != -ENOENT)
6200			goto out;
6201	} else {
6202		if (file_info->ReplaceIfExists) {
6203			rc = ksmbd_vfs_remove_file(work, &path);
6204			if (rc) {
6205				rc = -EINVAL;
6206				ksmbd_debug(SMB, "cannot delete %s\n",
6207					    link_name);
6208			}
6209		} else {
6210			rc = -EEXIST;
6211			ksmbd_debug(SMB, "link already exists\n");
6212		}
6213		ksmbd_vfs_kern_path_end_removing(&path);
6214		if (rc)
6215			goto out;
6216	}
6217	rc = ksmbd_vfs_link(work, target_name, link_name);
6218	if (rc)
6219		rc = -EINVAL;
6220out:
6221
6222	if (!IS_ERR(link_name))
6223		kfree(link_name);
6224	kfree(pathname);
6225	return rc;
6226}
6227
6228static int set_file_basic_info(struct ksmbd_file *fp,
6229			       struct smb2_file_basic_info *file_info,
6230			       struct ksmbd_share_config *share)
6231{
6232	struct iattr attrs;
6233	struct file *filp;
6234	struct inode *inode;
6235	struct mnt_idmap *idmap;
6236	int rc = 0;
6237
6238	if (!(fp->daccess & FILE_WRITE_ATTRIBUTES_LE))
6239		return -EACCES;
6240
6241	attrs.ia_valid = 0;
6242	filp = fp->filp;
6243	inode = file_inode(filp);
6244	idmap = file_mnt_idmap(filp);
6245
6246	if (file_info->CreationTime)
6247		fp->create_time = le64_to_cpu(file_info->CreationTime);
6248
6249	if (file_info->LastAccessTime) {
6250		attrs.ia_atime = ksmbd_NTtimeToUnix(file_info->LastAccessTime);
6251		attrs.ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
6252	}
6253
6254	if (file_info->ChangeTime)
6255		inode_set_ctime_to_ts(inode,
6256				ksmbd_NTtimeToUnix(file_info->ChangeTime));
6257
6258	if (file_info->LastWriteTime) {
6259		attrs.ia_mtime = ksmbd_NTtimeToUnix(file_info->LastWriteTime);
6260		attrs.ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET | ATTR_CTIME);
6261	}
6262
6263	if (file_info->Attributes) {
6264		if (!S_ISDIR(inode->i_mode) &&
6265		    file_info->Attributes & FILE_ATTRIBUTE_DIRECTORY_LE) {
6266			pr_err("can't change a file to a directory\n");
6267			return -EINVAL;
6268		}
6269
6270		if (!(S_ISDIR(inode->i_mode) && file_info->Attributes == FILE_ATTRIBUTE_NORMAL_LE))
6271			fp->f_ci->m_fattr = file_info->Attributes |
6272				(fp->f_ci->m_fattr & FILE_ATTRIBUTE_DIRECTORY_LE);
6273	}
6274
6275	if (test_share_config_flag(share, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS) &&
6276	    (file_info->CreationTime || file_info->Attributes)) {
6277		struct xattr_dos_attrib da = {0};
6278
6279		da.version = 4;
6280		da.itime = fp->itime;
6281		da.create_time = fp->create_time;
6282		da.attr = le32_to_cpu(fp->f_ci->m_fattr);
6283		da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
6284			XATTR_DOSINFO_ITIME;
6285
6286		rc = ksmbd_vfs_set_dos_attrib_xattr(idmap, &filp->f_path, &da,
6287				true);
6288		if (rc)
6289			ksmbd_debug(SMB,
6290				    "failed to restore file attribute in EA\n");
6291		rc = 0;
6292	}
6293
6294	if (attrs.ia_valid) {
6295		struct dentry *dentry = filp->f_path.dentry;
6296		struct inode *inode = d_inode(dentry);
6297
6298		if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
6299			return -EACCES;
6300
6301		inode_lock(inode);
6302		rc = notify_change(idmap, dentry, &attrs, NULL);
6303		inode_unlock(inode);
6304	}
6305	return rc;
6306}
6307
6308static int set_file_allocation_info(struct ksmbd_work *work,
6309				    struct ksmbd_file *fp,
6310				    struct smb2_file_alloc_info *file_alloc_info)
6311{
6312	/*
6313	 * TODO : It's working fine only when store dos attributes
6314	 * is not yes. need to implement a logic which works
6315	 * properly with any smb.conf option
6316	 */
6317
6318	loff_t alloc_blks;
6319	struct inode *inode;
6320	struct kstat stat;
6321	int rc;
6322
6323	if (!(fp->daccess & FILE_WRITE_DATA_LE))
6324		return -EACCES;
6325
6326	if (ksmbd_stream_fd(fp) == true)
6327		return 0;
6328
6329	rc = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
6330			 AT_STATX_SYNC_AS_STAT);
6331	if (rc)
6332		return rc;
6333
6334	alloc_blks = (le64_to_cpu(file_alloc_info->AllocationSize) + 511) >> 9;
6335	inode = file_inode(fp->filp);
6336
6337	if (alloc_blks > stat.blocks) {
6338		smb_break_all_levII_oplock(work, fp, 1);
6339		rc = vfs_fallocate(fp->filp, FALLOC_FL_KEEP_SIZE, 0,
6340				   alloc_blks * 512);
6341		if (rc && rc != -EOPNOTSUPP) {
6342			pr_err("vfs_fallocate is failed : %d\n", rc);
6343			return rc;
6344		}
6345	} else if (alloc_blks < stat.blocks) {
6346		loff_t size;
6347
6348		/*
6349		 * Allocation size could be smaller than original one
6350		 * which means allocated blocks in file should be
6351		 * deallocated. use truncate to cut out it, but inode
6352		 * size is also updated with truncate offset.
6353		 * inode size is retained by backup inode size.
6354		 */
6355		size = i_size_read(inode);
6356		rc = ksmbd_vfs_truncate(work, fp, alloc_blks * 512);
6357		if (rc) {
6358			pr_err("truncate failed!, err %d\n", rc);
6359			return rc;
6360		}
6361		if (size < alloc_blks * 512)
6362			i_size_write(inode, size);
6363	}
6364	return 0;
6365}
6366
6367static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
6368				struct smb2_file_eof_info *file_eof_info)
6369{
6370	loff_t newsize;
6371	struct inode *inode;
6372	int rc;
6373
6374	if (!(fp->daccess & FILE_WRITE_DATA_LE))
6375		return -EACCES;
6376
6377	newsize = le64_to_cpu(file_eof_info->EndOfFile);
6378	inode = file_inode(fp->filp);
6379
6380	/*
6381	 * If FILE_END_OF_FILE_INFORMATION of set_info_file is called
6382	 * on FAT32 shared device, truncate execution time is too long
6383	 * and network error could cause from windows client. because
6384	 * truncate of some filesystem like FAT32 fill zero data in
6385	 * truncated range.
6386	 */
6387	if (inode->i_sb->s_magic != MSDOS_SUPER_MAGIC &&
6388	    ksmbd_stream_fd(fp) == false) {
6389		ksmbd_debug(SMB, "truncated to newsize %lld\n", newsize);
6390		rc = ksmbd_vfs_truncate(work, fp, newsize);
6391		if (rc) {
6392			ksmbd_debug(SMB, "truncate failed!, err %d\n", rc);
6393			if (rc != -EAGAIN)
6394				rc = -EBADF;
6395			return rc;
6396		}
6397	}
6398	return 0;
6399}
6400
6401static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
6402			   struct smb2_file_rename_info *rename_info,
6403			   unsigned int buf_len)
6404{
6405	if (!(fp->daccess & FILE_DELETE_LE)) {
6406		pr_err("no right to delete : 0x%x\n", fp->daccess);
6407		return -EACCES;
6408	}
6409
6410	if (buf_len < (u64)sizeof(struct smb2_file_rename_info) +
6411			le32_to_cpu(rename_info->FileNameLength))
6412		return -EINVAL;
6413
6414	if (!le32_to_cpu(rename_info->FileNameLength))
6415		return -EINVAL;
6416
6417	return smb2_rename(work, fp, rename_info, work->conn->local_nls);
6418}
6419
6420static int set_file_disposition_info(struct ksmbd_file *fp,
6421				     struct smb2_file_disposition_info *file_info)
6422{
6423	struct inode *inode;
6424
6425	if (!(fp->daccess & FILE_DELETE_LE)) {
6426		pr_err("no right to delete : 0x%x\n", fp->daccess);
6427		return -EACCES;
6428	}
6429
6430	inode = file_inode(fp->filp);
6431	if (file_info->DeletePending) {
6432		if (S_ISDIR(inode->i_mode) &&
6433		    ksmbd_vfs_empty_dir(fp) == -ENOTEMPTY)
6434			return -EBUSY;
6435		ksmbd_set_inode_pending_delete(fp);
6436	} else {
6437		ksmbd_clear_inode_pending_delete(fp);
6438	}
6439	return 0;
6440}
6441
6442static int set_file_position_info(struct ksmbd_file *fp,
6443				  struct smb2_file_pos_info *file_info)
6444{
6445	loff_t current_byte_offset;
6446	unsigned long sector_size;
6447	struct inode *inode;
6448
6449	inode = file_inode(fp->filp);
6450	current_byte_offset = le64_to_cpu(file_info->CurrentByteOffset);
6451	sector_size = inode->i_sb->s_blocksize;
6452
6453	if (current_byte_offset < 0 ||
6454	    (fp->coption == FILE_NO_INTERMEDIATE_BUFFERING_LE &&
6455	     current_byte_offset & (sector_size - 1))) {
6456		pr_err("CurrentByteOffset is not valid : %llu\n",
6457		       current_byte_offset);
6458		return -EINVAL;
6459	}
6460
6461	if (ksmbd_stream_fd(fp) == false)
6462		fp->filp->f_pos = current_byte_offset;
6463	else {
6464		if (current_byte_offset > XATTR_SIZE_MAX)
6465			current_byte_offset = XATTR_SIZE_MAX;
6466		fp->stream.pos = current_byte_offset;
6467	}
6468	return 0;
6469}
6470
6471static int set_file_mode_info(struct ksmbd_file *fp,
6472			      struct smb2_file_mode_info *file_info)
6473{
6474	__le32 mode;
6475
6476	mode = file_info->Mode;
6477
6478	if ((mode & ~FILE_MODE_INFO_MASK)) {
6479		pr_err("Mode is not valid : 0x%x\n", le32_to_cpu(mode));
6480		return -EINVAL;
6481	}
6482
6483	/*
6484	 * TODO : need to implement consideration for
6485	 * FILE_SYNCHRONOUS_IO_ALERT and FILE_SYNCHRONOUS_IO_NONALERT
6486	 */
6487	ksmbd_vfs_set_fadvise(fp->filp, mode);
6488	fp->coption = mode;
6489	return 0;
6490}
6491
6492/**
6493 * smb2_set_info_file() - handler for smb2 set info command
6494 * @work:	smb work containing set info command buffer
6495 * @fp:		ksmbd_file pointer
6496 * @req:	request buffer pointer
6497 * @share:	ksmbd_share_config pointer
6498 *
6499 * Return:	0 on success, otherwise error
6500 */
6501static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
6502			      struct smb2_set_info_req *req,
6503			      struct ksmbd_share_config *share)
6504{
6505	unsigned int buf_len = le32_to_cpu(req->BufferLength);
6506	char *buffer = (char *)req + le16_to_cpu(req->BufferOffset);
6507
6508	switch (req->FileInfoClass) {
6509	case FILE_BASIC_INFORMATION:
6510	{
6511		if (buf_len < sizeof(struct smb2_file_basic_info))
6512			return -EMSGSIZE;
6513
6514		return set_file_basic_info(fp, (struct smb2_file_basic_info *)buffer, share);
6515	}
6516	case FILE_ALLOCATION_INFORMATION:
6517	{
6518		if (buf_len < sizeof(struct smb2_file_alloc_info))
6519			return -EMSGSIZE;
6520
6521		return set_file_allocation_info(work, fp,
6522						(struct smb2_file_alloc_info *)buffer);
6523	}
6524	case FILE_END_OF_FILE_INFORMATION:
6525	{
6526		if (buf_len < sizeof(struct smb2_file_eof_info))
6527			return -EMSGSIZE;
6528
6529		return set_end_of_file_info(work, fp,
6530					    (struct smb2_file_eof_info *)buffer);
6531	}
6532	case FILE_RENAME_INFORMATION:
6533	{
6534		if (buf_len < sizeof(struct smb2_file_rename_info))
6535			return -EMSGSIZE;
6536
6537		return set_rename_info(work, fp,
6538				       (struct smb2_file_rename_info *)buffer,
6539				       buf_len);
6540	}
6541	case FILE_LINK_INFORMATION:
6542	{
6543		if (buf_len < sizeof(struct smb2_file_link_info))
6544			return -EMSGSIZE;
6545
6546		return smb2_create_link(work, work->tcon->share_conf,
6547					(struct smb2_file_link_info *)buffer,
6548					buf_len, fp->filp,
6549					work->conn->local_nls);
6550	}
6551	case FILE_DISPOSITION_INFORMATION:
6552	{
6553		if (buf_len < sizeof(struct smb2_file_disposition_info))
6554			return -EMSGSIZE;
6555
6556		return set_file_disposition_info(fp,
6557						 (struct smb2_file_disposition_info *)buffer);
6558	}
6559	case FILE_FULL_EA_INFORMATION:
6560	{
6561		if (!(fp->daccess & FILE_WRITE_EA_LE)) {
6562			pr_err("Not permitted to write ext  attr: 0x%x\n",
6563			       fp->daccess);
6564			return -EACCES;
6565		}
6566
6567		if (buf_len < sizeof(struct smb2_ea_info))
6568			return -EMSGSIZE;
6569
6570		return smb2_set_ea((struct smb2_ea_info *)buffer,
6571				   buf_len, &fp->filp->f_path, true);
6572	}
6573	case FILE_POSITION_INFORMATION:
6574	{
6575		if (buf_len < sizeof(struct smb2_file_pos_info))
6576			return -EMSGSIZE;
6577
6578		return set_file_position_info(fp, (struct smb2_file_pos_info *)buffer);
6579	}
6580	case FILE_MODE_INFORMATION:
6581	{
6582		if (buf_len < sizeof(struct smb2_file_mode_info))
6583			return -EMSGSIZE;
6584
6585		return set_file_mode_info(fp, (struct smb2_file_mode_info *)buffer);
6586	}
6587	}
6588
6589	pr_err("Unimplemented Fileinfoclass :%d\n", req->FileInfoClass);
6590	return -EOPNOTSUPP;
6591}
6592
6593static int smb2_set_info_sec(struct ksmbd_file *fp, int addition_info,
6594			     char *buffer, int buf_len)
6595{
6596	struct smb_ntsd *pntsd = (struct smb_ntsd *)buffer;
6597
6598	fp->saccess |= FILE_SHARE_DELETE_LE;
6599
6600	return set_info_sec(fp->conn, fp->tcon, &fp->filp->f_path, pntsd,
6601			buf_len, false, true);
6602}
6603
6604/**
6605 * smb2_set_info() - handler for smb2 set info command handler
6606 * @work:	smb work containing set info request buffer
6607 *
6608 * Return:	0 on success, otherwise error
6609 */
6610int smb2_set_info(struct ksmbd_work *work)
6611{
6612	struct smb2_set_info_req *req;
6613	struct smb2_set_info_rsp *rsp;
6614	struct ksmbd_file *fp = NULL;
6615	int rc = 0;
6616	unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
6617
6618	ksmbd_debug(SMB, "Received smb2 set info request\n");
6619
6620	if (work->next_smb2_rcv_hdr_off) {
6621		req = ksmbd_req_buf_next(work);
6622		rsp = ksmbd_resp_buf_next(work);
6623		if (!has_file_id(req->VolatileFileId)) {
6624			ksmbd_debug(SMB, "Compound request set FID = %llu\n",
6625				    work->compound_fid);
6626			id = work->compound_fid;
6627			pid = work->compound_pfid;
6628		}
6629	} else {
6630		req = smb_get_msg(work->request_buf);
6631		rsp = smb_get_msg(work->response_buf);
6632	}
6633
6634	if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
6635		ksmbd_debug(SMB, "User does not have write permission\n");
6636		pr_err("User does not have write permission\n");
6637		rc = -EACCES;
6638		goto err_out;
6639	}
6640
6641	if (!has_file_id(id)) {
6642		id = req->VolatileFileId;
6643		pid = req->PersistentFileId;
6644	}
6645
6646	fp = ksmbd_lookup_fd_slow(work, id, pid);
6647	if (!fp) {
6648		ksmbd_debug(SMB, "Invalid id for close: %u\n", id);
6649		rc = -ENOENT;
6650		goto err_out;
6651	}
6652
6653	switch (req->InfoType) {
6654	case SMB2_O_INFO_FILE:
6655		ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILE\n");
6656		rc = smb2_set_info_file(work, fp, req, work->tcon->share_conf);
6657		break;
6658	case SMB2_O_INFO_SECURITY:
6659		ksmbd_debug(SMB, "GOT SMB2_O_INFO_SECURITY\n");
6660		if (ksmbd_override_fsids(work)) {
6661			rc = -ENOMEM;
6662			goto err_out;
6663		}
6664		rc = smb2_set_info_sec(fp,
6665				       le32_to_cpu(req->AdditionalInformation),
6666				       (char *)req + le16_to_cpu(req->BufferOffset),
6667				       le32_to_cpu(req->BufferLength));
6668		ksmbd_revert_fsids(work);
6669		break;
6670	default:
6671		rc = -EOPNOTSUPP;
6672	}
6673
6674	if (rc < 0)
6675		goto err_out;
6676
6677	rsp->StructureSize = cpu_to_le16(2);
6678	rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
6679			       sizeof(struct smb2_set_info_rsp));
6680	if (rc)
6681		goto err_out;
6682	ksmbd_fd_put(work, fp);
6683	return 0;
6684
6685err_out:
6686	if (rc == -EACCES || rc == -EPERM || rc == -EXDEV)
6687		rsp->hdr.Status = STATUS_ACCESS_DENIED;
6688	else if (rc == -EINVAL)
6689		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6690	else if (rc == -EMSGSIZE)
6691		rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH;
6692	else if (rc == -ESHARE)
6693		rsp->hdr.Status = STATUS_SHARING_VIOLATION;
6694	else if (rc == -ENOENT)
6695		rsp->hdr.Status = STATUS_OBJECT_NAME_INVALID;
6696	else if (rc == -EBUSY || rc == -ENOTEMPTY)
6697		rsp->hdr.Status = STATUS_DIRECTORY_NOT_EMPTY;
6698	else if (rc == -EAGAIN)
6699		rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
6700	else if (rc == -EBADF || rc == -ESTALE)
6701		rsp->hdr.Status = STATUS_INVALID_HANDLE;
6702	else if (rc == -EEXIST)
6703		rsp->hdr.Status = STATUS_OBJECT_NAME_COLLISION;
6704	else if (rsp->hdr.Status == 0 || rc == -EOPNOTSUPP)
6705		rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
6706	smb2_set_err_rsp(work);
6707	ksmbd_fd_put(work, fp);
6708	ksmbd_debug(SMB, "error while processing smb2 query rc = %d\n", rc);
6709	return rc;
6710}
6711
6712/**
6713 * smb2_read_pipe() - handler for smb2 read from IPC pipe
6714 * @work:	smb work containing read IPC pipe command buffer
6715 *
6716 * Return:	0 on success, otherwise error
6717 */
6718static noinline int smb2_read_pipe(struct ksmbd_work *work)
6719{
6720	int nbytes = 0, err;
6721	u64 id;
6722	struct ksmbd_rpc_command *rpc_resp;
6723	struct smb2_read_req *req;
6724	struct smb2_read_rsp *rsp;
6725
6726	WORK_BUFFERS(work, req, rsp);
6727
6728	id = req->VolatileFileId;
6729
6730	rpc_resp = ksmbd_rpc_read(work->sess, id);
6731	if (rpc_resp) {
6732		void *aux_payload_buf;
6733
6734		if (rpc_resp->flags != KSMBD_RPC_OK) {
6735			err = -EINVAL;
6736			goto out;
6737		}
6738
6739		aux_payload_buf =
6740			kvmalloc(rpc_resp->payload_sz, KSMBD_DEFAULT_GFP);
6741		if (!aux_payload_buf) {
6742			err = -ENOMEM;
6743			goto out;
6744		}
6745
6746		memcpy(aux_payload_buf, rpc_resp->payload, rpc_resp->payload_sz);
6747
6748		nbytes = rpc_resp->payload_sz;
6749		err = ksmbd_iov_pin_rsp_read(work, (void *)rsp,
6750					     offsetof(struct smb2_read_rsp, Buffer),
6751					     aux_payload_buf, nbytes);
6752		if (err) {
6753			kvfree(aux_payload_buf);
6754			goto out;
6755		}
6756		kvfree(rpc_resp);
6757	} else {
6758		err = ksmbd_iov_pin_rsp(work, (void *)rsp,
6759					offsetof(struct smb2_read_rsp, Buffer));
6760		if (err)
6761			goto out;
6762	}
6763
6764	rsp->StructureSize = cpu_to_le16(17);
6765	rsp->DataOffset = 80;
6766	rsp->Reserved = 0;
6767	rsp->DataLength = cpu_to_le32(nbytes);
6768	rsp->DataRemaining = 0;
6769	rsp->Flags = 0;
6770	return 0;
6771
6772out:
6773	rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
6774	smb2_set_err_rsp(work);
6775	kvfree(rpc_resp);
6776	return err;
6777}
6778
6779static int smb2_set_remote_key_for_rdma(struct ksmbd_work *work,
6780					struct smbdirect_buffer_descriptor_v1 *desc,
6781					__le32 Channel,
6782					__le16 ChannelInfoLength)
6783{
6784	unsigned int i, ch_count;
6785
6786	if (work->conn->dialect == SMB30_PROT_ID &&
6787	    Channel != SMB2_CHANNEL_RDMA_V1)
6788		return -EINVAL;
6789
6790	ch_count = le16_to_cpu(ChannelInfoLength) / sizeof(*desc);
6791	if (ksmbd_debug_types & KSMBD_DEBUG_RDMA) {
6792		for (i = 0; i < ch_count; i++) {
6793			pr_info("RDMA r/w request %#x: token %#x, length %#x\n",
6794				i,
6795				le32_to_cpu(desc[i].token),
6796				le32_to_cpu(desc[i].length));
6797		}
6798	}
6799	if (!ch_count)
6800		return -EINVAL;
6801
6802	work->need_invalidate_rkey =
6803		(Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE);
6804	if (Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE)
6805		work->remote_key = le32_to_cpu(desc->token);
6806	return 0;
6807}
6808
6809static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work,
6810				      struct smb2_read_req *req, void *data_buf,
6811				      size_t length)
6812{
6813	int err;
6814
6815	err = ksmbd_conn_rdma_write(work->conn, data_buf, length,
6816				    (struct smbdirect_buffer_descriptor_v1 *)
6817				    ((char *)req + le16_to_cpu(req->ReadChannelInfoOffset)),
6818				    le16_to_cpu(req->ReadChannelInfoLength));
6819	if (err)
6820		return err;
6821
6822	return length;
6823}
6824
6825/**
6826 * smb2_read() - handler for smb2 read from file
6827 * @work:	smb work containing read command buffer
6828 *
6829 * Return:	0 on success, otherwise error
6830 */
6831int smb2_read(struct ksmbd_work *work)
6832{
6833	struct ksmbd_conn *conn = work->conn;
6834	struct smb2_read_req *req;
6835	struct smb2_read_rsp *rsp;
6836	struct ksmbd_file *fp = NULL;
6837	loff_t offset;
6838	size_t length, mincount;
6839	ssize_t nbytes = 0, remain_bytes = 0;
6840	int err = 0;
6841	bool is_rdma_channel = false;
6842	unsigned int max_read_size = conn->vals->max_read_size;
6843	unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
6844	void *aux_payload_buf;
6845
6846	ksmbd_debug(SMB, "Received smb2 read request\n");
6847
6848	if (test_share_config_flag(work->tcon->share_conf,
6849				   KSMBD_SHARE_FLAG_PIPE)) {
6850		ksmbd_debug(SMB, "IPC pipe read request\n");
6851		return smb2_read_pipe(work);
6852	}
6853
6854	if (work->next_smb2_rcv_hdr_off) {
6855		req = ksmbd_req_buf_next(work);
6856		rsp = ksmbd_resp_buf_next(work);
6857		if (!has_file_id(req->VolatileFileId)) {
6858			ksmbd_debug(SMB, "Compound request set FID = %llu\n",
6859					work->compound_fid);
6860			id = work->compound_fid;
6861			pid = work->compound_pfid;
6862		}
6863	} else {
6864		req = smb_get_msg(work->request_buf);
6865		rsp = smb_get_msg(work->response_buf);
6866	}
6867
6868	if (!has_file_id(id)) {
6869		id = req->VolatileFileId;
6870		pid = req->PersistentFileId;
6871	}
6872
6873	if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE ||
6874	    req->Channel == SMB2_CHANNEL_RDMA_V1) {
6875		is_rdma_channel = true;
6876		max_read_size = get_smbd_max_read_write_size(work->conn->transport);
6877		if (max_read_size == 0) {
6878			err = -EINVAL;
6879			goto out;
6880		}
6881	}
6882
6883	if (is_rdma_channel == true) {
6884		unsigned int ch_offset = le16_to_cpu(req->ReadChannelInfoOffset);
6885
6886		if (ch_offset < offsetof(struct smb2_read_req, Buffer)) {
6887			err = -EINVAL;
6888			goto out;
6889		}
6890		err = smb2_set_remote_key_for_rdma(work,
6891						   (struct smbdirect_buffer_descriptor_v1 *)
6892						   ((char *)req + ch_offset),
6893						   req->Channel,
6894						   req->ReadChannelInfoLength);
6895		if (err)
6896			goto out;
6897	}
6898
6899	fp = ksmbd_lookup_fd_slow(work, id, pid);
6900	if (!fp) {
6901		err = -ENOENT;
6902		goto out;
6903	}
6904
6905	if (!(fp->daccess & (FILE_READ_DATA_LE | FILE_READ_ATTRIBUTES_LE))) {
6906		pr_err("Not permitted to read : 0x%x\n", fp->daccess);
6907		err = -EACCES;
6908		goto out;
6909	}
6910
6911	offset = le64_to_cpu(req->Offset);
6912	if (offset < 0) {
6913		err = -EINVAL;
6914		goto out;
6915	}
6916	length = le32_to_cpu(req->Length);
6917	mincount = le32_to_cpu(req->MinimumCount);
6918
6919	if (length > max_read_size) {
6920		ksmbd_debug(SMB, "limiting read size to max size(%u)\n",
6921			    max_read_size);
6922		err = -EINVAL;
6923		goto out;
6924	}
6925
6926	ksmbd_debug(SMB, "filename %pD, offset %lld, len %zu\n",
6927		    fp->filp, offset, length);
6928
6929	aux_payload_buf = kvzalloc(ALIGN(length, 8), KSMBD_DEFAULT_GFP);
6930	if (!aux_payload_buf) {
6931		err = -ENOMEM;
6932		goto out;
6933	}
6934
6935	nbytes = ksmbd_vfs_read(work, fp, length, &offset, aux_payload_buf);
6936	if (nbytes < 0) {
6937		kvfree(aux_payload_buf);
6938		err = nbytes;
6939		goto out;
6940	}
6941
6942	if ((nbytes == 0 && length != 0) || nbytes < mincount) {
6943		kvfree(aux_payload_buf);
6944		rsp->hdr.Status = STATUS_END_OF_FILE;
6945		smb2_set_err_rsp(work);
6946		ksmbd_fd_put(work, fp);
6947		return -ENODATA;
6948	}
6949
6950	ksmbd_debug(SMB, "nbytes %zu, offset %lld mincount %zu\n",
6951		    nbytes, offset, mincount);
6952
6953	if (is_rdma_channel == true) {
6954		/* write data to the client using rdma channel */
6955		remain_bytes = smb2_read_rdma_channel(work, req,
6956						      aux_payload_buf,
6957						      nbytes);
6958		kvfree(aux_payload_buf);
6959		aux_payload_buf = NULL;
6960		nbytes = 0;
6961		if (remain_bytes < 0) {
6962			err = (int)remain_bytes;
6963			goto out;
6964		}
6965	}
6966
6967	rsp->StructureSize = cpu_to_le16(17);
6968	rsp->DataOffset = 80;
6969	rsp->Reserved = 0;
6970	rsp->DataLength = cpu_to_le32(nbytes);
6971	rsp->DataRemaining = cpu_to_le32(remain_bytes);
6972	rsp->Flags = 0;
6973	err = ksmbd_iov_pin_rsp_read(work, (void *)rsp,
6974				     offsetof(struct smb2_read_rsp, Buffer),
6975				     aux_payload_buf, nbytes);
6976	if (err) {
6977		kvfree(aux_payload_buf);
6978		goto out;
6979	}
6980	ksmbd_fd_put(work, fp);
6981	return 0;
6982
6983out:
6984	if (err) {
6985		if (err == -EISDIR)
6986			rsp->hdr.Status = STATUS_INVALID_DEVICE_REQUEST;
6987		else if (err == -EAGAIN)
6988			rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
6989		else if (err == -ENOENT)
6990			rsp->hdr.Status = STATUS_FILE_CLOSED;
6991		else if (err == -EACCES)
6992			rsp->hdr.Status = STATUS_ACCESS_DENIED;
6993		else if (err == -ESHARE)
6994			rsp->hdr.Status = STATUS_SHARING_VIOLATION;
6995		else if (err == -EINVAL)
6996			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
6997		else
6998			rsp->hdr.Status = STATUS_INVALID_HANDLE;
6999
7000		smb2_set_err_rsp(work);
7001	}
7002	ksmbd_fd_put(work, fp);
7003	return err;
7004}
7005
7006/**
7007 * smb2_write_pipe() - handler for smb2 write on IPC pipe
7008 * @work:	smb work containing write IPC pipe command buffer
7009 *
7010 * Return:	0 on success, otherwise error
7011 */
7012static noinline int smb2_write_pipe(struct ksmbd_work *work)
7013{
7014	struct smb2_write_req *req;
7015	struct smb2_write_rsp *rsp;
7016	struct ksmbd_rpc_command *rpc_resp;
7017	u64 id = 0;
7018	int err = 0, ret = 0;
7019	char *data_buf;
7020	size_t length;
7021
7022	WORK_BUFFERS(work, req, rsp);
7023
7024	length = le32_to_cpu(req->Length);
7025	id = req->VolatileFileId;
7026
7027	if ((u64)le16_to_cpu(req->DataOffset) + length >
7028	    get_rfc1002_len(work->request_buf)) {
7029		pr_err("invalid write data offset %u, smb_len %u\n",
7030		       le16_to_cpu(req->DataOffset),
7031		       get_rfc1002_len(work->request_buf));
7032		err = -EINVAL;
7033		goto out;
7034	}
7035
7036	data_buf = (char *)(((char *)&req->hdr.ProtocolId) +
7037			   le16_to_cpu(req->DataOffset));
7038
7039	rpc_resp = ksmbd_rpc_write(work->sess, id, data_buf, length);
7040	if (rpc_resp) {
7041		if (rpc_resp->flags == KSMBD_RPC_ENOTIMPLEMENTED) {
7042			rsp->hdr.Status = STATUS_NOT_SUPPORTED;
7043			kvfree(rpc_resp);
7044			smb2_set_err_rsp(work);
7045			return -EOPNOTSUPP;
7046		}
7047		if (rpc_resp->flags != KSMBD_RPC_OK) {
7048			rsp->hdr.Status = STATUS_INVALID_HANDLE;
7049			smb2_set_err_rsp(work);
7050			kvfree(rpc_resp);
7051			return ret;
7052		}
7053		kvfree(rpc_resp);
7054	}
7055
7056	rsp->StructureSize = cpu_to_le16(17);
7057	rsp->DataOffset = 0;
7058	rsp->Reserved = 0;
7059	rsp->DataLength = cpu_to_le32(length);
7060	rsp->DataRemaining = 0;
7061	rsp->Reserved2 = 0;
7062	err = ksmbd_iov_pin_rsp(work, (void *)rsp,
7063				offsetof(struct smb2_write_rsp, Buffer));
7064out:
7065	if (err) {
7066		rsp->hdr.Status = STATUS_INVALID_HANDLE;
7067		smb2_set_err_rsp(work);
7068	}
7069
7070	return err;
7071}
7072
7073static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
7074				       struct smb2_write_req *req,
7075				       struct ksmbd_file *fp,
7076				       loff_t offset, size_t length, bool sync)
7077{
7078	char *data_buf;
7079	int ret;
7080	ssize_t nbytes;
7081
7082	data_buf = kvzalloc(length, KSMBD_DEFAULT_GFP);
7083	if (!data_buf)
7084		return -ENOMEM;
7085
7086	ret = ksmbd_conn_rdma_read(work->conn, data_buf, length,
7087				   (struct smbdirect_buffer_descriptor_v1 *)
7088				   ((char *)req + le16_to_cpu(req->WriteChannelInfoOffset)),
7089				   le16_to_cpu(req->WriteChannelInfoLength));
7090	if (ret < 0) {
7091		kvfree(data_buf);
7092		return ret;
7093	}
7094
7095	ret = ksmbd_vfs_write(work, fp, data_buf, length, &offset, sync, &nbytes);
7096	kvfree(data_buf);
7097	if (ret < 0)
7098		return ret;
7099
7100	return nbytes;
7101}
7102
7103/**
7104 * smb2_write() - handler for smb2 write from file
7105 * @work:	smb work containing write command buffer
7106 *
7107 * Return:	0 on success, otherwise error
7108 */
7109int smb2_write(struct ksmbd_work *work)
7110{
7111	struct smb2_write_req *req;
7112	struct smb2_write_rsp *rsp;
7113	struct ksmbd_file *fp = NULL;
7114	loff_t offset;
7115	size_t length;
7116	ssize_t nbytes;
7117	char *data_buf;
7118	bool writethrough = false, is_rdma_channel = false;
7119	int err = 0;
7120	unsigned int max_write_size = work->conn->vals->max_write_size;
7121
7122	ksmbd_debug(SMB, "Received smb2 write request\n");
7123
7124	WORK_BUFFERS(work, req, rsp);
7125
7126	if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_PIPE)) {
7127		ksmbd_debug(SMB, "IPC pipe write request\n");
7128		return smb2_write_pipe(work);
7129	}
7130
7131	offset = le64_to_cpu(req->Offset);
7132	if (offset < 0)
7133		return -EINVAL;
7134	length = le32_to_cpu(req->Length);
7135
7136	if (req->Channel == SMB2_CHANNEL_RDMA_V1 ||
7137	    req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE) {
7138		is_rdma_channel = true;
7139		max_write_size = get_smbd_max_read_write_size(work->conn->transport);
7140		if (max_write_size == 0) {
7141			err = -EINVAL;
7142			goto out;
7143		}
7144		length = le32_to_cpu(req->RemainingBytes);
7145	}
7146
7147	if (is_rdma_channel == true) {
7148		unsigned int ch_offset = le16_to_cpu(req->WriteChannelInfoOffset);
7149
7150		if (req->Length != 0 || req->DataOffset != 0 ||
7151		    ch_offset < offsetof(struct smb2_write_req, Buffer)) {
7152			err = -EINVAL;
7153			goto out;
7154		}
7155		err = smb2_set_remote_key_for_rdma(work,
7156						   (struct smbdirect_buffer_descriptor_v1 *)
7157						   ((char *)req + ch_offset),
7158						   req->Channel,
7159						   req->WriteChannelInfoLength);
7160		if (err)
7161			goto out;
7162	}
7163
7164	if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
7165		ksmbd_debug(SMB, "User does not have write permission\n");
7166		err = -EACCES;
7167		goto out;
7168	}
7169
7170	fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
7171	if (!fp) {
7172		err = -ENOENT;
7173		goto out;
7174	}
7175
7176	if (!(fp->daccess & (FILE_WRITE_DATA_LE | FILE_READ_ATTRIBUTES_LE))) {
7177		pr_err("Not permitted to write : 0x%x\n", fp->daccess);
7178		err = -EACCES;
7179		goto out;
7180	}
7181
7182	if (length > max_write_size) {
7183		ksmbd_debug(SMB, "limiting write size to max size(%u)\n",
7184			    max_write_size);
7185		err = -EINVAL;
7186		goto out;
7187	}
7188
7189	ksmbd_debug(SMB, "flags %u\n", le32_to_cpu(req->Flags));
7190	if (le32_to_cpu(req->Flags) & SMB2_WRITEFLAG_WRITE_THROUGH)
7191		writethrough = true;
7192
7193	if (is_rdma_channel == false) {
7194		if (le16_to_cpu(req->DataOffset) <
7195		    offsetof(struct smb2_write_req, Buffer)) {
7196			err = -EINVAL;
7197			goto out;
7198		}
7199
7200		data_buf = (char *)(((char *)&req->hdr.ProtocolId) +
7201				    le16_to_cpu(req->DataOffset));
7202
7203		ksmbd_debug(SMB, "filename %pD, offset %lld, len %zu\n",
7204			    fp->filp, offset, length);
7205		err = ksmbd_vfs_write(work, fp, data_buf, length, &offset,
7206				      writethrough, &nbytes);
7207		if (err < 0)
7208			goto out;
7209	} else {
7210		/* read data from the client using rdma channel, and
7211		 * write the data.
7212		 */
7213		nbytes = smb2_write_rdma_channel(work, req, fp, offset, length,
7214						 writethrough);
7215		if (nbytes < 0) {
7216			err = (int)nbytes;
7217			goto out;
7218		}
7219	}
7220
7221	rsp->StructureSize = cpu_to_le16(17);
7222	rsp->DataOffset = 0;
7223	rsp->Reserved = 0;
7224	rsp->DataLength = cpu_to_le32(nbytes);
7225	rsp->DataRemaining = 0;
7226	rsp->Reserved2 = 0;
7227	err = ksmbd_iov_pin_rsp(work, rsp, offsetof(struct smb2_write_rsp, Buffer));
7228	if (err)
7229		goto out;
7230	ksmbd_fd_put(work, fp);
7231	return 0;
7232
7233out:
7234	if (err == -EAGAIN)
7235		rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
7236	else if (err == -ENOSPC || err == -EFBIG)
7237		rsp->hdr.Status = STATUS_DISK_FULL;
7238	else if (err == -ENOENT)
7239		rsp->hdr.Status = STATUS_FILE_CLOSED;
7240	else if (err == -EACCES)
7241		rsp->hdr.Status = STATUS_ACCESS_DENIED;
7242	else if (err == -ESHARE)
7243		rsp->hdr.Status = STATUS_SHARING_VIOLATION;
7244	else if (err == -EINVAL)
7245		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
7246	else
7247		rsp->hdr.Status = STATUS_INVALID_HANDLE;
7248
7249	smb2_set_err_rsp(work);
7250	ksmbd_fd_put(work, fp);
7251	return err;
7252}
7253
7254/**
7255 * smb2_flush() - handler for smb2 flush file - fsync
7256 * @work:	smb work containing flush command buffer
7257 *
7258 * Return:	0 on success, otherwise error
7259 */
7260int smb2_flush(struct ksmbd_work *work)
7261{
7262	struct smb2_flush_req *req;
7263	struct smb2_flush_rsp *rsp;
7264	int err;
7265
7266	WORK_BUFFERS(work, req, rsp);
7267
7268	ksmbd_debug(SMB, "Received smb2 flush request(fid : %llu)\n", req->VolatileFileId);
7269
7270	err = ksmbd_vfs_fsync(work, req->VolatileFileId, req->PersistentFileId);
7271	if (err)
7272		goto out;
7273
7274	rsp->StructureSize = cpu_to_le16(4);
7275	rsp->Reserved = 0;
7276	return ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_flush_rsp));
7277
7278out:
7279	rsp->hdr.Status = STATUS_INVALID_HANDLE;
7280	smb2_set_err_rsp(work);
7281	return err;
7282}
7283
7284/**
7285 * smb2_cancel() - handler for smb2 cancel command
7286 * @work:	smb work containing cancel command buffer
7287 *
7288 * Return:	0 on success, otherwise error
7289 */
7290int smb2_cancel(struct ksmbd_work *work)
7291{
7292	struct ksmbd_conn *conn = work->conn;
7293	struct smb2_hdr *hdr = smb_get_msg(work->request_buf);
7294	struct smb2_hdr *chdr;
7295	struct ksmbd_work *iter;
7296	struct list_head *command_list;
7297
7298	if (work->next_smb2_rcv_hdr_off)
7299		hdr = ksmbd_resp_buf_next(work);
7300
7301	ksmbd_debug(SMB, "smb2 cancel called on mid %llu, async flags 0x%x\n",
7302		    hdr->MessageId, hdr->Flags);
7303
7304	if (hdr->Flags & SMB2_FLAGS_ASYNC_COMMAND) {
7305		command_list = &conn->async_requests;
7306
7307		spin_lock(&conn->request_lock);
7308		list_for_each_entry(iter, command_list,
7309				    async_request_entry) {
7310			chdr = smb_get_msg(iter->request_buf);
7311
7312			if (iter->async_id !=
7313			    le64_to_cpu(hdr->Id.AsyncId))
7314				continue;
7315
7316			ksmbd_debug(SMB,
7317				    "smb2 with AsyncId %llu cancelled command = 0x%x\n",
7318				    le64_to_cpu(hdr->Id.AsyncId),
7319				    le16_to_cpu(chdr->Command));
7320			iter->state = KSMBD_WORK_CANCELLED;
7321			if (iter->cancel_fn)
7322				iter->cancel_fn(iter->cancel_argv);
7323			break;
7324		}
7325		spin_unlock(&conn->request_lock);
7326	} else {
7327		command_list = &conn->requests;
7328
7329		spin_lock(&conn->request_lock);
7330		list_for_each_entry(iter, command_list, request_entry) {
7331			chdr = smb_get_msg(iter->request_buf);
7332
7333			if (chdr->MessageId != hdr->MessageId ||
7334			    iter == work)
7335				continue;
7336
7337			ksmbd_debug(SMB,
7338				    "smb2 with mid %llu cancelled command = 0x%x\n",
7339				    le64_to_cpu(hdr->MessageId),
7340				    le16_to_cpu(chdr->Command));
7341			iter->state = KSMBD_WORK_CANCELLED;
7342			break;
7343		}
7344		spin_unlock(&conn->request_lock);
7345	}
7346
7347	/* For SMB2_CANCEL command itself send no response*/
7348	work->send_no_response = 1;
7349	return 0;
7350}
7351
7352struct file_lock *smb_flock_init(struct file *f)
7353{
7354	struct file_lock *fl;
7355
7356	fl = locks_alloc_lock();
7357	if (!fl)
7358		goto out;
7359
7360	locks_init_lock(fl);
7361
7362	fl->c.flc_owner = f;
7363	fl->c.flc_pid = current->tgid;
7364	fl->c.flc_file = f;
7365	fl->c.flc_flags = FL_POSIX;
7366	fl->fl_ops = NULL;
7367	fl->fl_lmops = NULL;
7368
7369out:
7370	return fl;
7371}
7372
7373static int smb2_set_flock_flags(struct file_lock *flock, int flags)
7374{
7375	int cmd = -EINVAL;
7376
7377	/* Checking for wrong flag combination during lock request*/
7378	switch (flags) {
7379	case SMB2_LOCKFLAG_SHARED:
7380		ksmbd_debug(SMB, "received shared request\n");
7381		cmd = F_SETLKW;
7382		flock->c.flc_type = F_RDLCK;
7383		flock->c.flc_flags |= FL_SLEEP;
7384		break;
7385	case SMB2_LOCKFLAG_EXCLUSIVE:
7386		ksmbd_debug(SMB, "received exclusive request\n");
7387		cmd = F_SETLKW;
7388		flock->c.flc_type = F_WRLCK;
7389		flock->c.flc_flags |= FL_SLEEP;
7390		break;
7391	case SMB2_LOCKFLAG_SHARED | SMB2_LOCKFLAG_FAIL_IMMEDIATELY:
7392		ksmbd_debug(SMB,
7393			    "received shared & fail immediately request\n");
7394		cmd = F_SETLK;
7395		flock->c.flc_type = F_RDLCK;
7396		break;
7397	case SMB2_LOCKFLAG_EXCLUSIVE | SMB2_LOCKFLAG_FAIL_IMMEDIATELY:
7398		ksmbd_debug(SMB,
7399			    "received exclusive & fail immediately request\n");
7400		cmd = F_SETLK;
7401		flock->c.flc_type = F_WRLCK;
7402		break;
7403	case SMB2_LOCKFLAG_UNLOCK:
7404		ksmbd_debug(SMB, "received unlock request\n");
7405		flock->c.flc_type = F_UNLCK;
7406		cmd = F_SETLK;
7407		break;
7408	}
7409
7410	return cmd;
7411}
7412
7413static struct ksmbd_lock *smb2_lock_init(struct file_lock *flock,
7414					 unsigned int cmd, int flags,
7415					 struct list_head *lock_list)
7416{
7417	struct ksmbd_lock *lock;
7418
7419	lock = kzalloc(sizeof(struct ksmbd_lock), KSMBD_DEFAULT_GFP);
7420	if (!lock)
7421		return NULL;
7422
7423	lock->cmd = cmd;
7424	lock->fl = flock;
7425	lock->start = flock->fl_start;
7426	lock->end = flock->fl_end;
7427	lock->flags = flags;
7428	if (lock->start == lock->end)
7429		lock->zero_len = 1;
7430	INIT_LIST_HEAD(&lock->clist);
7431	INIT_LIST_HEAD(&lock->flist);
7432	INIT_LIST_HEAD(&lock->llist);
7433	list_add_tail(&lock->llist, lock_list);
7434
7435	return lock;
7436}
7437
7438static void smb2_remove_blocked_lock(void **argv)
7439{
7440	struct file_lock *flock = (struct file_lock *)argv[0];
7441
7442	ksmbd_vfs_posix_lock_unblock(flock);
7443	locks_wake_up(flock);
7444}
7445
7446static inline bool lock_defer_pending(struct file_lock *fl)
7447{
7448	/* check pending lock waiters */
7449	return waitqueue_active(&fl->c.flc_wait);
7450}
7451
7452/**
7453 * smb2_lock() - handler for smb2 file lock command
7454 * @work:	smb work containing lock command buffer
7455 *
7456 * Return:	0 on success, otherwise error
7457 */
7458int smb2_lock(struct ksmbd_work *work)
7459{
7460	struct smb2_lock_req *req;
7461	struct smb2_lock_rsp *rsp;
7462	struct smb2_lock_element *lock_ele;
7463	struct ksmbd_file *fp = NULL;
7464	struct file_lock *flock = NULL;
7465	struct file *filp = NULL;
7466	int lock_count;
7467	int flags = 0;
7468	int cmd = 0;
7469	int err = -EIO, i, rc = 0;
7470	u64 lock_start, lock_length;
7471	struct ksmbd_lock *smb_lock = NULL, *cmp_lock, *tmp, *tmp2;
7472	struct ksmbd_conn *conn;
7473	int nolock = 0;
7474	LIST_HEAD(lock_list);
7475	LIST_HEAD(rollback_list);
7476	int prior_lock = 0, bkt;
7477
7478	WORK_BUFFERS(work, req, rsp);
7479
7480	ksmbd_debug(SMB, "Received smb2 lock request\n");
7481	fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
7482	if (!fp) {
7483		ksmbd_debug(SMB, "Invalid file id for lock : %llu\n", req->VolatileFileId);
7484		err = -ENOENT;
7485		goto out2;
7486	}
7487
7488	filp = fp->filp;
7489	lock_count = le16_to_cpu(req->LockCount);
7490	lock_ele = req->locks;
7491
7492	ksmbd_debug(SMB, "lock count is %d\n", lock_count);
7493	if (!lock_count) {
7494		err = -EINVAL;
7495		goto out2;
7496	}
7497
7498	for (i = 0; i < lock_count; i++) {
7499		flags = le32_to_cpu(lock_ele[i].Flags);
7500
7501		flock = smb_flock_init(filp);
7502		if (!flock)
7503			goto out;
7504
7505		cmd = smb2_set_flock_flags(flock, flags);
7506
7507		lock_start = le64_to_cpu(lock_ele[i].Offset);
7508		lock_length = le64_to_cpu(lock_ele[i].Length);
7509		if (lock_start > U64_MAX - lock_length) {
7510			pr_err("Invalid lock range requested\n");
7511			rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE;
7512			locks_free_lock(flock);
7513			goto out;
7514		}
7515
7516		if (lock_start > OFFSET_MAX)
7517			flock->fl_start = OFFSET_MAX;
7518		else
7519			flock->fl_start = lock_start;
7520
7521		lock_length = le64_to_cpu(lock_ele[i].Length);
7522		if (lock_length > OFFSET_MAX - flock->fl_start)
7523			lock_length = OFFSET_MAX - flock->fl_start;
7524
7525		flock->fl_end = flock->fl_start + lock_length;
7526
7527		if (flock->fl_end < flock->fl_start) {
7528			ksmbd_debug(SMB,
7529				    "the end offset(%llx) is smaller than the start offset(%llx)\n",
7530				    flock->fl_end, flock->fl_start);
7531			rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE;
7532			locks_free_lock(flock);
7533			goto out;
7534		}
7535
7536		/* Check conflict locks in one request */
7537		list_for_each_entry(cmp_lock, &lock_list, llist) {
7538			if (cmp_lock->fl->fl_start <= flock->fl_start &&
7539			    cmp_lock->fl->fl_end >= flock->fl_end) {
7540				if (cmp_lock->fl->c.flc_type != F_UNLCK &&
7541				    flock->c.flc_type != F_UNLCK) {
7542					pr_err("conflict two locks in one request\n");
7543					err = -EINVAL;
7544					locks_free_lock(flock);
7545					goto out;
7546				}
7547			}
7548		}
7549
7550		smb_lock = smb2_lock_init(flock, cmd, flags, &lock_list);
7551		if (!smb_lock) {
7552			err = -EINVAL;
7553			locks_free_lock(flock);
7554			goto out;
7555		}
7556	}
7557
7558	list_for_each_entry_safe(smb_lock, tmp, &lock_list, llist) {
7559		if (smb_lock->cmd < 0) {
7560			err = -EINVAL;
7561			goto out;
7562		}
7563
7564		if (!(smb_lock->flags & SMB2_LOCKFLAG_MASK)) {
7565			err = -EINVAL;
7566			goto out;
7567		}
7568
7569		if ((prior_lock & (SMB2_LOCKFLAG_EXCLUSIVE | SMB2_LOCKFLAG_SHARED) &&
7570		     smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) ||
7571		    (prior_lock == SMB2_LOCKFLAG_UNLOCK &&
7572		     !(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK))) {
7573			err = -EINVAL;
7574			goto out;
7575		}
7576
7577		prior_lock = smb_lock->flags;
7578
7579		if (!(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) &&
7580		    !(smb_lock->flags & SMB2_LOCKFLAG_FAIL_IMMEDIATELY))
7581			goto no_check_cl;
7582
7583		nolock = 1;
7584		/* check locks in connection list */
7585		down_read(&conn_list_lock);
7586		hash_for_each(conn_list, bkt, conn, hlist) {
7587			spin_lock(&conn->llist_lock);
7588			list_for_each_entry_safe(cmp_lock, tmp2, &conn->lock_list, clist) {
7589				if (file_inode(cmp_lock->fl->c.flc_file) !=
7590				    file_inode(smb_lock->fl->c.flc_file))
7591					continue;
7592
7593				if (lock_is_unlock(smb_lock->fl)) {
7594					if (cmp_lock->fl->c.flc_file == smb_lock->fl->c.flc_file &&
7595					    cmp_lock->start == smb_lock->start &&
7596					    cmp_lock->end == smb_lock->end &&
7597					    !lock_defer_pending(cmp_lock->fl)) {
7598						nolock = 0;
7599						list_del(&cmp_lock->flist);
7600						list_del(&cmp_lock->clist);
7601						spin_unlock(&conn->llist_lock);
7602						up_read(&conn_list_lock);
7603
7604						locks_free_lock(cmp_lock->fl);
7605						kfree(cmp_lock);
7606						goto out_check_cl;
7607					}
7608					continue;
7609				}
7610
7611				if (cmp_lock->fl->c.flc_file == smb_lock->fl->c.flc_file) {
7612					if (smb_lock->flags & SMB2_LOCKFLAG_SHARED)
7613						continue;
7614				} else {
7615					if (cmp_lock->flags & SMB2_LOCKFLAG_SHARED)
7616						continue;
7617				}
7618
7619				/* check zero byte lock range */
7620				if (cmp_lock->zero_len && !smb_lock->zero_len &&
7621				    cmp_lock->start > smb_lock->start &&
7622				    cmp_lock->start < smb_lock->end) {
7623					spin_unlock(&conn->llist_lock);
7624					up_read(&conn_list_lock);
7625					pr_err("previous lock conflict with zero byte lock range\n");
7626					goto out;
7627				}
7628
7629				if (smb_lock->zero_len && !cmp_lock->zero_len &&
7630				    smb_lock->start > cmp_lock->start &&
7631				    smb_lock->start < cmp_lock->end) {
7632					spin_unlock(&conn->llist_lock);
7633					up_read(&conn_list_lock);
7634					pr_err("current lock conflict with zero byte lock range\n");
7635					goto out;
7636				}
7637
7638				if (((cmp_lock->start <= smb_lock->start &&
7639				      cmp_lock->end > smb_lock->start) ||
7640				     (cmp_lock->start < smb_lock->end &&
7641				      cmp_lock->end >= smb_lock->end)) &&
7642				    !cmp_lock->zero_len && !smb_lock->zero_len) {
7643					spin_unlock(&conn->llist_lock);
7644					up_read(&conn_list_lock);
7645					pr_err("Not allow lock operation on exclusive lock range\n");
7646					goto out;
7647				}
7648			}
7649			spin_unlock(&conn->llist_lock);
7650		}
7651		up_read(&conn_list_lock);
7652out_check_cl:
7653		if (lock_is_unlock(smb_lock->fl) && nolock) {
7654			pr_err("Try to unlock nolocked range\n");
7655			rsp->hdr.Status = STATUS_RANGE_NOT_LOCKED;
7656			goto out;
7657		}
7658
7659no_check_cl:
7660		flock = smb_lock->fl;
7661		list_del(&smb_lock->llist);
7662
7663		if (smb_lock->zero_len) {
7664			err = 0;
7665			goto skip;
7666		}
7667retry:
7668		rc = vfs_lock_file(filp, smb_lock->cmd, flock, NULL);
7669skip:
7670		if (smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) {
7671			locks_free_lock(flock);
7672			kfree(smb_lock);
7673			if (!rc) {
7674				ksmbd_debug(SMB, "File unlocked\n");
7675			} else if (rc == -ENOENT) {
7676				rsp->hdr.Status = STATUS_NOT_LOCKED;
7677				err = rc;
7678				goto out;
7679			}
7680		} else {
7681			if (rc == FILE_LOCK_DEFERRED) {
7682				void **argv;
7683
7684				ksmbd_debug(SMB,
7685					    "would have to wait for getting lock\n");
7686				list_add(&smb_lock->llist, &rollback_list);
7687
7688				argv = kmalloc(sizeof(void *), KSMBD_DEFAULT_GFP);
7689				if (!argv) {
7690					err = -ENOMEM;
7691					goto out;
7692				}
7693				argv[0] = flock;
7694
7695				rc = setup_async_work(work,
7696						      smb2_remove_blocked_lock,
7697						      argv);
7698				if (rc) {
7699					kfree(argv);
7700					err = -ENOMEM;
7701					goto out;
7702				}
7703				spin_lock(&fp->f_lock);
7704				list_add(&work->fp_entry, &fp->blocked_works);
7705				spin_unlock(&fp->f_lock);
7706
7707				smb2_send_interim_resp(work, STATUS_PENDING);
7708
7709				ksmbd_vfs_posix_lock_wait(flock);
7710
7711				spin_lock(&fp->f_lock);
7712				list_del(&work->fp_entry);
7713				spin_unlock(&fp->f_lock);
7714
7715				if (work->state != KSMBD_WORK_ACTIVE) {
7716					list_del(&smb_lock->llist);
7717					locks_free_lock(flock);
7718
7719					if (work->state == KSMBD_WORK_CANCELLED) {
7720						rsp->hdr.Status =
7721							STATUS_CANCELLED;
7722						kfree(smb_lock);
7723						smb2_send_interim_resp(work,
7724								       STATUS_CANCELLED);
7725						work->send_no_response = 1;
7726						goto out;
7727					}
7728
7729					rsp->hdr.Status =
7730						STATUS_RANGE_NOT_LOCKED;
7731					kfree(smb_lock);
7732					goto out2;
7733				}
7734
7735				list_del(&smb_lock->llist);
7736				release_async_work(work);
7737				goto retry;
7738			} else if (!rc) {
7739				list_add(&smb_lock->llist, &rollback_list);
7740				spin_lock(&work->conn->llist_lock);
7741				list_add_tail(&smb_lock->clist,
7742					      &work->conn->lock_list);
7743				list_add_tail(&smb_lock->flist,
7744					      &fp->lock_list);
7745				spin_unlock(&work->conn->llist_lock);
7746				ksmbd_debug(SMB, "successful in taking lock\n");
7747			} else {
7748				locks_free_lock(flock);
7749				kfree(smb_lock);
7750				err = rc;
7751				goto out;
7752			}
7753		}
7754	}
7755
7756	if (atomic_read(&fp->f_ci->op_count) > 1)
7757		smb_break_all_oplock(work, fp);
7758
7759	rsp->StructureSize = cpu_to_le16(4);
7760	ksmbd_debug(SMB, "successful in taking lock\n");
7761	rsp->hdr.Status = STATUS_SUCCESS;
7762	rsp->Reserved = 0;
7763	err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lock_rsp));
7764	if (err)
7765		goto out;
7766
7767	ksmbd_fd_put(work, fp);
7768	return 0;
7769
7770out:
7771	list_for_each_entry_safe(smb_lock, tmp, &lock_list, llist) {
7772		locks_free_lock(smb_lock->fl);
7773		list_del(&smb_lock->llist);
7774		kfree(smb_lock);
7775	}
7776
7777	list_for_each_entry_safe(smb_lock, tmp, &rollback_list, llist) {
7778		struct file_lock *rlock = NULL;
7779
7780		rlock = smb_flock_init(filp);
7781		if (rlock) {
7782			rlock->c.flc_type = F_UNLCK;
7783			rlock->fl_start = smb_lock->start;
7784			rlock->fl_end = smb_lock->end;
7785
7786			rc = vfs_lock_file(filp, F_SETLK, rlock, NULL);
7787			if (rc)
7788				pr_err("rollback unlock fail : %d\n", rc);
7789		} else {
7790			pr_err("rollback unlock alloc failed\n");
7791		}
7792
7793		list_del(&smb_lock->llist);
7794		spin_lock(&work->conn->llist_lock);
7795		if (!list_empty(&smb_lock->flist))
7796			list_del(&smb_lock->flist);
7797		list_del(&smb_lock->clist);
7798		spin_unlock(&work->conn->llist_lock);
7799
7800		locks_free_lock(smb_lock->fl);
7801		if (rlock)
7802			locks_free_lock(rlock);
7803		kfree(smb_lock);
7804	}
7805out2:
7806	ksmbd_debug(SMB, "failed in taking lock(flags : %x), err : %d\n", flags, err);
7807
7808	if (!rsp->hdr.Status) {
7809		if (err == -EINVAL)
7810			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
7811		else if (err == -ENOMEM)
7812			rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
7813		else if (err == -ENOENT)
7814			rsp->hdr.Status = STATUS_FILE_CLOSED;
7815		else
7816			rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED;
7817	}
7818
7819	smb2_set_err_rsp(work);
7820	ksmbd_fd_put(work, fp);
7821	return err;
7822}
7823
7824static int fsctl_copychunk(struct ksmbd_work *work,
7825			   struct copychunk_ioctl_req *ci_req,
7826			   unsigned int cnt_code,
7827			   unsigned int input_count,
7828			   unsigned long long volatile_id,
7829			   unsigned long long persistent_id,
7830			   struct smb2_ioctl_rsp *rsp)
7831{
7832	struct copychunk_ioctl_rsp *ci_rsp;
7833	struct ksmbd_file *src_fp = NULL, *dst_fp = NULL;
7834	struct srv_copychunk *chunks;
7835	unsigned int i, chunk_count, chunk_count_written = 0;
7836	unsigned int chunk_size_written = 0;
7837	loff_t total_size_written = 0;
7838	int ret = 0;
7839
7840	ci_rsp = (struct copychunk_ioctl_rsp *)&rsp->Buffer[0];
7841
7842	rsp->VolatileFileId = volatile_id;
7843	rsp->PersistentFileId = persistent_id;
7844	ci_rsp->ChunksWritten =
7845		cpu_to_le32(ksmbd_server_side_copy_max_chunk_count());
7846	ci_rsp->ChunkBytesWritten =
7847		cpu_to_le32(ksmbd_server_side_copy_max_chunk_size());
7848	ci_rsp->TotalBytesWritten =
7849		cpu_to_le32(ksmbd_server_side_copy_max_total_size());
7850
7851	chunk_count = le32_to_cpu(ci_req->ChunkCount);
7852	if (chunk_count == 0)
7853		goto out;
7854	total_size_written = 0;
7855
7856	/* verify the SRV_COPYCHUNK_COPY packet */
7857	if (chunk_count > ksmbd_server_side_copy_max_chunk_count() ||
7858	    input_count < struct_size(ci_req, Chunks, chunk_count)) {
7859		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
7860		return -EINVAL;
7861	}
7862
7863	chunks = &ci_req->Chunks[0];
7864	for (i = 0; i < chunk_count; i++) {
7865		if (le32_to_cpu(chunks[i].Length) == 0 ||
7866		    le32_to_cpu(chunks[i].Length) > ksmbd_server_side_copy_max_chunk_size())
7867			break;
7868		total_size_written += le32_to_cpu(chunks[i].Length);
7869	}
7870
7871	if (i < chunk_count ||
7872	    total_size_written > ksmbd_server_side_copy_max_total_size()) {
7873		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
7874		return -EINVAL;
7875	}
7876
7877	src_fp = ksmbd_lookup_foreign_fd(work,
7878					 le64_to_cpu(ci_req->SourceKeyU64[0]));
7879	dst_fp = ksmbd_lookup_fd_slow(work, volatile_id, persistent_id);
7880	ret = -EINVAL;
7881	if (!src_fp ||
7882	    src_fp->persistent_id != le64_to_cpu(ci_req->SourceKeyU64[1])) {
7883		rsp->hdr.Status = STATUS_OBJECT_NAME_NOT_FOUND;
7884		goto out;
7885	}
7886
7887	if (!dst_fp) {
7888		rsp->hdr.Status = STATUS_FILE_CLOSED;
7889		goto out;
7890	}
7891
7892	/*
7893	 * FILE_READ_DATA should only be included in
7894	 * the FSCTL_COPYCHUNK case
7895	 */
7896	if (cnt_code == FSCTL_COPYCHUNK &&
7897	    !(dst_fp->daccess & (FILE_READ_DATA_LE | FILE_GENERIC_READ_LE))) {
7898		rsp->hdr.Status = STATUS_ACCESS_DENIED;
7899		goto out;
7900	}
7901
7902	ret = ksmbd_vfs_copy_file_ranges(work, src_fp, dst_fp,
7903					 chunks, chunk_count,
7904					 &chunk_count_written,
7905					 &chunk_size_written,
7906					 &total_size_written);
7907	if (ret < 0) {
7908		if (ret == -EACCES)
7909			rsp->hdr.Status = STATUS_ACCESS_DENIED;
7910		if (ret == -EAGAIN)
7911			rsp->hdr.Status = STATUS_FILE_LOCK_CONFLICT;
7912		else if (ret == -EBADF)
7913			rsp->hdr.Status = STATUS_INVALID_HANDLE;
7914		else if (ret == -EFBIG || ret == -ENOSPC)
7915			rsp->hdr.Status = STATUS_DISK_FULL;
7916		else if (ret == -EINVAL)
7917			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
7918		else if (ret == -EISDIR)
7919			rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY;
7920		else if (ret == -E2BIG)
7921			rsp->hdr.Status = STATUS_INVALID_VIEW_SIZE;
7922		else
7923			rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
7924	}
7925
7926	ci_rsp->ChunksWritten = cpu_to_le32(chunk_count_written);
7927	ci_rsp->ChunkBytesWritten = cpu_to_le32(chunk_size_written);
7928	ci_rsp->TotalBytesWritten = cpu_to_le32(total_size_written);
7929out:
7930	ksmbd_fd_put(work, src_fp);
7931	ksmbd_fd_put(work, dst_fp);
7932	return ret;
7933}
7934
7935static __be32 idev_ipv4_address(struct in_device *idev)
7936{
7937	__be32 addr = 0;
7938
7939	struct in_ifaddr *ifa;
7940
7941	rcu_read_lock();
7942	in_dev_for_each_ifa_rcu(ifa, idev) {
7943		if (ifa->ifa_flags & IFA_F_SECONDARY)
7944			continue;
7945
7946		addr = ifa->ifa_address;
7947		break;
7948	}
7949	rcu_read_unlock();
7950	return addr;
7951}
7952
7953static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
7954					struct smb2_ioctl_rsp *rsp,
7955					unsigned int out_buf_len)
7956{
7957	struct network_interface_info_ioctl_rsp *nii_rsp = NULL;
7958	int nbytes = 0;
7959	struct net_device *netdev;
7960	struct sockaddr_storage_rsp *sockaddr_storage;
7961	unsigned int flags;
7962	unsigned long long speed;
7963
7964	rtnl_lock();
7965	for_each_netdev(&init_net, netdev) {
7966		bool ipv4_set = false;
7967
7968		if (netdev->type == ARPHRD_LOOPBACK)
7969			continue;
7970
7971		if (!ksmbd_find_netdev_name_iface_list(netdev->name))
7972			continue;
7973
7974		flags = netif_get_flags(netdev);
7975		if (!(flags & IFF_RUNNING))
7976			continue;
7977ipv6_retry:
7978		if (out_buf_len <
7979		    nbytes + sizeof(struct network_interface_info_ioctl_rsp)) {
7980			rtnl_unlock();
7981			return -ENOSPC;
7982		}
7983
7984		nii_rsp = (struct network_interface_info_ioctl_rsp *)
7985				&rsp->Buffer[nbytes];
7986		nii_rsp->IfIndex = cpu_to_le32(netdev->ifindex);
7987
7988		nii_rsp->Capability = 0;
7989		if (netdev->real_num_tx_queues > 1)
7990			nii_rsp->Capability |= RSS_CAPABLE;
7991		if (ksmbd_rdma_capable_netdev(netdev))
7992			nii_rsp->Capability |= RDMA_CAPABLE;
7993
7994		nii_rsp->Next = cpu_to_le32(152);
7995		nii_rsp->Reserved = 0;
7996
7997		if (netdev->ethtool_ops->get_link_ksettings) {
7998			struct ethtool_link_ksettings cmd;
7999
8000			netdev->ethtool_ops->get_link_ksettings(netdev, &cmd);
8001			speed = cmd.base.speed;
8002		} else {
8003			ksmbd_debug(SMB, "%s %s\n", netdev->name,
8004				    "speed is unknown, defaulting to 1Gb/sec");
8005			speed = SPEED_1000;
8006		}
8007
8008		speed *= 1000000;
8009		nii_rsp->LinkSpeed = cpu_to_le64(speed);
8010
8011		sockaddr_storage = (struct sockaddr_storage_rsp *)
8012					nii_rsp->SockAddr_Storage;
8013		memset(sockaddr_storage, 0, 128);
8014
8015		if (!ipv4_set) {
8016			struct in_device *idev;
8017
8018			sockaddr_storage->Family = INTERNETWORK;
8019			sockaddr_storage->addr4.Port = 0;
8020
8021			idev = __in_dev_get_rtnl(netdev);
8022			if (!idev)
8023				continue;
8024			sockaddr_storage->addr4.IPv4Address =
8025						idev_ipv4_address(idev);
8026			nbytes += sizeof(struct network_interface_info_ioctl_rsp);
8027			ipv4_set = true;
8028			goto ipv6_retry;
8029		} else {
8030			struct inet6_dev *idev6;
8031			struct inet6_ifaddr *ifa;
8032			__u8 *ipv6_addr = sockaddr_storage->addr6.IPv6Address;
8033
8034			sockaddr_storage->Family = INTERNETWORKV6;
8035			sockaddr_storage->addr6.Port = 0;
8036			sockaddr_storage->addr6.FlowInfo = 0;
8037
8038			idev6 = __in6_dev_get(netdev);
8039			if (!idev6)
8040				continue;
8041
8042			list_for_each_entry(ifa, &idev6->addr_list, if_list) {
8043				if (ifa->flags & (IFA_F_TENTATIVE |
8044							IFA_F_DEPRECATED))
8045					continue;
8046				memcpy(ipv6_addr, ifa->addr.s6_addr, 16);
8047				break;
8048			}
8049			sockaddr_storage->addr6.ScopeId = 0;
8050			nbytes += sizeof(struct network_interface_info_ioctl_rsp);
8051		}
8052	}
8053	rtnl_unlock();
8054
8055	/* zero if this is last one */
8056	if (nii_rsp)
8057		nii_rsp->Next = 0;
8058
8059	rsp->PersistentFileId = SMB2_NO_FID;
8060	rsp->VolatileFileId = SMB2_NO_FID;
8061	return nbytes;
8062}
8063
8064static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn,
8065					 struct validate_negotiate_info_req *neg_req,
8066					 struct validate_negotiate_info_rsp *neg_rsp,
8067					 unsigned int in_buf_len)
8068{
8069	int ret = 0;
8070	int dialect;
8071
8072	if (in_buf_len < offsetof(struct validate_negotiate_info_req, Dialects) +
8073			le16_to_cpu(neg_req->DialectCount) * sizeof(__le16))
8074		return -EINVAL;
8075
8076	dialect = ksmbd_lookup_dialect_by_id(neg_req->Dialects,
8077					     neg_req->DialectCount);
8078	if (dialect == BAD_PROT_ID || dialect != conn->dialect) {
8079		ret = -EINVAL;
8080		goto err_out;
8081	}
8082
8083	if (strncmp(neg_req->Guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE)) {
8084		ret = -EINVAL;
8085		goto err_out;
8086	}
8087
8088	if (le16_to_cpu(neg_req->SecurityMode) != conn->cli_sec_mode) {
8089		ret = -EINVAL;
8090		goto err_out;
8091	}
8092
8093	if (le32_to_cpu(neg_req->Capabilities) != conn->cli_cap) {
8094		ret = -EINVAL;
8095		goto err_out;
8096	}
8097
8098	neg_rsp->Capabilities = cpu_to_le32(conn->vals->req_capabilities);
8099	memset(neg_rsp->Guid, 0, SMB2_CLIENT_GUID_SIZE);
8100	neg_rsp->SecurityMode = cpu_to_le16(conn->srv_sec_mode);
8101	neg_rsp->Dialect = cpu_to_le16(conn->dialect);
8102err_out:
8103	return ret;
8104}
8105
8106static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id,
8107					struct file_allocated_range_buffer *qar_req,
8108					struct file_allocated_range_buffer *qar_rsp,
8109					unsigned int in_count, unsigned int *out_count)
8110{
8111	struct ksmbd_file *fp;
8112	loff_t start, length;
8113	int ret = 0;
8114
8115	*out_count = 0;
8116	if (in_count == 0)
8117		return -EINVAL;
8118
8119	start = le64_to_cpu(qar_req->file_offset);
8120	length = le64_to_cpu(qar_req->length);
8121
8122	if (start < 0 || length < 0)
8123		return -EINVAL;
8124
8125	fp = ksmbd_lookup_fd_fast(work, id);
8126	if (!fp)
8127		return -ENOENT;
8128
8129	ret = ksmbd_vfs_fqar_lseek(fp, start, length,
8130				   qar_rsp, in_count, out_count);
8131	if (ret && ret != -E2BIG)
8132		*out_count = 0;
8133
8134	ksmbd_fd_put(work, fp);
8135	return ret;
8136}
8137
8138static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id,
8139				 unsigned int out_buf_len,
8140				 struct smb2_ioctl_req *req,
8141				 struct smb2_ioctl_rsp *rsp)
8142{
8143	struct ksmbd_rpc_command *rpc_resp;
8144	char *data_buf = (char *)req + le32_to_cpu(req->InputOffset);
8145	int nbytes = 0;
8146
8147	rpc_resp = ksmbd_rpc_ioctl(work->sess, id, data_buf,
8148				   le32_to_cpu(req->InputCount));
8149	if (rpc_resp) {
8150		if (rpc_resp->flags == KSMBD_RPC_SOME_NOT_MAPPED) {
8151			/*
8152			 * set STATUS_SOME_NOT_MAPPED response
8153			 * for unknown domain sid.
8154			 */
8155			rsp->hdr.Status = STATUS_SOME_NOT_MAPPED;
8156		} else if (rpc_resp->flags == KSMBD_RPC_ENOTIMPLEMENTED) {
8157			rsp->hdr.Status = STATUS_NOT_SUPPORTED;
8158			goto out;
8159		} else if (rpc_resp->flags != KSMBD_RPC_OK) {
8160			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
8161			goto out;
8162		}
8163
8164		nbytes = rpc_resp->payload_sz;
8165		if (rpc_resp->payload_sz > out_buf_len) {
8166			rsp->hdr.Status = STATUS_BUFFER_OVERFLOW;
8167			nbytes = out_buf_len;
8168		}
8169
8170		if (!rpc_resp->payload_sz) {
8171			rsp->hdr.Status =
8172				STATUS_UNEXPECTED_IO_ERROR;
8173			goto out;
8174		}
8175
8176		memcpy((char *)rsp->Buffer, rpc_resp->payload, nbytes);
8177	}
8178out:
8179	kvfree(rpc_resp);
8180	return nbytes;
8181}
8182
8183static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
8184				   struct file_sparse *sparse)
8185{
8186	struct ksmbd_file *fp;
8187	struct mnt_idmap *idmap;
8188	int ret = 0;
8189	__le32 old_fattr;
8190
8191	fp = ksmbd_lookup_fd_fast(work, id);
8192	if (!fp)
8193		return -ENOENT;
8194	idmap = file_mnt_idmap(fp->filp);
8195
8196	old_fattr = fp->f_ci->m_fattr;
8197	if (sparse->SetSparse)
8198		fp->f_ci->m_fattr |= FILE_ATTRIBUTE_SPARSE_FILE_LE;
8199	else
8200		fp->f_ci->m_fattr &= ~FILE_ATTRIBUTE_SPARSE_FILE_LE;
8201
8202	if (fp->f_ci->m_fattr != old_fattr &&
8203	    test_share_config_flag(work->tcon->share_conf,
8204				   KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) {
8205		struct xattr_dos_attrib da;
8206
8207		ret = ksmbd_vfs_get_dos_attrib_xattr(idmap,
8208						     fp->filp->f_path.dentry, &da);
8209		if (ret <= 0)
8210			goto out;
8211
8212		da.attr = le32_to_cpu(fp->f_ci->m_fattr);
8213		ret = ksmbd_vfs_set_dos_attrib_xattr(idmap,
8214						     &fp->filp->f_path,
8215						     &da, true);
8216		if (ret)
8217			fp->f_ci->m_fattr = old_fattr;
8218	}
8219
8220out:
8221	ksmbd_fd_put(work, fp);
8222	return ret;
8223}
8224
8225static int fsctl_request_resume_key(struct ksmbd_work *work,
8226				    struct smb2_ioctl_req *req,
8227				    struct resume_key_ioctl_rsp *key_rsp)
8228{
8229	struct ksmbd_file *fp;
8230
8231	fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
8232	if (!fp)
8233		return -ENOENT;
8234
8235	memset(key_rsp, 0, sizeof(*key_rsp));
8236	key_rsp->ResumeKeyU64[0] = req->VolatileFileId;
8237	key_rsp->ResumeKeyU64[1] = req->PersistentFileId;
8238	ksmbd_fd_put(work, fp);
8239
8240	return 0;
8241}
8242
8243/**
8244 * smb2_ioctl() - handler for smb2 ioctl command
8245 * @work:	smb work containing ioctl command buffer
8246 *
8247 * Return:	0 on success, otherwise error
8248 */
8249int smb2_ioctl(struct ksmbd_work *work)
8250{
8251	struct smb2_ioctl_req *req;
8252	struct smb2_ioctl_rsp *rsp;
8253	unsigned int cnt_code, nbytes = 0, out_buf_len, in_buf_len;
8254	u64 id = KSMBD_NO_FID;
8255	struct ksmbd_conn *conn = work->conn;
8256	int ret = 0;
8257	char *buffer;
8258
8259	ksmbd_debug(SMB, "Received smb2 ioctl request\n");
8260
8261	if (work->next_smb2_rcv_hdr_off) {
8262		req = ksmbd_req_buf_next(work);
8263		rsp = ksmbd_resp_buf_next(work);
8264		if (!has_file_id(req->VolatileFileId)) {
8265			ksmbd_debug(SMB, "Compound request set FID = %llu\n",
8266				    work->compound_fid);
8267			id = work->compound_fid;
8268		}
8269	} else {
8270		req = smb_get_msg(work->request_buf);
8271		rsp = smb_get_msg(work->response_buf);
8272	}
8273
8274	if (!has_file_id(id))
8275		id = req->VolatileFileId;
8276
8277	if (req->Flags != cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL)) {
8278		ret = -EOPNOTSUPP;
8279		goto out;
8280	}
8281
8282	buffer = (char *)req + le32_to_cpu(req->InputOffset);
8283
8284	cnt_code = le32_to_cpu(req->CtlCode);
8285	ret = smb2_calc_max_out_buf_len(work,
8286			offsetof(struct smb2_ioctl_rsp, Buffer),
8287			le32_to_cpu(req->MaxOutputResponse));
8288	if (ret < 0) {
8289		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
8290		goto out;
8291	}
8292	out_buf_len = (unsigned int)ret;
8293	in_buf_len = le32_to_cpu(req->InputCount);
8294
8295	switch (cnt_code) {
8296	case FSCTL_DFS_GET_REFERRALS:
8297	case FSCTL_DFS_GET_REFERRALS_EX:
8298		/* Not support DFS yet */
8299		ret = -EOPNOTSUPP;
8300		rsp->hdr.Status = STATUS_FS_DRIVER_REQUIRED;
8301		goto out2;
8302	case FSCTL_CREATE_OR_GET_OBJECT_ID:
8303	{
8304		struct file_object_buf_type1_ioctl_rsp *obj_buf;
8305
8306		nbytes = sizeof(struct file_object_buf_type1_ioctl_rsp);
8307		obj_buf = (struct file_object_buf_type1_ioctl_rsp *)
8308			&rsp->Buffer[0];
8309
8310		/*
8311		 * TODO: This is dummy implementation to pass smbtorture
8312		 * Need to check correct response later
8313		 */
8314		memset(obj_buf->ObjectId, 0x0, 16);
8315		memset(obj_buf->BirthVolumeId, 0x0, 16);
8316		memset(obj_buf->BirthObjectId, 0x0, 16);
8317		memset(obj_buf->DomainId, 0x0, 16);
8318
8319		break;
8320	}
8321	case FSCTL_PIPE_TRANSCEIVE:
8322		out_buf_len = min_t(u32, KSMBD_IPC_MAX_PAYLOAD, out_buf_len);
8323		nbytes = fsctl_pipe_transceive(work, id, out_buf_len, req, rsp);
8324		break;
8325	case FSCTL_VALIDATE_NEGOTIATE_INFO:
8326		if (conn->dialect < SMB30_PROT_ID) {
8327			ret = -EOPNOTSUPP;
8328			goto out;
8329		}
8330
8331		if (in_buf_len < offsetof(struct validate_negotiate_info_req,
8332					  Dialects)) {
8333			ret = -EINVAL;
8334			goto out;
8335		}
8336
8337		if (out_buf_len < sizeof(struct validate_negotiate_info_rsp)) {
8338			ret = -EINVAL;
8339			goto out;
8340		}
8341
8342		ret = fsctl_validate_negotiate_info(conn,
8343			(struct validate_negotiate_info_req *)buffer,
8344			(struct validate_negotiate_info_rsp *)&rsp->Buffer[0],
8345			in_buf_len);
8346		if (ret < 0)
8347			goto out;
8348
8349		nbytes = sizeof(struct validate_negotiate_info_rsp);
8350		rsp->PersistentFileId = SMB2_NO_FID;
8351		rsp->VolatileFileId = SMB2_NO_FID;
8352		break;
8353	case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
8354		ret = fsctl_query_iface_info_ioctl(conn, rsp, out_buf_len);
8355		if (ret < 0)
8356			goto out;
8357		nbytes = ret;
8358		break;
8359	case FSCTL_REQUEST_RESUME_KEY:
8360		if (out_buf_len < sizeof(struct resume_key_ioctl_rsp)) {
8361			ret = -EINVAL;
8362			goto out;
8363		}
8364
8365		ret = fsctl_request_resume_key(work, req,
8366					       (struct resume_key_ioctl_rsp *)&rsp->Buffer[0]);
8367		if (ret < 0)
8368			goto out;
8369		rsp->PersistentFileId = req->PersistentFileId;
8370		rsp->VolatileFileId = req->VolatileFileId;
8371		nbytes = sizeof(struct resume_key_ioctl_rsp);
8372		break;
8373	case FSCTL_COPYCHUNK:
8374	case FSCTL_COPYCHUNK_WRITE:
8375		if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
8376			ksmbd_debug(SMB,
8377				    "User does not have write permission\n");
8378			ret = -EACCES;
8379			goto out;
8380		}
8381
8382		if (in_buf_len <= sizeof(struct copychunk_ioctl_req)) {
8383			ret = -EINVAL;
8384			goto out;
8385		}
8386
8387		if (out_buf_len < sizeof(struct copychunk_ioctl_rsp)) {
8388			ret = -EINVAL;
8389			goto out;
8390		}
8391
8392		nbytes = sizeof(struct copychunk_ioctl_rsp);
8393		rsp->VolatileFileId = req->VolatileFileId;
8394		rsp->PersistentFileId = req->PersistentFileId;
8395		fsctl_copychunk(work,
8396				(struct copychunk_ioctl_req *)buffer,
8397				le32_to_cpu(req->CtlCode),
8398				le32_to_cpu(req->InputCount),
8399				req->VolatileFileId,
8400				req->PersistentFileId,
8401				rsp);
8402		break;
8403	case FSCTL_SET_SPARSE:
8404		if (in_buf_len < sizeof(struct file_sparse)) {
8405			ret = -EINVAL;
8406			goto out;
8407		}
8408
8409		ret = fsctl_set_sparse(work, id, (struct file_sparse *)buffer);
8410		if (ret < 0)
8411			goto out;
8412		break;
8413	case FSCTL_SET_ZERO_DATA:
8414	{
8415		struct file_zero_data_information *zero_data;
8416		struct ksmbd_file *fp;
8417		loff_t off, len, bfz;
8418
8419		if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
8420			ksmbd_debug(SMB,
8421				    "User does not have write permission\n");
8422			ret = -EACCES;
8423			goto out;
8424		}
8425
8426		if (in_buf_len < sizeof(struct file_zero_data_information)) {
8427			ret = -EINVAL;
8428			goto out;
8429		}
8430
8431		zero_data =
8432			(struct file_zero_data_information *)buffer;
8433
8434		off = le64_to_cpu(zero_data->FileOffset);
8435		bfz = le64_to_cpu(zero_data->BeyondFinalZero);
8436		if (off < 0 || bfz < 0 || off > bfz) {
8437			ret = -EINVAL;
8438			goto out;
8439		}
8440
8441		len = bfz - off;
8442		if (len) {
8443			fp = ksmbd_lookup_fd_fast(work, id);
8444			if (!fp) {
8445				ret = -ENOENT;
8446				goto out;
8447			}
8448
8449			ret = ksmbd_vfs_zero_data(work, fp, off, len);
8450			ksmbd_fd_put(work, fp);
8451			if (ret < 0)
8452				goto out;
8453		}
8454		break;
8455	}
8456	case FSCTL_QUERY_ALLOCATED_RANGES:
8457		if (in_buf_len < sizeof(struct file_allocated_range_buffer)) {
8458			ret = -EINVAL;
8459			goto out;
8460		}
8461
8462		ret = fsctl_query_allocated_ranges(work, id,
8463			(struct file_allocated_range_buffer *)buffer,
8464			(struct file_allocated_range_buffer *)&rsp->Buffer[0],
8465			out_buf_len /
8466			sizeof(struct file_allocated_range_buffer), &nbytes);
8467		if (ret == -E2BIG) {
8468			rsp->hdr.Status = STATUS_BUFFER_OVERFLOW;
8469		} else if (ret < 0) {
8470			nbytes = 0;
8471			goto out;
8472		}
8473
8474		nbytes *= sizeof(struct file_allocated_range_buffer);
8475		break;
8476	case FSCTL_GET_REPARSE_POINT:
8477	{
8478		struct reparse_data_buffer *reparse_ptr;
8479		struct ksmbd_file *fp;
8480
8481		reparse_ptr = (struct reparse_data_buffer *)&rsp->Buffer[0];
8482		fp = ksmbd_lookup_fd_fast(work, id);
8483		if (!fp) {
8484			pr_err("not found fp!!\n");
8485			ret = -ENOENT;
8486			goto out;
8487		}
8488
8489		reparse_ptr->ReparseTag =
8490			smb2_get_reparse_tag_special_file(file_inode(fp->filp)->i_mode);
8491		reparse_ptr->ReparseDataLength = 0;
8492		ksmbd_fd_put(work, fp);
8493		nbytes = sizeof(struct reparse_data_buffer);
8494		break;
8495	}
8496	case FSCTL_DUPLICATE_EXTENTS_TO_FILE:
8497	{
8498		struct ksmbd_file *fp_in, *fp_out = NULL;
8499		struct duplicate_extents_to_file *dup_ext;
8500		loff_t src_off, dst_off, length, cloned;
8501
8502		if (in_buf_len < sizeof(struct duplicate_extents_to_file)) {
8503			ret = -EINVAL;
8504			goto out;
8505		}
8506
8507		dup_ext = (struct duplicate_extents_to_file *)buffer;
8508
8509		fp_in = ksmbd_lookup_fd_slow(work, dup_ext->VolatileFileHandle,
8510					     dup_ext->PersistentFileHandle);
8511		if (!fp_in) {
8512			pr_err("not found file handle in duplicate extent to file\n");
8513			ret = -ENOENT;
8514			goto out;
8515		}
8516
8517		fp_out = ksmbd_lookup_fd_fast(work, id);
8518		if (!fp_out) {
8519			pr_err("not found fp\n");
8520			ret = -ENOENT;
8521			goto dup_ext_out;
8522		}
8523
8524		src_off = le64_to_cpu(dup_ext->SourceFileOffset);
8525		dst_off = le64_to_cpu(dup_ext->TargetFileOffset);
8526		length = le64_to_cpu(dup_ext->ByteCount);
8527		/*
8528		 * XXX: It is not clear if FSCTL_DUPLICATE_EXTENTS_TO_FILE
8529		 * should fall back to vfs_copy_file_range().  This could be
8530		 * beneficial when re-exporting nfs/smb mount, but note that
8531		 * this can result in partial copy that returns an error status.
8532		 * If/when FSCTL_DUPLICATE_EXTENTS_TO_FILE_EX is implemented,
8533		 * fall back to vfs_copy_file_range(), should be avoided when
8534		 * the flag DUPLICATE_EXTENTS_DATA_EX_SOURCE_ATOMIC is set.
8535		 */
8536		cloned = vfs_clone_file_range(fp_in->filp, src_off,
8537					      fp_out->filp, dst_off, length, 0);
8538		if (cloned == -EXDEV || cloned == -EOPNOTSUPP) {
8539			ret = -EOPNOTSUPP;
8540			goto dup_ext_out;
8541		} else if (cloned != length) {
8542			cloned = vfs_copy_file_range(fp_in->filp, src_off,
8543						     fp_out->filp, dst_off,
8544						     length, 0);
8545			if (cloned != length) {
8546				if (cloned < 0)
8547					ret = cloned;
8548				else
8549					ret = -EINVAL;
8550			}
8551		}
8552
8553dup_ext_out:
8554		ksmbd_fd_put(work, fp_in);
8555		ksmbd_fd_put(work, fp_out);
8556		if (ret < 0)
8557			goto out;
8558		break;
8559	}
8560	default:
8561		ksmbd_debug(SMB, "not implemented yet ioctl command 0x%x\n",
8562			    cnt_code);
8563		ret = -EOPNOTSUPP;
8564		goto out;
8565	}
8566
8567	rsp->CtlCode = cpu_to_le32(cnt_code);
8568	rsp->InputCount = cpu_to_le32(0);
8569	rsp->InputOffset = cpu_to_le32(112);
8570	rsp->OutputOffset = cpu_to_le32(112);
8571	rsp->OutputCount = cpu_to_le32(nbytes);
8572	rsp->StructureSize = cpu_to_le16(49);
8573	rsp->Reserved = cpu_to_le16(0);
8574	rsp->Flags = cpu_to_le32(0);
8575	rsp->Reserved2 = cpu_to_le32(0);
8576	ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_ioctl_rsp) + nbytes);
8577	if (!ret)
8578		return ret;
8579
8580out:
8581	if (ret == -EACCES)
8582		rsp->hdr.Status = STATUS_ACCESS_DENIED;
8583	else if (ret == -ENOENT)
8584		rsp->hdr.Status = STATUS_OBJECT_NAME_NOT_FOUND;
8585	else if (ret == -EOPNOTSUPP)
8586		rsp->hdr.Status = STATUS_NOT_SUPPORTED;
8587	else if (ret == -ENOSPC)
8588		rsp->hdr.Status = STATUS_BUFFER_TOO_SMALL;
8589	else if (ret < 0 || rsp->hdr.Status == 0)
8590		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
8591
8592out2:
8593	smb2_set_err_rsp(work);
8594	return ret;
8595}
8596
8597/**
8598 * smb20_oplock_break_ack() - handler for smb2.0 oplock break command
8599 * @work:	smb work containing oplock break command buffer
8600 *
8601 * Return:	0
8602 */
8603static void smb20_oplock_break_ack(struct ksmbd_work *work)
8604{
8605	struct smb2_oplock_break *req;
8606	struct smb2_oplock_break *rsp;
8607	struct ksmbd_file *fp;
8608	struct oplock_info *opinfo = NULL;
8609	__le32 err = 0;
8610	int ret = 0;
8611	u64 volatile_id, persistent_id;
8612	char req_oplevel = 0, rsp_oplevel = 0;
8613	unsigned int oplock_change_type;
8614
8615	WORK_BUFFERS(work, req, rsp);
8616
8617	volatile_id = req->VolatileFid;
8618	persistent_id = req->PersistentFid;
8619	req_oplevel = req->OplockLevel;
8620	ksmbd_debug(OPLOCK, "v_id %llu, p_id %llu request oplock level %d\n",
8621		    volatile_id, persistent_id, req_oplevel);
8622
8623	fp = ksmbd_lookup_fd_slow(work, volatile_id, persistent_id);
8624	if (!fp) {
8625		rsp->hdr.Status = STATUS_FILE_CLOSED;
8626		smb2_set_err_rsp(work);
8627		return;
8628	}
8629
8630	opinfo = opinfo_get(fp);
8631	if (!opinfo) {
8632		pr_err("unexpected null oplock_info\n");
8633		rsp->hdr.Status = STATUS_INVALID_OPLOCK_PROTOCOL;
8634		smb2_set_err_rsp(work);
8635		ksmbd_fd_put(work, fp);
8636		return;
8637	}
8638
8639	if (opinfo->level == SMB2_OPLOCK_LEVEL_NONE) {
8640		rsp->hdr.Status = STATUS_INVALID_OPLOCK_PROTOCOL;
8641		goto err_out;
8642	}
8643
8644	if (opinfo->op_state == OPLOCK_STATE_NONE) {
8645		ksmbd_debug(SMB, "unexpected oplock state 0x%x\n", opinfo->op_state);
8646		rsp->hdr.Status = STATUS_UNSUCCESSFUL;
8647		goto err_out;
8648	}
8649
8650	if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
8651	     opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
8652	    (req_oplevel != SMB2_OPLOCK_LEVEL_II &&
8653	     req_oplevel != SMB2_OPLOCK_LEVEL_NONE)) {
8654		err = STATUS_INVALID_OPLOCK_PROTOCOL;
8655		oplock_change_type = OPLOCK_WRITE_TO_NONE;
8656	} else if (opinfo->level == SMB2_OPLOCK_LEVEL_II &&
8657		   req_oplevel != SMB2_OPLOCK_LEVEL_NONE) {
8658		err = STATUS_INVALID_OPLOCK_PROTOCOL;
8659		oplock_change_type = OPLOCK_READ_TO_NONE;
8660	} else if (req_oplevel == SMB2_OPLOCK_LEVEL_II ||
8661		   req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
8662		err = STATUS_INVALID_DEVICE_STATE;
8663		if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
8664		     opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
8665		    req_oplevel == SMB2_OPLOCK_LEVEL_II) {
8666			oplock_change_type = OPLOCK_WRITE_TO_READ;
8667		} else if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
8668			    opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
8669			   req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
8670			oplock_change_type = OPLOCK_WRITE_TO_NONE;
8671		} else if (opinfo->level == SMB2_OPLOCK_LEVEL_II &&
8672			   req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
8673			oplock_change_type = OPLOCK_READ_TO_NONE;
8674		} else {
8675			oplock_change_type = 0;
8676		}
8677	} else {
8678		oplock_change_type = 0;
8679	}
8680
8681	switch (oplock_change_type) {
8682	case OPLOCK_WRITE_TO_READ:
8683		ret = opinfo_write_to_read(opinfo);
8684		rsp_oplevel = SMB2_OPLOCK_LEVEL_II;
8685		break;
8686	case OPLOCK_WRITE_TO_NONE:
8687		ret = opinfo_write_to_none(opinfo);
8688		rsp_oplevel = SMB2_OPLOCK_LEVEL_NONE;
8689		break;
8690	case OPLOCK_READ_TO_NONE:
8691		ret = opinfo_read_to_none(opinfo);
8692		rsp_oplevel = SMB2_OPLOCK_LEVEL_NONE;
8693		break;
8694	default:
8695		pr_err("unknown oplock change 0x%x -> 0x%x\n",
8696		       opinfo->level, rsp_oplevel);
8697	}
8698
8699	if (ret < 0) {
8700		rsp->hdr.Status = err;
8701		goto err_out;
8702	}
8703
8704	rsp->StructureSize = cpu_to_le16(24);
8705	rsp->OplockLevel = rsp_oplevel;
8706	rsp->Reserved = 0;
8707	rsp->Reserved2 = 0;
8708	rsp->VolatileFid = volatile_id;
8709	rsp->PersistentFid = persistent_id;
8710	ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_oplock_break));
8711	if (ret) {
8712err_out:
8713		smb2_set_err_rsp(work);
8714	}
8715
8716	opinfo->op_state = OPLOCK_STATE_NONE;
8717	wake_up_interruptible_all(&opinfo->oplock_q);
8718	opinfo_put(opinfo);
8719	ksmbd_fd_put(work, fp);
8720}
8721
8722static int check_lease_state(struct lease *lease, __le32 req_state)
8723{
8724	if ((lease->new_state ==
8725	     (SMB2_LEASE_READ_CACHING_LE | SMB2_LEASE_HANDLE_CACHING_LE)) &&
8726	    !(req_state & SMB2_LEASE_WRITE_CACHING_LE)) {
8727		lease->new_state = req_state;
8728		return 0;
8729	}
8730
8731	if (lease->new_state == req_state)
8732		return 0;
8733
8734	return 1;
8735}
8736
8737/**
8738 * smb21_lease_break_ack() - handler for smb2.1 lease break command
8739 * @work:	smb work containing lease break command buffer
8740 *
8741 * Return:	0
8742 */
8743static void smb21_lease_break_ack(struct ksmbd_work *work)
8744{
8745	struct ksmbd_conn *conn = work->conn;
8746	struct smb2_lease_ack *req;
8747	struct smb2_lease_ack *rsp;
8748	struct oplock_info *opinfo;
8749	__le32 err = 0;
8750	int ret = 0;
8751	unsigned int lease_change_type;
8752	__le32 lease_state;
8753	struct lease *lease;
8754
8755	WORK_BUFFERS(work, req, rsp);
8756
8757	ksmbd_debug(OPLOCK, "smb21 lease break, lease state(0x%x)\n",
8758		    le32_to_cpu(req->LeaseState));
8759	opinfo = lookup_lease_in_table(conn, req->LeaseKey);
8760	if (!opinfo) {
8761		ksmbd_debug(OPLOCK, "file not opened\n");
8762		smb2_set_err_rsp(work);
8763		rsp->hdr.Status = STATUS_UNSUCCESSFUL;
8764		return;
8765	}
8766	lease = opinfo->o_lease;
8767
8768	if (opinfo->op_state == OPLOCK_STATE_NONE) {
8769		pr_err("unexpected lease break state 0x%x\n",
8770		       opinfo->op_state);
8771		rsp->hdr.Status = STATUS_UNSUCCESSFUL;
8772		goto err_out;
8773	}
8774
8775	if (check_lease_state(lease, req->LeaseState)) {
8776		rsp->hdr.Status = STATUS_REQUEST_NOT_ACCEPTED;
8777		ksmbd_debug(OPLOCK,
8778			    "req lease state: 0x%x, expected state: 0x%x\n",
8779			    req->LeaseState, lease->new_state);
8780		goto err_out;
8781	}
8782
8783	if (!atomic_read(&opinfo->breaking_cnt)) {
8784		rsp->hdr.Status = STATUS_UNSUCCESSFUL;
8785		goto err_out;
8786	}
8787
8788	/* check for bad lease state */
8789	if (req->LeaseState &
8790	    (~(SMB2_LEASE_READ_CACHING_LE | SMB2_LEASE_HANDLE_CACHING_LE))) {
8791		err = STATUS_INVALID_OPLOCK_PROTOCOL;
8792		if (lease->state & SMB2_LEASE_WRITE_CACHING_LE)
8793			lease_change_type = OPLOCK_WRITE_TO_NONE;
8794		else
8795			lease_change_type = OPLOCK_READ_TO_NONE;
8796		ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n",
8797			    le32_to_cpu(lease->state),
8798			    le32_to_cpu(req->LeaseState));
8799	} else if (lease->state == SMB2_LEASE_READ_CACHING_LE &&
8800		   req->LeaseState != SMB2_LEASE_NONE_LE) {
8801		err = STATUS_INVALID_OPLOCK_PROTOCOL;
8802		lease_change_type = OPLOCK_READ_TO_NONE;
8803		ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n",
8804			    le32_to_cpu(lease->state),
8805			    le32_to_cpu(req->LeaseState));
8806	} else {
8807		/* valid lease state changes */
8808		err = STATUS_INVALID_DEVICE_STATE;
8809		if (req->LeaseState == SMB2_LEASE_NONE_LE) {
8810			if (lease->state & SMB2_LEASE_WRITE_CACHING_LE)
8811				lease_change_type = OPLOCK_WRITE_TO_NONE;
8812			else
8813				lease_change_type = OPLOCK_READ_TO_NONE;
8814		} else if (req->LeaseState & SMB2_LEASE_READ_CACHING_LE) {
8815			if (lease->state & SMB2_LEASE_WRITE_CACHING_LE)
8816				lease_change_type = OPLOCK_WRITE_TO_READ;
8817			else
8818				lease_change_type = OPLOCK_READ_HANDLE_TO_READ;
8819		} else {
8820			lease_change_type = 0;
8821		}
8822	}
8823
8824	switch (lease_change_type) {
8825	case OPLOCK_WRITE_TO_READ:
8826		ret = opinfo_write_to_read(opinfo);
8827		break;
8828	case OPLOCK_READ_HANDLE_TO_READ:
8829		ret = opinfo_read_handle_to_read(opinfo);
8830		break;
8831	case OPLOCK_WRITE_TO_NONE:
8832		ret = opinfo_write_to_none(opinfo);
8833		break;
8834	case OPLOCK_READ_TO_NONE:
8835		ret = opinfo_read_to_none(opinfo);
8836		break;
8837	default:
8838		ksmbd_debug(OPLOCK, "unknown lease change 0x%x -> 0x%x\n",
8839			    le32_to_cpu(lease->state),
8840			    le32_to_cpu(req->LeaseState));
8841	}
8842
8843	if (ret < 0) {
8844		rsp->hdr.Status = err;
8845		goto err_out;
8846	}
8847
8848	lease_state = lease->state;
8849
8850	rsp->StructureSize = cpu_to_le16(36);
8851	rsp->Reserved = 0;
8852	rsp->Flags = 0;
8853	memcpy(rsp->LeaseKey, req->LeaseKey, 16);
8854	rsp->LeaseState = lease_state;
8855	rsp->LeaseDuration = 0;
8856	ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lease_ack));
8857	if (ret) {
8858err_out:
8859		smb2_set_err_rsp(work);
8860	}
8861
8862	opinfo->op_state = OPLOCK_STATE_NONE;
8863	wake_up_interruptible_all(&opinfo->oplock_q);
8864	atomic_dec(&opinfo->breaking_cnt);
8865	wake_up_interruptible_all(&opinfo->oplock_brk);
8866	opinfo_put(opinfo);
8867}
8868
8869/**
8870 * smb2_oplock_break() - dispatcher for smb2.0 and 2.1 oplock/lease break
8871 * @work:	smb work containing oplock/lease break command buffer
8872 *
8873 * Return:	0 on success, otherwise error
8874 */
8875int smb2_oplock_break(struct ksmbd_work *work)
8876{
8877	struct smb2_oplock_break *req;
8878	struct smb2_oplock_break *rsp;
8879
8880	ksmbd_debug(SMB, "Received smb2 oplock break acknowledgment request\n");
8881
8882	WORK_BUFFERS(work, req, rsp);
8883
8884	switch (le16_to_cpu(req->StructureSize)) {
8885	case OP_BREAK_STRUCT_SIZE_20:
8886		smb20_oplock_break_ack(work);
8887		break;
8888	case OP_BREAK_STRUCT_SIZE_21:
8889		smb21_lease_break_ack(work);
8890		break;
8891	default:
8892		ksmbd_debug(OPLOCK, "invalid break cmd %d\n",
8893			    le16_to_cpu(req->StructureSize));
8894		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
8895		smb2_set_err_rsp(work);
8896		return -EINVAL;
8897	}
8898
8899	return 0;
8900}
8901
8902/**
8903 * smb2_notify() - handler for smb2 notify request
8904 * @work:   smb work containing notify command buffer
8905 *
8906 * Return:      0 on success, otherwise error
8907 */
8908int smb2_notify(struct ksmbd_work *work)
8909{
8910	struct smb2_change_notify_req *req;
8911	struct smb2_change_notify_rsp *rsp;
8912
8913	ksmbd_debug(SMB, "Received smb2 notify\n");
8914
8915	WORK_BUFFERS(work, req, rsp);
8916
8917	if (work->next_smb2_rcv_hdr_off && req->hdr.NextCommand) {
8918		rsp->hdr.Status = STATUS_INTERNAL_ERROR;
8919		smb2_set_err_rsp(work);
8920		return -EIO;
8921	}
8922
8923	smb2_set_err_rsp(work);
8924	rsp->hdr.Status = STATUS_NOT_IMPLEMENTED;
8925	return -EOPNOTSUPP;
8926}
8927
8928/**
8929 * smb2_is_sign_req() - handler for checking packet signing status
8930 * @work:	smb work containing notify command buffer
8931 * @command:	SMB2 command id
8932 *
8933 * Return:	true if packed is signed, false otherwise
8934 */
8935bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command)
8936{
8937	struct smb2_hdr *rcv_hdr2 = smb_get_msg(work->request_buf);
8938
8939	if ((rcv_hdr2->Flags & SMB2_FLAGS_SIGNED) &&
8940	    command != SMB2_NEGOTIATE_HE &&
8941	    command != SMB2_SESSION_SETUP_HE &&
8942	    command != SMB2_OPLOCK_BREAK_HE)
8943		return true;
8944
8945	return false;
8946}
8947
8948/**
8949 * smb2_check_sign_req() - handler for req packet sign processing
8950 * @work:   smb work containing notify command buffer
8951 *
8952 * Return:	1 on success, 0 otherwise
8953 */
8954int smb2_check_sign_req(struct ksmbd_work *work)
8955{
8956	struct smb2_hdr *hdr;
8957	char signature_req[SMB2_SIGNATURE_SIZE];
8958	char signature[SMB2_HMACSHA256_SIZE];
8959	struct kvec iov[1];
8960	size_t len;
8961
8962	hdr = smb_get_msg(work->request_buf);
8963	if (work->next_smb2_rcv_hdr_off)
8964		hdr = ksmbd_req_buf_next(work);
8965
8966	if (!hdr->NextCommand && !work->next_smb2_rcv_hdr_off)
8967		len = get_rfc1002_len(work->request_buf);
8968	else if (hdr->NextCommand)
8969		len = le32_to_cpu(hdr->NextCommand);
8970	else
8971		len = get_rfc1002_len(work->request_buf) -
8972			work->next_smb2_rcv_hdr_off;
8973
8974	memcpy(signature_req, hdr->Signature, SMB2_SIGNATURE_SIZE);
8975	memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
8976
8977	iov[0].iov_base = (char *)&hdr->ProtocolId;
8978	iov[0].iov_len = len;
8979
8980	ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, 1,
8981			    signature);
8982
8983	if (crypto_memneq(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
8984		pr_err("bad smb2 signature\n");
8985		return 0;
8986	}
8987
8988	return 1;
8989}
8990
8991/**
8992 * smb2_set_sign_rsp() - handler for rsp packet sign processing
8993 * @work:   smb work containing notify command buffer
8994 *
8995 */
8996void smb2_set_sign_rsp(struct ksmbd_work *work)
8997{
8998	struct smb2_hdr *hdr;
8999	char signature[SMB2_HMACSHA256_SIZE];
9000	struct kvec *iov;
9001	int n_vec = 1;
9002
9003	hdr = ksmbd_resp_buf_curr(work);
9004	hdr->Flags |= SMB2_FLAGS_SIGNED;
9005	memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
9006
9007	if (hdr->Command == SMB2_READ) {
9008		iov = &work->iov[work->iov_idx - 1];
9009		n_vec++;
9010	} else {
9011		iov = &work->iov[work->iov_idx];
9012	}
9013
9014	ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec,
9015			    signature);
9016	memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
9017}
9018
9019/**
9020 * smb3_check_sign_req() - handler for req packet sign processing
9021 * @work:   smb work containing notify command buffer
9022 *
9023 * Return:	1 on success, 0 otherwise
9024 */
9025int smb3_check_sign_req(struct ksmbd_work *work)
9026{
9027	struct ksmbd_conn *conn = work->conn;
9028	char *signing_key;
9029	struct smb2_hdr *hdr;
9030	struct channel *chann;
9031	char signature_req[SMB2_SIGNATURE_SIZE];
9032	char signature[SMB2_CMACAES_SIZE];
9033	struct kvec iov[1];
9034	size_t len;
9035
9036	hdr = smb_get_msg(work->request_buf);
9037	if (work->next_smb2_rcv_hdr_off)
9038		hdr = ksmbd_req_buf_next(work);
9039
9040	if (!hdr->NextCommand && !work->next_smb2_rcv_hdr_off)
9041		len = get_rfc1002_len(work->request_buf);
9042	else if (hdr->NextCommand)
9043		len = le32_to_cpu(hdr->NextCommand);
9044	else
9045		len = get_rfc1002_len(work->request_buf) -
9046			work->next_smb2_rcv_hdr_off;
9047
9048	if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
9049		signing_key = work->sess->smb3signingkey;
9050	} else {
9051		chann = lookup_chann_list(work->sess, conn);
9052		if (!chann) {
9053			return 0;
9054		}
9055		signing_key = chann->smb3signingkey;
9056	}
9057
9058	if (!signing_key) {
9059		pr_err("SMB3 signing key is not generated\n");
9060		return 0;
9061	}
9062
9063	memcpy(signature_req, hdr->Signature, SMB2_SIGNATURE_SIZE);
9064	memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
9065	iov[0].iov_base = (char *)&hdr->ProtocolId;
9066	iov[0].iov_len = len;
9067
9068	if (ksmbd_sign_smb3_pdu(conn, signing_key, iov, 1, signature))
9069		return 0;
9070
9071	if (crypto_memneq(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
9072		pr_err("bad smb2 signature\n");
9073		return 0;
9074	}
9075
9076	return 1;
9077}
9078
9079/**
9080 * smb3_set_sign_rsp() - handler for rsp packet sign processing
9081 * @work:   smb work containing notify command buffer
9082 *
9083 */
9084void smb3_set_sign_rsp(struct ksmbd_work *work)
9085{
9086	struct ksmbd_conn *conn = work->conn;
9087	struct smb2_hdr *hdr;
9088	struct channel *chann;
9089	char signature[SMB2_CMACAES_SIZE];
9090	struct kvec *iov;
9091	int n_vec = 1;
9092	char *signing_key;
9093
9094	hdr = ksmbd_resp_buf_curr(work);
9095
9096	if (conn->binding == false &&
9097	    le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) {
9098		signing_key = work->sess->smb3signingkey;
9099	} else {
9100		chann = lookup_chann_list(work->sess, work->conn);
9101		if (!chann) {
9102			return;
9103		}
9104		signing_key = chann->smb3signingkey;
9105	}
9106
9107	if (!signing_key)
9108		return;
9109
9110	hdr->Flags |= SMB2_FLAGS_SIGNED;
9111	memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
9112
9113	if (hdr->Command == SMB2_READ) {
9114		iov = &work->iov[work->iov_idx - 1];
9115		n_vec++;
9116	} else {
9117		iov = &work->iov[work->iov_idx];
9118	}
9119
9120	if (!ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec,
9121				 signature))
9122		memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
9123}
9124
9125/**
9126 * smb3_preauth_hash_rsp() - handler for computing preauth hash on response
9127 * @work:   smb work containing response buffer
9128 *
9129 */
9130void smb3_preauth_hash_rsp(struct ksmbd_work *work)
9131{
9132	struct ksmbd_conn *conn = work->conn;
9133	struct ksmbd_session *sess = work->sess;
9134	struct smb2_hdr *req, *rsp;
9135
9136	if (conn->dialect != SMB311_PROT_ID)
9137		return;
9138
9139	WORK_BUFFERS(work, req, rsp);
9140
9141	if (le16_to_cpu(req->Command) == SMB2_NEGOTIATE_HE &&
9142	    conn->preauth_info)
9143		ksmbd_gen_preauth_integrity_hash(conn, work->response_buf,
9144						 conn->preauth_info->Preauth_HashValue);
9145
9146	if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE && sess) {
9147		__u8 *hash_value;
9148
9149		if (conn->binding) {
9150			struct preauth_session *preauth_sess;
9151
9152			preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
9153			if (!preauth_sess)
9154				return;
9155			hash_value = preauth_sess->Preauth_HashValue;
9156		} else {
9157			hash_value = sess->Preauth_HashValue;
9158			if (!hash_value)
9159				return;
9160		}
9161		ksmbd_gen_preauth_integrity_hash(conn, work->response_buf,
9162						 hash_value);
9163	}
9164}
9165
9166static void fill_transform_hdr(void *tr_buf, char *old_buf, __le16 cipher_type)
9167{
9168	struct smb2_transform_hdr *tr_hdr = tr_buf + 4;
9169	struct smb2_hdr *hdr = smb_get_msg(old_buf);
9170	unsigned int orig_len = get_rfc1002_len(old_buf);
9171
9172	/* tr_buf must be cleared by the caller */
9173	tr_hdr->ProtocolId = SMB2_TRANSFORM_PROTO_NUM;
9174	tr_hdr->OriginalMessageSize = cpu_to_le32(orig_len);
9175	tr_hdr->Flags = cpu_to_le16(TRANSFORM_FLAG_ENCRYPTED);
9176	if (cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
9177	    cipher_type == SMB2_ENCRYPTION_AES256_GCM)
9178		get_random_bytes(&tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
9179	else
9180		get_random_bytes(&tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
9181	memcpy(&tr_hdr->SessionId, &hdr->SessionId, 8);
9182	inc_rfc1001_len(tr_buf, sizeof(struct smb2_transform_hdr));
9183	inc_rfc1001_len(tr_buf, orig_len);
9184}
9185
9186int smb3_encrypt_resp(struct ksmbd_work *work)
9187{
9188	struct kvec *iov = work->iov;
9189	int rc = -ENOMEM;
9190	void *tr_buf;
9191
9192	tr_buf = kzalloc(sizeof(struct smb2_transform_hdr) + 4, KSMBD_DEFAULT_GFP);
9193	if (!tr_buf)
9194		return rc;
9195
9196	/* fill transform header */
9197	fill_transform_hdr(tr_buf, work->response_buf, work->conn->cipher_type);
9198
9199	iov[0].iov_base = tr_buf;
9200	iov[0].iov_len = sizeof(struct smb2_transform_hdr) + 4;
9201	work->tr_buf = tr_buf;
9202
9203	return ksmbd_crypt_message(work, iov, work->iov_idx + 1, 1);
9204}
9205
9206bool smb3_is_transform_hdr(void *buf)
9207{
9208	struct smb2_transform_hdr *trhdr = smb_get_msg(buf);
9209
9210	return trhdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM;
9211}
9212
9213int smb3_decrypt_req(struct ksmbd_work *work)
9214{
9215	struct ksmbd_session *sess;
9216	char *buf = work->request_buf;
9217	unsigned int pdu_length = get_rfc1002_len(buf);
9218	struct kvec iov[2];
9219	int buf_data_size = pdu_length - sizeof(struct smb2_transform_hdr);
9220	struct smb2_transform_hdr *tr_hdr = smb_get_msg(buf);
9221	int rc = 0;
9222
9223	if (pdu_length < sizeof(struct smb2_transform_hdr) ||
9224	    buf_data_size < sizeof(struct smb2_hdr)) {
9225		pr_err("Transform message is too small (%u)\n",
9226		       pdu_length);
9227		return -ECONNABORTED;
9228	}
9229
9230	if (buf_data_size < le32_to_cpu(tr_hdr->OriginalMessageSize)) {
9231		pr_err("Transform message is broken\n");
9232		return -ECONNABORTED;
9233	}
9234
9235	sess = ksmbd_session_lookup_all(work->conn, le64_to_cpu(tr_hdr->SessionId));
9236	if (!sess) {
9237		pr_err("invalid session id(%llx) in transform header\n",
9238		       le64_to_cpu(tr_hdr->SessionId));
9239		return -ECONNABORTED;
9240	}
9241	ksmbd_user_session_put(sess);
9242
9243	iov[0].iov_base = buf;
9244	iov[0].iov_len = sizeof(struct smb2_transform_hdr) + 4;
9245	iov[1].iov_base = buf + sizeof(struct smb2_transform_hdr) + 4;
9246	iov[1].iov_len = buf_data_size;
9247	rc = ksmbd_crypt_message(work, iov, 2, 0);
9248	if (rc)
9249		return rc;
9250
9251	memmove(buf + 4, iov[1].iov_base, buf_data_size);
9252	*(__be32 *)buf = cpu_to_be32(buf_data_size);
9253
9254	return rc;
9255}
9256
9257bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work)
9258{
9259	struct ksmbd_conn *conn = work->conn;
9260	struct ksmbd_session *sess = work->sess;
9261	struct smb2_hdr *rsp = smb_get_msg(work->response_buf);
9262
9263	if (conn->dialect < SMB30_PROT_ID)
9264		return false;
9265
9266	if (work->next_smb2_rcv_hdr_off)
9267		rsp = ksmbd_resp_buf_next(work);
9268
9269	if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE &&
9270	    sess->user && !user_guest(sess->user) &&
9271	    rsp->Status == STATUS_SUCCESS)
9272		return true;
9273	return false;
9274}
~/ Read-only file preview.