Merge tag 'objtool-core-2023-04-27' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-block.git] / fs / cifs / smb2pdu.c
CommitLineData
929be906 1// SPDX-License-Identifier: LGPL-2.1
ec2e4523 2/*
ec2e4523 3 *
2b80d049 4 * Copyright (C) International Business Machines Corp., 2009, 2013
ec2e4523
PS
5 * Etersoft, 2012
6 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Pavel Shilovsky (pshilovsky@samba.org) 2012
8 *
9 * Contains the routines for constructing the SMB2 PDUs themselves
10 *
ec2e4523
PS
11 */
12
13 /* SMB2 PDU handling routines here - except for leftovers (eg session setup) */
14 /* Note that there are handle based routines which must be */
15 /* treated slightly differently for reconnection purposes since we never */
16 /* want to reuse a stale file handle and only the caller knows the file info */
17
18#include <linux/fs.h>
19#include <linux/kernel.h>
20#include <linux/vfs.h>
09a4707e 21#include <linux/task_io_accounting_ops.h>
ec2e4523 22#include <linux/uaccess.h>
c6e970a0 23#include <linux/uuid.h>
33319141 24#include <linux/pagemap.h>
ec2e4523 25#include <linux/xattr.h>
ec2e4523
PS
26#include "cifsglob.h"
27#include "cifsacl.h"
28#include "cifsproto.h"
29#include "smb2proto.h"
30#include "cifs_unicode.h"
31#include "cifs_debug.h"
32#include "ntlmssp.h"
33#include "smb2status.h"
09a4707e 34#include "smb2glob.h"
d324f08d 35#include "cifspdu.h"
ceb1b0b9 36#include "cifs_spnego.h"
db223a59 37#include "smbdirect.h"
eccb4422 38#include "trace.h"
a3a53b76
PA
39#ifdef CONFIG_CIFS_DFS_UPCALL
40#include "dfs_cache.h"
41#endif
05b98fd2 42#include "cached_dir.h"
ec2e4523
PS
43
44/*
45 * The following table defines the expected "StructureSize" of SMB2 requests
46 * in order by SMB2 command. This is similar to "wct" in SMB/CIFS requests.
47 *
48 * Note that commands are defined in smb2pdu.h in le16 but the array below is
49 * indexed by command in host byte order.
50 */
51static const int smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
52 /* SMB2_NEGOTIATE */ 36,
53 /* SMB2_SESSION_SETUP */ 25,
54 /* SMB2_LOGOFF */ 4,
55 /* SMB2_TREE_CONNECT */ 9,
56 /* SMB2_TREE_DISCONNECT */ 4,
57 /* SMB2_CREATE */ 57,
58 /* SMB2_CLOSE */ 24,
59 /* SMB2_FLUSH */ 24,
60 /* SMB2_READ */ 49,
61 /* SMB2_WRITE */ 49,
62 /* SMB2_LOCK */ 48,
63 /* SMB2_IOCTL */ 57,
64 /* SMB2_CANCEL */ 4,
65 /* SMB2_ECHO */ 4,
66 /* SMB2_QUERY_DIRECTORY */ 33,
67 /* SMB2_CHANGE_NOTIFY */ 32,
68 /* SMB2_QUERY_INFO */ 41,
69 /* SMB2_SET_INFO */ 33,
70 /* SMB2_OPLOCK_BREAK */ 24 /* BB this is 36 for LEASE_BREAK variant */
71};
72
730928c8 73int smb3_encryption_required(const struct cifs_tcon *tcon)
7fb8986e 74{
edb16135 75 if (!tcon || !tcon->ses)
ae6f8dd4 76 return 0;
7fb8986e
PS
77 if ((tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) ||
78 (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA))
79 return 1;
ae6f8dd4
PS
80 if (tcon->seal &&
81 (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
82 return 1;
7fb8986e
PS
83 return 0;
84}
ec2e4523
PS
85
86static void
0d35e382 87smb2_hdr_assemble(struct smb2_hdr *shdr, __le16 smb2_cmd,
352d96f3
AA
88 const struct cifs_tcon *tcon,
89 struct TCP_Server_Info *server)
ec2e4523 90{
31473fc4
PS
91 shdr->ProtocolId = SMB2_PROTO_NUMBER;
92 shdr->StructureSize = cpu_to_le16(64);
93 shdr->Command = smb2_cmd;
352d96f3 94 if (server) {
7d414f39 95 spin_lock(&server->req_lock);
69dc4b18 96 /* Request up to 10 credits but don't go over the limit. */
141891f4 97 if (server->credits >= server->max_credits)
31473fc4 98 shdr->CreditRequest = cpu_to_le16(0);
7d414f39 99 else
31473fc4 100 shdr->CreditRequest = cpu_to_le16(
141891f4 101 min_t(int, server->max_credits -
69dc4b18 102 server->credits, 10));
7d414f39
RL
103 spin_unlock(&server->req_lock);
104 } else {
31473fc4 105 shdr->CreditRequest = cpu_to_le16(2);
7d414f39 106 }
0d35e382 107 shdr->Id.SyncId.ProcessId = cpu_to_le32((__u16)current->tgid);
ec2e4523
PS
108
109 if (!tcon)
110 goto out;
111
2b80d049
SF
112 /* GLOBAL_CAP_LARGE_MTU will only be set if dialect > SMB2.02 */
113 /* See sections 2.2.4 and 3.2.4.1.5 of MS-SMB2 */
352d96f3 114 if (server && (server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
31473fc4 115 shdr->CreditCharge = cpu_to_le16(1);
2b80d049
SF
116 /* else CreditCharge MBZ */
117
0d35e382 118 shdr->Id.SyncId.TreeId = cpu_to_le32(tcon->tid);
ec2e4523
PS
119 /* Uid is not converted */
120 if (tcon->ses)
0d35e382 121 shdr->SessionId = cpu_to_le64(tcon->ses->Suid);
f87ab88b
SF
122
123 /*
124 * If we would set SMB2_FLAGS_DFS_OPERATIONS on open we also would have
125 * to pass the path on the Open SMB prefixed by \\server\share.
126 * Not sure when we would need to do the augmented path (if ever) and
127 * setting this flag breaks the SMB2 open operation since it is
128 * illegal to send an empty path name (without \\server\share prefix)
129 * when the DFS flag is set in the SMB open header. We could
130 * consider setting the flag on all operations other than open
131 * but it is safer to net set it for now.
132 */
133/* if (tcon->share_flags & SHI1005_FLAGS_DFS)
31473fc4 134 shdr->Flags |= SMB2_FLAGS_DFS_OPERATIONS; */
f87ab88b 135
352d96f3 136 if (server && server->sign && !smb3_encryption_required(tcon))
31473fc4 137 shdr->Flags |= SMB2_FLAGS_SIGNED;
ec2e4523 138out:
ec2e4523
PS
139 return;
140}
141
142static int
352d96f3
AA
143smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
144 struct TCP_Server_Info *server)
ec2e4523 145{
350f4a56 146 int rc = 0;
c24bb1a8 147 struct nls_table *nls_codepage = NULL;
aa24d1e9 148 struct cifs_ses *ses;
aa24d1e9
PS
149
150 /*
151 * SMB2s NegProt, SessSetup, Logoff do not have tcon yet so
152 * check for tcp and smb session status done differently
153 * for those three - in the calling routine.
154 */
155 if (tcon == NULL)
7ffbe655 156 return 0;
aa24d1e9 157
c88f7dcd
PA
158 /*
159 * Need to also skip SMB2_IOCTL because it is used for checking nested dfs links in
160 * cifs_tree_connect().
161 */
162 if (smb2_command == SMB2_TREE_CONNECT || smb2_command == SMB2_IOCTL)
7ffbe655 163 return 0;
aa24d1e9 164
d7d7a66a 165 spin_lock(&tcon->tc_lock);
fdf59eb5 166 if (tcon->status == TID_EXITING) {
aa24d1e9 167 /*
491eafce 168 * only tree disconnect allowed when disconnecting ...
aa24d1e9 169 */
491eafce 170 if (smb2_command != SMB2_TREE_DISCONNECT) {
d7d7a66a 171 spin_unlock(&tcon->tc_lock);
f96637be
JP
172 cifs_dbg(FYI, "can not send cmd %d while umounting\n",
173 smb2_command);
aa24d1e9
PS
174 return -ENODEV;
175 }
176 }
d7d7a66a 177 spin_unlock(&tcon->tc_lock);
dd3cd870 178 if ((!tcon->ses) || (tcon->ses->ses_status == SES_EXITING) ||
352d96f3 179 (!tcon->ses->server) || !server)
aa24d1e9
PS
180 return -EIO;
181
1bcd548d
PA
182 spin_lock(&server->srv_lock);
183 if (server->tcpStatus == CifsNeedReconnect) {
184 /*
185 * Return to caller for TREE_DISCONNECT and LOGOFF and CLOSE
186 * here since they are implicitly done when session drops.
187 */
188 switch (smb2_command) {
189 /*
190 * BB Should we keep oplock break and add flush to exceptions?
191 */
192 case SMB2_TREE_DISCONNECT:
193 case SMB2_CANCEL:
194 case SMB2_CLOSE:
195 case SMB2_OPLOCK_BREAK:
196 spin_unlock(&server->srv_lock);
197 return -EAGAIN;
198 }
199 }
200 spin_unlock(&server->srv_lock);
201
bc962159 202again:
1bcd548d 203 rc = cifs_wait_for_server_reconnect(server, tcon->retry);
3c0070f5
PA
204 if (rc)
205 return rc;
a3a53b76 206
3c0070f5 207 ses = tcon->ses;
aa24d1e9 208
d1a931ce
SP
209 spin_lock(&ses->chan_lock);
210 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) {
211 spin_unlock(&ses->chan_lock);
7ffbe655 212 return 0;
d1a931ce 213 }
88b024f5 214 spin_unlock(&ses->chan_lock);
d1a931ce
SP
215 cifs_dbg(FYI, "sess reconnect mask: 0x%lx, tcon reconnect: %d",
216 tcon->ses->chans_need_reconnect,
217 tcon->need_reconnect);
aa24d1e9 218
bc962159 219 mutex_lock(&ses->session_mutex);
76e75270
SC
220 /*
221 * Recheck after acquire mutex. If another thread is negotiating
222 * and the server never sends an answer the socket will be closed
223 * and tcpStatus set to reconnect.
224 */
d7d7a66a 225 spin_lock(&server->srv_lock);
76e75270 226 if (server->tcpStatus == CifsNeedReconnect) {
d7d7a66a 227 spin_unlock(&server->srv_lock);
bc962159
SP
228 mutex_unlock(&ses->session_mutex);
229
230 if (tcon->retry)
231 goto again;
232
76e75270 233 rc = -EHOSTDOWN;
76e75270
SC
234 goto out;
235 }
d7d7a66a 236 spin_unlock(&server->srv_lock);
76e75270 237
c24bb1a8
PA
238 nls_codepage = load_nls_default();
239
d1a931ce
SP
240 /*
241 * need to prevent multiple threads trying to simultaneously
242 * reconnect the same SMB session
243 */
bc962159 244 spin_lock(&ses->ses_lock);
d1a931ce 245 spin_lock(&ses->chan_lock);
bc962159
SP
246 if (!cifs_chan_needs_reconnect(ses, server) &&
247 ses->ses_status == SES_GOOD) {
d1a931ce 248 spin_unlock(&ses->chan_lock);
bc962159 249 spin_unlock(&ses->ses_lock);
f486ef8e 250 /* this means that we only need to tree connect */
d1a931ce
SP
251 if (tcon->need_reconnect)
252 goto skip_sess_setup;
253
bc962159 254 mutex_unlock(&ses->session_mutex);
d1a931ce
SP
255 goto out;
256 }
257 spin_unlock(&ses->chan_lock);
bc962159 258 spin_unlock(&ses->ses_lock);
d1a931ce 259
f486ef8e 260 rc = cifs_negotiate_protocol(0, ses, server);
d1a931ce 261 if (!rc) {
f486ef8e 262 rc = cifs_setup_session(0, ses, server, nls_codepage);
b0dd940e 263 if ((rc == -EACCES) && !tcon->retry) {
f486ef8e 264 mutex_unlock(&ses->session_mutex);
73f9bfbe 265 rc = -EHOSTDOWN;
b0dd940e 266 goto failed;
8ea21823
SP
267 } else if (rc) {
268 mutex_unlock(&ses->session_mutex);
269 goto out;
b0dd940e 270 }
3663c904 271 } else {
73f9bfbe 272 mutex_unlock(&ses->session_mutex);
aa24d1e9
PS
273 goto out;
274 }
275
d1a931ce 276skip_sess_setup:
3663c904
SP
277 if (!tcon->need_reconnect) {
278 mutex_unlock(&ses->session_mutex);
279 goto out;
280 }
aa24d1e9 281 cifs_mark_open_files_invalid(tcon);
96a988ff
PS
282 if (tcon->use_persistent)
283 tcon->need_reopen_files = true;
52ace1ef 284
565674d6 285 rc = cifs_tree_connect(0, tcon, nls_codepage);
73f9bfbe 286 mutex_unlock(&ses->session_mutex);
52ace1ef 287
f96637be 288 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
c318e6c2
SF
289 if (rc) {
290 /* If sess reconnected but tcon didn't, something strange ... */
bc962159 291 cifs_dbg(VFS, "reconnect tcon failed rc = %d\n", rc);
aa24d1e9 292 goto out;
c318e6c2 293 }
96a988ff
PS
294
295 if (smb2_command != SMB2_INTERNAL_CMD)
b08484d7 296 mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
96a988ff 297
aa24d1e9 298 atomic_inc(&tconInfoReconnectCount);
aa24d1e9
PS
299out:
300 /*
301 * Check if handle based operation so we know whether we can continue
302 * or not without returning to caller to reset file handle.
303 */
304 /*
305 * BB Is flush done by server on drop of tcp session? Should we special
306 * case it and skip above?
307 */
308 switch (smb2_command) {
309 case SMB2_FLUSH:
310 case SMB2_READ:
311 case SMB2_WRITE:
312 case SMB2_LOCK:
aa24d1e9
PS
313 case SMB2_QUERY_DIRECTORY:
314 case SMB2_CHANGE_NOTIFY:
315 case SMB2_QUERY_INFO:
316 case SMB2_SET_INFO:
4772c795 317 rc = -EAGAIN;
aa24d1e9 318 }
b0dd940e 319failed:
aa24d1e9 320 unload_nls(nls_codepage);
ec2e4523
PS
321 return rc;
322}
323
cb200bd6 324static void
352d96f3
AA
325fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon,
326 struct TCP_Server_Info *server,
327 void *buf,
cb200bd6
PS
328 unsigned int *total_len)
329{
0f46608a 330 struct smb2_pdu *spdu = buf;
cb200bd6
PS
331 /* lookup word count ie StructureSize from table */
332 __u16 parmsize = smb2_req_struct_sizes[le16_to_cpu(smb2_command)];
333
334 /*
335 * smaller than SMALL_BUFFER_SIZE but bigger than fixed area of
336 * largest operations (Create)
337 */
338 memset(buf, 0, 256);
339
0d35e382 340 smb2_hdr_assemble(&spdu->hdr, smb2_command, tcon, server);
cb200bd6
PS
341 spdu->StructureSize2 = cpu_to_le16(parmsize);
342
0d35e382 343 *total_len = parmsize + sizeof(struct smb2_hdr);
cb200bd6
PS
344}
345
ec2e4523
PS
346/*
347 * Allocate and return pointer to an SMB request hdr, and set basic
348 * SMB information in the SMB header. If the return code is zero, this
305428ac 349 * function must have filled in request_buf pointer.
ec2e4523 350 */
84a1f5b1 351static int __smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
352d96f3
AA
352 struct TCP_Server_Info *server,
353 void **request_buf, unsigned int *total_len)
ec2e4523 354{
ec2e4523 355 /* BB eventually switch this to SMB2 specific small buf size */
f46ecbd9
SB
356 if (smb2_command == SMB2_SET_INFO)
357 *request_buf = cifs_buf_get();
358 else
359 *request_buf = cifs_small_buf_get();
ec2e4523
PS
360 if (*request_buf == NULL) {
361 /* BB should we add a retry in here if not a writepage? */
362 return -ENOMEM;
363 }
364
352d96f3 365 fill_small_buf(smb2_command, tcon, server,
0d35e382 366 (struct smb2_hdr *)(*request_buf),
305428ac 367 total_len);
ec2e4523
PS
368
369 if (tcon != NULL) {
ec2e4523
PS
370 uint16_t com_code = le16_to_cpu(smb2_command);
371 cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_sent[com_code]);
ec2e4523
PS
372 cifs_stats_inc(&tcon->num_smbs_sent);
373 }
374
84a1f5b1
PAS
375 return 0;
376}
377
378static int smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
352d96f3 379 struct TCP_Server_Info *server,
84a1f5b1
PAS
380 void **request_buf, unsigned int *total_len)
381{
382 int rc;
383
352d96f3 384 rc = smb2_reconnect(smb2_command, tcon, server);
84a1f5b1
PAS
385 if (rc)
386 return rc;
387
352d96f3 388 return __smb2_plain_req_init(smb2_command, tcon, server, request_buf,
84a1f5b1
PAS
389 total_len);
390}
391
392static int smb2_ioctl_req_init(u32 opcode, struct cifs_tcon *tcon,
352d96f3 393 struct TCP_Server_Info *server,
84a1f5b1
PAS
394 void **request_buf, unsigned int *total_len)
395{
396 /* Skip reconnect only for FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs */
397 if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO) {
352d96f3
AA
398 return __smb2_plain_req_init(SMB2_IOCTL, tcon, server,
399 request_buf, total_len);
84a1f5b1 400 }
352d96f3
AA
401 return smb2_plain_req_init(SMB2_IOCTL, tcon, server,
402 request_buf, total_len);
ec2e4523
PS
403}
404
d7bef4c4 405/* For explanation of negotiate contexts see MS-SMB2 section 2.2.3.1 */
ebb3a9d4
SF
406
407static void
408build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt)
409{
410 pneg_ctxt->ContextType = SMB2_PREAUTH_INTEGRITY_CAPABILITIES;
411 pneg_ctxt->DataLength = cpu_to_le16(38);
412 pneg_ctxt->HashAlgorithmCount = cpu_to_le16(1);
fc0b3844
RS
413 pneg_ctxt->SaltLength = cpu_to_le16(SMB311_SALT_SIZE);
414 get_random_bytes(pneg_ctxt->Salt, SMB311_SALT_SIZE);
ebb3a9d4
SF
415 pneg_ctxt->HashAlgorithms = SMB2_PREAUTH_INTEGRITY_SHA512;
416}
417
26ea888f
SF
418static void
419build_compression_ctxt(struct smb2_compression_capabilities_context *pneg_ctxt)
420{
421 pneg_ctxt->ContextType = SMB2_COMPRESSION_CAPABILITIES;
422 pneg_ctxt->DataLength =
423 cpu_to_le16(sizeof(struct smb2_compression_capabilities_context)
424 - sizeof(struct smb2_neg_context));
425 pneg_ctxt->CompressionAlgorithmCount = cpu_to_le16(3);
426 pneg_ctxt->CompressionAlgorithms[0] = SMB3_COMPRESS_LZ77;
427 pneg_ctxt->CompressionAlgorithms[1] = SMB3_COMPRESS_LZ77_HUFF;
428 pneg_ctxt->CompressionAlgorithms[2] = SMB3_COMPRESS_LZNT1;
429}
430
53d31a3f
SF
431static unsigned int
432build_signing_ctxt(struct smb2_signing_capabilities *pneg_ctxt)
433{
434 unsigned int ctxt_len = sizeof(struct smb2_signing_capabilities);
435 unsigned short num_algs = 1; /* number of signing algorithms sent */
436
437 pneg_ctxt->ContextType = SMB2_SIGNING_CAPABILITIES;
438 /*
439 * Context Data length must be rounded to multiple of 8 for some servers
440 */
d7173623
EM
441 pneg_ctxt->DataLength = cpu_to_le16(ALIGN(sizeof(struct smb2_signing_capabilities) -
442 sizeof(struct smb2_neg_context) +
443 (num_algs * sizeof(u16)), 8));
53d31a3f
SF
444 pneg_ctxt->SigningAlgorithmCount = cpu_to_le16(num_algs);
445 pneg_ctxt->SigningAlgorithms[0] = cpu_to_le16(SIGNING_ALG_AES_CMAC);
446
d7173623
EM
447 ctxt_len += sizeof(__le16) * num_algs;
448 ctxt_len = ALIGN(ctxt_len, 8);
53d31a3f
SF
449 return ctxt_len;
450 /* TBD add SIGNING_ALG_AES_GMAC and/or SIGNING_ALG_HMAC_SHA256 */
451}
452
ebb3a9d4
SF
453static void
454build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt)
455{
456 pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES;
fbfd0b46
SF
457 if (require_gcm_256) {
458 pneg_ctxt->DataLength = cpu_to_le16(4); /* Cipher Count + 1 cipher */
459 pneg_ctxt->CipherCount = cpu_to_le16(1);
460 pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES256_GCM;
29e27923
SF
461 } else if (enable_gcm_256) {
462 pneg_ctxt->DataLength = cpu_to_le16(8); /* Cipher Count + 3 ciphers */
463 pneg_ctxt->CipherCount = cpu_to_le16(3);
464 pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;
465 pneg_ctxt->Ciphers[1] = SMB2_ENCRYPTION_AES256_GCM;
466 pneg_ctxt->Ciphers[2] = SMB2_ENCRYPTION_AES128_CCM;
fbfd0b46
SF
467 } else {
468 pneg_ctxt->DataLength = cpu_to_le16(6); /* Cipher Count + 2 ciphers */
469 pneg_ctxt->CipherCount = cpu_to_le16(2);
470 pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;
471 pneg_ctxt->Ciphers[1] = SMB2_ENCRYPTION_AES128_CCM;
472 }
ebb3a9d4
SF
473}
474
96d3cca1
SF
475static unsigned int
476build_netname_ctxt(struct smb2_netname_neg_context *pneg_ctxt, char *hostname)
477{
478 struct nls_table *cp = load_nls_default();
479
480 pneg_ctxt->ContextType = SMB2_NETNAME_NEGOTIATE_CONTEXT_ID;
481
482 /* copy up to max of first 100 bytes of server name to NetName field */
df58fae7 483 pneg_ctxt->DataLength = cpu_to_le16(2 * cifs_strtoUTF16(pneg_ctxt->NetName, hostname, 100, cp));
96d3cca1 484 /* context size is DataLength + minimal smb2_neg_context */
d7173623 485 return ALIGN(le16_to_cpu(pneg_ctxt->DataLength) + sizeof(struct smb2_neg_context), 8);
96d3cca1
SF
486}
487
fcef0db6
SF
488static void
489build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
490{
491 pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE;
492 pneg_ctxt->DataLength = cpu_to_le16(POSIX_CTXT_DATA_LEN);
0d481325
SF
493 /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
494 pneg_ctxt->Name[0] = 0x93;
495 pneg_ctxt->Name[1] = 0xAD;
496 pneg_ctxt->Name[2] = 0x25;
497 pneg_ctxt->Name[3] = 0x50;
498 pneg_ctxt->Name[4] = 0x9C;
499 pneg_ctxt->Name[5] = 0xB4;
500 pneg_ctxt->Name[6] = 0x11;
501 pneg_ctxt->Name[7] = 0xE7;
502 pneg_ctxt->Name[8] = 0xB4;
503 pneg_ctxt->Name[9] = 0x23;
504 pneg_ctxt->Name[10] = 0x83;
505 pneg_ctxt->Name[11] = 0xDE;
506 pneg_ctxt->Name[12] = 0x96;
507 pneg_ctxt->Name[13] = 0x8B;
508 pneg_ctxt->Name[14] = 0xCD;
509 pneg_ctxt->Name[15] = 0x7C;
fcef0db6
SF
510}
511
ebb3a9d4 512static void
13cacea7 513assemble_neg_contexts(struct smb2_negotiate_req *req,
9fe5ff1c 514 struct TCP_Server_Info *server, unsigned int *total_len)
ebb3a9d4 515{
53d31a3f 516 unsigned int ctxt_len, neg_context_count;
775e44d6
PA
517 struct TCP_Server_Info *pserver;
518 char *pneg_ctxt;
519 char *hostname;
ebb3a9d4 520
d5c7076b
SF
521 if (*total_len > 200) {
522 /* In case length corrupted don't want to overrun smb buffer */
afe6f653 523 cifs_server_dbg(VFS, "Bad frame length assembling neg contexts\n");
d5c7076b
SF
524 return;
525 }
526
527 /*
528 * round up total_len of fixed part of SMB3 negotiate request to 8
529 * byte boundary before adding negotiate contexts
530 */
d7173623 531 *total_len = ALIGN(*total_len, 8);
d5c7076b
SF
532
533 pneg_ctxt = (*total_len) + (char *)req;
534 req->NegotiateContextOffset = cpu_to_le32(*total_len);
535
ebb3a9d4 536 build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt);
d7173623 537 ctxt_len = ALIGN(sizeof(struct smb2_preauth_neg_context), 8);
fcef0db6
SF
538 *total_len += ctxt_len;
539 pneg_ctxt += ctxt_len;
13cacea7 540
ebb3a9d4 541 build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt);
d7173623 542 ctxt_len = ALIGN(sizeof(struct smb2_encryption_neg_context), 8);
fcef0db6
SF
543 *total_len += ctxt_len;
544 pneg_ctxt += ctxt_len;
545
9de74996
SP
546 /*
547 * secondary channels don't have the hostname field populated
548 * use the hostname field in the primary channel instead
549 */
775e44d6
PA
550 pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
551 cifs_server_lock(pserver);
552 hostname = pserver->hostname;
9de74996 553 if (hostname && (hostname[0] != 0)) {
73130a7b 554 ctxt_len = build_netname_ctxt((struct smb2_netname_neg_context *)pneg_ctxt,
9de74996 555 hostname);
73130a7b
SF
556 *total_len += ctxt_len;
557 pneg_ctxt += ctxt_len;
73130a7b 558 neg_context_count = 3;
32f31918
SF
559 } else
560 neg_context_count = 2;
775e44d6 561 cifs_server_unlock(pserver);
32f31918
SF
562
563 build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
564 *total_len += sizeof(struct smb2_posix_neg_context);
565 pneg_ctxt += sizeof(struct smb2_posix_neg_context);
566 neg_context_count++;
53d31a3f 567
9fe5ff1c
SF
568 if (server->compress_algorithm) {
569 build_compression_ctxt((struct smb2_compression_capabilities_context *)
26ea888f 570 pneg_ctxt);
d7173623 571 ctxt_len = ALIGN(sizeof(struct smb2_compression_capabilities_context), 8);
9fe5ff1c
SF
572 *total_len += ctxt_len;
573 pneg_ctxt += ctxt_len;
53d31a3f
SF
574 neg_context_count++;
575 }
96d3cca1 576
53d31a3f
SF
577 if (enable_negotiate_signing) {
578 ctxt_len = build_signing_ctxt((struct smb2_signing_capabilities *)
579 pneg_ctxt);
580 *total_len += ctxt_len;
581 pneg_ctxt += ctxt_len;
582 neg_context_count++;
583 }
584
585 /* check for and add transport_capabilities and signing capabilities */
586 req->NegotiateContextCount = cpu_to_le16(neg_context_count);
96d3cca1 587
ebb3a9d4 588}
5100d8a3 589
5105a7ff 590/* If invalid preauth context warn but use what we requested, SHA-512 */
5100d8a3
SF
591static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt)
592{
593 unsigned int len = le16_to_cpu(ctxt->DataLength);
594
5105a7ff
DD
595 /*
596 * Caller checked that DataLength remains within SMB boundary. We still
597 * need to confirm that one HashAlgorithms member is accounted for.
598 */
5100d8a3 599 if (len < MIN_PREAUTH_CTXT_DATA_LEN) {
a0a3036b 600 pr_warn_once("server sent bad preauth context\n");
5100d8a3 601 return;
7955f105
SF
602 } else if (len < MIN_PREAUTH_CTXT_DATA_LEN + le16_to_cpu(ctxt->SaltLength)) {
603 pr_warn_once("server sent invalid SaltLength\n");
604 return;
5100d8a3
SF
605 }
606 if (le16_to_cpu(ctxt->HashAlgorithmCount) != 1)
a0a3036b 607 pr_warn_once("Invalid SMB3 hash algorithm count\n");
5100d8a3 608 if (ctxt->HashAlgorithms != SMB2_PREAUTH_INTEGRITY_SHA512)
a0a3036b 609 pr_warn_once("unknown SMB3 hash algorithm\n");
5100d8a3
SF
610}
611
26ea888f
SF
612static void decode_compress_ctx(struct TCP_Server_Info *server,
613 struct smb2_compression_capabilities_context *ctxt)
614{
615 unsigned int len = le16_to_cpu(ctxt->DataLength);
616
5105a7ff
DD
617 /*
618 * Caller checked that DataLength remains within SMB boundary. We still
619 * need to confirm that one CompressionAlgorithms member is accounted
620 * for.
621 */
26ea888f 622 if (len < 10) {
a0a3036b 623 pr_warn_once("server sent bad compression cntxt\n");
26ea888f
SF
624 return;
625 }
626 if (le16_to_cpu(ctxt->CompressionAlgorithmCount) != 1) {
a0a3036b 627 pr_warn_once("Invalid SMB3 compress algorithm count\n");
26ea888f
SF
628 return;
629 }
630 if (le16_to_cpu(ctxt->CompressionAlgorithms[0]) > 3) {
a0a3036b 631 pr_warn_once("unknown compression algorithm\n");
26ea888f
SF
632 return;
633 }
634 server->compress_algorithm = ctxt->CompressionAlgorithms[0];
635}
636
5100d8a3
SF
637static int decode_encrypt_ctx(struct TCP_Server_Info *server,
638 struct smb2_encryption_neg_context *ctxt)
639{
640 unsigned int len = le16_to_cpu(ctxt->DataLength);
641
642 cifs_dbg(FYI, "decode SMB3.11 encryption neg context of len %d\n", len);
5105a7ff
DD
643 /*
644 * Caller checked that DataLength remains within SMB boundary. We still
645 * need to confirm that one Cipher flexible array member is accounted
646 * for.
647 */
5100d8a3 648 if (len < MIN_ENCRYPT_CTXT_DATA_LEN) {
a0a3036b 649 pr_warn_once("server sent bad crypto ctxt len\n");
5100d8a3
SF
650 return -EINVAL;
651 }
652
653 if (le16_to_cpu(ctxt->CipherCount) != 1) {
a0a3036b 654 pr_warn_once("Invalid SMB3.11 cipher count\n");
5100d8a3
SF
655 return -EINVAL;
656 }
657 cifs_dbg(FYI, "SMB311 cipher type:%d\n", le16_to_cpu(ctxt->Ciphers[0]));
511ac89e
SF
658 if (require_gcm_256) {
659 if (ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES256_GCM) {
660 cifs_dbg(VFS, "Server does not support requested encryption type (AES256 GCM)\n");
661 return -EOPNOTSUPP;
662 }
663 } else if (ctxt->Ciphers[0] == 0) {
acf96fef
SF
664 /*
665 * e.g. if server only supported AES256_CCM (very unlikely)
666 * or server supported no encryption types or had all disabled.
667 * Since GLOBAL_CAP_ENCRYPTION will be not set, in the case
668 * in which mount requested encryption ("seal") checks later
669 * on during tree connection will return proper rc, but if
670 * seal not requested by client, since server is allowed to
671 * return 0 to indicate no supported cipher, we can't fail here
672 */
673 server->cipher_type = 0;
674 server->capabilities &= ~SMB2_GLOBAL_CAP_ENCRYPTION;
675 pr_warn_once("Server does not support requested encryption types\n");
676 return 0;
511ac89e
SF
677 } else if ((ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES128_CCM) &&
678 (ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES128_GCM) &&
679 (ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES256_GCM)) {
680 /* server returned a cipher we didn't ask for */
a0a3036b 681 pr_warn_once("Invalid SMB3.11 cipher returned\n");
5100d8a3
SF
682 return -EINVAL;
683 }
684 server->cipher_type = ctxt->Ciphers[0];
23657ad7 685 server->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
5100d8a3
SF
686 return 0;
687}
688
53d31a3f
SF
689static void decode_signing_ctx(struct TCP_Server_Info *server,
690 struct smb2_signing_capabilities *pctxt)
691{
692 unsigned int len = le16_to_cpu(pctxt->DataLength);
693
5105a7ff
DD
694 /*
695 * Caller checked that DataLength remains within SMB boundary. We still
696 * need to confirm that one SigningAlgorithms flexible array member is
697 * accounted for.
698 */
53d31a3f
SF
699 if ((len < 4) || (len > 16)) {
700 pr_warn_once("server sent bad signing negcontext\n");
701 return;
702 }
703 if (le16_to_cpu(pctxt->SigningAlgorithmCount) != 1) {
704 pr_warn_once("Invalid signing algorithm count\n");
705 return;
706 }
707 if (le16_to_cpu(pctxt->SigningAlgorithms[0]) > 2) {
708 pr_warn_once("unknown signing algorithm\n");
709 return;
710 }
711
712 server->signing_negotiated = true;
713 server->signing_algorithm = le16_to_cpu(pctxt->SigningAlgorithms[0]);
714 cifs_dbg(FYI, "signing algorithm %d chosen\n",
715 server->signing_algorithm);
716}
717
718
5100d8a3 719static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp,
977b6170
RS
720 struct TCP_Server_Info *server,
721 unsigned int len_of_smb)
5100d8a3
SF
722{
723 struct smb2_neg_context *pctx;
724 unsigned int offset = le32_to_cpu(rsp->NegotiateContextOffset);
725 unsigned int ctxt_cnt = le16_to_cpu(rsp->NegotiateContextCount);
5100d8a3
SF
726 unsigned int len_of_ctxts, i;
727 int rc = 0;
728
729 cifs_dbg(FYI, "decoding %d negotiate contexts\n", ctxt_cnt);
730 if (len_of_smb <= offset) {
afe6f653 731 cifs_server_dbg(VFS, "Invalid response: negotiate context offset\n");
5100d8a3
SF
732 return -EINVAL;
733 }
734
735 len_of_ctxts = len_of_smb - offset;
736
737 for (i = 0; i < ctxt_cnt; i++) {
738 int clen;
739 /* check that offset is not beyond end of SMB */
5100d8a3
SF
740 if (len_of_ctxts < sizeof(struct smb2_neg_context))
741 break;
742
1fc6ad2f 743 pctx = (struct smb2_neg_context *)(offset + (char *)rsp);
5105a7ff
DD
744 clen = sizeof(struct smb2_neg_context)
745 + le16_to_cpu(pctx->DataLength);
746 /*
747 * 2.2.4 SMB2 NEGOTIATE Response
748 * Subsequent negotiate contexts MUST appear at the first 8-byte
749 * aligned offset following the previous negotiate context.
750 */
751 if (i + 1 != ctxt_cnt)
752 clen = ALIGN(clen, 8);
5100d8a3
SF
753 if (clen > len_of_ctxts)
754 break;
755
756 if (pctx->ContextType == SMB2_PREAUTH_INTEGRITY_CAPABILITIES)
757 decode_preauth_context(
758 (struct smb2_preauth_neg_context *)pctx);
759 else if (pctx->ContextType == SMB2_ENCRYPTION_CAPABILITIES)
760 rc = decode_encrypt_ctx(server,
761 (struct smb2_encryption_neg_context *)pctx);
26ea888f
SF
762 else if (pctx->ContextType == SMB2_COMPRESSION_CAPABILITIES)
763 decode_compress_ctx(server,
764 (struct smb2_compression_capabilities_context *)pctx);
fcef0db6
SF
765 else if (pctx->ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE)
766 server->posix_ext_supported = true;
53d31a3f
SF
767 else if (pctx->ContextType == SMB2_SIGNING_CAPABILITIES)
768 decode_signing_ctx(server,
769 (struct smb2_signing_capabilities *)pctx);
5100d8a3 770 else
afe6f653 771 cifs_server_dbg(VFS, "unknown negcontext of type %d ignored\n",
5100d8a3 772 le16_to_cpu(pctx->ContextType));
5100d8a3
SF
773 if (rc)
774 break;
5105a7ff
DD
775
776 offset += clen;
5100d8a3
SF
777 len_of_ctxts -= clen;
778 }
779 return rc;
780}
781
ce558b0e
SF
782static struct create_posix *
783create_posix_buf(umode_t mode)
784{
785 struct create_posix *buf;
786
787 buf = kzalloc(sizeof(struct create_posix),
788 GFP_KERNEL);
789 if (!buf)
790 return NULL;
791
792 buf->ccontext.DataOffset =
793 cpu_to_le16(offsetof(struct create_posix, Mode));
794 buf->ccontext.DataLength = cpu_to_le32(4);
795 buf->ccontext.NameOffset =
796 cpu_to_le16(offsetof(struct create_posix, Name));
797 buf->ccontext.NameLength = cpu_to_le16(16);
798
799 /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
800 buf->Name[0] = 0x93;
801 buf->Name[1] = 0xAD;
802 buf->Name[2] = 0x25;
803 buf->Name[3] = 0x50;
804 buf->Name[4] = 0x9C;
805 buf->Name[5] = 0xB4;
806 buf->Name[6] = 0x11;
807 buf->Name[7] = 0xE7;
808 buf->Name[8] = 0xB4;
809 buf->Name[9] = 0x23;
810 buf->Name[10] = 0x83;
811 buf->Name[11] = 0xDE;
812 buf->Name[12] = 0x96;
813 buf->Name[13] = 0x8B;
814 buf->Name[14] = 0xCD;
815 buf->Name[15] = 0x7C;
816 buf->Mode = cpu_to_le32(mode);
a0a3036b 817 cifs_dbg(FYI, "mode on posix create 0%o\n", mode);
ce558b0e
SF
818 return buf;
819}
820
821static int
822add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode)
823{
824 struct smb2_create_req *req = iov[0].iov_base;
825 unsigned int num = *num_iovec;
826
827 iov[num].iov_base = create_posix_buf(mode);
d0959b08 828 if (mode == ACL_NO_MODE)
a0a3036b 829 cifs_dbg(FYI, "Invalid mode\n");
ce558b0e
SF
830 if (iov[num].iov_base == NULL)
831 return -ENOMEM;
832 iov[num].iov_len = sizeof(struct create_posix);
833 if (!req->CreateContextsOffset)
834 req->CreateContextsOffset = cpu_to_le32(
835 sizeof(struct smb2_create_req) +
836 iov[num - 1].iov_len);
837 le32_add_cpu(&req->CreateContextsLength, sizeof(struct create_posix));
838 *num_iovec = num + 1;
839 return 0;
840}
841
ebb3a9d4 842
ec2e4523
PS
843/*
844 *
845 * SMB2 Worker functions follow:
846 *
847 * The general structure of the worker functions is:
848 * 1) Call smb2_init (assembles SMB2 header)
849 * 2) Initialize SMB2 command specific fields in fixed length area of SMB
850 * 3) Call smb_sendrcv2 (sends request on socket and waits for response)
851 * 4) Decode SMB2 command specific fields in the fixed length area
852 * 5) Decode variable length data area (if any for this SMB2 command type)
853 * 6) Call free smb buffer
854 * 7) return
855 *
856 */
857
858int
f486ef8e
SP
859SMB2_negotiate(const unsigned int xid,
860 struct cifs_ses *ses,
861 struct TCP_Server_Info *server)
ec2e4523 862{
40eff45b 863 struct smb_rqst rqst;
ec2e4523
PS
864 struct smb2_negotiate_req *req;
865 struct smb2_negotiate_rsp *rsp;
866 struct kvec iov[1];
da502f7d 867 struct kvec rsp_iov;
f5823f5e 868 int rc;
ec2e4523 869 int resp_buftype;
ec2e4523
PS
870 int blob_offset, blob_length;
871 char *security_blob;
872 int flags = CIFS_NEG_OP;
13cacea7 873 unsigned int total_len;
ec2e4523 874
f96637be 875 cifs_dbg(FYI, "Negotiate protocol\n");
ec2e4523 876
3534b850
JL
877 if (!server) {
878 WARN(1, "%s: server is NULL!\n", __func__);
879 return -EIO;
ec2e4523
PS
880 }
881
352d96f3
AA
882 rc = smb2_plain_req_init(SMB2_NEGOTIATE, NULL, server,
883 (void **) &req, &total_len);
ec2e4523
PS
884 if (rc)
885 return rc;
886
0d35e382 887 req->hdr.SessionId = 0;
0fdfef9a 888
8bd68c6e
AA
889 memset(server->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE);
890 memset(ses->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE);
ec2e4523 891
f6a6bf7c 892 if (strcmp(server->vals->version_string,
9764c02f
SF
893 SMB3ANY_VERSION_STRING) == 0) {
894 req->Dialects[0] = cpu_to_le16(SMB30_PROT_ID);
895 req->Dialects[1] = cpu_to_le16(SMB302_PROT_ID);
6dffa4c2
SF
896 req->Dialects[2] = cpu_to_le16(SMB311_PROT_ID);
897 req->DialectCount = cpu_to_le16(3);
898 total_len += 6;
afe6f653 899 } else if (strcmp(server->vals->version_string,
9764c02f
SF
900 SMBDEFAULT_VERSION_STRING) == 0) {
901 req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
902 req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
903 req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
d5c7076b
SF
904 req->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
905 req->DialectCount = cpu_to_le16(4);
906 total_len += 8;
9764c02f
SF
907 } else {
908 /* otherwise send specific dialect */
f6a6bf7c 909 req->Dialects[0] = cpu_to_le16(server->vals->protocol_id);
9764c02f 910 req->DialectCount = cpu_to_le16(1);
13cacea7 911 total_len += 2;
9764c02f 912 }
ec2e4523
PS
913
914 /* only one of SMB2 signing flags may be set in SMB2 request */
38d77c50 915 if (ses->sign)
9cd2e62c 916 req->SecurityMode = cpu_to_le16(SMB2_NEGOTIATE_SIGNING_REQUIRED);
38d77c50 917 else if (global_secflags & CIFSSEC_MAY_SIGN)
9cd2e62c 918 req->SecurityMode = cpu_to_le16(SMB2_NEGOTIATE_SIGNING_ENABLED);
38d77c50
JL
919 else
920 req->SecurityMode = 0;
ec2e4523 921
afe6f653 922 req->Capabilities = cpu_to_le32(server->vals->req_capabilities);
679971e7
SF
923 if (ses->chan_max > 1)
924 req->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL);
ec2e4523 925
3c5f9be1 926 /* ClientGUID must be zero for SMB2.02 dialect */
afe6f653 927 if (server->vals->protocol_id == SMB20_PROT_ID)
3c5f9be1 928 memset(req->ClientGUID, 0, SMB2_CLIENT_GUID_SIZE);
ebb3a9d4 929 else {
3c5f9be1
SF
930 memcpy(req->ClientGUID, server->client_guid,
931 SMB2_CLIENT_GUID_SIZE);
afe6f653 932 if ((server->vals->protocol_id == SMB311_PROT_ID) ||
6dffa4c2
SF
933 (strcmp(server->vals->version_string,
934 SMB3ANY_VERSION_STRING) == 0) ||
afe6f653 935 (strcmp(server->vals->version_string,
d5c7076b 936 SMBDEFAULT_VERSION_STRING) == 0))
9fe5ff1c 937 assemble_neg_contexts(req, server, &total_len);
ebb3a9d4 938 }
ec2e4523 939 iov[0].iov_base = (char *)req;
13cacea7 940 iov[0].iov_len = total_len;
ec2e4523 941
40eff45b
RS
942 memset(&rqst, 0, sizeof(struct smb_rqst));
943 rqst.rq_iov = iov;
944 rqst.rq_nvec = 1;
945
352d96f3
AA
946 rc = cifs_send_recv(xid, ses, server,
947 &rqst, &resp_buftype, flags, &rsp_iov);
da502f7d
PS
948 cifs_small_buf_release(req);
949 rsp = (struct smb2_negotiate_rsp *)rsp_iov.iov_base;
ec2e4523
PS
950 /*
951 * No tcon so can't do
952 * cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]);
953 */
7e682f76 954 if (rc == -EOPNOTSUPP) {
a0a3036b 955 cifs_server_dbg(VFS, "Dialect not supported by server. Consider specifying vers=1.0 or vers=2.0 on mount for accessing older servers\n");
7e682f76
SF
956 goto neg_exit;
957 } else if (rc != 0)
ec2e4523
PS
958 goto neg_exit;
959
27893dfc 960 rc = -EIO;
afe6f653 961 if (strcmp(server->vals->version_string,
9764c02f
SF
962 SMB3ANY_VERSION_STRING) == 0) {
963 if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
afe6f653 964 cifs_server_dbg(VFS,
9764c02f 965 "SMB2 dialect returned but not requested\n");
27893dfc 966 goto neg_exit;
9764c02f 967 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
afe6f653 968 cifs_server_dbg(VFS,
9764c02f 969 "SMB2.1 dialect returned but not requested\n");
27893dfc 970 goto neg_exit;
6dffa4c2
SF
971 } else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
972 /* ops set to 3.0 by default for default so update */
973 server->ops = &smb311_operations;
974 server->vals = &smb311_values;
9764c02f 975 }
afe6f653 976 } else if (strcmp(server->vals->version_string,
9764c02f
SF
977 SMBDEFAULT_VERSION_STRING) == 0) {
978 if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
afe6f653 979 cifs_server_dbg(VFS,
9764c02f 980 "SMB2 dialect returned but not requested\n");
27893dfc 981 goto neg_exit;
9764c02f
SF
982 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
983 /* ops set to 3.0 by default for default so update */
afe6f653
RS
984 server->ops = &smb21_operations;
985 server->vals = &smb21_values;
b57a55e2 986 } else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
afe6f653
RS
987 server->ops = &smb311_operations;
988 server->vals = &smb311_values;
b57a55e2 989 }
590d08d3 990 } else if (le16_to_cpu(rsp->DialectRevision) !=
afe6f653 991 server->vals->protocol_id) {
9764c02f 992 /* if requested single dialect ensure returned dialect matched */
a0a3036b
JP
993 cifs_server_dbg(VFS, "Invalid 0x%x dialect returned: not requested\n",
994 le16_to_cpu(rsp->DialectRevision));
27893dfc 995 goto neg_exit;
9764c02f
SF
996 }
997
f96637be 998 cifs_dbg(FYI, "mode 0x%x\n", rsp->SecurityMode);
ec2e4523 999
e4aa25e7 1000 if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID))
f96637be 1001 cifs_dbg(FYI, "negotiated smb2.0 dialect\n");
e4aa25e7 1002 else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID))
f96637be 1003 cifs_dbg(FYI, "negotiated smb2.1 dialect\n");
e4aa25e7 1004 else if (rsp->DialectRevision == cpu_to_le16(SMB30_PROT_ID))
f96637be 1005 cifs_dbg(FYI, "negotiated smb3.0 dialect\n");
20b6d8b4
SF
1006 else if (rsp->DialectRevision == cpu_to_le16(SMB302_PROT_ID))
1007 cifs_dbg(FYI, "negotiated smb3.02 dialect\n");
5f7fbf73
SF
1008 else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID))
1009 cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n");
ec2e4523 1010 else {
a0a3036b
JP
1011 cifs_server_dbg(VFS, "Invalid dialect returned by server 0x%x\n",
1012 le16_to_cpu(rsp->DialectRevision));
ec2e4523
PS
1013 goto neg_exit;
1014 }
27893dfc
EM
1015
1016 rc = 0;
ec2e4523
PS
1017 server->dialect = le16_to_cpu(rsp->DialectRevision);
1018
8bd68c6e
AA
1019 /*
1020 * Keep a copy of the hash after negprot. This hash will be
1021 * the starting hash value for all sessions made from this
1022 * server.
1023 */
1024 memcpy(server->preauth_sha_hash, ses->preauth_sha_hash,
1025 SMB2_PREAUTH_HASH_SIZE);
0fdfef9a 1026
e598d1d8
JL
1027 /* SMB2 only has an extended negflavor */
1028 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
2365c4ea
PS
1029 /* set it to the maximum buffer size value we can send with 1 credit */
1030 server->maxBuf = min_t(unsigned int, le32_to_cpu(rsp->MaxTransactSize),
1031 SMB2_MAX_BUFFER_SIZE);
ec2e4523
PS
1032 server->max_read = le32_to_cpu(rsp->MaxReadSize);
1033 server->max_write = le32_to_cpu(rsp->MaxWriteSize);
ec2e4523 1034 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
07108d0e
SF
1035 if ((server->sec_mode & SMB2_SEC_MODE_FLAGS_ALL) != server->sec_mode)
1036 cifs_dbg(FYI, "Server returned unexpected security mode 0x%x\n",
1037 server->sec_mode);
ec2e4523 1038 server->capabilities = le32_to_cpu(rsp->Capabilities);
29e20f9c
PS
1039 /* Internal types */
1040 server->capabilities |= SMB2_NT_FIND | SMB2_LARGE_FILES;
ec2e4523 1041
6d2fcfe6
AA
1042 /*
1043 * SMB3.0 supports only 1 cipher and doesn't have a encryption neg context
1044 * Set the cipher type manually.
1045 */
1046 if (server->dialect == SMB30_PROT_ID && (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
1047 server->cipher_type = SMB2_ENCRYPTION_AES128_CCM;
1048
ec2e4523 1049 security_blob = smb2_get_data_area_len(&blob_offset, &blob_length,
0d35e382 1050 (struct smb2_hdr *)rsp);
5d875cc9
SF
1051 /*
1052 * See MS-SMB2 section 2.2.4: if no blob, client picks default which
1053 * for us will be
1054 * ses->sectype = RawNTLMSSP;
1055 * but for time being this is our only auth choice so doesn't matter.
1056 * We just found a server which sets blob length to zero expecting raw.
1057 */
67dbea2c 1058 if (blob_length == 0) {
5d875cc9 1059 cifs_dbg(FYI, "missing security blob on negprot\n");
67dbea2c
PS
1060 server->sec_ntlmssp = true;
1061 }
3c1bf7e4 1062
38d77c50 1063 rc = cifs_enable_signing(server, ses->sign);
9ddec561
JL
1064 if (rc)
1065 goto neg_exit;
ceb1b0b9 1066 if (blob_length) {
ebdd207e 1067 rc = decode_negTokenInit(security_blob, blob_length, server);
ceb1b0b9
SF
1068 if (rc == 1)
1069 rc = 0;
1070 else if (rc == 0)
1071 rc = -EIO;
ec2e4523 1072 }
5100d8a3 1073
5100d8a3
SF
1074 if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
1075 if (rsp->NegotiateContextCount)
977b6170
RS
1076 rc = smb311_decode_neg_context(rsp, server,
1077 rsp_iov.iov_len);
5100d8a3 1078 else
afe6f653 1079 cifs_server_dbg(VFS, "Missing expected negotiate contexts\n");
5100d8a3 1080 }
ec2e4523
PS
1081neg_exit:
1082 free_rsp_buf(resp_buftype, rsp);
1083 return rc;
1084}
5478f9ba 1085
ff1c038a
SF
1086int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
1087{
2796d303
LL
1088 int rc;
1089 struct validate_negotiate_info_req *pneg_inbuf;
fe83bebc 1090 struct validate_negotiate_info_rsp *pneg_rsp = NULL;
ff1c038a 1091 u32 rsplen;
9764c02f 1092 u32 inbuflen; /* max of 4 dialects */
afe6f653 1093 struct TCP_Server_Info *server = tcon->ses->server;
ff1c038a
SF
1094
1095 cifs_dbg(FYI, "validate negotiate\n");
1096
8bd68c6e 1097 /* In SMB3.11 preauth integrity supersedes validate negotiate */
afe6f653 1098 if (server->dialect == SMB311_PROT_ID)
8bd68c6e
AA
1099 return 0;
1100
ff1c038a
SF
1101 /*
1102 * validation ioctl must be signed, so no point sending this if we
0603c96f
SF
1103 * can not sign it (ie are not known user). Even if signing is not
1104 * required (enabled but not negotiated), in those cases we selectively
ff1c038a 1105 * sign just this, the first and only signed request on a connection.
0603c96f 1106 * Having validation of negotiate info helps reduce attack vectors.
ff1c038a 1107 */
0603c96f 1108 if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST)
ff1c038a
SF
1109 return 0; /* validation requires signing */
1110
0603c96f
SF
1111 if (tcon->ses->user_name == NULL) {
1112 cifs_dbg(FYI, "Can't validate negotiate: null user mount\n");
1113 return 0; /* validation requires signing */
1114 }
1115
1116 if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL)
3175eb9b 1117 cifs_tcon_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n");
0603c96f 1118
2796d303
LL
1119 pneg_inbuf = kmalloc(sizeof(*pneg_inbuf), GFP_NOFS);
1120 if (!pneg_inbuf)
1121 return -ENOMEM;
1122
1123 pneg_inbuf->Capabilities =
afe6f653 1124 cpu_to_le32(server->vals->req_capabilities);
679971e7
SF
1125 if (tcon->ses->chan_max > 1)
1126 pneg_inbuf->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL);
1127
afe6f653 1128 memcpy(pneg_inbuf->Guid, server->client_guid,
39552ea8 1129 SMB2_CLIENT_GUID_SIZE);
ff1c038a
SF
1130
1131 if (tcon->ses->sign)
2796d303 1132 pneg_inbuf->SecurityMode =
ff1c038a
SF
1133 cpu_to_le16(SMB2_NEGOTIATE_SIGNING_REQUIRED);
1134 else if (global_secflags & CIFSSEC_MAY_SIGN)
2796d303 1135 pneg_inbuf->SecurityMode =
ff1c038a
SF
1136 cpu_to_le16(SMB2_NEGOTIATE_SIGNING_ENABLED);
1137 else
2796d303 1138 pneg_inbuf->SecurityMode = 0;
ff1c038a 1139
9764c02f 1140
afe6f653 1141 if (strcmp(server->vals->version_string,
9764c02f 1142 SMB3ANY_VERSION_STRING) == 0) {
2796d303
LL
1143 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB30_PROT_ID);
1144 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB302_PROT_ID);
6dffa4c2
SF
1145 pneg_inbuf->Dialects[2] = cpu_to_le16(SMB311_PROT_ID);
1146 pneg_inbuf->DialectCount = cpu_to_le16(3);
1147 /* SMB 2.1 not included so subtract one dialect from len */
2796d303 1148 inbuflen = sizeof(*pneg_inbuf) -
6dffa4c2 1149 (sizeof(pneg_inbuf->Dialects[0]));
afe6f653 1150 } else if (strcmp(server->vals->version_string,
9764c02f 1151 SMBDEFAULT_VERSION_STRING) == 0) {
2796d303
LL
1152 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
1153 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
1154 pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
d5c7076b
SF
1155 pneg_inbuf->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
1156 pneg_inbuf->DialectCount = cpu_to_le16(4);
6dffa4c2 1157 /* structure is big enough for 4 dialects */
2796d303 1158 inbuflen = sizeof(*pneg_inbuf);
9764c02f
SF
1159 } else {
1160 /* otherwise specific dialect was requested */
2796d303 1161 pneg_inbuf->Dialects[0] =
afe6f653 1162 cpu_to_le16(server->vals->protocol_id);
2796d303 1163 pneg_inbuf->DialectCount = cpu_to_le16(1);
e98ecc6e 1164 /* structure is big enough for 4 dialects, sending only 1 */
2796d303 1165 inbuflen = sizeof(*pneg_inbuf) -
e98ecc6e 1166 sizeof(pneg_inbuf->Dialects[0]) * 3;
9764c02f 1167 }
ff1c038a
SF
1168
1169 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
400d0ad6 1170 FSCTL_VALIDATE_NEGOTIATE_INFO,
153322f7
SF
1171 (char *)pneg_inbuf, inbuflen, CIFSMaxBufSize,
1172 (char **)&pneg_rsp, &rsplen);
969ae8e8
NJ
1173 if (rc == -EOPNOTSUPP) {
1174 /*
1175 * Old Windows versions or Netapp SMB server can return
1176 * not supported error. Client should accept it.
1177 */
3175eb9b 1178 cifs_tcon_dbg(VFS, "Server does not support validate negotiate\n");
21078203
CIK
1179 rc = 0;
1180 goto out_free_inbuf;
969ae8e8 1181 } else if (rc != 0) {
a0a3036b
JP
1182 cifs_tcon_dbg(VFS, "validate protocol negotiate failed: %d\n",
1183 rc);
2796d303
LL
1184 rc = -EIO;
1185 goto out_free_inbuf;
ff1c038a
SF
1186 }
1187
2796d303
LL
1188 rc = -EIO;
1189 if (rsplen != sizeof(*pneg_rsp)) {
a0a3036b
JP
1190 cifs_tcon_dbg(VFS, "Invalid protocol negotiate response size: %d\n",
1191 rsplen);
7db0a6ef
SF
1192
1193 /* relax check since Mac returns max bufsize allowed on ioctl */
2796d303
LL
1194 if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp))
1195 goto out_free_rsp;
ff1c038a
SF
1196 }
1197
1198 /* check validate negotiate info response matches what we got earlier */
afe6f653 1199 if (pneg_rsp->Dialect != cpu_to_le16(server->dialect))
ff1c038a
SF
1200 goto vneg_out;
1201
afe6f653 1202 if (pneg_rsp->SecurityMode != cpu_to_le16(server->sec_mode))
ff1c038a
SF
1203 goto vneg_out;
1204
1205 /* do not validate server guid because not saved at negprot time yet */
1206
1207 if ((le32_to_cpu(pneg_rsp->Capabilities) | SMB2_NT_FIND |
afe6f653 1208 SMB2_LARGE_FILES) != server->capabilities)
ff1c038a
SF
1209 goto vneg_out;
1210
1211 /* validate negotiate successful */
2796d303 1212 rc = 0;
ff1c038a 1213 cifs_dbg(FYI, "validate negotiate info successful\n");
2796d303 1214 goto out_free_rsp;
ff1c038a
SF
1215
1216vneg_out:
3175eb9b 1217 cifs_tcon_dbg(VFS, "protocol revalidation - security settings mismatch\n");
2796d303 1218out_free_rsp:
fe83bebc 1219 kfree(pneg_rsp);
2796d303
LL
1220out_free_inbuf:
1221 kfree(pneg_inbuf);
1222 return rc;
ff1c038a
SF
1223}
1224
ef65aaed
SP
1225enum securityEnum
1226smb2_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
1227{
1228 switch (requested) {
1229 case Kerberos:
1230 case RawNTLMSSP:
1231 return requested;
1232 case NTLMv2:
1233 return RawNTLMSSP;
1234 case Unspecified:
1235 if (server->sec_ntlmssp &&
1236 (global_secflags & CIFSSEC_MAY_NTLMSSP))
1237 return RawNTLMSSP;
1238 if ((server->sec_kerberos || server->sec_mskerberos) &&
1239 (global_secflags & CIFSSEC_MAY_KRB5))
1240 return Kerberos;
df561f66 1241 fallthrough;
ef65aaed
SP
1242 default:
1243 return Unspecified;
1244 }
1245}
1246
3baf1a7b
SP
1247struct SMB2_sess_data {
1248 unsigned int xid;
1249 struct cifs_ses *ses;
f486ef8e 1250 struct TCP_Server_Info *server;
3baf1a7b
SP
1251 struct nls_table *nls_cp;
1252 void (*func)(struct SMB2_sess_data *);
1253 int result;
1254 u64 previous_session;
1255
1256 /* we will send the SMB in three pieces:
1257 * a fixed length beginning part, an optional
1258 * SPNEGO blob (which can be zero length), and a
1259 * last part which will include the strings
1260 * and rest of bcc area. This allows us to avoid
1261 * a large buffer 17K allocation
1262 */
1263 int buf0_type;
1264 struct kvec iov[2];
1265};
1266
1267static int
1268SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data)
1269{
1270 int rc;
1271 struct cifs_ses *ses = sess_data->ses;
f486ef8e 1272 struct TCP_Server_Info *server = sess_data->server;
3baf1a7b 1273 struct smb2_sess_setup_req *req;
88ea5cb7 1274 unsigned int total_len;
f486ef8e 1275 bool is_binding = false;
3baf1a7b 1276
352d96f3
AA
1277 rc = smb2_plain_req_init(SMB2_SESSION_SETUP, NULL, server,
1278 (void **) &req,
1279 &total_len);
3baf1a7b
SP
1280 if (rc)
1281 return rc;
1282
bc962159
SP
1283 spin_lock(&ses->ses_lock);
1284 is_binding = (ses->ses_status == SES_GOOD);
1285 spin_unlock(&ses->ses_lock);
f486ef8e
SP
1286
1287 if (is_binding) {
1288 req->hdr.SessionId = cpu_to_le64(ses->Suid);
0d35e382 1289 req->hdr.Flags |= SMB2_FLAGS_SIGNED;
d70e9fa5
AA
1290 req->PreviousSessionId = 0;
1291 req->Flags = SMB2_SESSION_REQ_FLAG_BINDING;
f486ef8e 1292 cifs_dbg(FYI, "Binding to sess id: %llx\n", ses->Suid);
d70e9fa5
AA
1293 } else {
1294 /* First session, not a reauthenticate */
0d35e382 1295 req->hdr.SessionId = 0;
d70e9fa5
AA
1296 /*
1297 * if reconnect, we need to send previous sess id
1298 * otherwise it is 0
1299 */
d8d9de53 1300 req->PreviousSessionId = cpu_to_le64(sess_data->previous_session);
d70e9fa5 1301 req->Flags = 0; /* MBZ */
f486ef8e
SP
1302 cifs_dbg(FYI, "Fresh session. Previous: %llx\n",
1303 sess_data->previous_session);
d70e9fa5 1304 }
d409014e
SF
1305
1306 /* enough to enable echos and oplocks and one max size write */
0d35e382 1307 req->hdr.CreditRequest = cpu_to_le16(130);
3baf1a7b
SP
1308
1309 /* only one of SMB2 signing flags may be set in SMB2 request */
1310 if (server->sign)
1311 req->SecurityMode = SMB2_NEGOTIATE_SIGNING_REQUIRED;
1312 else if (global_secflags & CIFSSEC_MAY_SIGN) /* one flag unlike MUST_ */
1313 req->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED;
1314 else
1315 req->SecurityMode = 0;
1316
8d33096a
SF
1317#ifdef CONFIG_CIFS_DFS_UPCALL
1318 req->Capabilities = cpu_to_le32(SMB2_GLOBAL_CAP_DFS);
1319#else
3baf1a7b 1320 req->Capabilities = 0;
8d33096a
SF
1321#endif /* DFS_UPCALL */
1322
3baf1a7b
SP
1323 req->Channel = 0; /* MBZ */
1324
1325 sess_data->iov[0].iov_base = (char *)req;
88ea5cb7
RS
1326 /* 1 for pad */
1327 sess_data->iov[0].iov_len = total_len - 1;
3baf1a7b
SP
1328 /*
1329 * This variable will be used to clear the buffer
1330 * allocated above in case of any error in the calling function.
1331 */
1332 sess_data->buf0_type = CIFS_SMALL_BUFFER;
1333
1334 return 0;
1335}
1336
1337static void
1338SMB2_sess_free_buffer(struct SMB2_sess_data *sess_data)
1339{
01f2ee7e 1340 struct kvec *iov = sess_data->iov;
a4e430c8 1341
01f2ee7e
PA
1342 /* iov[1] is already freed by caller */
1343 if (sess_data->buf0_type != CIFS_NO_BUFFER && iov[0].iov_base)
1344 memzero_explicit(iov[0].iov_base, iov[0].iov_len);
a4e430c8 1345
01f2ee7e 1346 free_rsp_buf(sess_data->buf0_type, iov[0].iov_base);
3baf1a7b
SP
1347 sess_data->buf0_type = CIFS_NO_BUFFER;
1348}
1349
1350static int
1351SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data)
1352{
1353 int rc;
40eff45b 1354 struct smb_rqst rqst;
3baf1a7b 1355 struct smb2_sess_setup_req *req = sess_data->iov[0].iov_base;
da502f7d 1356 struct kvec rsp_iov = { NULL, 0 };
3baf1a7b
SP
1357
1358 /* Testing shows that buffer offset must be at location of Buffer[0] */
1359 req->SecurityBufferOffset =
eb3e28c1 1360 cpu_to_le16(sizeof(struct smb2_sess_setup_req));
3baf1a7b
SP
1361 req->SecurityBufferLength = cpu_to_le16(sess_data->iov[1].iov_len);
1362
40eff45b
RS
1363 memset(&rqst, 0, sizeof(struct smb_rqst));
1364 rqst.rq_iov = sess_data->iov;
1365 rqst.rq_nvec = 2;
3baf1a7b 1366
40eff45b
RS
1367 /* BB add code to build os and lm fields */
1368 rc = cifs_send_recv(sess_data->xid, sess_data->ses,
f486ef8e 1369 sess_data->server,
40eff45b 1370 &rqst,
88ea5cb7 1371 &sess_data->buf0_type,
0f56db83 1372 CIFS_LOG_ERROR | CIFS_SESS_OP, &rsp_iov);
da502f7d
PS
1373 cifs_small_buf_release(sess_data->iov[0].iov_base);
1374 memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec));
3baf1a7b
SP
1375
1376 return rc;
1377}
1378
1379static int
1380SMB2_sess_establish_session(struct SMB2_sess_data *sess_data)
1381{
1382 int rc = 0;
1383 struct cifs_ses *ses = sess_data->ses;
f486ef8e 1384 struct TCP_Server_Info *server = sess_data->server;
3baf1a7b 1385
cc391b69 1386 cifs_server_lock(server);
f6a6bf7c 1387 if (server->ops->generate_signingkey) {
f486ef8e 1388 rc = server->ops->generate_signingkey(ses, server);
3baf1a7b
SP
1389 if (rc) {
1390 cifs_dbg(FYI,
1391 "SMB3 session key generation failed\n");
cc391b69 1392 cifs_server_unlock(server);
cabfb368 1393 return rc;
3baf1a7b
SP
1394 }
1395 }
f6a6bf7c
AA
1396 if (!server->session_estab) {
1397 server->sequence_number = 0x2;
1398 server->session_estab = true;
3baf1a7b 1399 }
cc391b69 1400 cifs_server_unlock(server);
3baf1a7b
SP
1401
1402 cifs_dbg(FYI, "SMB2/3 session established successfully\n");
3baf1a7b
SP
1403 return rc;
1404}
1405
1406#ifdef CONFIG_CIFS_UPCALL
1407static void
1408SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
1409{
1410 int rc;
1411 struct cifs_ses *ses = sess_data->ses;
f486ef8e 1412 struct TCP_Server_Info *server = sess_data->server;
3baf1a7b
SP
1413 struct cifs_spnego_msg *msg;
1414 struct key *spnego_key = NULL;
1415 struct smb2_sess_setup_rsp *rsp = NULL;
f486ef8e 1416 bool is_binding = false;
3baf1a7b
SP
1417
1418 rc = SMB2_sess_alloc_buffer(sess_data);
1419 if (rc)
1420 goto out;
1421
f486ef8e 1422 spnego_key = cifs_get_spnego_key(ses, server);
3baf1a7b
SP
1423 if (IS_ERR(spnego_key)) {
1424 rc = PTR_ERR(spnego_key);
0a018944
SF
1425 if (rc == -ENOKEY)
1426 cifs_dbg(VFS, "Verify user has a krb5 ticket and keyutils is installed\n");
3baf1a7b
SP
1427 spnego_key = NULL;
1428 goto out;
1429 }
1430
1431 msg = spnego_key->payload.data[0];
1432 /*
1433 * check version field to make sure that cifs.upcall is
1434 * sending us a response in an expected form
1435 */
1436 if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
a0a3036b
JP
1437 cifs_dbg(VFS, "bad cifs.upcall version. Expected %d got %d\n",
1438 CIFS_SPNEGO_UPCALL_VERSION, msg->version);
3baf1a7b
SP
1439 rc = -EKEYREJECTED;
1440 goto out_put_spnego_key;
1441 }
1442
bc962159
SP
1443 spin_lock(&ses->ses_lock);
1444 is_binding = (ses->ses_status == SES_GOOD);
1445 spin_unlock(&ses->ses_lock);
f486ef8e 1446
d70e9fa5 1447 /* keep session key if binding */
f486ef8e 1448 if (!is_binding) {
2fe58d97 1449 kfree_sensitive(ses->auth_key.response);
d70e9fa5
AA
1450 ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
1451 GFP_KERNEL);
1452 if (!ses->auth_key.response) {
a0a3036b 1453 cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n",
d70e9fa5
AA
1454 msg->sesskey_len);
1455 rc = -ENOMEM;
1456 goto out_put_spnego_key;
1457 }
1458 ses->auth_key.len = msg->sesskey_len;
3baf1a7b 1459 }
3baf1a7b
SP
1460
1461 sess_data->iov[1].iov_base = msg->data + msg->sesskey_len;
1462 sess_data->iov[1].iov_len = msg->secblob_len;
1463
1464 rc = SMB2_sess_sendreceive(sess_data);
1465 if (rc)
1466 goto out_put_spnego_key;
1467
1468 rsp = (struct smb2_sess_setup_rsp *)sess_data->iov[0].iov_base;
d70e9fa5 1469 /* keep session id and flags if binding */
f486ef8e 1470 if (!is_binding) {
0d35e382 1471 ses->Suid = le64_to_cpu(rsp->hdr.SessionId);
d70e9fa5
AA
1472 ses->session_flags = le16_to_cpu(rsp->SessionFlags);
1473 }
3baf1a7b
SP
1474
1475 rc = SMB2_sess_establish_session(sess_data);
1476out_put_spnego_key:
1477 key_invalidate(spnego_key);
1478 key_put(spnego_key);
39e8db3c 1479 if (rc) {
a4e430c8 1480 kfree_sensitive(ses->auth_key.response);
39e8db3c
PA
1481 ses->auth_key.response = NULL;
1482 ses->auth_key.len = 0;
1483 }
3baf1a7b
SP
1484out:
1485 sess_data->result = rc;
1486 sess_data->func = NULL;
1487 SMB2_sess_free_buffer(sess_data);
1488}
1489#else
1490static void
1491SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
1492{
1493 cifs_dbg(VFS, "Kerberos negotiated but upcall support disabled!\n");
1494 sess_data->result = -EOPNOTSUPP;
1495 sess_data->func = NULL;
1496}
1497#endif
1498
166cea4d
SP
1499static void
1500SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data);
1501
1502static void
1503SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
5478f9ba 1504{
166cea4d
SP
1505 int rc;
1506 struct cifs_ses *ses = sess_data->ses;
f486ef8e 1507 struct TCP_Server_Info *server = sess_data->server;
5478f9ba 1508 struct smb2_sess_setup_rsp *rsp = NULL;
49bd49f9 1509 unsigned char *ntlmssp_blob = NULL;
5478f9ba 1510 bool use_spnego = false; /* else use raw ntlmssp */
166cea4d 1511 u16 blob_length = 0;
f486ef8e 1512 bool is_binding = false;
d4e63bd6 1513
5478f9ba
PS
1514 /*
1515 * If memory allocation is successful, caller of this function
1516 * frees it.
1517 */
1518 ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
166cea4d
SP
1519 if (!ses->ntlmssp) {
1520 rc = -ENOMEM;
1521 goto out_err;
1522 }
5c234aa5 1523 ses->ntlmssp->sesskey_per_smbsess = true;
5478f9ba 1524
166cea4d 1525 rc = SMB2_sess_alloc_buffer(sess_data);
5478f9ba 1526 if (rc)
166cea4d 1527 goto out_err;
5478f9ba 1528
52d00533 1529 rc = build_ntlmssp_smb3_negotiate_blob(&ntlmssp_blob,
f486ef8e 1530 &blob_length, ses, server,
49bd49f9
SP
1531 sess_data->nls_cp);
1532 if (rc)
30b2d7f8 1533 goto out;
c2afb814 1534
166cea4d
SP
1535 if (use_spnego) {
1536 /* BB eventually need to add this */
1537 cifs_dbg(VFS, "spnego not supported for SMB2 yet\n");
1538 rc = -EOPNOTSUPP;
1539 goto out;
166cea4d
SP
1540 }
1541 sess_data->iov[1].iov_base = ntlmssp_blob;
1542 sess_data->iov[1].iov_len = blob_length;
c2afb814 1543
166cea4d
SP
1544 rc = SMB2_sess_sendreceive(sess_data);
1545 rsp = (struct smb2_sess_setup_rsp *)sess_data->iov[0].iov_base;
5478f9ba 1546
166cea4d
SP
1547 /* If true, rc here is expected and not an error */
1548 if (sess_data->buf0_type != CIFS_NO_BUFFER &&
0d35e382 1549 rsp->hdr.Status == STATUS_MORE_PROCESSING_REQUIRED)
166cea4d 1550 rc = 0;
38d77c50 1551
166cea4d
SP
1552 if (rc)
1553 goto out;
5478f9ba 1554
1fc6ad2f 1555 if (offsetof(struct smb2_sess_setup_rsp, Buffer) !=
166cea4d
SP
1556 le16_to_cpu(rsp->SecurityBufferOffset)) {
1557 cifs_dbg(VFS, "Invalid security buffer offset %d\n",
1558 le16_to_cpu(rsp->SecurityBufferOffset));
5478f9ba 1559 rc = -EIO;
166cea4d 1560 goto out;
5478f9ba 1561 }
166cea4d
SP
1562 rc = decode_ntlmssp_challenge(rsp->Buffer,
1563 le16_to_cpu(rsp->SecurityBufferLength), ses);
1564 if (rc)
1565 goto out;
5478f9ba 1566
166cea4d 1567 cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
5478f9ba 1568
bc962159
SP
1569 spin_lock(&ses->ses_lock);
1570 is_binding = (ses->ses_status == SES_GOOD);
1571 spin_unlock(&ses->ses_lock);
f486ef8e 1572
d70e9fa5 1573 /* keep existing ses id and flags if binding */
f486ef8e 1574 if (!is_binding) {
0d35e382 1575 ses->Suid = le64_to_cpu(rsp->hdr.SessionId);
d70e9fa5
AA
1576 ses->session_flags = le16_to_cpu(rsp->SessionFlags);
1577 }
166cea4d
SP
1578
1579out:
01f2ee7e 1580 kfree_sensitive(ntlmssp_blob);
166cea4d
SP
1581 SMB2_sess_free_buffer(sess_data);
1582 if (!rc) {
1583 sess_data->result = 0;
1584 sess_data->func = SMB2_sess_auth_rawntlmssp_authenticate;
1585 return;
1586 }
1587out_err:
a4e430c8 1588 kfree_sensitive(ses->ntlmssp);
166cea4d
SP
1589 ses->ntlmssp = NULL;
1590 sess_data->result = rc;
1591 sess_data->func = NULL;
1592}
5478f9ba 1593
166cea4d
SP
1594static void
1595SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data)
1596{
1597 int rc;
1598 struct cifs_ses *ses = sess_data->ses;
f486ef8e 1599 struct TCP_Server_Info *server = sess_data->server;
166cea4d
SP
1600 struct smb2_sess_setup_req *req;
1601 struct smb2_sess_setup_rsp *rsp = NULL;
1602 unsigned char *ntlmssp_blob = NULL;
1603 bool use_spnego = false; /* else use raw ntlmssp */
1604 u16 blob_length = 0;
f486ef8e 1605 bool is_binding = false;
5478f9ba 1606
166cea4d
SP
1607 rc = SMB2_sess_alloc_buffer(sess_data);
1608 if (rc)
1609 goto out;
5478f9ba 1610
166cea4d 1611 req = (struct smb2_sess_setup_req *) sess_data->iov[0].iov_base;
0d35e382 1612 req->hdr.SessionId = cpu_to_le64(ses->Suid);
166cea4d 1613
f486ef8e
SP
1614 rc = build_ntlmssp_auth_blob(&ntlmssp_blob, &blob_length,
1615 ses, server,
1616 sess_data->nls_cp);
166cea4d
SP
1617 if (rc) {
1618 cifs_dbg(FYI, "build_ntlmssp_auth_blob failed %d\n", rc);
1619 goto out;
5478f9ba
PS
1620 }
1621
166cea4d
SP
1622 if (use_spnego) {
1623 /* BB eventually need to add this */
1624 cifs_dbg(VFS, "spnego not supported for SMB2 yet\n");
1625 rc = -EOPNOTSUPP;
1626 goto out;
1627 }
1628 sess_data->iov[1].iov_base = ntlmssp_blob;
1629 sess_data->iov[1].iov_len = blob_length;
5478f9ba 1630
166cea4d
SP
1631 rc = SMB2_sess_sendreceive(sess_data);
1632 if (rc)
1633 goto out;
1634
1635 rsp = (struct smb2_sess_setup_rsp *)sess_data->iov[0].iov_base;
1636
bc962159
SP
1637 spin_lock(&ses->ses_lock);
1638 is_binding = (ses->ses_status == SES_GOOD);
1639 spin_unlock(&ses->ses_lock);
f486ef8e 1640
d70e9fa5 1641 /* keep existing ses id and flags if binding */
f486ef8e 1642 if (!is_binding) {
0d35e382 1643 ses->Suid = le64_to_cpu(rsp->hdr.SessionId);
d70e9fa5
AA
1644 ses->session_flags = le16_to_cpu(rsp->SessionFlags);
1645 }
5478f9ba 1646
166cea4d 1647 rc = SMB2_sess_establish_session(sess_data);
f560cda9
RS
1648#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
1649 if (ses->server->dialect < SMB30_PROT_ID) {
1650 cifs_dbg(VFS, "%s: dumping generated SMB2 session keys\n", __func__);
1651 /*
1652 * The session id is opaque in terms of endianness, so we can't
1653 * print it as a long long. we dump it as we got it on the wire
1654 */
1655 cifs_dbg(VFS, "Session Id %*ph\n", (int)sizeof(ses->Suid),
1656 &ses->Suid);
1657 cifs_dbg(VFS, "Session Key %*ph\n",
1658 SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
1659 cifs_dbg(VFS, "Signing Key %*ph\n",
1660 SMB3_SIGN_KEY_SIZE, ses->auth_key.response);
1661 }
1662#endif
166cea4d 1663out:
01f2ee7e 1664 kfree_sensitive(ntlmssp_blob);
166cea4d 1665 SMB2_sess_free_buffer(sess_data);
a4e430c8 1666 kfree_sensitive(ses->ntlmssp);
166cea4d
SP
1667 ses->ntlmssp = NULL;
1668 sess_data->result = rc;
1669 sess_data->func = NULL;
1670}
d4e63bd6 1671
166cea4d 1672static int
f486ef8e 1673SMB2_select_sec(struct SMB2_sess_data *sess_data)
166cea4d 1674{
ef65aaed 1675 int type;
f486ef8e
SP
1676 struct cifs_ses *ses = sess_data->ses;
1677 struct TCP_Server_Info *server = sess_data->server;
ef65aaed 1678
f486ef8e 1679 type = smb2_select_sectype(server, ses->sectype);
ef65aaed
SP
1680 cifs_dbg(FYI, "sess setup type %d\n", type);
1681 if (type == Unspecified) {
a0a3036b 1682 cifs_dbg(VFS, "Unable to select appropriate authentication method!\n");
ef65aaed
SP
1683 return -EINVAL;
1684 }
d4e63bd6 1685
ef65aaed 1686 switch (type) {
166cea4d
SP
1687 case Kerberos:
1688 sess_data->func = SMB2_auth_kerberos;
1689 break;
1690 case RawNTLMSSP:
1691 sess_data->func = SMB2_sess_auth_rawntlmssp_negotiate;
1692 break;
1693 default:
ef65aaed 1694 cifs_dbg(VFS, "secType %d not supported!\n", type);
166cea4d 1695 return -EOPNOTSUPP;
d4e63bd6
SP
1696 }
1697
166cea4d
SP
1698 return 0;
1699}
1700
1701int
1702SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
f486ef8e 1703 struct TCP_Server_Info *server,
166cea4d
SP
1704 const struct nls_table *nls_cp)
1705{
1706 int rc = 0;
166cea4d
SP
1707 struct SMB2_sess_data *sess_data;
1708
1709 cifs_dbg(FYI, "Session Setup\n");
1710
1711 if (!server) {
1712 WARN(1, "%s: server is NULL!\n", __func__);
1713 return -EIO;
d4e63bd6 1714 }
d4e63bd6 1715
166cea4d
SP
1716 sess_data = kzalloc(sizeof(struct SMB2_sess_data), GFP_KERNEL);
1717 if (!sess_data)
1718 return -ENOMEM;
1719
166cea4d
SP
1720 sess_data->xid = xid;
1721 sess_data->ses = ses;
f486ef8e 1722 sess_data->server = server;
166cea4d
SP
1723 sess_data->buf0_type = CIFS_NO_BUFFER;
1724 sess_data->nls_cp = (struct nls_table *) nls_cp;
b2adf22f 1725 sess_data->previous_session = ses->Suid;
166cea4d 1726
f486ef8e
SP
1727 rc = SMB2_select_sec(sess_data);
1728 if (rc)
1729 goto out;
1730
8bd68c6e
AA
1731 /*
1732 * Initialize the session hash with the server one.
1733 */
f6a6bf7c 1734 memcpy(ses->preauth_sha_hash, server->preauth_sha_hash,
8bd68c6e 1735 SMB2_PREAUTH_HASH_SIZE);
8bd68c6e 1736
166cea4d
SP
1737 while (sess_data->func)
1738 sess_data->func(sess_data);
1739
c721c389 1740 if ((ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST) && (ses->sign))
afe6f653 1741 cifs_server_dbg(VFS, "signing requested but authenticated as guest\n");
3baf1a7b 1742 rc = sess_data->result;
166cea4d 1743out:
a4e430c8 1744 kfree_sensitive(sess_data);
5478f9ba
PS
1745 return rc;
1746}
1747
1748int
1749SMB2_logoff(const unsigned int xid, struct cifs_ses *ses)
1750{
40eff45b 1751 struct smb_rqst rqst;
5478f9ba
PS
1752 struct smb2_logoff_req *req; /* response is also trivial struct */
1753 int rc = 0;
1754 struct TCP_Server_Info *server;
7fb8986e 1755 int flags = 0;
45305eda
RS
1756 unsigned int total_len;
1757 struct kvec iov[1];
1758 struct kvec rsp_iov;
1759 int resp_buf_type;
5478f9ba 1760
f96637be 1761 cifs_dbg(FYI, "disconnect session %p\n", ses);
5478f9ba
PS
1762
1763 if (ses && (ses->server))
1764 server = ses->server;
1765 else
1766 return -EIO;
1767
eb4c7df6 1768 /* no need to send SMB logoff if uid already closed due to reconnect */
d1a931ce
SP
1769 spin_lock(&ses->chan_lock);
1770 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
1771 spin_unlock(&ses->chan_lock);
eb4c7df6 1772 goto smb2_session_already_dead;
d1a931ce
SP
1773 }
1774 spin_unlock(&ses->chan_lock);
eb4c7df6 1775
352d96f3
AA
1776 rc = smb2_plain_req_init(SMB2_LOGOFF, NULL, ses->server,
1777 (void **) &req, &total_len);
5478f9ba
PS
1778 if (rc)
1779 return rc;
1780
1781 /* since no tcon, smb2_init can not do this, so do here */
0d35e382 1782 req->hdr.SessionId = cpu_to_le64(ses->Suid);
7fb8986e
PS
1783
1784 if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
1785 flags |= CIFS_TRANSFORM_REQ;
1786 else if (server->sign)
0d35e382 1787 req->hdr.Flags |= SMB2_FLAGS_SIGNED;
45305eda 1788
392e1c5d 1789 flags |= CIFS_NO_RSP_BUF;
45305eda
RS
1790
1791 iov[0].iov_base = (char *)req;
1792 iov[0].iov_len = total_len;
5478f9ba 1793
40eff45b
RS
1794 memset(&rqst, 0, sizeof(struct smb_rqst));
1795 rqst.rq_iov = iov;
1796 rqst.rq_nvec = 1;
1797
352d96f3
AA
1798 rc = cifs_send_recv(xid, ses, ses->server,
1799 &rqst, &resp_buf_type, flags, &rsp_iov);
da502f7d 1800 cifs_small_buf_release(req);
5478f9ba
PS
1801 /*
1802 * No tcon so can't do
1803 * cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]);
1804 */
eb4c7df6
SP
1805
1806smb2_session_already_dead:
5478f9ba
PS
1807 return rc;
1808}
faaf946a
PS
1809
1810static inline void cifs_stats_fail_inc(struct cifs_tcon *tcon, uint16_t code)
1811{
d60622eb 1812 cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_failed[code]);
faaf946a
PS
1813}
1814
1815#define MAX_SHARENAME_LENGTH (255 /* server */ + 80 /* share */ + 1 /* NULL */)
1816
de9f68df
SF
1817/* These are similar values to what Windows uses */
1818static inline void init_copy_chunk_defaults(struct cifs_tcon *tcon)
1819{
1820 tcon->max_chunks = 256;
1821 tcon->max_bytes_chunk = 1048576;
1822 tcon->max_bytes_copy = 16777216;
1823}
1824
faaf946a
PS
1825int
1826SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
1827 struct cifs_tcon *tcon, const struct nls_table *cp)
1828{
40eff45b 1829 struct smb_rqst rqst;
faaf946a
PS
1830 struct smb2_tree_connect_req *req;
1831 struct smb2_tree_connect_rsp *rsp = NULL;
1832 struct kvec iov[2];
db3b5474 1833 struct kvec rsp_iov = { NULL, 0 };
faaf946a
PS
1834 int rc = 0;
1835 int resp_buftype;
1836 int unc_path_len;
faaf946a 1837 __le16 *unc_path = NULL;
7fb8986e 1838 int flags = 0;
661bb943 1839 unsigned int total_len;
352d96f3
AA
1840 struct TCP_Server_Info *server;
1841
1842 /* always use master channel */
1843 server = ses->server;
faaf946a 1844
f96637be 1845 cifs_dbg(FYI, "TCON\n");
faaf946a 1846
afe6f653 1847 if (!server || !tree)
faaf946a
PS
1848 return -EIO;
1849
faaf946a
PS
1850 unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
1851 if (unc_path == NULL)
1852 return -ENOMEM;
1853
5574920c
NJ
1854 unc_path_len = cifs_strtoUTF16(unc_path, tree, strlen(tree), cp);
1855 if (unc_path_len <= 0) {
faaf946a
PS
1856 kfree(unc_path);
1857 return -EINVAL;
1858 }
5574920c 1859 unc_path_len *= 2;
faaf946a 1860
806a28ef 1861 /* SMB2 TREE_CONNECT request must be called with TreeId == 0 */
b327a717 1862 tcon->tid = 0;
fae8044c 1863 atomic_set(&tcon->num_remote_opens, 0);
352d96f3
AA
1864 rc = smb2_plain_req_init(SMB2_TREE_CONNECT, tcon, server,
1865 (void **) &req, &total_len);
faaf946a
PS
1866 if (rc) {
1867 kfree(unc_path);
1868 return rc;
1869 }
1870
5a77e75f 1871 if (smb3_encryption_required(tcon))
ae6f8dd4 1872 flags |= CIFS_TRANSFORM_REQ;
faaf946a
PS
1873
1874 iov[0].iov_base = (char *)req;
661bb943
RS
1875 /* 1 for pad */
1876 iov[0].iov_len = total_len - 1;
faaf946a
PS
1877
1878 /* Testing shows that buffer offset must be at location of Buffer[0] */
eb3e28c1 1879 req->PathOffset = cpu_to_le16(sizeof(struct smb2_tree_connect_req));
5574920c 1880 req->PathLength = cpu_to_le16(unc_path_len);
faaf946a
PS
1881 iov[1].iov_base = unc_path;
1882 iov[1].iov_len = unc_path_len;
1883
e71ab2aa
RS
1884 /*
1885 * 3.11 tcon req must be signed if not encrypted. See MS-SMB2 3.2.4.1.1
1886 * unless it is guest or anonymous user. See MS-SMB2 3.2.5.3.1
8c11a607 1887 * (Samba servers don't always set the flag so also check if null user)
e71ab2aa 1888 */
afe6f653 1889 if ((server->dialect == SMB311_PROT_ID) &&
e71ab2aa 1890 !smb3_encryption_required(tcon) &&
8c11a607
SF
1891 !(ses->session_flags &
1892 (SMB2_SESSION_FLAG_IS_GUEST|SMB2_SESSION_FLAG_IS_NULL)) &&
1893 ((ses->user_name != NULL) || (ses->sectype == Kerberos)))
0d35e382 1894 req->hdr.Flags |= SMB2_FLAGS_SIGNED;
6188f28b 1895
40eff45b
RS
1896 memset(&rqst, 0, sizeof(struct smb_rqst));
1897 rqst.rq_iov = iov;
1898 rqst.rq_nvec = 2;
1899
4fe75c4e 1900 /* Need 64 for max size write so ask for more in case not there yet */
0d35e382 1901 req->hdr.CreditRequest = cpu_to_le16(64);
4fe75c4e 1902
352d96f3
AA
1903 rc = cifs_send_recv(xid, ses, server,
1904 &rqst, &resp_buftype, flags, &rsp_iov);
da502f7d
PS
1905 cifs_small_buf_release(req);
1906 rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base;
f8af49dd 1907 trace_smb3_tcon(xid, tcon->tid, ses->Suid, tree, rc);
bac35395 1908 if ((rc != 0) || (rsp == NULL)) {
3559134e
SF
1909 cifs_stats_fail_inc(tcon, SMB2_TREE_CONNECT_HE);
1910 tcon->need_reconnect = true;
faaf946a
PS
1911 goto tcon_error_exit;
1912 }
1913
cd123007
CJ
1914 switch (rsp->ShareType) {
1915 case SMB2_SHARE_TYPE_DISK:
f96637be 1916 cifs_dbg(FYI, "connection to disk share\n");
cd123007
CJ
1917 break;
1918 case SMB2_SHARE_TYPE_PIPE:
b327a717 1919 tcon->pipe = true;
f96637be 1920 cifs_dbg(FYI, "connection to pipe share\n");
cd123007
CJ
1921 break;
1922 case SMB2_SHARE_TYPE_PRINT:
b327a717 1923 tcon->print = true;
f96637be 1924 cifs_dbg(FYI, "connection to printer\n");
cd123007
CJ
1925 break;
1926 default:
afe6f653 1927 cifs_server_dbg(VFS, "unknown share type %d\n", rsp->ShareType);
faaf946a
PS
1928 rc = -EOPNOTSUPP;
1929 goto tcon_error_exit;
1930 }
1931
1932 tcon->share_flags = le32_to_cpu(rsp->ShareFlags);
769ee6a4 1933 tcon->capabilities = rsp->Capabilities; /* we keep caps little endian */
faaf946a 1934 tcon->maximal_access = le32_to_cpu(rsp->MaximalAccess);
0d35e382 1935 tcon->tid = le32_to_cpu(rsp->hdr.Id.SyncId.TreeId);
68e14569 1936 strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name));
faaf946a
PS
1937
1938 if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) &&
1939 ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0))
3175eb9b 1940 cifs_tcon_dbg(VFS, "DFS capability contradicts DFS flag\n");
ae6f8dd4
PS
1941
1942 if (tcon->seal &&
afe6f653 1943 !(server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
3175eb9b 1944 cifs_tcon_dbg(VFS, "Encryption is requested but not supported\n");
ae6f8dd4 1945
de9f68df 1946 init_copy_chunk_defaults(tcon);
afe6f653
RS
1947 if (server->ops->validate_negotiate)
1948 rc = server->ops->validate_negotiate(xid, tcon);
faaf946a 1949tcon_exit:
f8af49dd 1950
faaf946a
PS
1951 free_rsp_buf(resp_buftype, rsp);
1952 kfree(unc_path);
1953 return rc;
1954
1955tcon_error_exit:
0d35e382 1956 if (rsp && rsp->hdr.Status == STATUS_BAD_NETWORK_NAME)
3175eb9b 1957 cifs_tcon_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
faaf946a
PS
1958 goto tcon_exit;
1959}
1960
1961int
1962SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
1963{
40eff45b 1964 struct smb_rqst rqst;
faaf946a
PS
1965 struct smb2_tree_disconnect_req *req; /* response is trivial */
1966 int rc = 0;
faaf946a 1967 struct cifs_ses *ses = tcon->ses;
7fb8986e 1968 int flags = 0;
4eecf4cf
RS
1969 unsigned int total_len;
1970 struct kvec iov[1];
1971 struct kvec rsp_iov;
1972 int resp_buf_type;
faaf946a 1973
f96637be 1974 cifs_dbg(FYI, "Tree Disconnect\n");
faaf946a 1975
68a6afa7 1976 if (!ses || !(ses->server))
faaf946a
PS
1977 return -EIO;
1978
68e14569 1979 trace_smb3_tdis_enter(xid, tcon->tid, ses->Suid, tcon->tree_name);
d1a931ce
SP
1980 spin_lock(&ses->chan_lock);
1981 if ((tcon->need_reconnect) ||
1982 (CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses))) {
1983 spin_unlock(&ses->chan_lock);
faaf946a 1984 return 0;
d1a931ce
SP
1985 }
1986 spin_unlock(&ses->chan_lock);
faaf946a 1987
dcb45fd7 1988 invalidate_all_cached_dirs(tcon);
72e73c78 1989
352d96f3
AA
1990 rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, ses->server,
1991 (void **) &req,
1992 &total_len);
faaf946a
PS
1993 if (rc)
1994 return rc;
1995
5a77e75f 1996 if (smb3_encryption_required(tcon))
7fb8986e
PS
1997 flags |= CIFS_TRANSFORM_REQ;
1998
392e1c5d 1999 flags |= CIFS_NO_RSP_BUF;
4eecf4cf
RS
2000
2001 iov[0].iov_base = (char *)req;
2002 iov[0].iov_len = total_len;
2003
40eff45b
RS
2004 memset(&rqst, 0, sizeof(struct smb_rqst));
2005 rqst.rq_iov = iov;
2006 rqst.rq_nvec = 1;
2007
352d96f3
AA
2008 rc = cifs_send_recv(xid, ses, ses->server,
2009 &rqst, &resp_buf_type, flags, &rsp_iov);
da502f7d 2010 cifs_small_buf_release(req);
68e14569 2011 if (rc) {
faaf946a 2012 cifs_stats_fail_inc(tcon, SMB2_TREE_DISCONNECT_HE);
68e14569
SF
2013 trace_smb3_tdis_err(xid, tcon->tid, ses->Suid, rc);
2014 }
2015 trace_smb3_tdis_done(xid, tcon->tid, ses->Suid);
faaf946a
PS
2016
2017 return rc;
2018}
2503a0db 2019
b8c32dbb 2020
63eb3def
PS
2021static struct create_durable *
2022create_durable_buf(void)
2023{
2024 struct create_durable *buf;
2025
2026 buf = kzalloc(sizeof(struct create_durable), GFP_KERNEL);
2027 if (!buf)
2028 return NULL;
2029
2030 buf->ccontext.DataOffset = cpu_to_le16(offsetof
9cbc0b73 2031 (struct create_durable, Data));
63eb3def
PS
2032 buf->ccontext.DataLength = cpu_to_le32(16);
2033 buf->ccontext.NameOffset = cpu_to_le16(offsetof
2034 (struct create_durable, Name));
2035 buf->ccontext.NameLength = cpu_to_le16(4);
12197a7f 2036 /* SMB2_CREATE_DURABLE_HANDLE_REQUEST is "DHnQ" */
63eb3def
PS
2037 buf->Name[0] = 'D';
2038 buf->Name[1] = 'H';
2039 buf->Name[2] = 'n';
2040 buf->Name[3] = 'Q';
2041 return buf;
2042}
2043
9cbc0b73
PS
2044static struct create_durable *
2045create_reconnect_durable_buf(struct cifs_fid *fid)
2046{
2047 struct create_durable *buf;
2048
2049 buf = kzalloc(sizeof(struct create_durable), GFP_KERNEL);
2050 if (!buf)
2051 return NULL;
2052
2053 buf->ccontext.DataOffset = cpu_to_le16(offsetof
2054 (struct create_durable, Data));
2055 buf->ccontext.DataLength = cpu_to_le32(16);
2056 buf->ccontext.NameOffset = cpu_to_le16(offsetof
2057 (struct create_durable, Name));
2058 buf->ccontext.NameLength = cpu_to_le16(4);
2059 buf->Data.Fid.PersistentFileId = fid->persistent_fid;
2060 buf->Data.Fid.VolatileFileId = fid->volatile_fid;
12197a7f 2061 /* SMB2_CREATE_DURABLE_HANDLE_RECONNECT is "DHnC" */
9cbc0b73
PS
2062 buf->Name[0] = 'D';
2063 buf->Name[1] = 'H';
2064 buf->Name[2] = 'n';
2065 buf->Name[3] = 'C';
2066 return buf;
2067}
2068
89a5bfa3
SF
2069static void
2070parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
2071{
2072 struct create_on_disk_id *pdisk_id = (struct create_on_disk_id *)cc;
2073
2074 cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n",
2075 pdisk_id->DiskFileId, pdisk_id->VolumeId);
2076 buf->IndexNumber = pdisk_id->DiskFileId;
2077}
2078
ab3459d8 2079static void
69dda305
AA
2080parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info,
2081 struct create_posix_rsp *posix)
ab3459d8 2082{
69dda305
AA
2083 int sid_len;
2084 u8 *beg = (u8 *)cc + le16_to_cpu(cc->DataOffset);
2085 u8 *end = beg + le32_to_cpu(cc->DataLength);
2086 u8 *sid;
ab3459d8 2087
69dda305
AA
2088 memset(posix, 0, sizeof(*posix));
2089
2090 posix->nlink = le32_to_cpu(*(__le32 *)(beg + 0));
2091 posix->reparse_tag = le32_to_cpu(*(__le32 *)(beg + 4));
2092 posix->mode = le32_to_cpu(*(__le32 *)(beg + 8));
2093
2094 sid = beg + 12;
2095 sid_len = posix_info_sid_size(sid, end);
2096 if (sid_len < 0) {
2097 cifs_dbg(VFS, "bad owner sid in posix create response\n");
2098 return;
2099 }
2100 memcpy(&posix->owner, sid, sid_len);
2101
2102 sid = sid + sid_len;
2103 sid_len = posix_info_sid_size(sid, end);
2104 if (sid_len < 0) {
2105 cifs_dbg(VFS, "bad group sid in posix create response\n");
2106 return;
2107 }
2108 memcpy(&posix->group, sid, sid_len);
2e8af978 2109
69dda305
AA
2110 cifs_dbg(FYI, "nlink=%d mode=%o reparse_tag=%x\n",
2111 posix->nlink, posix->mode, posix->reparse_tag);
ab3459d8
SF
2112}
2113
89a5bfa3
SF
2114void
2115smb2_parse_contexts(struct TCP_Server_Info *server,
69dda305
AA
2116 struct smb2_create_rsp *rsp,
2117 unsigned int *epoch, char *lease_key, __u8 *oplock,
2118 struct smb2_file_all_info *buf,
2119 struct create_posix_rsp *posix)
b8c32dbb
PS
2120{
2121 char *data_offset;
b5c7cde3 2122 struct create_context *cc;
deb7deff
JM
2123 unsigned int next;
2124 unsigned int remaining;
fd554396 2125 char *name;
3ece60e3
CIK
2126 static const char smb3_create_tag_posix[] = {
2127 0x93, 0xAD, 0x25, 0x50, 0x9C,
2128 0xB4, 0x11, 0xE7, 0xB4, 0x23, 0x83,
2129 0xDE, 0x96, 0x8B, 0xCD, 0x7C
2130 };
b8c32dbb 2131
89a5bfa3 2132 *oplock = 0;
1fc6ad2f 2133 data_offset = (char *)rsp + le32_to_cpu(rsp->CreateContextsOffset);
deb7deff 2134 remaining = le32_to_cpu(rsp->CreateContextsLength);
b5c7cde3 2135 cc = (struct create_context *)data_offset;
89a5bfa3
SF
2136
2137 /* Initialize inode number to 0 in case no valid data in qfid context */
2138 if (buf)
2139 buf->IndexNumber = 0;
2140
deb7deff 2141 while (remaining >= sizeof(struct create_context)) {
b5c7cde3 2142 name = le16_to_cpu(cc->NameOffset) + (char *)cc;
deb7deff 2143 if (le16_to_cpu(cc->NameLength) == 4 &&
89a5bfa3
SF
2144 strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4) == 0)
2145 *oplock = server->ops->parse_lease_buf(cc, epoch,
2146 lease_key);
2147 else if (buf && (le16_to_cpu(cc->NameLength) == 4) &&
2148 strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4) == 0)
2149 parse_query_id_ctxt(cc, buf);
ab3459d8 2150 else if ((le16_to_cpu(cc->NameLength) == 16)) {
69dda305
AA
2151 if (posix &&
2152 memcmp(name, smb3_create_tag_posix, 16) == 0)
2153 parse_posix_ctxt(cc, buf, posix);
ab3459d8
SF
2154 }
2155 /* else {
2156 cifs_dbg(FYI, "Context not matched with len %d\n",
2157 le16_to_cpu(cc->NameLength));
2158 cifs_dump_mem("Cctxt name: ", name, 4);
2159 } */
deb7deff
JM
2160
2161 next = le32_to_cpu(cc->Next);
2162 if (!next)
2163 break;
2164 remaining -= next;
2165 cc = (struct create_context *)((char *)cc + next);
2166 }
b8c32dbb 2167
89a5bfa3
SF
2168 if (rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
2169 *oplock = rsp->OplockLevel;
2170
2171 return;
b8c32dbb
PS
2172}
2173
d22cbfec 2174static int
a41a28bd 2175add_lease_context(struct TCP_Server_Info *server, struct kvec *iov,
729c0c9d 2176 unsigned int *num_iovec, u8 *lease_key, __u8 *oplock)
d22cbfec
PS
2177{
2178 struct smb2_create_req *req = iov[0].iov_base;
2179 unsigned int num = *num_iovec;
2180
729c0c9d 2181 iov[num].iov_base = server->ops->create_lease_buf(lease_key, *oplock);
d22cbfec
PS
2182 if (iov[num].iov_base == NULL)
2183 return -ENOMEM;
a41a28bd 2184 iov[num].iov_len = server->vals->create_lease_size;
d22cbfec
PS
2185 req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_LEASE;
2186 if (!req->CreateContextsOffset)
2187 req->CreateContextsOffset = cpu_to_le32(
4f33bc35 2188 sizeof(struct smb2_create_req) +
d22cbfec 2189 iov[num - 1].iov_len);
a41a28bd
PS
2190 le32_add_cpu(&req->CreateContextsLength,
2191 server->vals->create_lease_size);
d22cbfec
PS
2192 *num_iovec = num + 1;
2193 return 0;
2194}
2195
b56eae4d 2196static struct create_durable_v2 *
ca567eb2 2197create_durable_v2_buf(struct cifs_open_parms *oparms)
b56eae4d 2198{
ca567eb2 2199 struct cifs_fid *pfid = oparms->fid;
b56eae4d
SF
2200 struct create_durable_v2 *buf;
2201
2202 buf = kzalloc(sizeof(struct create_durable_v2), GFP_KERNEL);
2203 if (!buf)
2204 return NULL;
2205
2206 buf->ccontext.DataOffset = cpu_to_le16(offsetof
2207 (struct create_durable_v2, dcontext));
2208 buf->ccontext.DataLength = cpu_to_le32(sizeof(struct durable_context_v2));
2209 buf->ccontext.NameOffset = cpu_to_le16(offsetof
2210 (struct create_durable_v2, Name));
2211 buf->ccontext.NameLength = cpu_to_le16(4);
2212
ca567eb2
SF
2213 /*
2214 * NB: Handle timeout defaults to 0, which allows server to choose
2215 * (most servers default to 120 seconds) and most clients default to 0.
2216 * This can be overridden at mount ("handletimeout=") if the user wants
2217 * a different persistent (or resilient) handle timeout for all opens
2218 * opens on a particular SMB3 mount.
2219 */
2220 buf->dcontext.Timeout = cpu_to_le32(oparms->tcon->handle_timeout);
b56eae4d 2221 buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
fa70b87c 2222 generate_random_uuid(buf->dcontext.CreateGuid);
b56eae4d
SF
2223 memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16);
2224
2225 /* SMB2_CREATE_DURABLE_HANDLE_REQUEST is "DH2Q" */
2226 buf->Name[0] = 'D';
2227 buf->Name[1] = 'H';
2228 buf->Name[2] = '2';
2229 buf->Name[3] = 'Q';
2230 return buf;
2231}
2232
2233static struct create_durable_handle_reconnect_v2 *
2234create_reconnect_durable_v2_buf(struct cifs_fid *fid)
2235{
2236 struct create_durable_handle_reconnect_v2 *buf;
2237
2238 buf = kzalloc(sizeof(struct create_durable_handle_reconnect_v2),
2239 GFP_KERNEL);
2240 if (!buf)
2241 return NULL;
2242
2243 buf->ccontext.DataOffset =
2244 cpu_to_le16(offsetof(struct create_durable_handle_reconnect_v2,
2245 dcontext));
2246 buf->ccontext.DataLength =
2247 cpu_to_le32(sizeof(struct durable_reconnect_context_v2));
2248 buf->ccontext.NameOffset =
2249 cpu_to_le16(offsetof(struct create_durable_handle_reconnect_v2,
2250 Name));
2251 buf->ccontext.NameLength = cpu_to_le16(4);
2252
2253 buf->dcontext.Fid.PersistentFileId = fid->persistent_fid;
2254 buf->dcontext.Fid.VolatileFileId = fid->volatile_fid;
2255 buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
2256 memcpy(buf->dcontext.CreateGuid, fid->create_guid, 16);
2257
2258 /* SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 is "DH2C" */
2259 buf->Name[0] = 'D';
2260 buf->Name[1] = 'H';
2261 buf->Name[2] = '2';
2262 buf->Name[3] = 'C';
2263 return buf;
2264}
2265
63eb3def 2266static int
b56eae4d
SF
2267add_durable_v2_context(struct kvec *iov, unsigned int *num_iovec,
2268 struct cifs_open_parms *oparms)
2269{
2270 struct smb2_create_req *req = iov[0].iov_base;
2271 unsigned int num = *num_iovec;
2272
ca567eb2 2273 iov[num].iov_base = create_durable_v2_buf(oparms);
b56eae4d
SF
2274 if (iov[num].iov_base == NULL)
2275 return -ENOMEM;
2276 iov[num].iov_len = sizeof(struct create_durable_v2);
2277 if (!req->CreateContextsOffset)
2278 req->CreateContextsOffset =
4f33bc35 2279 cpu_to_le32(sizeof(struct smb2_create_req) +
b56eae4d
SF
2280 iov[1].iov_len);
2281 le32_add_cpu(&req->CreateContextsLength, sizeof(struct create_durable_v2));
b56eae4d
SF
2282 *num_iovec = num + 1;
2283 return 0;
2284}
2285
2286static int
2287add_durable_reconnect_v2_context(struct kvec *iov, unsigned int *num_iovec,
9cbc0b73 2288 struct cifs_open_parms *oparms)
63eb3def
PS
2289{
2290 struct smb2_create_req *req = iov[0].iov_base;
2291 unsigned int num = *num_iovec;
2292
b56eae4d
SF
2293 /* indicate that we don't need to relock the file */
2294 oparms->reconnect = false;
2295
2296 iov[num].iov_base = create_reconnect_durable_v2_buf(oparms->fid);
2297 if (iov[num].iov_base == NULL)
2298 return -ENOMEM;
2299 iov[num].iov_len = sizeof(struct create_durable_handle_reconnect_v2);
2300 if (!req->CreateContextsOffset)
2301 req->CreateContextsOffset =
4f33bc35 2302 cpu_to_le32(sizeof(struct smb2_create_req) +
b56eae4d
SF
2303 iov[1].iov_len);
2304 le32_add_cpu(&req->CreateContextsLength,
2305 sizeof(struct create_durable_handle_reconnect_v2));
b56eae4d
SF
2306 *num_iovec = num + 1;
2307 return 0;
2308}
2309
2310static int
2311add_durable_context(struct kvec *iov, unsigned int *num_iovec,
2312 struct cifs_open_parms *oparms, bool use_persistent)
2313{
2314 struct smb2_create_req *req = iov[0].iov_base;
2315 unsigned int num = *num_iovec;
2316
2317 if (use_persistent) {
2318 if (oparms->reconnect)
2319 return add_durable_reconnect_v2_context(iov, num_iovec,
2320 oparms);
2321 else
2322 return add_durable_v2_context(iov, num_iovec, oparms);
2323 }
2324
9cbc0b73
PS
2325 if (oparms->reconnect) {
2326 iov[num].iov_base = create_reconnect_durable_buf(oparms->fid);
2327 /* indicate that we don't need to relock the file */
2328 oparms->reconnect = false;
2329 } else
2330 iov[num].iov_base = create_durable_buf();
63eb3def
PS
2331 if (iov[num].iov_base == NULL)
2332 return -ENOMEM;
2333 iov[num].iov_len = sizeof(struct create_durable);
2334 if (!req->CreateContextsOffset)
2335 req->CreateContextsOffset =
4f33bc35 2336 cpu_to_le32(sizeof(struct smb2_create_req) +
63eb3def 2337 iov[1].iov_len);
31f92e9a 2338 le32_add_cpu(&req->CreateContextsLength, sizeof(struct create_durable));
63eb3def
PS
2339 *num_iovec = num + 1;
2340 return 0;
2341}
2342
cdeaf9d0
SF
2343/* See MS-SMB2 2.2.13.2.7 */
2344static struct crt_twarp_ctxt *
2345create_twarp_buf(__u64 timewarp)
2346{
2347 struct crt_twarp_ctxt *buf;
2348
2349 buf = kzalloc(sizeof(struct crt_twarp_ctxt), GFP_KERNEL);
2350 if (!buf)
2351 return NULL;
2352
2353 buf->ccontext.DataOffset = cpu_to_le16(offsetof
2354 (struct crt_twarp_ctxt, Timestamp));
2355 buf->ccontext.DataLength = cpu_to_le32(8);
2356 buf->ccontext.NameOffset = cpu_to_le16(offsetof
2357 (struct crt_twarp_ctxt, Name));
2358 buf->ccontext.NameLength = cpu_to_le16(4);
2359 /* SMB2_CREATE_TIMEWARP_TOKEN is "TWrp" */
2360 buf->Name[0] = 'T';
2361 buf->Name[1] = 'W';
2362 buf->Name[2] = 'r';
2363 buf->Name[3] = 'p';
2364 buf->Timestamp = cpu_to_le64(timewarp);
2365 return buf;
2366}
2367
2368/* See MS-SMB2 2.2.13.2.7 */
2369static int
2370add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp)
2371{
2372 struct smb2_create_req *req = iov[0].iov_base;
2373 unsigned int num = *num_iovec;
2374
2375 iov[num].iov_base = create_twarp_buf(timewarp);
2376 if (iov[num].iov_base == NULL)
2377 return -ENOMEM;
2378 iov[num].iov_len = sizeof(struct crt_twarp_ctxt);
2379 if (!req->CreateContextsOffset)
2380 req->CreateContextsOffset = cpu_to_le32(
2381 sizeof(struct smb2_create_req) +
2382 iov[num - 1].iov_len);
2383 le32_add_cpu(&req->CreateContextsLength, sizeof(struct crt_twarp_ctxt));
2384 *num_iovec = num + 1;
2385 return 0;
2386}
2387
975221ec
SF
2388/* See See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx */
2389static void setup_owner_group_sids(char *buf)
2390{
2391 struct owner_group_sids *sids = (struct owner_group_sids *)buf;
2392
2393 /* Populate the user ownership fields S-1-5-88-1 */
2394 sids->owner.Revision = 1;
2395 sids->owner.NumAuth = 3;
2396 sids->owner.Authority[5] = 5;
2397 sids->owner.SubAuthorities[0] = cpu_to_le32(88);
2398 sids->owner.SubAuthorities[1] = cpu_to_le32(1);
2399 sids->owner.SubAuthorities[2] = cpu_to_le32(current_fsuid().val);
2400
2401 /* Populate the group ownership fields S-1-5-88-2 */
2402 sids->group.Revision = 1;
2403 sids->group.NumAuth = 3;
2404 sids->group.Authority[5] = 5;
2405 sids->group.SubAuthorities[0] = cpu_to_le32(88);
2406 sids->group.SubAuthorities[1] = cpu_to_le32(2);
2407 sids->group.SubAuthorities[2] = cpu_to_le32(current_fsgid().val);
a7a519a4
SF
2408
2409 cifs_dbg(FYI, "owner S-1-5-88-1-%d, group S-1-5-88-2-%d\n", current_fsuid().val, current_fsgid().val);
975221ec
SF
2410}
2411
fdef665b
SF
2412/* See MS-SMB2 2.2.13.2.2 and MS-DTYP 2.4.6 */
2413static struct crt_sd_ctxt *
975221ec 2414create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
fdef665b
SF
2415{
2416 struct crt_sd_ctxt *buf;
ea64370b
RS
2417 __u8 *ptr, *aclptr;
2418 unsigned int acelen, acl_size, ace_count;
975221ec
SF
2419 unsigned int owner_offset = 0;
2420 unsigned int group_offset = 0;
f09bd695 2421 struct smb3_acl acl = {};
975221ec 2422
d7173623 2423 *len = round_up(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 4), 8);
975221ec
SF
2424
2425 if (set_owner) {
975221ec
SF
2426 /* sizeof(struct owner_group_sids) is already multiple of 8 so no need to round */
2427 *len += sizeof(struct owner_group_sids);
2428 }
fdef665b 2429
fdef665b
SF
2430 buf = kzalloc(*len, GFP_KERNEL);
2431 if (buf == NULL)
2432 return buf;
2433
ea64370b 2434 ptr = (__u8 *)&buf[1];
975221ec 2435 if (set_owner) {
ea64370b
RS
2436 /* offset fields are from beginning of security descriptor not of create context */
2437 owner_offset = ptr - (__u8 *)&buf->sd;
975221ec 2438 buf->sd.OffsetOwner = cpu_to_le32(owner_offset);
ea64370b 2439 group_offset = owner_offset + offsetof(struct owner_group_sids, group);
975221ec 2440 buf->sd.OffsetGroup = cpu_to_le32(group_offset);
ea64370b
RS
2441
2442 setup_owner_group_sids(ptr);
2443 ptr += sizeof(struct owner_group_sids);
975221ec
SF
2444 } else {
2445 buf->sd.OffsetOwner = 0;
2446 buf->sd.OffsetGroup = 0;
2447 }
2448
ea64370b 2449 buf->ccontext.DataOffset = cpu_to_le16(offsetof(struct crt_sd_ctxt, sd));
975221ec 2450 buf->ccontext.NameOffset = cpu_to_le16(offsetof(struct crt_sd_ctxt, Name));
fdef665b
SF
2451 buf->ccontext.NameLength = cpu_to_le16(4);
2452 /* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */
2453 buf->Name[0] = 'S';
2454 buf->Name[1] = 'e';
2455 buf->Name[2] = 'c';
2456 buf->Name[3] = 'D';
2457 buf->sd.Revision = 1; /* Must be one see MS-DTYP 2.4.6 */
ea64370b 2458
fdef665b
SF
2459 /*
2460 * ACL is "self relative" ie ACL is stored in contiguous block of memory
2461 * and "DP" ie the DACL is present
2462 */
2463 buf->sd.Control = cpu_to_le16(ACL_CONTROL_SR | ACL_CONTROL_DP);
2464
2465 /* offset owner, group and Sbz1 and SACL are all zero */
ea64370b
RS
2466 buf->sd.OffsetDacl = cpu_to_le32(ptr - (__u8 *)&buf->sd);
2467 /* Ship the ACL for now. we will copy it into buf later. */
2468 aclptr = ptr;
b06d893e 2469 ptr += sizeof(struct smb3_acl);
fdef665b
SF
2470
2471 /* create one ACE to hold the mode embedded in reserved special SID */
ea64370b
RS
2472 acelen = setup_special_mode_ACE((struct cifs_ace *)ptr, (__u64)mode);
2473 ptr += acelen;
2474 acl_size = acelen + sizeof(struct smb3_acl);
2475 ace_count = 1;
975221ec
SF
2476
2477 if (set_owner) {
2478 /* we do not need to reallocate buffer to add the two more ACEs. plenty of space */
ea64370b
RS
2479 acelen = setup_special_user_owner_ACE((struct cifs_ace *)ptr);
2480 ptr += acelen;
2481 acl_size += acelen;
2482 ace_count += 1;
2483 }
975221ec 2484
643fbcee 2485 /* and one more ACE to allow access for authenticated users */
ea64370b
RS
2486 acelen = setup_authusers_ACE((struct cifs_ace *)ptr);
2487 ptr += acelen;
2488 acl_size += acelen;
2489 ace_count += 1;
2490
2491 acl.AclRevision = ACL_REVISION; /* See 2.4.4.1 of MS-DTYP */
2492 acl.AclSize = cpu_to_le16(acl_size);
2493 acl.AceCount = cpu_to_le16(ace_count);
f09bd695 2494 /* acl.Sbz1 and Sbz2 MBZ so are not set here, but initialized above */
b06d893e 2495 memcpy(aclptr, &acl, sizeof(struct smb3_acl));
ea64370b
RS
2496
2497 buf->ccontext.DataLength = cpu_to_le32(ptr - (__u8 *)&buf->sd);
d7173623 2498 *len = round_up((unsigned int)(ptr - (__u8 *)buf), 8);
975221ec 2499
fdef665b
SF
2500 return buf;
2501}
2502
2503static int
975221ec 2504add_sd_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode, bool set_owner)
fdef665b
SF
2505{
2506 struct smb2_create_req *req = iov[0].iov_base;
2507 unsigned int num = *num_iovec;
2508 unsigned int len = 0;
2509
975221ec 2510 iov[num].iov_base = create_sd_buf(mode, set_owner, &len);
fdef665b
SF
2511 if (iov[num].iov_base == NULL)
2512 return -ENOMEM;
2513 iov[num].iov_len = len;
2514 if (!req->CreateContextsOffset)
2515 req->CreateContextsOffset = cpu_to_le32(
2516 sizeof(struct smb2_create_req) +
2517 iov[num - 1].iov_len);
2518 le32_add_cpu(&req->CreateContextsLength, len);
2519 *num_iovec = num + 1;
2520 return 0;
2521}
2522
ff2a09e9
SF
2523static struct crt_query_id_ctxt *
2524create_query_id_buf(void)
2525{
2526 struct crt_query_id_ctxt *buf;
2527
2528 buf = kzalloc(sizeof(struct crt_query_id_ctxt), GFP_KERNEL);
2529 if (!buf)
2530 return NULL;
2531
2532 buf->ccontext.DataOffset = cpu_to_le16(0);
2533 buf->ccontext.DataLength = cpu_to_le32(0);
2534 buf->ccontext.NameOffset = cpu_to_le16(offsetof
2535 (struct crt_query_id_ctxt, Name));
2536 buf->ccontext.NameLength = cpu_to_le16(4);
2537 /* SMB2_CREATE_QUERY_ON_DISK_ID is "QFid" */
2538 buf->Name[0] = 'Q';
2539 buf->Name[1] = 'F';
2540 buf->Name[2] = 'i';
2541 buf->Name[3] = 'd';
2542 return buf;
2543}
2544
2545/* See MS-SMB2 2.2.13.2.9 */
2546static int
2547add_query_id_context(struct kvec *iov, unsigned int *num_iovec)
2548{
2549 struct smb2_create_req *req = iov[0].iov_base;
2550 unsigned int num = *num_iovec;
2551
2552 iov[num].iov_base = create_query_id_buf();
2553 if (iov[num].iov_base == NULL)
2554 return -ENOMEM;
2555 iov[num].iov_len = sizeof(struct crt_query_id_ctxt);
2556 if (!req->CreateContextsOffset)
2557 req->CreateContextsOffset = cpu_to_le32(
2558 sizeof(struct smb2_create_req) +
2559 iov[num - 1].iov_len);
2560 le32_add_cpu(&req->CreateContextsLength, sizeof(struct crt_query_id_ctxt));
2561 *num_iovec = num + 1;
2562 return 0;
2563}
2564
f0712928
AA
2565static int
2566alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len,
2567 const char *treename, const __le16 *path)
2568{
2569 int treename_len, path_len;
2570 struct nls_table *cp;
2571 const __le16 sep[] = {cpu_to_le16('\\'), cpu_to_le16(0x0000)};
2572
2573 /*
2574 * skip leading "\\"
2575 */
2576 treename_len = strlen(treename);
2577 if (treename_len < 2 || !(treename[0] == '\\' && treename[1] == '\\'))
2578 return -EINVAL;
2579
2580 treename += 2;
2581 treename_len -= 2;
2582
2583 path_len = UniStrnlen((wchar_t *)path, PATH_MAX);
2584
a1d2eb51
PA
2585 /* make room for one path separator only if @path isn't empty */
2586 *out_len = treename_len + (path[0] ? 1 : 0) + path_len;
f0712928
AA
2587
2588 /*
a1d2eb51
PA
2589 * final path needs to be 8-byte aligned as specified in
2590 * MS-SMB2 2.2.13 SMB2 CREATE Request.
f0712928 2591 */
d7173623 2592 *out_size = round_up(*out_len * sizeof(__le16), 8);
a1d2eb51 2593 *out_path = kzalloc(*out_size + sizeof(__le16) /* null */, GFP_KERNEL);
f0712928
AA
2594 if (!*out_path)
2595 return -ENOMEM;
2596
2597 cp = load_nls_default();
2598 cifs_strtoUTF16(*out_path, treename, treename_len, cp);
7eacba3b
EK
2599
2600 /* Do not append the separator if the path is empty */
2601 if (path[0] != cpu_to_le16(0x0000)) {
2602 UniStrcat(*out_path, sep);
2603 UniStrcat(*out_path, path);
2604 }
2605
f0712928
AA
2606 unload_nls(cp);
2607
2608 return 0;
2609}
2610
bea851b8
SF
2611int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
2612 umode_t mode, struct cifs_tcon *tcon,
2613 const char *full_path,
2614 struct cifs_sb_info *cifs_sb)
2615{
2616 struct smb_rqst rqst;
2617 struct smb2_create_req *req;
256b4c3f 2618 struct smb2_create_rsp *rsp = NULL;
bea851b8
SF
2619 struct cifs_ses *ses = tcon->ses;
2620 struct kvec iov[3]; /* make sure at least one for each open context */
2621 struct kvec rsp_iov = {NULL, 0};
2622 int resp_buftype;
2623 int uni_path_len;
2624 __le16 *copy_path = NULL;
2625 int copy_size;
2626 int rc = 0;
2627 unsigned int n_iov = 2;
2628 __u32 file_attributes = 0;
2629 char *pc_buf = NULL;
2630 int flags = 0;
2631 unsigned int total_len;
256b4c3f 2632 __le16 *utf16_path = NULL;
352d96f3 2633 struct TCP_Server_Info *server = cifs_pick_channel(ses);
bea851b8
SF
2634
2635 cifs_dbg(FYI, "mkdir\n");
2636
256b4c3f
AA
2637 /* resource #1: path allocation */
2638 utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
2639 if (!utf16_path)
2640 return -ENOMEM;
2641
352d96f3 2642 if (!ses || !server) {
256b4c3f
AA
2643 rc = -EIO;
2644 goto err_free_path;
2645 }
bea851b8 2646
256b4c3f 2647 /* resource #2: request */
352d96f3
AA
2648 rc = smb2_plain_req_init(SMB2_CREATE, tcon, server,
2649 (void **) &req, &total_len);
bea851b8 2650 if (rc)
256b4c3f
AA
2651 goto err_free_path;
2652
bea851b8
SF
2653
2654 if (smb3_encryption_required(tcon))
2655 flags |= CIFS_TRANSFORM_REQ;
2656
bea851b8
SF
2657 req->ImpersonationLevel = IL_IMPERSONATION;
2658 req->DesiredAccess = cpu_to_le32(FILE_WRITE_ATTRIBUTES);
2659 /* File attributes ignored on open (used in create though) */
2660 req->FileAttributes = cpu_to_le32(file_attributes);
2661 req->ShareAccess = FILE_SHARE_ALL_LE;
2662 req->CreateDisposition = cpu_to_le32(FILE_CREATE);
2663 req->CreateOptions = cpu_to_le32(CREATE_NOT_FILE);
2664
2665 iov[0].iov_base = (char *)req;
2666 /* -1 since last byte is buf[0] which is sent below (path) */
2667 iov[0].iov_len = total_len - 1;
2668
2669 req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req));
2670
2671 /* [MS-SMB2] 2.2.13 NameOffset:
2672 * If SMB2_FLAGS_DFS_OPERATIONS is set in the Flags field of
2673 * the SMB2 header, the file name includes a prefix that will
2674 * be processed during DFS name normalization as specified in
2675 * section 3.3.5.9. Otherwise, the file name is relative to
2676 * the share that is identified by the TreeId in the SMB2
2677 * header.
2678 */
2679 if (tcon->share_flags & SHI1005_FLAGS_DFS) {
2680 int name_len;
2681
0d35e382 2682 req->hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
bea851b8
SF
2683 rc = alloc_path_with_tree_prefix(&copy_path, &copy_size,
2684 &name_len,
68e14569 2685 tcon->tree_name, utf16_path);
256b4c3f
AA
2686 if (rc)
2687 goto err_free_req;
2688
bea851b8
SF
2689 req->NameLength = cpu_to_le16(name_len * 2);
2690 uni_path_len = copy_size;
256b4c3f
AA
2691 /* free before overwriting resource */
2692 kfree(utf16_path);
2693 utf16_path = copy_path;
bea851b8 2694 } else {
256b4c3f 2695 uni_path_len = (2 * UniStrnlen((wchar_t *)utf16_path, PATH_MAX)) + 2;
bea851b8
SF
2696 /* MUST set path len (NameLength) to 0 opening root of share */
2697 req->NameLength = cpu_to_le16(uni_path_len - 2);
2698 if (uni_path_len % 8 != 0) {
2699 copy_size = roundup(uni_path_len, 8);
2700 copy_path = kzalloc(copy_size, GFP_KERNEL);
2701 if (!copy_path) {
256b4c3f
AA
2702 rc = -ENOMEM;
2703 goto err_free_req;
bea851b8 2704 }
256b4c3f 2705 memcpy((char *)copy_path, (const char *)utf16_path,
bea851b8
SF
2706 uni_path_len);
2707 uni_path_len = copy_size;
256b4c3f
AA
2708 /* free before overwriting resource */
2709 kfree(utf16_path);
2710 utf16_path = copy_path;
bea851b8
SF
2711 }
2712 }
2713
2714 iov[1].iov_len = uni_path_len;
256b4c3f 2715 iov[1].iov_base = utf16_path;
bea851b8
SF
2716 req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_NONE;
2717
2718 if (tcon->posix_extensions) {
256b4c3f 2719 /* resource #3: posix buf */
bea851b8 2720 rc = add_posix_context(iov, &n_iov, mode);
256b4c3f
AA
2721 if (rc)
2722 goto err_free_req;
bea851b8
SF
2723 pc_buf = iov[n_iov-1].iov_base;
2724 }
2725
2726
2727 memset(&rqst, 0, sizeof(struct smb_rqst));
2728 rqst.rq_iov = iov;
2729 rqst.rq_nvec = n_iov;
2730
d2f15428 2731 /* no need to inc num_remote_opens because we close it just below */
fddc6ccc 2732 trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, full_path, CREATE_NOT_FILE,
efe2e9f3 2733 FILE_WRITE_ATTRIBUTES);
256b4c3f 2734 /* resource #4: response buffer */
352d96f3
AA
2735 rc = cifs_send_recv(xid, ses, server,
2736 &rqst, &resp_buftype, flags, &rsp_iov);
256b4c3f 2737 if (rc) {
bea851b8
SF
2738 cifs_stats_fail_inc(tcon, SMB2_CREATE_HE);
2739 trace_smb3_posix_mkdir_err(xid, tcon->tid, ses->Suid,
256b4c3f
AA
2740 CREATE_NOT_FILE,
2741 FILE_WRITE_ATTRIBUTES, rc);
2742 goto err_free_rsp_buf;
2743 }
2744
ca780da5
SF
2745 /*
2746 * Although unlikely to be possible for rsp to be null and rc not set,
2747 * adding check below is slightly safer long term (and quiets Coverity
2748 * warning)
2749 */
256b4c3f 2750 rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
ca780da5
SF
2751 if (rsp == NULL) {
2752 rc = -EIO;
2753 kfree(pc_buf);
2754 goto err_free_req;
2755 }
2756
351a59da
PA
2757 trace_smb3_posix_mkdir_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid,
2758 CREATE_NOT_FILE, FILE_WRITE_ATTRIBUTES);
bea851b8 2759
351a59da 2760 SMB2_close(xid, tcon, rsp->PersistentFileId, rsp->VolatileFileId);
bea851b8
SF
2761
2762 /* Eventually save off posix specific response info and timestaps */
2763
256b4c3f 2764err_free_rsp_buf:
bea851b8 2765 free_rsp_buf(resp_buftype, rsp);
256b4c3f
AA
2766 kfree(pc_buf);
2767err_free_req:
2768 cifs_small_buf_release(req);
2769err_free_path:
2770 kfree(utf16_path);
bea851b8 2771 return rc;
bea851b8 2772}
bea851b8 2773
2503a0db 2774int
352d96f3
AA
2775SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
2776 struct smb_rqst *rqst, __u8 *oplock,
1eb9fb52 2777 struct cifs_open_parms *oparms, __le16 *path)
2503a0db
PS
2778{
2779 struct smb2_create_req *req;
da502f7d 2780 unsigned int n_iov = 2;
ca81983f 2781 __u32 file_attributes = 0;
1eb9fb52
RS
2782 int copy_size;
2783 int uni_path_len;
4f33bc35 2784 unsigned int total_len;
1eb9fb52
RS
2785 struct kvec *iov = rqst->rq_iov;
2786 __le16 *copy_path;
2787 int rc;
2503a0db 2788
352d96f3
AA
2789 rc = smb2_plain_req_init(SMB2_CREATE, tcon, server,
2790 (void **) &req, &total_len);
2503a0db
PS
2791 if (rc)
2792 return rc;
2793
1eb9fb52
RS
2794 iov[0].iov_base = (char *)req;
2795 /* -1 since last byte is buf[0] which is sent below (path) */
2796 iov[0].iov_len = total_len - 1;
7fb8986e 2797
064f6047 2798 if (oparms->create_options & CREATE_OPTION_READONLY)
ca81983f 2799 file_attributes |= ATTR_READONLY;
db8b631d
SF
2800 if (oparms->create_options & CREATE_OPTION_SPECIAL)
2801 file_attributes |= ATTR_SYSTEM;
ca81983f 2802
2503a0db 2803 req->ImpersonationLevel = IL_IMPERSONATION;
064f6047 2804 req->DesiredAccess = cpu_to_le32(oparms->desired_access);
2503a0db
PS
2805 /* File attributes ignored on open (used in create though) */
2806 req->FileAttributes = cpu_to_le32(file_attributes);
2807 req->ShareAccess = FILE_SHARE_ALL_LE;
c3ca78e2 2808
064f6047
PS
2809 req->CreateDisposition = cpu_to_le32(oparms->disposition);
2810 req->CreateOptions = cpu_to_le32(oparms->create_options & CREATE_OPTIONS_MASK);
4f33bc35 2811 req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req));
f0712928
AA
2812
2813 /* [MS-SMB2] 2.2.13 NameOffset:
2814 * If SMB2_FLAGS_DFS_OPERATIONS is set in the Flags field of
2815 * the SMB2 header, the file name includes a prefix that will
2816 * be processed during DFS name normalization as specified in
2817 * section 3.3.5.9. Otherwise, the file name is relative to
2818 * the share that is identified by the TreeId in the SMB2
2819 * header.
2820 */
2821 if (tcon->share_flags & SHI1005_FLAGS_DFS) {
2822 int name_len;
2823
0d35e382 2824 req->hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
f0712928
AA
2825 rc = alloc_path_with_tree_prefix(&copy_path, &copy_size,
2826 &name_len,
68e14569 2827 tcon->tree_name, path);
1eb9fb52 2828 if (rc)
f0712928
AA
2829 return rc;
2830 req->NameLength = cpu_to_le16(name_len * 2);
59aa3718
PS
2831 uni_path_len = copy_size;
2832 path = copy_path;
f0712928
AA
2833 } else {
2834 uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2;
2835 /* MUST set path len (NameLength) to 0 opening root of share */
2836 req->NameLength = cpu_to_le16(uni_path_len - 2);
d7173623 2837 copy_size = round_up(uni_path_len, 8);
1eb9fb52
RS
2838 copy_path = kzalloc(copy_size, GFP_KERNEL);
2839 if (!copy_path)
2840 return -ENOMEM;
2841 memcpy((char *)copy_path, (const char *)path,
2842 uni_path_len);
2843 uni_path_len = copy_size;
2844 path = copy_path;
2503a0db
PS
2845 }
2846
59aa3718
PS
2847 iov[1].iov_len = uni_path_len;
2848 iov[1].iov_base = path;
59aa3718 2849
3e7a02d4 2850 if ((!server->oplocks) || (tcon->no_lease))
b8c32dbb
PS
2851 *oplock = SMB2_OPLOCK_LEVEL_NONE;
2852
a41a28bd 2853 if (!(server->capabilities & SMB2_GLOBAL_CAP_LEASING) ||
b8c32dbb
PS
2854 *oplock == SMB2_OPLOCK_LEVEL_NONE)
2855 req->RequestedOplockLevel = *oplock;
f8015683
SF
2856 else if (!(server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) &&
2857 (oparms->create_options & CREATE_NOT_FILE))
2858 req->RequestedOplockLevel = *oplock; /* no srv lease support */
b8c32dbb 2859 else {
729c0c9d
SB
2860 rc = add_lease_context(server, iov, &n_iov,
2861 oparms->fid->lease_key, oplock);
1eb9fb52 2862 if (rc)
d22cbfec 2863 return rc;
b8c32dbb
PS
2864 }
2865
63eb3def
PS
2866 if (*oplock == SMB2_OPLOCK_LEVEL_BATCH) {
2867 /* need to set Next field of lease context if we request it */
a41a28bd 2868 if (server->capabilities & SMB2_GLOBAL_CAP_LEASING) {
63eb3def 2869 struct create_context *ccontext =
da502f7d 2870 (struct create_context *)iov[n_iov-1].iov_base;
1c46943f 2871 ccontext->Next =
a41a28bd 2872 cpu_to_le32(server->vals->create_lease_size);
63eb3def 2873 }
b56eae4d 2874
da502f7d 2875 rc = add_durable_context(iov, &n_iov, oparms,
b56eae4d 2876 tcon->use_persistent);
1eb9fb52 2877 if (rc)
63eb3def 2878 return rc;
63eb3def
PS
2879 }
2880
ce558b0e
SF
2881 if (tcon->posix_extensions) {
2882 if (n_iov > 2) {
2883 struct create_context *ccontext =
2884 (struct create_context *)iov[n_iov-1].iov_base;
2885 ccontext->Next =
2886 cpu_to_le32(iov[n_iov-1].iov_len);
2887 }
2888
2889 rc = add_posix_context(iov, &n_iov, oparms->mode);
1eb9fb52 2890 if (rc)
ce558b0e 2891 return rc;
ce558b0e 2892 }
ce558b0e 2893
cdeaf9d0
SF
2894 if (tcon->snapshot_time) {
2895 cifs_dbg(FYI, "adding snapshot context\n");
2896 if (n_iov > 2) {
2897 struct create_context *ccontext =
2898 (struct create_context *)iov[n_iov-1].iov_base;
2899 ccontext->Next =
2900 cpu_to_le32(iov[n_iov-1].iov_len);
2901 }
2902
2903 rc = add_twarp_context(iov, &n_iov, tcon->snapshot_time);
2904 if (rc)
2905 return rc;
2906 }
2907
975221ec
SF
2908 if ((oparms->disposition != FILE_OPEN) && (oparms->cifs_sb)) {
2909 bool set_mode;
2910 bool set_owner;
2911
2912 if ((oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) &&
2913 (oparms->mode != ACL_NO_MODE))
2914 set_mode = true;
2915 else {
2916 set_mode = false;
2917 oparms->mode = ACL_NO_MODE;
c3ca78e2
SF
2918 }
2919
975221ec
SF
2920 if (oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
2921 set_owner = true;
2922 else
2923 set_owner = false;
2924
2925 if (set_owner | set_mode) {
2926 if (n_iov > 2) {
2927 struct create_context *ccontext =
2928 (struct create_context *)iov[n_iov-1].iov_base;
2929 ccontext->Next = cpu_to_le32(iov[n_iov-1].iov_len);
2930 }
2931
2932 cifs_dbg(FYI, "add sd with mode 0x%x\n", oparms->mode);
2933 rc = add_sd_context(iov, &n_iov, oparms->mode, set_owner);
2934 if (rc)
2935 return rc;
2936 }
c3ca78e2
SF
2937 }
2938
ff2a09e9
SF
2939 if (n_iov > 2) {
2940 struct create_context *ccontext =
2941 (struct create_context *)iov[n_iov-1].iov_base;
2942 ccontext->Next = cpu_to_le32(iov[n_iov-1].iov_len);
2943 }
2944 add_query_id_context(iov, &n_iov);
cdeaf9d0 2945
1eb9fb52
RS
2946 rqst->rq_nvec = n_iov;
2947 return 0;
2948}
2949
2950/* rq_iov[0] is the request and is released by cifs_small_buf_release().
2951 * All other vectors are freed by kfree().
2952 */
2953void
2954SMB2_open_free(struct smb_rqst *rqst)
2955{
2956 int i;
2957
32a1fb36
RS
2958 if (rqst && rqst->rq_iov) {
2959 cifs_small_buf_release(rqst->rq_iov[0].iov_base);
2960 for (i = 1; i < rqst->rq_nvec; i++)
2961 if (rqst->rq_iov[i].iov_base != smb2_padding)
2962 kfree(rqst->rq_iov[i].iov_base);
2963 }
1eb9fb52
RS
2964}
2965
2966int
2967SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
2968 __u8 *oplock, struct smb2_file_all_info *buf,
69dda305 2969 struct create_posix_rsp *posix,
1eb9fb52
RS
2970 struct kvec *err_iov, int *buftype)
2971{
2972 struct smb_rqst rqst;
2973 struct smb2_create_rsp *rsp = NULL;
1eb9fb52
RS
2974 struct cifs_tcon *tcon = oparms->tcon;
2975 struct cifs_ses *ses = tcon->ses;
352d96f3 2976 struct TCP_Server_Info *server = cifs_pick_channel(ses);
4d8dfafc 2977 struct kvec iov[SMB2_CREATE_IOV_SIZE];
1eb9fb52 2978 struct kvec rsp_iov = {NULL, 0};
ef2298a0 2979 int resp_buftype = CIFS_NO_BUFFER;
1eb9fb52
RS
2980 int rc = 0;
2981 int flags = 0;
2982
2983 cifs_dbg(FYI, "create/open\n");
352d96f3 2984 if (!ses || !server)
1eb9fb52
RS
2985 return -EIO;
2986
2987 if (smb3_encryption_required(tcon))
2988 flags |= CIFS_TRANSFORM_REQ;
2989
40eff45b 2990 memset(&rqst, 0, sizeof(struct smb_rqst));
1eb9fb52 2991 memset(&iov, 0, sizeof(iov));
40eff45b 2992 rqst.rq_iov = iov;
4d8dfafc 2993 rqst.rq_nvec = SMB2_CREATE_IOV_SIZE;
1eb9fb52 2994
352d96f3
AA
2995 rc = SMB2_open_init(tcon, server,
2996 &rqst, oplock, oparms, path);
1eb9fb52
RS
2997 if (rc)
2998 goto creat_exit;
40eff45b 2999
fddc6ccc 3000 trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid, oparms->path,
efe2e9f3
SF
3001 oparms->create_options, oparms->desired_access);
3002
352d96f3
AA
3003 rc = cifs_send_recv(xid, ses, server,
3004 &rqst, &resp_buftype, flags,
4f33bc35 3005 &rsp_iov);
da502f7d 3006 rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
2503a0db
PS
3007
3008 if (rc != 0) {
3009 cifs_stats_fail_inc(tcon, SMB2_CREATE_HE);
91cb74f5
RS
3010 if (err_iov && rsp) {
3011 *err_iov = rsp_iov;
9d874c36 3012 *buftype = resp_buftype;
91cb74f5
RS
3013 resp_buftype = CIFS_NO_BUFFER;
3014 rsp = NULL;
3015 }
28d59363
SF
3016 trace_smb3_open_err(xid, tcon->tid, ses->Suid,
3017 oparms->create_options, oparms->desired_access, rc);
7dcc82c2 3018 if (rc == -EREMCHG) {
a0a3036b 3019 pr_warn_once("server share %s deleted\n",
68e14569 3020 tcon->tree_name);
7dcc82c2
SF
3021 tcon->need_reconnect = true;
3022 }
2503a0db 3023 goto creat_exit;
6b789518
SF
3024 } else if (rsp == NULL) /* unlikely to happen, but safer to check */
3025 goto creat_exit;
3026 else
351a59da
PA
3027 trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid,
3028 oparms->create_options, oparms->desired_access);
2503a0db 3029
fae8044c 3030 atomic_inc(&tcon->num_remote_opens);
351a59da
PA
3031 oparms->fid->persistent_fid = rsp->PersistentFileId;
3032 oparms->fid->volatile_fid = rsp->VolatileFileId;
86f740f2 3033 oparms->fid->access = oparms->desired_access;
dfe33f9a 3034#ifdef CONFIG_CIFS_DEBUG2
0d35e382 3035 oparms->fid->mid = le64_to_cpu(rsp->hdr.MessageId);
dfe33f9a 3036#endif /* CIFS_DEBUG2 */
f0df737e
PS
3037
3038 if (buf) {
fbcff33d
KC
3039 buf->CreationTime = rsp->CreationTime;
3040 buf->LastAccessTime = rsp->LastAccessTime;
3041 buf->LastWriteTime = rsp->LastWriteTime;
3042 buf->ChangeTime = rsp->ChangeTime;
f0df737e
PS
3043 buf->AllocationSize = rsp->AllocationSize;
3044 buf->EndOfFile = rsp->EndofFile;
3045 buf->Attributes = rsp->FileAttributes;
3046 buf->NumberOfLinks = cpu_to_le32(1);
3047 buf->DeletePending = 0;
3048 }
2e44b288 3049
89a5bfa3
SF
3050
3051 smb2_parse_contexts(server, rsp, &oparms->fid->epoch,
69dda305 3052 oparms->fid->lease_key, oplock, buf, posix);
2503a0db 3053creat_exit:
1eb9fb52 3054 SMB2_open_free(&rqst);
2503a0db
PS
3055 free_rsp_buf(resp_buftype, rsp);
3056 return rc;
3057}
3058
4a72dafa 3059int
352d96f3
AA
3060SMB2_ioctl_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
3061 struct smb_rqst *rqst,
ccdc77a3 3062 u64 persistent_fid, u64 volatile_fid, u32 opcode,
400d0ad6 3063 char *in_data, u32 indatalen,
153322f7 3064 __u32 max_response_size)
4a72dafa
SF
3065{
3066 struct smb2_ioctl_req *req;
ccdc77a3 3067 struct kvec *iov = rqst->rq_iov;
97754680 3068 unsigned int total_len;
ccdc77a3 3069 int rc;
2c87d6a9 3070 char *in_data_buf;
4a72dafa 3071
352d96f3
AA
3072 rc = smb2_ioctl_req_init(opcode, tcon, server,
3073 (void **) &req, &total_len);
4a72dafa
SF
3074 if (rc)
3075 return rc;
3076
2c87d6a9
LL
3077 if (indatalen) {
3078 /*
3079 * indatalen is usually small at a couple of bytes max, so
3080 * just allocate through generic pool
3081 */
d81f0974 3082 in_data_buf = kmemdup(in_data, indatalen, GFP_NOFS);
2c87d6a9
LL
3083 if (!in_data_buf) {
3084 cifs_small_buf_release(req);
3085 return -ENOMEM;
3086 }
2c87d6a9
LL
3087 }
3088
4a72dafa
SF
3089 req->CtlCode = cpu_to_le32(opcode);
3090 req->PersistentFileId = persistent_fid;
3091 req->VolatileFileId = volatile_fid;
3092
ccdc77a3
RS
3093 iov[0].iov_base = (char *)req;
3094 /*
3095 * If no input data, the size of ioctl struct in
3096 * protocol spec still includes a 1 byte data buffer,
3097 * but if input data passed to ioctl, we do not
3098 * want to double count this, so we do not send
3099 * the dummy one byte of data in iovec[0] if sending
3100 * input data (in iovec[1]).
3101 */
4a72dafa
SF
3102 if (indatalen) {
3103 req->InputCount = cpu_to_le32(indatalen);
3104 /* do not set InputOffset if no input data */
3105 req->InputOffset =
97754680 3106 cpu_to_le32(offsetof(struct smb2_ioctl_req, Buffer));
ccdc77a3
RS
3107 rqst->rq_nvec = 2;
3108 iov[0].iov_len = total_len - 1;
2c87d6a9 3109 iov[1].iov_base = in_data_buf;
4a72dafa 3110 iov[1].iov_len = indatalen;
ccdc77a3
RS
3111 } else {
3112 rqst->rq_nvec = 1;
3113 iov[0].iov_len = total_len;
3114 }
4a72dafa
SF
3115
3116 req->OutputOffset = 0;
3117 req->OutputCount = 0; /* MBZ */
3118
3119 /*
153322f7
SF
3120 * In most cases max_response_size is set to 16K (CIFSMaxBufSize)
3121 * We Could increase default MaxOutputResponse, but that could require
3122 * more credits. Windows typically sets this smaller, but for some
4a72dafa
SF
3123 * ioctls it may be useful to allow server to send more. No point
3124 * limiting what the server can send as long as fits in one credit
153322f7
SF
3125 * We can not handle more than CIFS_MAX_BUF_SIZE yet but may want
3126 * to increase this limit up in the future.
3127 * Note that for snapshot queries that servers like Azure expect that
3128 * the first query be minimal size (and just used to get the number/size
3129 * of previous versions) so response size must be specified as EXACTLY
3130 * sizeof(struct snapshot_array) which is 16 when rounded up to multiple
3131 * of eight bytes. Currently that is the only case where we set max
3132 * response size smaller.
4a72dafa 3133 */
153322f7 3134 req->MaxOutputResponse = cpu_to_le32(max_response_size);
0d35e382 3135 req->hdr.CreditCharge =
ebf57440
NJ
3136 cpu_to_le16(DIV_ROUND_UP(max(indatalen, max_response_size),
3137 SMB2_MAX_BUFFER_SIZE));
400d0ad6
EM
3138 /* always an FSCTL (for now) */
3139 req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL);
4a72dafa 3140
4587eee0
SF
3141 /* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
3142 if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
0d35e382 3143 req->hdr.Flags |= SMB2_FLAGS_SIGNED;
4a72dafa 3144
ccdc77a3
RS
3145 return 0;
3146}
3147
3148void
3149SMB2_ioctl_free(struct smb_rqst *rqst)
3150{
6457c20e 3151 int i;
2c87d6a9 3152 if (rqst && rqst->rq_iov) {
ccdc77a3 3153 cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
6457c20e
MZ
3154 for (i = 1; i < rqst->rq_nvec; i++)
3155 if (rqst->rq_iov[i].iov_base != smb2_padding)
3156 kfree(rqst->rq_iov[i].iov_base);
2c87d6a9 3157 }
ccdc77a3
RS
3158}
3159
153322f7 3160
ccdc77a3
RS
3161/*
3162 * SMB2 IOCTL is used for both IOCTLs and FSCTLs
3163 */
3164int
3165SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
400d0ad6
EM
3166 u64 volatile_fid, u32 opcode, char *in_data, u32 indatalen,
3167 u32 max_out_data_len, char **out_data,
3168 u32 *plen /* returned data len */)
ccdc77a3
RS
3169{
3170 struct smb_rqst rqst;
3171 struct smb2_ioctl_rsp *rsp = NULL;
3172 struct cifs_ses *ses;
352d96f3 3173 struct TCP_Server_Info *server;
72c419d9 3174 struct kvec iov[SMB2_IOCTL_IOV_SIZE];
ccdc77a3
RS
3175 struct kvec rsp_iov = {NULL, 0};
3176 int resp_buftype = CIFS_NO_BUFFER;
3177 int rc = 0;
3178 int flags = 0;
3179
3180 cifs_dbg(FYI, "SMB2 IOCTL\n");
3181
3182 if (out_data != NULL)
3183 *out_data = NULL;
3184
3185 /* zero out returned data len, in case of error */
3186 if (plen)
3187 *plen = 0;
3188
352d96f3 3189 if (!tcon)
ccdc77a3
RS
3190 return -EIO;
3191
352d96f3 3192 ses = tcon->ses;
ac6ad7a8
CIK
3193 if (!ses)
3194 return -EIO;
352d96f3
AA
3195
3196 server = cifs_pick_channel(ses);
ac6ad7a8 3197 if (!server)
ccdc77a3
RS
3198 return -EIO;
3199
3200 if (smb3_encryption_required(tcon))
3201 flags |= CIFS_TRANSFORM_REQ;
3202
40eff45b 3203 memset(&rqst, 0, sizeof(struct smb_rqst));
ccdc77a3 3204 memset(&iov, 0, sizeof(iov));
40eff45b 3205 rqst.rq_iov = iov;
72c419d9 3206 rqst.rq_nvec = SMB2_IOCTL_IOV_SIZE;
ccdc77a3 3207
352d96f3
AA
3208 rc = SMB2_ioctl_init(tcon, server,
3209 &rqst, persistent_fid, volatile_fid, opcode,
400d0ad6 3210 in_data, indatalen, max_out_data_len);
ccdc77a3
RS
3211 if (rc)
3212 goto ioctl_exit;
40eff45b 3213
352d96f3
AA
3214 rc = cifs_send_recv(xid, ses, server,
3215 &rqst, &resp_buftype, flags,
97754680 3216 &rsp_iov);
da502f7d 3217 rsp = (struct smb2_ioctl_rsp *)rsp_iov.iov_base;
4a72dafa 3218
eccb4422
SF
3219 if (rc != 0)
3220 trace_smb3_fsctl_err(xid, persistent_fid, tcon->tid,
3221 ses->Suid, 0, opcode, rc);
3222
2f3ebaba 3223 if ((rc != 0) && (rc != -EINVAL) && (rc != -E2BIG)) {
8e353106 3224 cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
4a72dafa 3225 goto ioctl_exit;
9bf0c9cd
SF
3226 } else if (rc == -EINVAL) {
3227 if ((opcode != FSCTL_SRV_COPYCHUNK_WRITE) &&
3228 (opcode != FSCTL_SRV_COPYCHUNK)) {
8e353106 3229 cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
9bf0c9cd
SF
3230 goto ioctl_exit;
3231 }
2f3ebaba
RS
3232 } else if (rc == -E2BIG) {
3233 if (opcode != FSCTL_QUERY_ALLOCATED_RANGES) {
3234 cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
3235 goto ioctl_exit;
3236 }
4a72dafa
SF
3237 }
3238
3239 /* check if caller wants to look at return data or just return rc */
3240 if ((plen == NULL) || (out_data == NULL))
3241 goto ioctl_exit;
3242
4d9beec2
SF
3243 /*
3244 * Although unlikely to be possible for rsp to be null and rc not set,
3245 * adding check below is slightly safer long term (and quiets Coverity
3246 * warning)
3247 */
3248 if (rsp == NULL) {
3249 rc = -EIO;
3250 goto ioctl_exit;
3251 }
3252
4a72dafa
SF
3253 *plen = le32_to_cpu(rsp->OutputCount);
3254
3255 /* We check for obvious errors in the output buffer length and offset */
3256 if (*plen == 0)
3257 goto ioctl_exit; /* server returned no data */
2d204ee9 3258 else if (*plen > rsp_iov.iov_len || *plen > 0xFF00) {
3175eb9b 3259 cifs_tcon_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen);
4a72dafa
SF
3260 *plen = 0;
3261 rc = -EIO;
3262 goto ioctl_exit;
3263 }
3264
2d204ee9 3265 if (rsp_iov.iov_len - *plen < le32_to_cpu(rsp->OutputOffset)) {
3175eb9b 3266 cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen,
4a72dafa
SF
3267 le32_to_cpu(rsp->OutputOffset));
3268 *plen = 0;
3269 rc = -EIO;
3270 goto ioctl_exit;
3271 }
3272
d034feeb
Y
3273 *out_data = kmemdup((char *)rsp + le32_to_cpu(rsp->OutputOffset),
3274 *plen, GFP_KERNEL);
4a72dafa
SF
3275 if (*out_data == NULL) {
3276 rc = -ENOMEM;
3277 goto ioctl_exit;
3278 }
3279
4a72dafa 3280ioctl_exit:
ccdc77a3 3281 SMB2_ioctl_free(&rqst);
4a72dafa
SF
3282 free_rsp_buf(resp_buftype, rsp);
3283 return rc;
3284}
3285
64a5cfa6
SF
3286/*
3287 * Individual callers to ioctl worker function follow
3288 */
3289
3290int
3291SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
3292 u64 persistent_fid, u64 volatile_fid)
3293{
3294 int rc;
64a5cfa6
SF
3295 struct compress_ioctl fsctl_input;
3296 char *ret_data = NULL;
3297
3298 fsctl_input.CompressionState =
bc09d141 3299 cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
64a5cfa6
SF
3300
3301 rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid,
400d0ad6 3302 FSCTL_SET_COMPRESSION,
64a5cfa6 3303 (char *)&fsctl_input /* data input */,
153322f7
SF
3304 2 /* in data len */, CIFSMaxBufSize /* max out data */,
3305 &ret_data /* out data */, NULL);
64a5cfa6
SF
3306
3307 cifs_dbg(FYI, "set compression rc %d\n", rc);
64a5cfa6
SF
3308
3309 return rc;
3310}
3311
8eb4ecfa 3312int
352d96f3
AA
3313SMB2_close_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
3314 struct smb_rqst *rqst,
43f8a6a7 3315 u64 persistent_fid, u64 volatile_fid, bool query_attrs)
8eb4ecfa
RS
3316{
3317 struct smb2_close_req *req;
3318 struct kvec *iov = rqst->rq_iov;
3319 unsigned int total_len;
3320 int rc;
3321
352d96f3
AA
3322 rc = smb2_plain_req_init(SMB2_CLOSE, tcon, server,
3323 (void **) &req, &total_len);
8eb4ecfa
RS
3324 if (rc)
3325 return rc;
3326
351a59da
PA
3327 req->PersistentFileId = persistent_fid;
3328 req->VolatileFileId = volatile_fid;
43f8a6a7
SF
3329 if (query_attrs)
3330 req->Flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
3331 else
3332 req->Flags = 0;
8eb4ecfa
RS
3333 iov[0].iov_base = (char *)req;
3334 iov[0].iov_len = total_len;
3335
3336 return 0;
3337}
3338
3339void
3340SMB2_close_free(struct smb_rqst *rqst)
3341{
32a1fb36
RS
3342 if (rqst && rqst->rq_iov)
3343 cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
8eb4ecfa
RS
3344}
3345
2503a0db 3346int
43f8a6a7
SF
3347__SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
3348 u64 persistent_fid, u64 volatile_fid,
3349 struct smb2_file_network_open_info *pbuf)
2503a0db 3350{
40eff45b 3351 struct smb_rqst rqst;
8eb4ecfa 3352 struct smb2_close_rsp *rsp = NULL;
2503a0db 3353 struct cifs_ses *ses = tcon->ses;
352d96f3 3354 struct TCP_Server_Info *server = cifs_pick_channel(ses);
2503a0db 3355 struct kvec iov[1];
da502f7d 3356 struct kvec rsp_iov;
ef2298a0 3357 int resp_buftype = CIFS_NO_BUFFER;
2503a0db 3358 int rc = 0;
9e8fae25 3359 int flags = 0;
43f8a6a7 3360 bool query_attrs = false;
2503a0db 3361
f96637be 3362 cifs_dbg(FYI, "Close\n");
2503a0db 3363
352d96f3 3364 if (!ses || !server)
2503a0db
PS
3365 return -EIO;
3366
5a77e75f 3367 if (smb3_encryption_required(tcon))
7fb8986e
PS
3368 flags |= CIFS_TRANSFORM_REQ;
3369
40eff45b 3370 memset(&rqst, 0, sizeof(struct smb_rqst));
8eb4ecfa 3371 memset(&iov, 0, sizeof(iov));
40eff45b
RS
3372 rqst.rq_iov = iov;
3373 rqst.rq_nvec = 1;
3374
43f8a6a7
SF
3375 /* check if need to ask server to return timestamps in close response */
3376 if (pbuf)
3377 query_attrs = true;
3378
f90f9797 3379 trace_smb3_close_enter(xid, persistent_fid, tcon->tid, ses->Suid);
352d96f3
AA
3380 rc = SMB2_close_init(tcon, server,
3381 &rqst, persistent_fid, volatile_fid,
43f8a6a7 3382 query_attrs);
8eb4ecfa
RS
3383 if (rc)
3384 goto close_exit;
3385
352d96f3
AA
3386 rc = cifs_send_recv(xid, ses, server,
3387 &rqst, &resp_buftype, flags, &rsp_iov);
da502f7d 3388 rsp = (struct smb2_close_rsp *)rsp_iov.iov_base;
2503a0db
PS
3389
3390 if (rc != 0) {
d4a029d2 3391 cifs_stats_fail_inc(tcon, SMB2_CLOSE_HE);
eccb4422
SF
3392 trace_smb3_close_err(xid, persistent_fid, tcon->tid, ses->Suid,
3393 rc);
2503a0db 3394 goto close_exit;
43f8a6a7 3395 } else {
f90f9797
SF
3396 trace_smb3_close_done(xid, persistent_fid, tcon->tid,
3397 ses->Suid);
43f8a6a7
SF
3398 /*
3399 * Note that have to subtract 4 since struct network_open_info
3400 * has a final 4 byte pad that close response does not have
3401 */
3402 if (pbuf)
3403 memcpy(pbuf, (char *)&rsp->CreationTime, sizeof(*pbuf) - 4);
3404 }
2503a0db 3405
fae8044c 3406 atomic_dec(&tcon->num_remote_opens);
2503a0db 3407close_exit:
8eb4ecfa 3408 SMB2_close_free(&rqst);
2503a0db 3409 free_rsp_buf(resp_buftype, rsp);
9150c3ad
PS
3410
3411 /* retry close in a worker thread if this one is interrupted */
2659d3bf 3412 if (is_interrupt_error(rc)) {
9e8fae25
SF
3413 int tmp_rc;
3414
9150c3ad
PS
3415 tmp_rc = smb2_handle_cancelled_close(tcon, persistent_fid,
3416 volatile_fid);
3417 if (tmp_rc)
3418 cifs_dbg(VFS, "handle cancelled close fid 0x%llx returned error %d\n",
3419 persistent_fid, tmp_rc);
3420 }
9150c3ad 3421 return rc;
97ca1762
RS
3422}
3423
43f8a6a7
SF
3424int
3425SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
3426 u64 persistent_fid, u64 volatile_fid)
3427{
3428 return __SMB2_close(xid, tcon, persistent_fid, volatile_fid, NULL);
3429}
3430
730928c8
RS
3431int
3432smb2_validate_iov(unsigned int offset, unsigned int buffer_length,
3433 struct kvec *iov, unsigned int min_buf_size)
be4cb9e3 3434{
c1596ff5 3435 unsigned int smb_len = iov->iov_len;
1fc6ad2f
RS
3436 char *end_of_smb = smb_len + (char *)iov->iov_base;
3437 char *begin_of_buf = offset + (char *)iov->iov_base;
be4cb9e3
PS
3438 char *end_of_buf = begin_of_buf + buffer_length;
3439
3440
3441 if (buffer_length < min_buf_size) {
f96637be
JP
3442 cifs_dbg(VFS, "buffer length %d smaller than minimum size %d\n",
3443 buffer_length, min_buf_size);
be4cb9e3
PS
3444 return -EINVAL;
3445 }
3446
3447 /* check if beyond RFC1001 maximum length */
3448 if ((smb_len > 0x7FFFFF) || (buffer_length > 0x7FFFFF)) {
f96637be
JP
3449 cifs_dbg(VFS, "buffer length %d or smb length %d too large\n",
3450 buffer_length, smb_len);
be4cb9e3
PS
3451 return -EINVAL;
3452 }
3453
3454 if ((begin_of_buf > end_of_smb) || (end_of_buf > end_of_smb)) {
a0a3036b 3455 cifs_dbg(VFS, "Invalid server response, bad offset to data\n");
be4cb9e3
PS
3456 return -EINVAL;
3457 }
3458
3459 return 0;
3460}
3461
3462/*
3463 * If SMB buffer fields are valid, copy into temporary buffer to hold result.
3464 * Caller must free buffer.
3465 */
c5a5f38f
RS
3466int
3467smb2_validate_and_copy_iov(unsigned int offset, unsigned int buffer_length,
3468 struct kvec *iov, unsigned int minbufsize,
3469 char *data)
be4cb9e3 3470{
1fc6ad2f 3471 char *begin_of_buf = offset + (char *)iov->iov_base;
be4cb9e3
PS
3472 int rc;
3473
3474 if (!data)
3475 return -EINVAL;
3476
730928c8 3477 rc = smb2_validate_iov(offset, buffer_length, iov, minbufsize);
be4cb9e3
PS
3478 if (rc)
3479 return rc;
3480
9ee2afe5 3481 memcpy(data, begin_of_buf, minbufsize);
be4cb9e3
PS
3482
3483 return 0;
3484}
3485
296ecbae 3486int
352d96f3
AA
3487SMB2_query_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
3488 struct smb_rqst *rqst,
296ecbae
RS
3489 u64 persistent_fid, u64 volatile_fid,
3490 u8 info_class, u8 info_type, u32 additional_info,
f5b05d62 3491 size_t output_len, size_t input_len, void *input)
be4cb9e3
PS
3492{
3493 struct smb2_query_info_req *req;
296ecbae 3494 struct kvec *iov = rqst->rq_iov;
b2fb7fec 3495 unsigned int total_len;
296ecbae 3496 int rc;
be4cb9e3 3497
352d96f3
AA
3498 rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server,
3499 (void **) &req, &total_len);
be4cb9e3
PS
3500 if (rc)
3501 return rc;
3502
42c493c1 3503 req->InfoType = info_type;
f0df737e 3504 req->FileInfoClass = info_class;
be4cb9e3
PS
3505 req->PersistentFileId = persistent_fid;
3506 req->VolatileFileId = volatile_fid;
42c493c1 3507 req->AdditionalInformation = cpu_to_le32(additional_info);
48923d2a 3508
f0df737e 3509 req->OutputBufferLength = cpu_to_le32(output_len);
f5b05d62
RS
3510 if (input_len) {
3511 req->InputBufferLength = cpu_to_le32(input_len);
3512 /* total_len for smb query request never close to le16 max */
3513 req->InputBufferOffset = cpu_to_le16(total_len - 1);
3514 memcpy(req->Buffer, input, input_len);
3515 }
be4cb9e3
PS
3516
3517 iov[0].iov_base = (char *)req;
b2fb7fec 3518 /* 1 for Buffer */
f5b05d62 3519 iov[0].iov_len = total_len - 1 + input_len;
296ecbae
RS
3520 return 0;
3521}
3522
3523void
3524SMB2_query_info_free(struct smb_rqst *rqst)
3525{
32a1fb36
RS
3526 if (rqst && rqst->rq_iov)
3527 cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
296ecbae
RS
3528}
3529
3530static int
3531query_info(const unsigned int xid, struct cifs_tcon *tcon,
3532 u64 persistent_fid, u64 volatile_fid, u8 info_class, u8 info_type,
3533 u32 additional_info, size_t output_len, size_t min_len, void **data,
3534 u32 *dlen)
3535{
3536 struct smb_rqst rqst;
3537 struct smb2_query_info_rsp *rsp = NULL;
3538 struct kvec iov[1];
3539 struct kvec rsp_iov;
3540 int rc = 0;
ef2298a0 3541 int resp_buftype = CIFS_NO_BUFFER;
296ecbae 3542 struct cifs_ses *ses = tcon->ses;
ac6ad7a8 3543 struct TCP_Server_Info *server;
296ecbae 3544 int flags = 0;
73aaf920 3545 bool allocated = false;
296ecbae
RS
3546
3547 cifs_dbg(FYI, "Query Info\n");
3548
ac6ad7a8
CIK
3549 if (!ses)
3550 return -EIO;
352d96f3 3551 server = cifs_pick_channel(ses);
ac6ad7a8 3552 if (!server)
296ecbae
RS
3553 return -EIO;
3554
3555 if (smb3_encryption_required(tcon))
3556 flags |= CIFS_TRANSFORM_REQ;
be4cb9e3 3557
40eff45b 3558 memset(&rqst, 0, sizeof(struct smb_rqst));
296ecbae 3559 memset(&iov, 0, sizeof(iov));
40eff45b
RS
3560 rqst.rq_iov = iov;
3561 rqst.rq_nvec = 1;
3562
352d96f3
AA
3563 rc = SMB2_query_info_init(tcon, server,
3564 &rqst, persistent_fid, volatile_fid,
296ecbae 3565 info_class, info_type, additional_info,
f5b05d62 3566 output_len, 0, NULL);
296ecbae
RS
3567 if (rc)
3568 goto qinf_exit;
3569
d42043a6
SF
3570 trace_smb3_query_info_enter(xid, persistent_fid, tcon->tid,
3571 ses->Suid, info_class, (__u32)info_type);
3572
352d96f3
AA
3573 rc = cifs_send_recv(xid, ses, server,
3574 &rqst, &resp_buftype, flags, &rsp_iov);
da502f7d 3575 rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
e5d04887 3576
be4cb9e3
PS
3577 if (rc) {
3578 cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
eccb4422
SF
3579 trace_smb3_query_info_err(xid, persistent_fid, tcon->tid,
3580 ses->Suid, info_class, (__u32)info_type, rc);
be4cb9e3
PS
3581 goto qinf_exit;
3582 }
3583
d42043a6
SF
3584 trace_smb3_query_info_done(xid, persistent_fid, tcon->tid,
3585 ses->Suid, info_class, (__u32)info_type);
3586
42c493c1
SP
3587 if (dlen) {
3588 *dlen = le32_to_cpu(rsp->OutputBufferLength);
3589 if (!*data) {
3590 *data = kmalloc(*dlen, GFP_KERNEL);
3591 if (!*data) {
3175eb9b 3592 cifs_tcon_dbg(VFS,
42c493c1
SP
3593 "Error %d allocating memory for acl\n",
3594 rc);
3595 *dlen = 0;
73aaf920 3596 rc = -ENOMEM;
42c493c1
SP
3597 goto qinf_exit;
3598 }
73aaf920 3599 allocated = true;
42c493c1
SP
3600 }
3601 }
3602
c5a5f38f
RS
3603 rc = smb2_validate_and_copy_iov(le16_to_cpu(rsp->OutputBufferOffset),
3604 le32_to_cpu(rsp->OutputBufferLength),
9ee2afe5 3605 &rsp_iov, dlen ? *dlen : min_len, *data);
73aaf920
CIK
3606 if (rc && allocated) {
3607 kfree(*data);
3608 *data = NULL;
3609 *dlen = 0;
3610 }
be4cb9e3
PS
3611
3612qinf_exit:
296ecbae 3613 SMB2_query_info_free(&rqst);
be4cb9e3
PS
3614 free_rsp_buf(resp_buftype, rsp);
3615 return rc;
3616}
9094fad1 3617
42c493c1
SP
3618int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
3619 u64 persistent_fid, u64 volatile_fid, struct smb2_file_all_info *data)
3620{
3621 return query_info(xid, tcon, persistent_fid, volatile_fid,
3622 FILE_ALL_INFORMATION, SMB2_O_INFO_FILE, 0,
3623 sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
3624 sizeof(struct smb2_file_all_info), (void **)&data,
3625 NULL);
3626}
3627
e0ae8a9a
SF
3628#if 0
3629/* currently unused, as now we are doing compounding instead (see smb311_posix_query_path_info) */
b1bc1874
SF
3630int
3631SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon,
3632 u64 persistent_fid, u64 volatile_fid, struct smb311_posix_qinfo *data, u32 *plen)
3633{
3634 size_t output_len = sizeof(struct smb311_posix_qinfo *) +
3635 (sizeof(struct cifs_sid) * 2) + (PATH_MAX * 2);
3636 *plen = 0;
3637
3638 return query_info(xid, tcon, persistent_fid, volatile_fid,
3639 SMB_FIND_FILE_POSIX_INFO, SMB2_O_INFO_FILE, 0,
3640 output_len, sizeof(struct smb311_posix_qinfo), (void **)&data, plen);
e0ae8a9a 3641 /* Note caller must free "data" (passed in above). It may be allocated in query_info call */
b1bc1874 3642}
e0ae8a9a 3643#endif
b1bc1874 3644
f0df737e 3645int
42c493c1 3646SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon,
3970acf7 3647 u64 persistent_fid, u64 volatile_fid,
9541b813 3648 void **data, u32 *plen, u32 extra_info)
f0df737e 3649{
9541b813
BP
3650 __u32 additional_info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO |
3651 extra_info;
42c493c1
SP
3652 *plen = 0;
3653
f0df737e 3654 return query_info(xid, tcon, persistent_fid, volatile_fid,
42c493c1 3655 0, SMB2_O_INFO_SECURITY, additional_info,
ee25c6dd 3656 SMB2_MAX_BUFFER_SIZE, MIN_SEC_DESC_LEN, data, plen);
f0df737e
PS
3657}
3658
3659int
3660SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
3661 u64 persistent_fid, u64 volatile_fid, __le64 *uniqueid)
3662{
3663 return query_info(xid, tcon, persistent_fid, volatile_fid,
42c493c1
SP
3664 FILE_INTERNAL_INFORMATION, SMB2_O_INFO_FILE, 0,
3665 sizeof(struct smb2_file_internal_info),
f0df737e 3666 sizeof(struct smb2_file_internal_info),
42c493c1 3667 (void **)&uniqueid, NULL);
f0df737e
PS
3668}
3669
c3498185
SF
3670/*
3671 * CHANGE_NOTIFY Request is sent to get notifications on changes to a directory
3672 * See MS-SMB2 2.2.35 and 2.2.36
3673 */
3674
388962e8 3675static int
c3498185 3676SMB2_notify_init(const unsigned int xid, struct smb_rqst *rqst,
352d96f3
AA
3677 struct cifs_tcon *tcon, struct TCP_Server_Info *server,
3678 u64 persistent_fid, u64 volatile_fid,
3679 u32 completion_filter, bool watch_tree)
c3498185
SF
3680{
3681 struct smb2_change_notify_req *req;
3682 struct kvec *iov = rqst->rq_iov;
3683 unsigned int total_len;
3684 int rc;
3685
352d96f3
AA
3686 rc = smb2_plain_req_init(SMB2_CHANGE_NOTIFY, tcon, server,
3687 (void **) &req, &total_len);
c3498185
SF
3688 if (rc)
3689 return rc;
3690
351a59da
PA
3691 req->PersistentFileId = persistent_fid;
3692 req->VolatileFileId = volatile_fid;
d26c2ddd 3693 /* See note 354 of MS-SMB2, 64K max */
52870d50
SF
3694 req->OutputBufferLength =
3695 cpu_to_le32(SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE);
c3498185
SF
3696 req->CompletionFilter = cpu_to_le32(completion_filter);
3697 if (watch_tree)
3698 req->Flags = cpu_to_le16(SMB2_WATCH_TREE);
3699 else
3700 req->Flags = 0;
3701
3702 iov[0].iov_base = (char *)req;
3703 iov[0].iov_len = total_len;
3704
3705 return 0;
3706}
3707
3708int
3709SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
3710 u64 persistent_fid, u64 volatile_fid, bool watch_tree,
e3e94634
SF
3711 u32 completion_filter, u32 max_out_data_len, char **out_data,
3712 u32 *plen /* returned data len */)
c3498185
SF
3713{
3714 struct cifs_ses *ses = tcon->ses;
352d96f3 3715 struct TCP_Server_Info *server = cifs_pick_channel(ses);
c3498185 3716 struct smb_rqst rqst;
e3e94634 3717 struct smb2_change_notify_rsp *smb_rsp;
c3498185
SF
3718 struct kvec iov[1];
3719 struct kvec rsp_iov = {NULL, 0};
3720 int resp_buftype = CIFS_NO_BUFFER;
3721 int flags = 0;
3722 int rc = 0;
3723
3724 cifs_dbg(FYI, "change notify\n");
352d96f3 3725 if (!ses || !server)
c3498185
SF
3726 return -EIO;
3727
3728 if (smb3_encryption_required(tcon))
3729 flags |= CIFS_TRANSFORM_REQ;
3730
3731 memset(&rqst, 0, sizeof(struct smb_rqst));
3732 memset(&iov, 0, sizeof(iov));
e3e94634
SF
3733 if (plen)
3734 *plen = 0;
3735
c3498185
SF
3736 rqst.rq_iov = iov;
3737 rqst.rq_nvec = 1;
3738
352d96f3
AA
3739 rc = SMB2_notify_init(xid, &rqst, tcon, server,
3740 persistent_fid, volatile_fid,
c3498185
SF
3741 completion_filter, watch_tree);
3742 if (rc)
3743 goto cnotify_exit;
3744
3745 trace_smb3_notify_enter(xid, persistent_fid, tcon->tid, ses->Suid,
3746 (u8)watch_tree, completion_filter);
352d96f3
AA
3747 rc = cifs_send_recv(xid, ses, server,
3748 &rqst, &resp_buftype, flags, &rsp_iov);
c3498185
SF
3749
3750 if (rc != 0) {
3751 cifs_stats_fail_inc(tcon, SMB2_CHANGE_NOTIFY_HE);
3752 trace_smb3_notify_err(xid, persistent_fid, tcon->tid, ses->Suid,
3753 (u8)watch_tree, completion_filter, rc);
e3e94634 3754 } else {
c3498185 3755 trace_smb3_notify_done(xid, persistent_fid, tcon->tid,
e3e94634
SF
3756 ses->Suid, (u8)watch_tree, completion_filter);
3757 /* validate that notify information is plausible */
3758 if ((rsp_iov.iov_base == NULL) ||
eb3e28c1 3759 (rsp_iov.iov_len < sizeof(struct smb2_change_notify_rsp) + 1))
e3e94634
SF
3760 goto cnotify_exit;
3761
3762 smb_rsp = (struct smb2_change_notify_rsp *)rsp_iov.iov_base;
3763
3764 smb2_validate_iov(le16_to_cpu(smb_rsp->OutputBufferOffset),
3765 le32_to_cpu(smb_rsp->OutputBufferLength), &rsp_iov,
3766 sizeof(struct file_notify_information));
3767
3768 *out_data = kmemdup((char *)smb_rsp + le16_to_cpu(smb_rsp->OutputBufferOffset),
3769 le32_to_cpu(smb_rsp->OutputBufferLength), GFP_KERNEL);
3770 if (*out_data == NULL) {
3771 rc = -ENOMEM;
3772 goto cnotify_exit;
3773 } else
3774 *plen = le32_to_cpu(smb_rsp->OutputBufferLength);
3775 }
c3498185
SF
3776
3777 cnotify_exit:
3778 if (rqst.rq_iov)
3779 cifs_small_buf_release(rqst.rq_iov[0].iov_base); /* request */
3780 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
3781 return rc;
3782}
3783
3784
3785
9094fad1
PS
3786/*
3787 * This is a no-op for now. We're not really interested in the reply, but
3788 * rather in the fact that the server sent one and that server->lstrp
3789 * gets updated.
3790 *
3791 * FIXME: maybe we should consider checking that the reply matches request?
3792 */
3793static void
3794smb2_echo_callback(struct mid_q_entry *mid)
3795{
3796 struct TCP_Server_Info *server = mid->callback_data;
31473fc4 3797 struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)mid->resp_buf;
34f4deb7 3798 struct cifs_credits credits = { .value = 0, .instance = 0 };
9094fad1 3799
0fd1d37b 3800 if (mid->mid_state == MID_RESPONSE_RECEIVED
34f4deb7 3801 || mid->mid_state == MID_RESPONSE_MALFORMED) {
0d35e382 3802 credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
34f4deb7
PS
3803 credits.instance = server->reconnect_instance;
3804 }
9094fad1 3805
70f08f91 3806 release_mid(mid);
34f4deb7 3807 add_credits(server, &credits, CIFS_ECHO_OP);
9094fad1
PS
3808}
3809
53e0e11e
PS
3810void smb2_reconnect_server(struct work_struct *work)
3811{
3812 struct TCP_Server_Info *server = container_of(work,
3813 struct TCP_Server_Info, reconnect.work);
3663c904
SP
3814 struct TCP_Server_Info *pserver;
3815 struct cifs_ses *ses, *ses2;
53e0e11e 3816 struct cifs_tcon *tcon, *tcon2;
3663c904
SP
3817 struct list_head tmp_list, tmp_ses_list;
3818 bool tcon_exist = false, ses_exist = false;
8a409cda 3819 bool tcon_selected = false;
18ea4311 3820 int rc;
3663c904 3821 bool resched = false;
18ea4311 3822
3663c904
SP
3823 /* If server is a channel, select the primary channel */
3824 pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
53e0e11e
PS
3825
3826 /* Prevent simultaneous reconnects that can corrupt tcon->rlist list */
3663c904 3827 mutex_lock(&pserver->reconnect_mutex);
53e0e11e
PS
3828
3829 INIT_LIST_HEAD(&tmp_list);
3663c904
SP
3830 INIT_LIST_HEAD(&tmp_ses_list);
3831 cifs_dbg(FYI, "Reconnecting tcons and channels\n");
53e0e11e
PS
3832
3833 spin_lock(&cifs_tcp_ses_lock);
3663c904
SP
3834 list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
3835
8a409cda 3836 tcon_selected = false;
3663c904 3837
53e0e11e 3838 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
96a988ff 3839 if (tcon->need_reconnect || tcon->need_reopen_files) {
53e0e11e
PS
3840 tcon->tc_count++;
3841 list_add_tail(&tcon->rlist, &tmp_list);
3663c904 3842 tcon_selected = tcon_exist = true;
53e0e11e
PS
3843 }
3844 }
0ff2b018
RS
3845 /*
3846 * IPC has the same lifetime as its session and uses its
3847 * refcount.
3848 */
b327a717
AA
3849 if (ses->tcon_ipc && ses->tcon_ipc->need_reconnect) {
3850 list_add_tail(&ses->tcon_ipc->rlist, &tmp_list);
3663c904
SP
3851 tcon_selected = tcon_exist = true;
3852 ses->ses_count++;
3853 }
3854 /*
3855 * handle the case where channel needs to reconnect
3856 * binding session, but tcon is healthy (some other channel
3857 * is active)
3858 */
88b024f5 3859 spin_lock(&ses->chan_lock);
3663c904
SP
3860 if (!tcon_selected && cifs_chan_needs_reconnect(ses, server)) {
3861 list_add_tail(&ses->rlist, &tmp_ses_list);
8a409cda 3862 ses_exist = true;
0ff2b018 3863 ses->ses_count++;
b327a717 3864 }
88b024f5 3865 spin_unlock(&ses->chan_lock);
53e0e11e
PS
3866 }
3867 /*
3868 * Get the reference to server struct to be sure that the last call of
3869 * cifs_put_tcon() in the loop below won't release the server pointer.
3870 */
3663c904 3871 if (tcon_exist || ses_exist)
53e0e11e
PS
3872 server->srv_count++;
3873
3874 spin_unlock(&cifs_tcp_ses_lock);
3875
3876 list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) {
352d96f3 3877 rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon, server);
18ea4311 3878 if (!rc)
96a988ff 3879 cifs_reopen_persistent_handles(tcon);
18ea4311
GP
3880 else
3881 resched = true;
53e0e11e 3882 list_del_init(&tcon->rlist);
0ff2b018
RS
3883 if (tcon->ipc)
3884 cifs_put_smb_ses(tcon->ses);
3885 else
3886 cifs_put_tcon(tcon);
53e0e11e
PS
3887 }
3888
3663c904
SP
3889 if (!ses_exist)
3890 goto done;
3891
3892 /* allocate a dummy tcon struct used for reconnect */
df57109b 3893 tcon = tconInfoAlloc();
3663c904
SP
3894 if (!tcon) {
3895 resched = true;
a96c9448
XT
3896 list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) {
3897 list_del_init(&ses->rlist);
3898 cifs_put_smb_ses(ses);
3899 }
3663c904
SP
3900 goto done;
3901 }
3902
fdf59eb5 3903 tcon->status = TID_GOOD;
3663c904
SP
3904 tcon->retry = false;
3905 tcon->need_reconnect = false;
3906
3907 /* now reconnect sessions for necessary channels */
3908 list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) {
3909 tcon->ses = ses;
3910 rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon, server);
3911 if (rc)
3912 resched = true;
3913 list_del_init(&ses->rlist);
3914 cifs_put_smb_ses(ses);
3915 }
df57109b 3916 tconInfoFree(tcon);
3663c904
SP
3917
3918done:
3919 cifs_dbg(FYI, "Reconnecting tcons and channels finished\n");
18ea4311
GP
3920 if (resched)
3921 queue_delayed_work(cifsiod_wq, &server->reconnect, 2 * HZ);
3663c904 3922 mutex_unlock(&pserver->reconnect_mutex);
53e0e11e
PS
3923
3924 /* now we can safely release srv struct */
3663c904 3925 if (tcon_exist || ses_exist)
53e0e11e
PS
3926 cifs_put_tcp_session(server, 1);
3927}
3928
9094fad1
PS
3929int
3930SMB2_echo(struct TCP_Server_Info *server)
3931{
3932 struct smb2_echo_req *req;
3933 int rc = 0;
c713c877 3934 struct kvec iov[1];
738f9de5 3935 struct smb_rqst rqst = { .rq_iov = iov,
c713c877 3936 .rq_nvec = 1 };
7f7ae759 3937 unsigned int total_len;
9094fad1 3938
bda487ac 3939 cifs_dbg(FYI, "In echo request for conn_id %lld\n", server->conn_id);
9094fad1 3940
d7d7a66a 3941 spin_lock(&server->srv_lock);
1a6a41d4
SP
3942 if (server->ops->need_neg &&
3943 server->ops->need_neg(server)) {
d7d7a66a 3944 spin_unlock(&server->srv_lock);
53e0e11e 3945 /* No need to send echo on newly established connections */
b08484d7 3946 mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
53e0e11e 3947 return rc;
4fcd1813 3948 }
d7d7a66a 3949 spin_unlock(&server->srv_lock);
4fcd1813 3950
352d96f3
AA
3951 rc = smb2_plain_req_init(SMB2_ECHO, NULL, server,
3952 (void **)&req, &total_len);
9094fad1
PS
3953 if (rc)
3954 return rc;
3955
0d35e382 3956 req->hdr.CreditRequest = cpu_to_le16(1);
9094fad1 3957
c713c877
RS
3958 iov[0].iov_len = total_len;
3959 iov[0].iov_base = (char *)req;
9094fad1 3960
9b7c18a2 3961 rc = cifs_call_async(server, &rqst, NULL, smb2_echo_callback, NULL,
3349c3a7 3962 server, CIFS_ECHO_OP, NULL);
9094fad1 3963 if (rc)
f96637be 3964 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
9094fad1
PS
3965
3966 cifs_small_buf_release(req);
3967 return rc;
3968}
7a5cfb19 3969
86e14e12
RS
3970void
3971SMB2_flush_free(struct smb_rqst *rqst)
3972{
3973 if (rqst && rqst->rq_iov)
3974 cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
3975}
3976
7a5cfb19 3977int
86e14e12 3978SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst,
352d96f3
AA
3979 struct cifs_tcon *tcon, struct TCP_Server_Info *server,
3980 u64 persistent_fid, u64 volatile_fid)
7a5cfb19
PS
3981{
3982 struct smb2_flush_req *req;
86e14e12 3983 struct kvec *iov = rqst->rq_iov;
1f444e4c 3984 unsigned int total_len;
86e14e12 3985 int rc;
7a5cfb19 3986
352d96f3
AA
3987 rc = smb2_plain_req_init(SMB2_FLUSH, tcon, server,
3988 (void **) &req, &total_len);
7a5cfb19
PS
3989 if (rc)
3990 return rc;
3991
351a59da
PA
3992 req->PersistentFileId = persistent_fid;
3993 req->VolatileFileId = volatile_fid;
7a5cfb19
PS
3994
3995 iov[0].iov_base = (char *)req;
1f444e4c 3996 iov[0].iov_len = total_len;
7a5cfb19 3997
86e14e12
RS
3998 return 0;
3999}
4000
4001int
4002SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
4003 u64 volatile_fid)
4004{
4005 struct cifs_ses *ses = tcon->ses;
4006 struct smb_rqst rqst;
4007 struct kvec iov[1];
4008 struct kvec rsp_iov = {NULL, 0};
352d96f3 4009 struct TCP_Server_Info *server = cifs_pick_channel(ses);
86e14e12
RS
4010 int resp_buftype = CIFS_NO_BUFFER;
4011 int flags = 0;
4012 int rc = 0;
4013
4014 cifs_dbg(FYI, "flush\n");
4015 if (!ses || !(ses->server))
4016 return -EIO;
4017
4018 if (smb3_encryption_required(tcon))
4019 flags |= CIFS_TRANSFORM_REQ;
4020
40eff45b 4021 memset(&rqst, 0, sizeof(struct smb_rqst));
86e14e12 4022 memset(&iov, 0, sizeof(iov));
40eff45b
RS
4023 rqst.rq_iov = iov;
4024 rqst.rq_nvec = 1;
4025
352d96f3
AA
4026 rc = SMB2_flush_init(xid, &rqst, tcon, server,
4027 persistent_fid, volatile_fid);
86e14e12
RS
4028 if (rc)
4029 goto flush_exit;
4030
f90f9797 4031 trace_smb3_flush_enter(xid, persistent_fid, tcon->tid, ses->Suid);
352d96f3
AA
4032 rc = cifs_send_recv(xid, ses, server,
4033 &rqst, &resp_buftype, flags, &rsp_iov);
7a5cfb19 4034
eccb4422 4035 if (rc != 0) {
7a5cfb19 4036 cifs_stats_fail_inc(tcon, SMB2_FLUSH_HE);
eccb4422
SF
4037 trace_smb3_flush_err(xid, persistent_fid, tcon->tid, ses->Suid,
4038 rc);
f90f9797
SF
4039 } else
4040 trace_smb3_flush_done(xid, persistent_fid, tcon->tid,
4041 ses->Suid);
7a5cfb19 4042
86e14e12
RS
4043 flush_exit:
4044 SMB2_flush_free(&rqst);
da502f7d 4045 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
7a5cfb19
PS
4046 return rc;
4047}
09a4707e 4048
a6559cc1
SM
4049#ifdef CONFIG_CIFS_SMB_DIRECT
4050static inline bool smb3_use_rdma_offload(struct cifs_io_parms *io_parms)
4051{
4052 struct TCP_Server_Info *server = io_parms->server;
4053 struct cifs_tcon *tcon = io_parms->tcon;
4054
4055 /* we can only offload if we're connected */
4056 if (!server || !tcon)
4057 return false;
4058
4059 /* we can only offload on an rdma connection */
4060 if (!server->rdma || !server->smbd_conn)
4061 return false;
4062
4063 /* we don't support signed offload yet */
4064 if (server->sign)
4065 return false;
4066
3891f6c7
SM
4067 /* we don't support encrypted offload yet */
4068 if (smb3_encryption_required(tcon))
4069 return false;
4070
a6559cc1
SM
4071 /* offload also has its overhead, so only do it if desired */
4072 if (io_parms->length < server->smbd_conn->rdma_readwrite_threshold)
4073 return false;
4074
4075 return true;
4076}
4077#endif /* CONFIG_CIFS_SMB_DIRECT */
4078
09a4707e
PS
4079/*
4080 * To form a chain of read requests, any read requests after the first should
4081 * have the end_of_chain boolean set to true.
4082 */
4083static int
738f9de5 4084smb2_new_read_req(void **buf, unsigned int *total_len,
2dabfd5b
LL
4085 struct cifs_io_parms *io_parms, struct cifs_readdata *rdata,
4086 unsigned int remaining_bytes, int request_type)
09a4707e
PS
4087{
4088 int rc = -EACCES;
d8d9de53 4089 struct smb2_read_req *req = NULL;
0d35e382 4090 struct smb2_hdr *shdr;
352d96f3 4091 struct TCP_Server_Info *server = io_parms->server;
09a4707e 4092
352d96f3
AA
4093 rc = smb2_plain_req_init(SMB2_READ, io_parms->tcon, server,
4094 (void **) &req, total_len);
09a4707e
PS
4095 if (rc)
4096 return rc;
2dabfd5b 4097
2dabfd5b 4098 if (server == NULL)
09a4707e
PS
4099 return -ECONNABORTED;
4100
0d35e382
RS
4101 shdr = &req->hdr;
4102 shdr->Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
09a4707e 4103
351a59da
PA
4104 req->PersistentFileId = io_parms->persistent_fid;
4105 req->VolatileFileId = io_parms->volatile_fid;
09a4707e
PS
4106 req->ReadChannelInfoOffset = 0; /* reserved */
4107 req->ReadChannelInfoLength = 0; /* reserved */
4108 req->Channel = 0; /* reserved */
4109 req->MinimumCount = 0;
4110 req->Length = cpu_to_le32(io_parms->length);
4111 req->Offset = cpu_to_le64(io_parms->offset);
d323c246
SF
4112
4113 trace_smb3_read_enter(0 /* xid */,
4114 io_parms->persistent_fid,
4115 io_parms->tcon->tid, io_parms->tcon->ses->Suid,
4116 io_parms->offset, io_parms->length);
bd3dcc6a
LL
4117#ifdef CONFIG_CIFS_SMB_DIRECT
4118 /*
4119 * If we want to do a RDMA write, fill in and append
4120 * smbd_buffer_descriptor_v1 to the end of read request
4121 */
a6559cc1 4122 if (smb3_use_rdma_offload(io_parms)) {
bd3dcc6a 4123 struct smbd_buffer_descriptor_v1 *v1;
352d96f3 4124 bool need_invalidate = server->dialect == SMB30_PROT_ID;
bd3dcc6a 4125
d08089f6
DH
4126 rdata->mr = smbd_register_mr(server->smbd_conn, &rdata->iter,
4127 true, need_invalidate);
bd3dcc6a 4128 if (!rdata->mr)
b7972092 4129 return -EAGAIN;
bd3dcc6a
LL
4130
4131 req->Channel = SMB2_CHANNEL_RDMA_V1_INVALIDATE;
4132 if (need_invalidate)
4133 req->Channel = SMB2_CHANNEL_RDMA_V1;
4134 req->ReadChannelInfoOffset =
d8d9de53 4135 cpu_to_le16(offsetof(struct smb2_read_req, Buffer));
bd3dcc6a 4136 req->ReadChannelInfoLength =
2026b06e 4137 cpu_to_le16(sizeof(struct smbd_buffer_descriptor_v1));
bd3dcc6a 4138 v1 = (struct smbd_buffer_descriptor_v1 *) &req->Buffer[0];
2026b06e
SF
4139 v1->offset = cpu_to_le64(rdata->mr->mr->iova);
4140 v1->token = cpu_to_le32(rdata->mr->mr->rkey);
4141 v1->length = cpu_to_le32(rdata->mr->mr->length);
bd3dcc6a
LL
4142
4143 *total_len += sizeof(*v1) - 1;
4144 }
4145#endif
09a4707e
PS
4146 if (request_type & CHAINED_REQUEST) {
4147 if (!(request_type & END_OF_CHAIN)) {
b8f57ee8 4148 /* next 8-byte aligned request */
d7173623 4149 *total_len = ALIGN(*total_len, 8);
b8f57ee8 4150 shdr->NextCommand = cpu_to_le32(*total_len);
09a4707e 4151 } else /* END_OF_CHAIN */
31473fc4 4152 shdr->NextCommand = 0;
09a4707e 4153 if (request_type & RELATED_REQUEST) {
31473fc4 4154 shdr->Flags |= SMB2_FLAGS_RELATED_OPERATIONS;
09a4707e
PS
4155 /*
4156 * Related requests use info from previous read request
4157 * in chain.
4158 */
0d35e382
RS
4159 shdr->SessionId = cpu_to_le64(0xFFFFFFFFFFFFFFFF);
4160 shdr->Id.SyncId.TreeId = cpu_to_le32(0xFFFFFFFF);
351a59da
PA
4161 req->PersistentFileId = (u64)-1;
4162 req->VolatileFileId = (u64)-1;
09a4707e
PS
4163 }
4164 }
4165 if (remaining_bytes > io_parms->length)
4166 req->RemainingBytes = cpu_to_le32(remaining_bytes);
4167 else
4168 req->RemainingBytes = 0;
4169
738f9de5 4170 *buf = req;
09a4707e
PS
4171 return rc;
4172}
4173
4174static void
4175smb2_readv_callback(struct mid_q_entry *mid)
4176{
4177 struct cifs_readdata *rdata = mid->callback_data;
4178 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
352d96f3 4179 struct TCP_Server_Info *server = rdata->server;
0d35e382
RS
4180 struct smb2_hdr *shdr =
4181 (struct smb2_hdr *)rdata->iov[0].iov_base;
34f4deb7 4182 struct cifs_credits credits = { .value = 0, .instance = 0 };
023fc150
DH
4183 struct smb_rqst rqst = { .rq_iov = &rdata->iov[1], .rq_nvec = 1 };
4184
4185 if (rdata->got_bytes) {
4186 rqst.rq_iter = rdata->iter;
4187 rqst.rq_iter_size = iov_iter_count(&rdata->iter);
4188 };
09a4707e 4189
352d96f3
AA
4190 WARN_ONCE(rdata->server != mid->server,
4191 "rdata server %p != mid server %p",
4192 rdata->server, mid->server);
4193
f96637be
JP
4194 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
4195 __func__, mid->mid, mid->mid_state, rdata->result,
4196 rdata->bytes);
09a4707e
PS
4197
4198 switch (mid->mid_state) {
4199 case MID_RESPONSE_RECEIVED:
34f4deb7
PS
4200 credits.value = le16_to_cpu(shdr->CreditRequest);
4201 credits.instance = server->reconnect_instance;
09a4707e 4202 /* result already set, check signature */
4326ed2f 4203 if (server->sign && !mid->decrypted) {
3c1bf7e4
PS
4204 int rc;
4205
d08089f6
DH
4206 iov_iter_revert(&rqst.rq_iter, rdata->got_bytes);
4207 iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes);
0b688cfc 4208 rc = smb2_verify_signature(&rqst, server);
3c1bf7e4 4209 if (rc)
3175eb9b 4210 cifs_tcon_dbg(VFS, "SMB signature verification returned error = %d\n",
f96637be 4211 rc);
3c1bf7e4 4212 }
09a4707e 4213 /* FIXME: should this be counted toward the initiating task? */
34a54d61
PS
4214 task_io_account_read(rdata->got_bytes);
4215 cifs_stats_bytes_read(tcon, rdata->got_bytes);
09a4707e
PS
4216 break;
4217 case MID_REQUEST_SUBMITTED:
4218 case MID_RETRY_NEEDED:
4219 rdata->result = -EAGAIN;
d913ed17
PS
4220 if (server->sign && rdata->got_bytes)
4221 /* reset bytes number since we can not check a sign */
4222 rdata->got_bytes = 0;
4223 /* FIXME: should this be counted toward the initiating task? */
4224 task_io_account_read(rdata->got_bytes);
4225 cifs_stats_bytes_read(tcon, rdata->got_bytes);
09a4707e 4226 break;
0fd1d37b 4227 case MID_RESPONSE_MALFORMED:
34f4deb7
PS
4228 credits.value = le16_to_cpu(shdr->CreditRequest);
4229 credits.instance = server->reconnect_instance;
30b5ae21 4230 fallthrough;
09a4707e 4231 default:
6b15eb18 4232 rdata->result = -EIO;
09a4707e 4233 }
bd3dcc6a
LL
4234#ifdef CONFIG_CIFS_SMB_DIRECT
4235 /*
4236 * If this rdata has a memmory registered, the MR can be freed
4237 * MR needs to be freed as soon as I/O finishes to prevent deadlock
4238 * because they have limited number and are used for future I/Os
4239 */
4240 if (rdata->mr) {
4241 smbd_deregister_mr(rdata->mr);
4242 rdata->mr = NULL;
4243 }
4244#endif
082aaa87 4245 if (rdata->result && rdata->result != -ENODATA) {
09a4707e 4246 cifs_stats_fail_inc(tcon, SMB2_READ_HE);
7d42e72f
PS
4247 trace_smb3_read_err(0 /* xid */,
4248 rdata->cfile->fid.persistent_fid,
4249 tcon->tid, tcon->ses->Suid, rdata->offset,
4250 rdata->bytes, rdata->result);
4251 } else
4252 trace_smb3_read_done(0 /* xid */,
4253 rdata->cfile->fid.persistent_fid,
4254 tcon->tid, tcon->ses->Suid,
4255 rdata->offset, rdata->got_bytes);
09a4707e
PS
4256
4257 queue_work(cifsiod_wq, &rdata->work);
70f08f91 4258 release_mid(mid);
34f4deb7 4259 add_credits(server, &credits, 0);
09a4707e
PS
4260}
4261
738f9de5 4262/* smb2_async_readv - send an async read, and set up mid to handle result */
09a4707e
PS
4263int
4264smb2_async_readv(struct cifs_readdata *rdata)
4265{
bed9da02 4266 int rc, flags = 0;
31473fc4 4267 char *buf;
0d35e382 4268 struct smb2_hdr *shdr;
09a4707e 4269 struct cifs_io_parms io_parms;
738f9de5 4270 struct smb_rqst rqst = { .rq_iov = rdata->iov,
c713c877 4271 .rq_nvec = 1 };
bed9da02 4272 struct TCP_Server_Info *server;
352d96f3 4273 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
738f9de5 4274 unsigned int total_len;
09a4707e 4275
f96637be
JP
4276 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
4277 __func__, rdata->offset, rdata->bytes);
09a4707e 4278
352d96f3
AA
4279 if (!rdata->server)
4280 rdata->server = cifs_pick_channel(tcon->ses);
4281
09a4707e 4282 io_parms.tcon = tlink_tcon(rdata->cfile->tlink);
352d96f3 4283 io_parms.server = server = rdata->server;
09a4707e
PS
4284 io_parms.offset = rdata->offset;
4285 io_parms.length = rdata->bytes;
4286 io_parms.persistent_fid = rdata->cfile->fid.persistent_fid;
4287 io_parms.volatile_fid = rdata->cfile->fid.volatile_fid;
4288 io_parms.pid = rdata->pid;
bed9da02 4289
2dabfd5b
LL
4290 rc = smb2_new_read_req(
4291 (void **) &buf, &total_len, &io_parms, rdata, 0, 0);
f0b93cb9 4292 if (rc)
09a4707e
PS
4293 return rc;
4294
5a77e75f 4295 if (smb3_encryption_required(io_parms.tcon))
7fb8986e
PS
4296 flags |= CIFS_TRANSFORM_REQ;
4297
c713c877
RS
4298 rdata->iov[0].iov_base = buf;
4299 rdata->iov[0].iov_len = total_len;
b8f57ee8 4300
0d35e382 4301 shdr = (struct smb2_hdr *)buf;
09a4707e 4302
335b7b62 4303 if (rdata->credits.value > 0) {
31473fc4 4304 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
bed9da02 4305 SMB2_MAX_BUFFER_SIZE));
88fd98a2 4306 shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
9a1c67e8
PS
4307
4308 rc = adjust_credits(server, &rdata->credits, rdata->bytes);
4309 if (rc)
335b7b62 4310 goto async_readv_out;
9a1c67e8 4311
7fb8986e 4312 flags |= CIFS_HAS_CREDITS;
bed9da02
PS
4313 }
4314
09a4707e 4315 kref_get(&rdata->refcount);
352d96f3 4316 rc = cifs_call_async(server, &rqst,
09a4707e 4317 cifs_readv_receive, smb2_readv_callback,
3349c3a7
PS
4318 smb3_handle_read_data, rdata, flags,
4319 &rdata->credits);
e5d04887 4320 if (rc) {
09a4707e 4321 kref_put(&rdata->refcount, cifs_readdata_release);
e5d04887 4322 cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
7d42e72f
PS
4323 trace_smb3_read_err(0 /* xid */, io_parms.persistent_fid,
4324 io_parms.tcon->tid,
4325 io_parms.tcon->ses->Suid,
4326 io_parms.offset, io_parms.length, rc);
4327 }
09a4707e 4328
335b7b62 4329async_readv_out:
09a4707e
PS
4330 cifs_small_buf_release(buf);
4331 return rc;
4332}
33319141 4333
d8e05039
PS
4334int
4335SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
4336 unsigned int *nbytes, char **buf, int *buf_type)
4337{
40eff45b 4338 struct smb_rqst rqst;
1efd4fc7 4339 int resp_buftype, rc;
d8d9de53 4340 struct smb2_read_req *req = NULL;
d8e05039 4341 struct smb2_read_rsp *rsp = NULL;
f5688a6d 4342 struct kvec iov[1];
da502f7d 4343 struct kvec rsp_iov;
738f9de5 4344 unsigned int total_len;
7fb8986e
PS
4345 int flags = CIFS_LOG_ERROR;
4346 struct cifs_ses *ses = io_parms->tcon->ses;
d8e05039 4347
352d96f3
AA
4348 if (!io_parms->server)
4349 io_parms->server = cifs_pick_channel(io_parms->tcon->ses);
4350
d8e05039 4351 *nbytes = 0;
2dabfd5b 4352 rc = smb2_new_read_req((void **)&req, &total_len, io_parms, NULL, 0, 0);
d8e05039
PS
4353 if (rc)
4354 return rc;
4355
5a77e75f 4356 if (smb3_encryption_required(io_parms->tcon))
7fb8986e
PS
4357 flags |= CIFS_TRANSFORM_REQ;
4358
f5688a6d
RS
4359 iov[0].iov_base = (char *)req;
4360 iov[0].iov_len = total_len;
b8f57ee8 4361
40eff45b
RS
4362 memset(&rqst, 0, sizeof(struct smb_rqst));
4363 rqst.rq_iov = iov;
4364 rqst.rq_nvec = 1;
4365
352d96f3
AA
4366 rc = cifs_send_recv(xid, ses, io_parms->server,
4367 &rqst, &resp_buftype, flags, &rsp_iov);
da502f7d 4368 rsp = (struct smb2_read_rsp *)rsp_iov.iov_base;
d8e05039 4369
a821df3f
RS
4370 if (rc) {
4371 if (rc != -ENODATA) {
4372 cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE);
4373 cifs_dbg(VFS, "Send error in read = %d\n", rc);
d8d9de53 4374 trace_smb3_read_err(xid,
351a59da 4375 req->PersistentFileId,
7d42e72f
PS
4376 io_parms->tcon->tid, ses->Suid,
4377 io_parms->offset, io_parms->length,
4378 rc);
b0a42f2a 4379 } else
351a59da
PA
4380 trace_smb3_read_done(xid, req->PersistentFileId, io_parms->tcon->tid,
4381 ses->Suid, io_parms->offset, 0);
da502f7d 4382 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
05fd5c2c 4383 cifs_small_buf_release(req);
a821df3f 4384 return rc == -ENODATA ? 0 : rc;
eccb4422 4385 } else
d8d9de53 4386 trace_smb3_read_done(xid,
351a59da 4387 req->PersistentFileId,
eccb4422
SF
4388 io_parms->tcon->tid, ses->Suid,
4389 io_parms->offset, io_parms->length);
d8e05039 4390
088aaf17
Z
4391 cifs_small_buf_release(req);
4392
a821df3f
RS
4393 *nbytes = le32_to_cpu(rsp->DataLength);
4394 if ((*nbytes > CIFS_MAX_MSGSIZE) ||
4395 (*nbytes > io_parms->length)) {
4396 cifs_dbg(FYI, "bad length %d for count %d\n",
4397 *nbytes, io_parms->length);
4398 rc = -EIO;
4399 *nbytes = 0;
d8e05039
PS
4400 }
4401
4402 if (*buf) {
977b6170 4403 memcpy(*buf, (char *)rsp + rsp->DataOffset, *nbytes);
da502f7d 4404 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
d8e05039 4405 } else if (resp_buftype != CIFS_NO_BUFFER) {
da502f7d 4406 *buf = rsp_iov.iov_base;
d8e05039
PS
4407 if (resp_buftype == CIFS_SMALL_BUFFER)
4408 *buf_type = CIFS_SMALL_BUFFER;
4409 else if (resp_buftype == CIFS_LARGE_BUFFER)
4410 *buf_type = CIFS_LARGE_BUFFER;
4411 }
4412 return rc;
4413}
4414
33319141
PS
4415/*
4416 * Check the mid_state and signature on received buffer (if any), and queue the
4417 * workqueue completion task.
4418 */
4419static void
4420smb2_writev_callback(struct mid_q_entry *mid)
4421{
4422 struct cifs_writedata *wdata = mid->callback_data;
4423 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
352d96f3 4424 struct TCP_Server_Info *server = wdata->server;
33319141
PS
4425 unsigned int written;
4426 struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
34f4deb7 4427 struct cifs_credits credits = { .value = 0, .instance = 0 };
33319141 4428
352d96f3
AA
4429 WARN_ONCE(wdata->server != mid->server,
4430 "wdata server %p != mid server %p",
4431 wdata->server, mid->server);
4432
33319141
PS
4433 switch (mid->mid_state) {
4434 case MID_RESPONSE_RECEIVED:
0d35e382 4435 credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
34f4deb7
PS
4436 credits.instance = server->reconnect_instance;
4437 wdata->result = smb2_check_receive(mid, server, 0);
33319141
PS
4438 if (wdata->result != 0)
4439 break;
4440
4441 written = le32_to_cpu(rsp->DataLength);
4442 /*
4443 * Mask off high 16 bits when bytes written as returned
4444 * by the server is greater than bytes requested by the
4445 * client. OS/2 servers are known to set incorrect
4446 * CountHigh values.
4447 */
4448 if (written > wdata->bytes)
4449 written &= 0xFFFF;
4450
4451 if (written < wdata->bytes)
4452 wdata->result = -ENOSPC;
4453 else
4454 wdata->bytes = written;
4455 break;
4456 case MID_REQUEST_SUBMITTED:
4457 case MID_RETRY_NEEDED:
4458 wdata->result = -EAGAIN;
4459 break;
0fd1d37b 4460 case MID_RESPONSE_MALFORMED:
0d35e382 4461 credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
34f4deb7 4462 credits.instance = server->reconnect_instance;
30b5ae21 4463 fallthrough;
33319141
PS
4464 default:
4465 wdata->result = -EIO;
4466 break;
4467 }
db223a59
LL
4468#ifdef CONFIG_CIFS_SMB_DIRECT
4469 /*
4470 * If this wdata has a memory registered, the MR can be freed
4471 * The number of MRs available is limited, it's important to recover
4472 * used MR as soon as I/O is finished. Hold MR longer in the later
4473 * I/O process can possibly result in I/O deadlock due to lack of MR
4474 * to send request on I/O retry
4475 */
4476 if (wdata->mr) {
4477 smbd_deregister_mr(wdata->mr);
4478 wdata->mr = NULL;
4479 }
4480#endif
7d42e72f 4481 if (wdata->result) {
33319141 4482 cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
7d42e72f
PS
4483 trace_smb3_write_err(0 /* no xid */,
4484 wdata->cfile->fid.persistent_fid,
4485 tcon->tid, tcon->ses->Suid, wdata->offset,
4486 wdata->bytes, wdata->result);
d6fd4190 4487 if (wdata->result == -ENOSPC)
a0a3036b 4488 pr_warn_once("Out of space writing to %s\n",
68e14569 4489 tcon->tree_name);
7d42e72f
PS
4490 } else
4491 trace_smb3_write_done(0 /* no xid */,
4492 wdata->cfile->fid.persistent_fid,
4493 tcon->tid, tcon->ses->Suid,
4494 wdata->offset, wdata->bytes);
33319141
PS
4495
4496 queue_work(cifsiod_wq, &wdata->work);
70f08f91 4497 release_mid(mid);
34f4deb7 4498 add_credits(server, &credits, 0);
33319141
PS
4499}
4500
4501/* smb2_async_writev - send an async write, and set up mid to handle result */
4502int
4a5c80d7
SF
4503smb2_async_writev(struct cifs_writedata *wdata,
4504 void (*release)(struct kref *kref))
33319141 4505{
cb7e9eab 4506 int rc = -EACCES, flags = 0;
33319141 4507 struct smb2_write_req *req = NULL;
0d35e382 4508 struct smb2_hdr *shdr;
33319141 4509 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
352d96f3 4510 struct TCP_Server_Info *server = wdata->server;
c713c877 4511 struct kvec iov[1];
738f9de5 4512 struct smb_rqst rqst = { };
f5688a6d 4513 unsigned int total_len;
d643a8a4
SM
4514 struct cifs_io_parms _io_parms;
4515 struct cifs_io_parms *io_parms = NULL;
33319141 4516
352d96f3
AA
4517 if (!wdata->server)
4518 server = wdata->server = cifs_pick_channel(tcon->ses);
4519
d643a8a4
SM
4520 /*
4521 * in future we may get cifs_io_parms passed in from the caller,
4522 * but for now we construct it here...
4523 */
4524 _io_parms = (struct cifs_io_parms) {
4525 .tcon = tcon,
4526 .server = server,
4527 .offset = wdata->offset,
4528 .length = wdata->bytes,
4529 .persistent_fid = wdata->cfile->fid.persistent_fid,
4530 .volatile_fid = wdata->cfile->fid.volatile_fid,
4531 .pid = wdata->pid,
4532 };
4533 io_parms = &_io_parms;
4534
352d96f3
AA
4535 rc = smb2_plain_req_init(SMB2_WRITE, tcon, server,
4536 (void **) &req, &total_len);
f0b93cb9
PS
4537 if (rc)
4538 return rc;
33319141 4539
5a77e75f 4540 if (smb3_encryption_required(tcon))
7fb8986e
PS
4541 flags |= CIFS_TRANSFORM_REQ;
4542
0d35e382 4543 shdr = (struct smb2_hdr *)req;
d643a8a4 4544 shdr->Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
33319141 4545
d643a8a4
SM
4546 req->PersistentFileId = io_parms->persistent_fid;
4547 req->VolatileFileId = io_parms->volatile_fid;
33319141
PS
4548 req->WriteChannelInfoOffset = 0;
4549 req->WriteChannelInfoLength = 0;
d08089f6 4550 req->Channel = SMB2_CHANNEL_NONE;
d643a8a4 4551 req->Offset = cpu_to_le64(io_parms->offset);
33319141 4552 req->DataOffset = cpu_to_le16(
f5688a6d 4553 offsetof(struct smb2_write_req, Buffer));
33319141 4554 req->RemainingBytes = 0;
d323c246 4555
d643a8a4
SM
4556 trace_smb3_write_enter(0 /* xid */,
4557 io_parms->persistent_fid,
4558 io_parms->tcon->tid,
4559 io_parms->tcon->ses->Suid,
4560 io_parms->offset,
4561 io_parms->length);
4562
db223a59
LL
4563#ifdef CONFIG_CIFS_SMB_DIRECT
4564 /*
4565 * If we want to do a server RDMA read, fill in and append
4566 * smbd_buffer_descriptor_v1 to the end of write request
4567 */
a6559cc1 4568 if (smb3_use_rdma_offload(io_parms)) {
db223a59 4569 struct smbd_buffer_descriptor_v1 *v1;
d08089f6 4570 size_t data_size = iov_iter_count(&wdata->iter);
db223a59
LL
4571 bool need_invalidate = server->dialect == SMB30_PROT_ID;
4572
d08089f6
DH
4573 wdata->mr = smbd_register_mr(server->smbd_conn, &wdata->iter,
4574 false, need_invalidate);
db223a59 4575 if (!wdata->mr) {
b7972092 4576 rc = -EAGAIN;
db223a59
LL
4577 goto async_writev_out;
4578 }
4579 req->Length = 0;
4580 req->DataOffset = 0;
d08089f6 4581 req->RemainingBytes = cpu_to_le32(data_size);
db223a59
LL
4582 req->Channel = SMB2_CHANNEL_RDMA_V1_INVALIDATE;
4583 if (need_invalidate)
4584 req->Channel = SMB2_CHANNEL_RDMA_V1;
4585 req->WriteChannelInfoOffset =
2026b06e 4586 cpu_to_le16(offsetof(struct smb2_write_req, Buffer));
db223a59 4587 req->WriteChannelInfoLength =
2026b06e 4588 cpu_to_le16(sizeof(struct smbd_buffer_descriptor_v1));
db223a59 4589 v1 = (struct smbd_buffer_descriptor_v1 *) &req->Buffer[0];
2026b06e
SF
4590 v1->offset = cpu_to_le64(wdata->mr->mr->iova);
4591 v1->token = cpu_to_le32(wdata->mr->mr->rkey);
4592 v1->length = cpu_to_le32(wdata->mr->mr->length);
db223a59
LL
4593 }
4594#endif
c713c877
RS
4595 iov[0].iov_len = total_len - 1;
4596 iov[0].iov_base = (char *)req;
33319141 4597
738f9de5 4598 rqst.rq_iov = iov;
c713c877 4599 rqst.rq_nvec = 1;
d08089f6
DH
4600 rqst.rq_iter = wdata->iter;
4601 rqst.rq_iter_size = iov_iter_count(&rqst.rq_iter);
db223a59 4602#ifdef CONFIG_CIFS_SMB_DIRECT
d08089f6 4603 if (wdata->mr)
c713c877 4604 iov[0].iov_len += sizeof(struct smbd_buffer_descriptor_v1);
db223a59 4605#endif
d08089f6
DH
4606 cifs_dbg(FYI, "async write at %llu %u bytes iter=%zx\n",
4607 io_parms->offset, io_parms->length, iov_iter_count(&rqst.rq_iter));
33319141 4608
db223a59
LL
4609#ifdef CONFIG_CIFS_SMB_DIRECT
4610 /* For RDMA read, I/O size is in RemainingBytes not in Length */
4611 if (!wdata->mr)
d643a8a4 4612 req->Length = cpu_to_le32(io_parms->length);
db223a59 4613#else
d643a8a4 4614 req->Length = cpu_to_le32(io_parms->length);
db223a59 4615#endif
33319141 4616
335b7b62 4617 if (wdata->credits.value > 0) {
31473fc4 4618 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
cb7e9eab 4619 SMB2_MAX_BUFFER_SIZE));
88fd98a2 4620 shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
9a1c67e8 4621
d643a8a4 4622 rc = adjust_credits(server, &wdata->credits, io_parms->length);
9a1c67e8 4623 if (rc)
335b7b62 4624 goto async_writev_out;
9a1c67e8 4625
7fb8986e 4626 flags |= CIFS_HAS_CREDITS;
cb7e9eab
PS
4627 }
4628
33319141 4629 kref_get(&wdata->refcount);
9b7c18a2 4630 rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL,
3349c3a7 4631 wdata, flags, &wdata->credits);
33319141 4632
e5d04887 4633 if (rc) {
d8d9de53 4634 trace_smb3_write_err(0 /* no xid */,
d643a8a4
SM
4635 io_parms->persistent_fid,
4636 io_parms->tcon->tid,
4637 io_parms->tcon->ses->Suid,
4638 io_parms->offset,
4639 io_parms->length,
4640 rc);
4a5c80d7 4641 kref_put(&wdata->refcount, release);
e5d04887 4642 cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
7d42e72f 4643 }
33319141 4644
33319141
PS
4645async_writev_out:
4646 cifs_small_buf_release(req);
33319141
PS
4647 return rc;
4648}
009d3443
PS
4649
4650/*
4651 * SMB2_write function gets iov pointer to kvec array with n_vec as a length.
4652 * The length field from io_parms must be at least 1 and indicates a number of
4653 * elements with data to write that begins with position 1 in iov array. All
4654 * data length is specified by count.
4655 */
4656int
4657SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
4658 unsigned int *nbytes, struct kvec *iov, int n_vec)
4659{
40eff45b 4660 struct smb_rqst rqst;
009d3443
PS
4661 int rc = 0;
4662 struct smb2_write_req *req = NULL;
4663 struct smb2_write_rsp *rsp = NULL;
4664 int resp_buftype;
da502f7d 4665 struct kvec rsp_iov;
7fb8986e 4666 int flags = 0;
f5688a6d 4667 unsigned int total_len;
352d96f3 4668 struct TCP_Server_Info *server;
da502f7d 4669
009d3443
PS
4670 *nbytes = 0;
4671
4672 if (n_vec < 1)
4673 return rc;
4674
352d96f3
AA
4675 if (!io_parms->server)
4676 io_parms->server = cifs_pick_channel(io_parms->tcon->ses);
4677 server = io_parms->server;
4678 if (server == NULL)
4679 return -ECONNABORTED;
4680
4681 rc = smb2_plain_req_init(SMB2_WRITE, io_parms->tcon, server,
4682 (void **) &req, &total_len);
009d3443
PS
4683 if (rc)
4684 return rc;
4685
5a77e75f 4686 if (smb3_encryption_required(io_parms->tcon))
7fb8986e
PS
4687 flags |= CIFS_TRANSFORM_REQ;
4688
0d35e382 4689 req->hdr.Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
009d3443 4690
351a59da
PA
4691 req->PersistentFileId = io_parms->persistent_fid;
4692 req->VolatileFileId = io_parms->volatile_fid;
009d3443
PS
4693 req->WriteChannelInfoOffset = 0;
4694 req->WriteChannelInfoLength = 0;
4695 req->Channel = 0;
4696 req->Length = cpu_to_le32(io_parms->length);
4697 req->Offset = cpu_to_le64(io_parms->offset);
009d3443 4698 req->DataOffset = cpu_to_le16(
f5688a6d 4699 offsetof(struct smb2_write_req, Buffer));
009d3443
PS
4700 req->RemainingBytes = 0;
4701
d323c246
SF
4702 trace_smb3_write_enter(xid, io_parms->persistent_fid,
4703 io_parms->tcon->tid, io_parms->tcon->ses->Suid,
4704 io_parms->offset, io_parms->length);
4705
009d3443 4706 iov[0].iov_base = (char *)req;
f5688a6d
RS
4707 /* 1 for Buffer */
4708 iov[0].iov_len = total_len - 1;
009d3443 4709
40eff45b
RS
4710 memset(&rqst, 0, sizeof(struct smb_rqst));
4711 rqst.rq_iov = iov;
4712 rqst.rq_nvec = n_vec + 1;
4713
352d96f3
AA
4714 rc = cifs_send_recv(xid, io_parms->tcon->ses, server,
4715 &rqst,
f5688a6d 4716 &resp_buftype, flags, &rsp_iov);
da502f7d 4717 rsp = (struct smb2_write_rsp *)rsp_iov.iov_base;
009d3443
PS
4718
4719 if (rc) {
d8d9de53 4720 trace_smb3_write_err(xid,
351a59da 4721 req->PersistentFileId,
eccb4422
SF
4722 io_parms->tcon->tid,
4723 io_parms->tcon->ses->Suid,
4724 io_parms->offset, io_parms->length, rc);
009d3443 4725 cifs_stats_fail_inc(io_parms->tcon, SMB2_WRITE_HE);
f96637be 4726 cifs_dbg(VFS, "Send error in write = %d\n", rc);
eccb4422 4727 } else {
009d3443 4728 *nbytes = le32_to_cpu(rsp->DataLength);
d8d9de53 4729 trace_smb3_write_done(xid,
351a59da 4730 req->PersistentFileId,
d8d9de53
RS
4731 io_parms->tcon->tid,
4732 io_parms->tcon->ses->Suid,
4733 io_parms->offset, *nbytes);
eccb4422 4734 }
e5d04887 4735
6a3eb336 4736 cifs_small_buf_release(req);
e5d04887 4737 free_rsp_buf(resp_buftype, rsp);
009d3443
PS
4738 return rc;
4739}
35143eb5 4740
69dda305 4741int posix_info_sid_size(const void *beg, const void *end)
349e13ad
AA
4742{
4743 size_t subauth;
4744 int total;
4745
4746 if (beg + 1 > end)
4747 return -1;
4748
4749 subauth = *(u8 *)(beg+1);
4750 if (subauth < 1 || subauth > 15)
4751 return -1;
4752
4753 total = 1 + 1 + 6 + 4*subauth;
4754 if (beg + total > end)
4755 return -1;
4756
4757 return total;
4758}
4759
4760int posix_info_parse(const void *beg, const void *end,
4761 struct smb2_posix_info_parsed *out)
4762
4763{
4764 int total_len = 0;
ca38fabc 4765 int owner_len, group_len;
349e13ad
AA
4766 int name_len;
4767 const void *owner_sid;
4768 const void *group_sid;
4769 const void *name;
4770
4771 /* if no end bound given, assume payload to be correct */
4772 if (!end) {
4773 const struct smb2_posix_info *p = beg;
4774
4775 end = beg + le32_to_cpu(p->NextEntryOffset);
4776 /* last element will have a 0 offset, pick a sensible bound */
4777 if (end == beg)
4778 end += 0xFFFF;
4779 }
4780
4781 /* check base buf */
4782 if (beg + sizeof(struct smb2_posix_info) > end)
4783 return -1;
4784 total_len = sizeof(struct smb2_posix_info);
4785
4786 /* check owner sid */
4787 owner_sid = beg + total_len;
ca38fabc
RS
4788 owner_len = posix_info_sid_size(owner_sid, end);
4789 if (owner_len < 0)
349e13ad 4790 return -1;
ca38fabc 4791 total_len += owner_len;
349e13ad
AA
4792
4793 /* check group sid */
4794 group_sid = beg + total_len;
ca38fabc
RS
4795 group_len = posix_info_sid_size(group_sid, end);
4796 if (group_len < 0)
349e13ad 4797 return -1;
ca38fabc 4798 total_len += group_len;
349e13ad
AA
4799
4800 /* check name len */
4801 if (beg + total_len + 4 > end)
4802 return -1;
4803 name_len = le32_to_cpu(*(__le32 *)(beg + total_len));
4804 if (name_len < 1 || name_len > 0xFFFF)
4805 return -1;
4806 total_len += 4;
4807
4808 /* check name */
4809 name = beg + total_len;
4810 if (name + name_len > end)
4811 return -1;
4812 total_len += name_len;
4813
4814 if (out) {
4815 out->base = beg;
4816 out->size = total_len;
4817 out->name_len = name_len;
4818 out->name = name;
ca38fabc
RS
4819 memcpy(&out->owner, owner_sid, owner_len);
4820 memcpy(&out->group, group_sid, group_len);
349e13ad
AA
4821 }
4822 return total_len;
4823}
4824
4825static int posix_info_extra_size(const void *beg, const void *end)
4826{
4827 int len = posix_info_parse(beg, end, NULL);
4828
4829 if (len < 0)
4830 return -1;
4831 return len - sizeof(struct smb2_posix_info);
4832}
4833
d324f08d 4834static unsigned int
3d519bd1
AA
4835num_entries(int infotype, char *bufstart, char *end_of_buf, char **lastentry,
4836 size_t size)
d324f08d
PS
4837{
4838 int len;
4839 unsigned int entrycount = 0;
4840 unsigned int next_offset = 0;
56446f21
DC
4841 char *entryptr;
4842 FILE_DIRECTORY_INFO *dir_info;
d324f08d
PS
4843
4844 if (bufstart == NULL)
4845 return 0;
4846
56446f21 4847 entryptr = bufstart;
d324f08d
PS
4848
4849 while (1) {
56446f21
DC
4850 if (entryptr + next_offset < entryptr ||
4851 entryptr + next_offset > end_of_buf ||
4852 entryptr + next_offset + size > end_of_buf) {
f96637be 4853 cifs_dbg(VFS, "malformed search entry would overflow\n");
d324f08d
PS
4854 break;
4855 }
4856
56446f21
DC
4857 entryptr = entryptr + next_offset;
4858 dir_info = (FILE_DIRECTORY_INFO *)entryptr;
4859
3d519bd1
AA
4860 if (infotype == SMB_FIND_FILE_POSIX_INFO)
4861 len = posix_info_extra_size(entryptr, end_of_buf);
4862 else
4863 len = le32_to_cpu(dir_info->FileNameLength);
4864
4865 if (len < 0 ||
4866 entryptr + len < entryptr ||
56446f21
DC
4867 entryptr + len > end_of_buf ||
4868 entryptr + len + size > end_of_buf) {
f96637be
JP
4869 cifs_dbg(VFS, "directory entry name would overflow frame end of buf %p\n",
4870 end_of_buf);
d324f08d
PS
4871 break;
4872 }
4873
56446f21 4874 *lastentry = entryptr;
d324f08d
PS
4875 entrycount++;
4876
56446f21 4877 next_offset = le32_to_cpu(dir_info->NextEntryOffset);
d324f08d
PS
4878 if (!next_offset)
4879 break;
4880 }
4881
4882 return entrycount;
4883}
4884
4885/*
4886 * Readdir/FindFirst
4887 */
0a17799c 4888int SMB2_query_directory_init(const unsigned int xid,
352d96f3
AA
4889 struct cifs_tcon *tcon,
4890 struct TCP_Server_Info *server,
4891 struct smb_rqst *rqst,
0a17799c
RS
4892 u64 persistent_fid, u64 volatile_fid,
4893 int index, int info_level)
d324f08d
PS
4894{
4895 struct smb2_query_directory_req *req;
d324f08d 4896 unsigned char *bufptr;
d324f08d 4897 __le16 asteriks = cpu_to_le16('*');
0a17799c
RS
4898 unsigned int output_size = CIFSMaxBufSize -
4899 MAX_SMB2_CREATE_RESPONSE_SIZE -
4900 MAX_SMB2_CLOSE_RESPONSE_SIZE;
7c00c3a6 4901 unsigned int total_len;
0a17799c
RS
4902 struct kvec *iov = rqst->rq_iov;
4903 int len, rc;
d324f08d 4904
352d96f3
AA
4905 rc = smb2_plain_req_init(SMB2_QUERY_DIRECTORY, tcon, server,
4906 (void **) &req, &total_len);
d324f08d
PS
4907 if (rc)
4908 return rc;
4909
0a17799c 4910 switch (info_level) {
d324f08d
PS
4911 case SMB_FIND_FILE_DIRECTORY_INFO:
4912 req->FileInformationClass = FILE_DIRECTORY_INFORMATION;
d324f08d
PS
4913 break;
4914 case SMB_FIND_FILE_ID_FULL_DIR_INFO:
4915 req->FileInformationClass = FILEID_FULL_DIRECTORY_INFORMATION;
d324f08d 4916 break;
3d519bd1
AA
4917 case SMB_FIND_FILE_POSIX_INFO:
4918 req->FileInformationClass = SMB_FIND_FILE_POSIX_INFO;
4919 break;
d324f08d 4920 default:
3175eb9b 4921 cifs_tcon_dbg(VFS, "info level %u isn't supported\n",
0a17799c
RS
4922 info_level);
4923 return -EINVAL;
d324f08d
PS
4924 }
4925
4926 req->FileIndex = cpu_to_le32(index);
4927 req->PersistentFileId = persistent_fid;
4928 req->VolatileFileId = volatile_fid;
4929
4930 len = 0x2;
4931 bufptr = req->Buffer;
4932 memcpy(bufptr, &asteriks, len);
4933
4934 req->FileNameOffset =
eb3e28c1 4935 cpu_to_le16(sizeof(struct smb2_query_directory_req));
d324f08d
PS
4936 req->FileNameLength = cpu_to_le16(len);
4937 /*
4938 * BB could be 30 bytes or so longer if we used SMB2 specific
4939 * buffer lengths, but this is safe and close enough.
4940 */
4941 output_size = min_t(unsigned int, output_size, server->maxBuf);
4942 output_size = min_t(unsigned int, output_size, 2 << 15);
4943 req->OutputBufferLength = cpu_to_le32(output_size);
4944
4945 iov[0].iov_base = (char *)req;
7c00c3a6
RS
4946 /* 1 for Buffer */
4947 iov[0].iov_len = total_len - 1;
d324f08d
PS
4948
4949 iov[1].iov_base = (char *)(req->Buffer);
4950 iov[1].iov_len = len;
4951
0a17799c
RS
4952 trace_smb3_query_dir_enter(xid, persistent_fid, tcon->tid,
4953 tcon->ses->Suid, index, output_size);
4954
4955 return 0;
4956}
4957
4958void SMB2_query_directory_free(struct smb_rqst *rqst)
4959{
4960 if (rqst && rqst->rq_iov) {
4961 cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
4962 }
4963}
4964
af08f9e7
RS
4965int
4966smb2_parse_query_directory(struct cifs_tcon *tcon,
4967 struct kvec *rsp_iov,
4968 int resp_buftype,
4969 struct cifs_search_info *srch_inf)
4970{
4971 struct smb2_query_directory_rsp *rsp;
4972 size_t info_buf_size;
4973 char *end_of_smb;
4974 int rc;
4975
4976 rsp = (struct smb2_query_directory_rsp *)rsp_iov->iov_base;
4977
4978 switch (srch_inf->info_level) {
4979 case SMB_FIND_FILE_DIRECTORY_INFO:
35235e19 4980 info_buf_size = sizeof(FILE_DIRECTORY_INFO);
af08f9e7
RS
4981 break;
4982 case SMB_FIND_FILE_ID_FULL_DIR_INFO:
35235e19 4983 info_buf_size = sizeof(SEARCH_ID_FULL_DIR_INFO);
af08f9e7 4984 break;
3d519bd1
AA
4985 case SMB_FIND_FILE_POSIX_INFO:
4986 /* note that posix payload are variable size */
4987 info_buf_size = sizeof(struct smb2_posix_info);
4988 break;
af08f9e7
RS
4989 default:
4990 cifs_tcon_dbg(VFS, "info level %u isn't supported\n",
4991 srch_inf->info_level);
4992 return -EINVAL;
4993 }
4994
4995 rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset),
4996 le32_to_cpu(rsp->OutputBufferLength), rsp_iov,
4997 info_buf_size);
3d519bd1
AA
4998 if (rc) {
4999 cifs_tcon_dbg(VFS, "bad info payload");
af08f9e7 5000 return rc;
3d519bd1 5001 }
af08f9e7
RS
5002
5003 srch_inf->unicode = true;
5004
5005 if (srch_inf->ntwrk_buf_start) {
5006 if (srch_inf->smallBuf)
5007 cifs_small_buf_release(srch_inf->ntwrk_buf_start);
5008 else
5009 cifs_buf_release(srch_inf->ntwrk_buf_start);
5010 }
5011 srch_inf->ntwrk_buf_start = (char *)rsp;
5012 srch_inf->srch_entries_start = srch_inf->last_entry =
5013 (char *)rsp + le16_to_cpu(rsp->OutputBufferOffset);
5014 end_of_smb = rsp_iov->iov_len + (char *)rsp;
3d519bd1
AA
5015
5016 srch_inf->entries_in_buffer = num_entries(
5017 srch_inf->info_level,
5018 srch_inf->srch_entries_start,
5019 end_of_smb,
5020 &srch_inf->last_entry,
5021 info_buf_size);
5022
af08f9e7
RS
5023 srch_inf->index_of_last_entry += srch_inf->entries_in_buffer;
5024 cifs_dbg(FYI, "num entries %d last_index %lld srch start %p srch end %p\n",
5025 srch_inf->entries_in_buffer, srch_inf->index_of_last_entry,
5026 srch_inf->srch_entries_start, srch_inf->last_entry);
5027 if (resp_buftype == CIFS_LARGE_BUFFER)
5028 srch_inf->smallBuf = false;
5029 else if (resp_buftype == CIFS_SMALL_BUFFER)
5030 srch_inf->smallBuf = true;
5031 else
a0a3036b 5032 cifs_tcon_dbg(VFS, "Invalid search buffer type\n");
af08f9e7
RS
5033
5034 return 0;
5035}
5036
0a17799c
RS
5037int
5038SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
5039 u64 persistent_fid, u64 volatile_fid, int index,
5040 struct cifs_search_info *srch_inf)
5041{
5042 struct smb_rqst rqst;
5043 struct kvec iov[SMB2_QUERY_DIRECTORY_IOV_SIZE];
5044 struct smb2_query_directory_rsp *rsp = NULL;
5045 int resp_buftype = CIFS_NO_BUFFER;
5046 struct kvec rsp_iov;
5047 int rc = 0;
0a17799c 5048 struct cifs_ses *ses = tcon->ses;
352d96f3 5049 struct TCP_Server_Info *server = cifs_pick_channel(ses);
0a17799c
RS
5050 int flags = 0;
5051
c4985c3d 5052 if (!ses || !(ses->server))
0a17799c
RS
5053 return -EIO;
5054
5055 if (smb3_encryption_required(tcon))
5056 flags |= CIFS_TRANSFORM_REQ;
5057
40eff45b 5058 memset(&rqst, 0, sizeof(struct smb_rqst));
0a17799c 5059 memset(&iov, 0, sizeof(iov));
40eff45b 5060 rqst.rq_iov = iov;
0a17799c 5061 rqst.rq_nvec = SMB2_QUERY_DIRECTORY_IOV_SIZE;
40eff45b 5062
352d96f3
AA
5063 rc = SMB2_query_directory_init(xid, tcon, server,
5064 &rqst, persistent_fid,
0a17799c
RS
5065 volatile_fid, index,
5066 srch_inf->info_level);
5067 if (rc)
5068 goto qdir_exit;
d323c246 5069
352d96f3
AA
5070 rc = cifs_send_recv(xid, ses, server,
5071 &rqst, &resp_buftype, flags, &rsp_iov);
da502f7d 5072 rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base;
e5d04887 5073
d324f08d 5074 if (rc) {
31473fc4 5075 if (rc == -ENODATA &&
0d35e382 5076 rsp->hdr.Status == STATUS_NO_MORE_FILES) {
adb3b4e9
SF
5077 trace_smb3_query_dir_done(xid, persistent_fid,
5078 tcon->tid, tcon->ses->Suid, index, 0);
52755808
PS
5079 srch_inf->endOfSearch = true;
5080 rc = 0;
adb3b4e9
SF
5081 } else {
5082 trace_smb3_query_dir_err(xid, persistent_fid, tcon->tid,
5083 tcon->ses->Suid, index, 0, rc);
8e6e72ae 5084 cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE);
adb3b4e9 5085 }
d324f08d
PS
5086 goto qdir_exit;
5087 }
d324f08d 5088
af08f9e7
RS
5089 rc = smb2_parse_query_directory(tcon, &rsp_iov, resp_buftype,
5090 srch_inf);
adb3b4e9
SF
5091 if (rc) {
5092 trace_smb3_query_dir_err(xid, persistent_fid, tcon->tid,
5093 tcon->ses->Suid, index, 0, rc);
d324f08d 5094 goto qdir_exit;
adb3b4e9 5095 }
0a17799c
RS
5096 resp_buftype = CIFS_NO_BUFFER;
5097
adb3b4e9
SF
5098 trace_smb3_query_dir_done(xid, persistent_fid, tcon->tid,
5099 tcon->ses->Suid, index, srch_inf->entries_in_buffer);
d324f08d
PS
5100
5101qdir_exit:
0a17799c 5102 SMB2_query_directory_free(&rqst);
d324f08d
PS
5103 free_rsp_buf(resp_buftype, rsp);
5104 return rc;
5105}
5106
ba8ca116 5107int
352d96f3
AA
5108SMB2_set_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
5109 struct smb_rqst *rqst,
5110 u64 persistent_fid, u64 volatile_fid, u32 pid,
5111 u8 info_class, u8 info_type, u32 additional_info,
5112 void **data, unsigned int *size)
35143eb5
PS
5113{
5114 struct smb2_set_info_req *req;
ba8ca116
RS
5115 struct kvec *iov = rqst->rq_iov;
5116 unsigned int i, total_len;
5117 int rc;
35143eb5 5118
352d96f3
AA
5119 rc = smb2_plain_req_init(SMB2_SET_INFO, tcon, server,
5120 (void **) &req, &total_len);
ba8ca116 5121 if (rc)
35143eb5 5122 return rc;
7fb8986e 5123
0d35e382 5124 req->hdr.Id.SyncId.ProcessId = cpu_to_le32(pid);
dac95340 5125 req->InfoType = info_type;
35143eb5
PS
5126 req->FileInfoClass = info_class;
5127 req->PersistentFileId = persistent_fid;
5128 req->VolatileFileId = volatile_fid;
dac95340 5129 req->AdditionalInformation = cpu_to_le32(additional_info);
35143eb5 5130
eb3e28c1 5131 req->BufferOffset = cpu_to_le16(sizeof(struct smb2_set_info_req));
35143eb5
PS
5132 req->BufferLength = cpu_to_le32(*size);
5133
35143eb5 5134 memcpy(req->Buffer, *data, *size);
2fc803ef 5135 total_len += *size;
35143eb5
PS
5136
5137 iov[0].iov_base = (char *)req;
2fc803ef
RS
5138 /* 1 for Buffer */
5139 iov[0].iov_len = total_len - 1;
35143eb5 5140
ba8ca116 5141 for (i = 1; i < rqst->rq_nvec; i++) {
35143eb5
PS
5142 le32_add_cpu(&req->BufferLength, size[i]);
5143 iov[i].iov_base = (char *)data[i];
5144 iov[i].iov_len = size[i];
5145 }
5146
ba8ca116
RS
5147 return 0;
5148}
5149
5150void
5151SMB2_set_info_free(struct smb_rqst *rqst)
5152{
32a1fb36
RS
5153 if (rqst && rqst->rq_iov)
5154 cifs_buf_release(rqst->rq_iov[0].iov_base); /* request */
ba8ca116
RS
5155}
5156
5157static int
5158send_set_info(const unsigned int xid, struct cifs_tcon *tcon,
5159 u64 persistent_fid, u64 volatile_fid, u32 pid, u8 info_class,
5160 u8 info_type, u32 additional_info, unsigned int num,
5161 void **data, unsigned int *size)
5162{
5163 struct smb_rqst rqst;
5164 struct smb2_set_info_rsp *rsp = NULL;
5165 struct kvec *iov;
5166 struct kvec rsp_iov;
5167 int rc = 0;
5168 int resp_buftype;
5169 struct cifs_ses *ses = tcon->ses;
352d96f3 5170 struct TCP_Server_Info *server = cifs_pick_channel(ses);
ba8ca116
RS
5171 int flags = 0;
5172
352d96f3 5173 if (!ses || !server)
ba8ca116
RS
5174 return -EIO;
5175
5176 if (!num)
5177 return -EINVAL;
5178
5179 if (smb3_encryption_required(tcon))
5180 flags |= CIFS_TRANSFORM_REQ;
5181
5182 iov = kmalloc_array(num, sizeof(struct kvec), GFP_KERNEL);
5183 if (!iov)
5184 return -ENOMEM;
5185
40eff45b
RS
5186 memset(&rqst, 0, sizeof(struct smb_rqst));
5187 rqst.rq_iov = iov;
5188 rqst.rq_nvec = num;
5189
352d96f3
AA
5190 rc = SMB2_set_info_init(tcon, server,
5191 &rqst, persistent_fid, volatile_fid, pid,
ba8ca116
RS
5192 info_class, info_type, additional_info,
5193 data, size);
5194 if (rc) {
5195 kfree(iov);
5196 return rc;
5197 }
5198
5199
352d96f3
AA
5200 rc = cifs_send_recv(xid, ses, server,
5201 &rqst, &resp_buftype, flags,
2fc803ef 5202 &rsp_iov);
ba8ca116 5203 SMB2_set_info_free(&rqst);
da502f7d 5204 rsp = (struct smb2_set_info_rsp *)rsp_iov.iov_base;
35143eb5 5205
eccb4422 5206 if (rc != 0) {
35143eb5 5207 cifs_stats_fail_inc(tcon, SMB2_SET_INFO_HE);
eccb4422
SF
5208 trace_smb3_set_info_err(xid, persistent_fid, tcon->tid,
5209 ses->Suid, info_class, (__u32)info_type, rc);
5210 }
7d3fb24b 5211
35143eb5
PS
5212 free_rsp_buf(resp_buftype, rsp);
5213 kfree(iov);
5214 return rc;
5215}
5216
c839ff24
PS
5217int
5218SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
3764cbd1 5219 u64 volatile_fid, u32 pid, __le64 *eof)
c839ff24
PS
5220{
5221 struct smb2_file_eof_info info;
5222 void *data;
5223 unsigned int size;
5224
5225 info.EndOfFile = *eof;
5226
5227 data = &info;
5228 size = sizeof(struct smb2_file_eof_info);
5229
7c05eae8
SF
5230 trace_smb3_set_eof(xid, persistent_fid, tcon->tid, tcon->ses->Suid, le64_to_cpu(*eof));
5231
3764cbd1 5232 return send_set_info(xid, tcon, persistent_fid, volatile_fid,
dac95340
SP
5233 pid, FILE_END_OF_FILE_INFORMATION, SMB2_O_INFO_FILE,
5234 0, 1, &data, &size);
c839ff24 5235}
1feeaac7 5236
dac95340
SP
5237int
5238SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
5239 u64 persistent_fid, u64 volatile_fid,
5240 struct cifs_ntsd *pnntsd, int pacllen, int aclflag)
5241{
5242 return send_set_info(xid, tcon, persistent_fid, volatile_fid,
5243 current->tgid, 0, SMB2_O_INFO_SECURITY, aclflag,
5244 1, (void **)&pnntsd, &pacllen);
1feeaac7 5245}
983c88a4 5246
5517554e
RS
5247int
5248SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
5249 u64 persistent_fid, u64 volatile_fid,
5250 struct smb2_file_full_ea_info *buf, int len)
5251{
5252 return send_set_info(xid, tcon, persistent_fid, volatile_fid,
5253 current->tgid, FILE_FULL_EA_INFORMATION, SMB2_O_INFO_FILE,
5254 0, 1, (void **)&buf, &len);
5255}
5256
983c88a4
PS
5257int
5258SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
5259 const u64 persistent_fid, const u64 volatile_fid,
5260 __u8 oplock_level)
5261{
40eff45b 5262 struct smb_rqst rqst;
983c88a4 5263 int rc;
0d5a288d 5264 struct smb2_oplock_break *req = NULL;
21ad9487 5265 struct cifs_ses *ses = tcon->ses;
352d96f3 5266 struct TCP_Server_Info *server = cifs_pick_channel(ses);
7fb8986e 5267 int flags = CIFS_OBREAK_OP;
21ad9487
RS
5268 unsigned int total_len;
5269 struct kvec iov[1];
5270 struct kvec rsp_iov;
5271 int resp_buf_type;
983c88a4 5272
f96637be 5273 cifs_dbg(FYI, "SMB2_oplock_break\n");
352d96f3
AA
5274 rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, server,
5275 (void **) &req, &total_len);
983c88a4
PS
5276 if (rc)
5277 return rc;
5278
5a77e75f 5279 if (smb3_encryption_required(tcon))
7fb8986e
PS
5280 flags |= CIFS_TRANSFORM_REQ;
5281
983c88a4
PS
5282 req->VolatileFid = volatile_fid;
5283 req->PersistentFid = persistent_fid;
5284 req->OplockLevel = oplock_level;
0d35e382 5285 req->hdr.CreditRequest = cpu_to_le16(1);
983c88a4 5286
392e1c5d 5287 flags |= CIFS_NO_RSP_BUF;
21ad9487
RS
5288
5289 iov[0].iov_base = (char *)req;
5290 iov[0].iov_len = total_len;
5291
40eff45b
RS
5292 memset(&rqst, 0, sizeof(struct smb_rqst));
5293 rqst.rq_iov = iov;
5294 rqst.rq_nvec = 1;
5295
352d96f3
AA
5296 rc = cifs_send_recv(xid, ses, server,
5297 &rqst, &resp_buf_type, flags, &rsp_iov);
da502f7d 5298 cifs_small_buf_release(req);
983c88a4
PS
5299
5300 if (rc) {
5301 cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE);
f96637be 5302 cifs_dbg(FYI, "Send error in Oplock Break = %d\n", rc);
983c88a4
PS
5303 }
5304
5305 return rc;
5306}
6fc05c25 5307
730928c8
RS
5308void
5309smb2_copy_fs_info_to_kstatfs(struct smb2_fs_full_size_info *pfs_inf,
5310 struct kstatfs *kst)
6fc05c25
PS
5311{
5312 kst->f_bsize = le32_to_cpu(pfs_inf->BytesPerSector) *
5313 le32_to_cpu(pfs_inf->SectorsPerAllocationUnit);
5314 kst->f_blocks = le64_to_cpu(pfs_inf->TotalAllocationUnits);
42bec214
SP
5315 kst->f_bfree = kst->f_bavail =
5316 le64_to_cpu(pfs_inf->CallerAvailableAllocationUnits);
6fc05c25
PS
5317 return;
5318}
5319
2d304217
SF
5320static void
5321copy_posix_fs_info_to_kstatfs(FILE_SYSTEM_POSIX_INFO *response_data,
5322 struct kstatfs *kst)
5323{
5324 kst->f_bsize = le32_to_cpu(response_data->BlockSize);
5325 kst->f_blocks = le64_to_cpu(response_data->TotalBlocks);
5326 kst->f_bfree = le64_to_cpu(response_data->BlocksAvail);
5327 if (response_data->UserBlocksAvail == cpu_to_le64(-1))
5328 kst->f_bavail = kst->f_bfree;
5329 else
5330 kst->f_bavail = le64_to_cpu(response_data->UserBlocksAvail);
5331 if (response_data->TotalFileNodes != cpu_to_le64(-1))
5332 kst->f_files = le64_to_cpu(response_data->TotalFileNodes);
5333 if (response_data->FreeFileNodes != cpu_to_le64(-1))
5334 kst->f_ffree = le64_to_cpu(response_data->FreeFileNodes);
5335
5336 return;
5337}
2d304217 5338
6fc05c25 5339static int
352d96f3
AA
5340build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon,
5341 struct TCP_Server_Info *server,
5342 int level, int outbuf_len, u64 persistent_fid,
5343 u64 volatile_fid)
6fc05c25
PS
5344{
5345 int rc;
5346 struct smb2_query_info_req *req;
b2fb7fec 5347 unsigned int total_len;
6fc05c25 5348
f96637be 5349 cifs_dbg(FYI, "Query FSInfo level %d\n", level);
6fc05c25 5350
352d96f3 5351 if ((tcon->ses == NULL) || server == NULL)
6fc05c25
PS
5352 return -EIO;
5353
352d96f3
AA
5354 rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server,
5355 (void **) &req, &total_len);
6fc05c25
PS
5356 if (rc)
5357 return rc;
5358
5359 req->InfoType = SMB2_O_INFO_FILESYSTEM;
5360 req->FileInfoClass = level;
5361 req->PersistentFileId = persistent_fid;
5362 req->VolatileFileId = volatile_fid;
b2fb7fec 5363 /* 1 for pad */
6fc05c25 5364 req->InputBufferOffset =
eb3e28c1 5365 cpu_to_le16(sizeof(struct smb2_query_info_req));
6fc05c25 5366 req->OutputBufferLength = cpu_to_le32(
eb3e28c1 5367 outbuf_len + sizeof(struct smb2_query_info_rsp));
6fc05c25
PS
5368
5369 iov->iov_base = (char *)req;
b2fb7fec 5370 iov->iov_len = total_len;
6fc05c25
PS
5371 return 0;
5372}
5373
2d304217
SF
5374int
5375SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon,
5376 u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata)
5377{
5378 struct smb_rqst rqst;
5379 struct smb2_query_info_rsp *rsp = NULL;
5380 struct kvec iov;
5381 struct kvec rsp_iov;
5382 int rc = 0;
5383 int resp_buftype;
5384 struct cifs_ses *ses = tcon->ses;
352d96f3 5385 struct TCP_Server_Info *server = cifs_pick_channel(ses);
2d304217
SF
5386 FILE_SYSTEM_POSIX_INFO *info = NULL;
5387 int flags = 0;
5388
352d96f3
AA
5389 rc = build_qfs_info_req(&iov, tcon, server,
5390 FS_POSIX_INFORMATION,
2d304217
SF
5391 sizeof(FILE_SYSTEM_POSIX_INFO),
5392 persistent_fid, volatile_fid);
5393 if (rc)
5394 return rc;
5395
5396 if (smb3_encryption_required(tcon))
5397 flags |= CIFS_TRANSFORM_REQ;
5398
5399 memset(&rqst, 0, sizeof(struct smb_rqst));
5400 rqst.rq_iov = &iov;
5401 rqst.rq_nvec = 1;
5402
352d96f3
AA
5403 rc = cifs_send_recv(xid, ses, server,
5404 &rqst, &resp_buftype, flags, &rsp_iov);
2d304217
SF
5405 cifs_small_buf_release(iov.iov_base);
5406 if (rc) {
5407 cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
5408 goto posix_qfsinf_exit;
5409 }
5410 rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
5411
5412 info = (FILE_SYSTEM_POSIX_INFO *)(
5413 le16_to_cpu(rsp->OutputBufferOffset) + (char *)rsp);
730928c8
RS
5414 rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset),
5415 le32_to_cpu(rsp->OutputBufferLength), &rsp_iov,
5416 sizeof(FILE_SYSTEM_POSIX_INFO));
2d304217
SF
5417 if (!rc)
5418 copy_posix_fs_info_to_kstatfs(info, fsdata);
5419
5420posix_qfsinf_exit:
5421 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
5422 return rc;
5423}
2d304217 5424
6fc05c25
PS
5425int
5426SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
5427 u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata)
5428{
40eff45b 5429 struct smb_rqst rqst;
6fc05c25
PS
5430 struct smb2_query_info_rsp *rsp = NULL;
5431 struct kvec iov;
da502f7d 5432 struct kvec rsp_iov;
6fc05c25
PS
5433 int rc = 0;
5434 int resp_buftype;
5435 struct cifs_ses *ses = tcon->ses;
352d96f3 5436 struct TCP_Server_Info *server = cifs_pick_channel(ses);
6fc05c25 5437 struct smb2_fs_full_size_info *info = NULL;
7fb8986e 5438 int flags = 0;
6fc05c25 5439
352d96f3
AA
5440 rc = build_qfs_info_req(&iov, tcon, server,
5441 FS_FULL_SIZE_INFORMATION,
6fc05c25
PS
5442 sizeof(struct smb2_fs_full_size_info),
5443 persistent_fid, volatile_fid);
5444 if (rc)
5445 return rc;
5446
5a77e75f 5447 if (smb3_encryption_required(tcon))
7fb8986e
PS
5448 flags |= CIFS_TRANSFORM_REQ;
5449
40eff45b
RS
5450 memset(&rqst, 0, sizeof(struct smb_rqst));
5451 rqst.rq_iov = &iov;
5452 rqst.rq_nvec = 1;
5453
352d96f3
AA
5454 rc = cifs_send_recv(xid, ses, server,
5455 &rqst, &resp_buftype, flags, &rsp_iov);
da502f7d 5456 cifs_small_buf_release(iov.iov_base);
6fc05c25
PS
5457 if (rc) {
5458 cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
34f62640 5459 goto qfsinf_exit;
6fc05c25 5460 }
da502f7d 5461 rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
6fc05c25 5462
1fc6ad2f 5463 info = (struct smb2_fs_full_size_info *)(
49f466bd 5464 le16_to_cpu(rsp->OutputBufferOffset) + (char *)rsp);
730928c8
RS
5465 rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset),
5466 le32_to_cpu(rsp->OutputBufferLength), &rsp_iov,
5467 sizeof(struct smb2_fs_full_size_info));
6fc05c25 5468 if (!rc)
730928c8 5469 smb2_copy_fs_info_to_kstatfs(info, fsdata);
6fc05c25 5470
34f62640 5471qfsinf_exit:
da502f7d 5472 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
34f62640
SF
5473 return rc;
5474}
5475
5476int
5477SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
2167114c 5478 u64 persistent_fid, u64 volatile_fid, int level)
34f62640 5479{
40eff45b 5480 struct smb_rqst rqst;
34f62640
SF
5481 struct smb2_query_info_rsp *rsp = NULL;
5482 struct kvec iov;
da502f7d 5483 struct kvec rsp_iov;
34f62640 5484 int rc = 0;
2167114c 5485 int resp_buftype, max_len, min_len;
34f62640 5486 struct cifs_ses *ses = tcon->ses;
352d96f3 5487 struct TCP_Server_Info *server = cifs_pick_channel(ses);
34f62640 5488 unsigned int rsp_len, offset;
7fb8986e 5489 int flags = 0;
34f62640 5490
2167114c
SF
5491 if (level == FS_DEVICE_INFORMATION) {
5492 max_len = sizeof(FILE_SYSTEM_DEVICE_INFO);
5493 min_len = sizeof(FILE_SYSTEM_DEVICE_INFO);
5494 } else if (level == FS_ATTRIBUTE_INFORMATION) {
5495 max_len = sizeof(FILE_SYSTEM_ATTRIBUTE_INFO);
5496 min_len = MIN_FS_ATTR_INFO_SIZE;
af6a12ea
SF
5497 } else if (level == FS_SECTOR_SIZE_INFORMATION) {
5498 max_len = sizeof(struct smb3_fs_ss_info);
5499 min_len = sizeof(struct smb3_fs_ss_info);
21ba3845
SF
5500 } else if (level == FS_VOLUME_INFORMATION) {
5501 max_len = sizeof(struct smb3_fs_vol_info) + MAX_VOL_LABEL_LEN;
5502 min_len = sizeof(struct smb3_fs_vol_info);
2167114c 5503 } else {
af6a12ea 5504 cifs_dbg(FYI, "Invalid qfsinfo level %d\n", level);
2167114c
SF
5505 return -EINVAL;
5506 }
5507
352d96f3
AA
5508 rc = build_qfs_info_req(&iov, tcon, server,
5509 level, max_len,
34f62640
SF
5510 persistent_fid, volatile_fid);
5511 if (rc)
5512 return rc;
5513
5a77e75f 5514 if (smb3_encryption_required(tcon))
7fb8986e
PS
5515 flags |= CIFS_TRANSFORM_REQ;
5516
40eff45b
RS
5517 memset(&rqst, 0, sizeof(struct smb_rqst));
5518 rqst.rq_iov = &iov;
5519 rqst.rq_nvec = 1;
5520
352d96f3
AA
5521 rc = cifs_send_recv(xid, ses, server,
5522 &rqst, &resp_buftype, flags, &rsp_iov);
da502f7d 5523 cifs_small_buf_release(iov.iov_base);
34f62640
SF
5524 if (rc) {
5525 cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
5526 goto qfsattr_exit;
5527 }
da502f7d 5528 rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
34f62640
SF
5529
5530 rsp_len = le32_to_cpu(rsp->OutputBufferLength);
5531 offset = le16_to_cpu(rsp->OutputBufferOffset);
730928c8 5532 rc = smb2_validate_iov(offset, rsp_len, &rsp_iov, min_len);
2167114c
SF
5533 if (rc)
5534 goto qfsattr_exit;
5535
5536 if (level == FS_ATTRIBUTE_INFORMATION)
1fc6ad2f 5537 memcpy(&tcon->fsAttrInfo, offset
49f466bd 5538 + (char *)rsp, min_t(unsigned int,
2167114c
SF
5539 rsp_len, max_len));
5540 else if (level == FS_DEVICE_INFORMATION)
1fc6ad2f 5541 memcpy(&tcon->fsDevInfo, offset
49f466bd 5542 + (char *)rsp, sizeof(FILE_SYSTEM_DEVICE_INFO));
af6a12ea
SF
5543 else if (level == FS_SECTOR_SIZE_INFORMATION) {
5544 struct smb3_fs_ss_info *ss_info = (struct smb3_fs_ss_info *)
1fc6ad2f 5545 (offset + (char *)rsp);
af6a12ea
SF
5546 tcon->ss_flags = le32_to_cpu(ss_info->Flags);
5547 tcon->perf_sector_size =
5548 le32_to_cpu(ss_info->PhysicalBytesPerSectorForPerf);
21ba3845
SF
5549 } else if (level == FS_VOLUME_INFORMATION) {
5550 struct smb3_fs_vol_info *vol_info = (struct smb3_fs_vol_info *)
5551 (offset + (char *)rsp);
5552 tcon->vol_serial_number = vol_info->VolumeSerialNumber;
5553 tcon->vol_create_time = vol_info->VolumeCreationTime;
af6a12ea 5554 }
34f62640
SF
5555
5556qfsattr_exit:
da502f7d 5557 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
6fc05c25
PS
5558 return rc;
5559}
f7ba7fe6
PS
5560
5561int
5562smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon,
5563 const __u64 persist_fid, const __u64 volatile_fid, const __u32 pid,
5564 const __u32 num_lock, struct smb2_lock_element *buf)
5565{
40eff45b 5566 struct smb_rqst rqst;
f7ba7fe6
PS
5567 int rc = 0;
5568 struct smb2_lock_req *req = NULL;
5569 struct kvec iov[2];
da502f7d 5570 struct kvec rsp_iov;
f7ba7fe6
PS
5571 int resp_buf_type;
5572 unsigned int count;
392e1c5d 5573 int flags = CIFS_NO_RSP_BUF;
ced93679 5574 unsigned int total_len;
352d96f3 5575 struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
f7ba7fe6 5576
f96637be 5577 cifs_dbg(FYI, "smb2_lockv num lock %d\n", num_lock);
f7ba7fe6 5578
352d96f3
AA
5579 rc = smb2_plain_req_init(SMB2_LOCK, tcon, server,
5580 (void **) &req, &total_len);
f7ba7fe6
PS
5581 if (rc)
5582 return rc;
5583
5a77e75f 5584 if (smb3_encryption_required(tcon))
7fb8986e
PS
5585 flags |= CIFS_TRANSFORM_REQ;
5586
0d35e382 5587 req->hdr.Id.SyncId.ProcessId = cpu_to_le32(pid);
f7ba7fe6
PS
5588 req->LockCount = cpu_to_le16(num_lock);
5589
5590 req->PersistentFileId = persist_fid;
5591 req->VolatileFileId = volatile_fid;
5592
5593 count = num_lock * sizeof(struct smb2_lock_element);
f7ba7fe6
PS
5594
5595 iov[0].iov_base = (char *)req;
ced93679 5596 iov[0].iov_len = total_len - sizeof(struct smb2_lock_element);
f7ba7fe6
PS
5597 iov[1].iov_base = (char *)buf;
5598 iov[1].iov_len = count;
5599
5600 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
40eff45b
RS
5601
5602 memset(&rqst, 0, sizeof(struct smb_rqst));
5603 rqst.rq_iov = iov;
5604 rqst.rq_nvec = 2;
5605
352d96f3
AA
5606 rc = cifs_send_recv(xid, tcon->ses, server,
5607 &rqst, &resp_buf_type, flags,
ced93679 5608 &rsp_iov);
da502f7d 5609 cifs_small_buf_release(req);
f7ba7fe6 5610 if (rc) {
f96637be 5611 cifs_dbg(FYI, "Send error in smb2_lockv = %d\n", rc);
f7ba7fe6 5612 cifs_stats_fail_inc(tcon, SMB2_LOCK_HE);
eccb4422
SF
5613 trace_smb3_lock_err(xid, persist_fid, tcon->tid,
5614 tcon->ses->Suid, rc);
f7ba7fe6
PS
5615 }
5616
5617 return rc;
5618}
5619
5620int
5621SMB2_lock(const unsigned int xid, struct cifs_tcon *tcon,
5622 const __u64 persist_fid, const __u64 volatile_fid, const __u32 pid,
5623 const __u64 length, const __u64 offset, const __u32 lock_flags,
5624 const bool wait)
5625{
5626 struct smb2_lock_element lock;
5627
5628 lock.Offset = cpu_to_le64(offset);
5629 lock.Length = cpu_to_le64(length);
5630 lock.Flags = cpu_to_le32(lock_flags);
5631 if (!wait && lock_flags != SMB2_LOCKFLAG_UNLOCK)
5632 lock.Flags |= cpu_to_le32(SMB2_LOCKFLAG_FAIL_IMMEDIATELY);
5633
5634 return smb2_lockv(xid, tcon, persist_fid, volatile_fid, pid, 1, &lock);
5635}
0822f514
PS
5636
5637int
5638SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
5639 __u8 *lease_key, const __le32 lease_state)
5640{
40eff45b 5641 struct smb_rqst rqst;
0822f514
PS
5642 int rc;
5643 struct smb2_lease_ack *req = NULL;
8eb7998e 5644 struct cifs_ses *ses = tcon->ses;
7fb8986e 5645 int flags = CIFS_OBREAK_OP;
8eb7998e
RS
5646 unsigned int total_len;
5647 struct kvec iov[1];
5648 struct kvec rsp_iov;
5649 int resp_buf_type;
179e44d4
SF
5650 __u64 *please_key_high;
5651 __u64 *please_key_low;
352d96f3 5652 struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
0822f514 5653
f96637be 5654 cifs_dbg(FYI, "SMB2_lease_break\n");
352d96f3
AA
5655 rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, server,
5656 (void **) &req, &total_len);
0822f514
PS
5657 if (rc)
5658 return rc;
5659
5a77e75f 5660 if (smb3_encryption_required(tcon))
7fb8986e
PS
5661 flags |= CIFS_TRANSFORM_REQ;
5662
0d35e382 5663 req->hdr.CreditRequest = cpu_to_le16(1);
0822f514 5664 req->StructureSize = cpu_to_le16(36);
8eb7998e 5665 total_len += 12;
0822f514
PS
5666
5667 memcpy(req->LeaseKey, lease_key, 16);
5668 req->LeaseState = lease_state;
5669
392e1c5d 5670 flags |= CIFS_NO_RSP_BUF;
8eb7998e
RS
5671
5672 iov[0].iov_base = (char *)req;
5673 iov[0].iov_len = total_len;
5674
40eff45b
RS
5675 memset(&rqst, 0, sizeof(struct smb_rqst));
5676 rqst.rq_iov = iov;
5677 rqst.rq_nvec = 1;
5678
352d96f3
AA
5679 rc = cifs_send_recv(xid, ses, server,
5680 &rqst, &resp_buf_type, flags, &rsp_iov);
da502f7d 5681 cifs_small_buf_release(req);
0822f514 5682
d339adc1
AA
5683 please_key_low = (__u64 *)lease_key;
5684 please_key_high = (__u64 *)(lease_key+8);
0822f514
PS
5685 if (rc) {
5686 cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE);
179e44d4
SF
5687 trace_smb3_lease_err(le32_to_cpu(lease_state), tcon->tid,
5688 ses->Suid, *please_key_low, *please_key_high, rc);
f96637be 5689 cifs_dbg(FYI, "Send error in Lease Break = %d\n", rc);
179e44d4
SF
5690 } else
5691 trace_smb3_lease_done(le32_to_cpu(lease_state), tcon->tid,
5692 ses->Suid, *please_key_low, *please_key_high);
0822f514
PS
5693
5694 return rc;
5695}