]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - fs/cifs/smb2transport.c
CIFS: Separate SMB2 sync header processing
[mirror_ubuntu-zesty-kernel.git] / fs / cifs / smb2transport.c
CommitLineData
2dc7e1c0
PS
1/*
2 * fs/cifs/smb2transport.c
3 *
4 * Copyright (C) International Business Machines Corp., 2002, 2011
5 * Etersoft, 2012
6 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Jeremy Allison (jra@samba.org) 2006
8 * Pavel Shilovsky (pshilovsky@samba.org) 2012
9 *
10 * This library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published
12 * by the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
18 * the GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/fs.h>
26#include <linux/list.h>
27#include <linux/wait.h>
28#include <linux/net.h>
29#include <linux/delay.h>
30#include <linux/uaccess.h>
31#include <asm/processor.h>
32#include <linux/mempool.h>
fb308a6f 33#include <linux/highmem.h>
2dc7e1c0
PS
34#include "smb2pdu.h"
35#include "cifsglob.h"
36#include "cifsproto.h"
37#include "smb2proto.h"
38#include "cifs_debug.h"
39#include "smb2status.h"
3c1bf7e4
PS
40#include "smb2glob.h"
41
95dc8dd1
SF
42static int
43smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
44{
ba482029 45 int rc;
95dc8dd1
SF
46 unsigned int size;
47
48 if (server->secmech.sdeschmacsha256 != NULL)
49 return 0; /* already allocated */
50
51 server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
52 if (IS_ERR(server->secmech.hmacsha256)) {
53 cifs_dbg(VFS, "could not allocate crypto hmacsha256\n");
ba482029
JL
54 rc = PTR_ERR(server->secmech.hmacsha256);
55 server->secmech.hmacsha256 = NULL;
56 return rc;
95dc8dd1
SF
57 }
58
59 size = sizeof(struct shash_desc) +
60 crypto_shash_descsize(server->secmech.hmacsha256);
61 server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
62 if (!server->secmech.sdeschmacsha256) {
63 crypto_free_shash(server->secmech.hmacsha256);
64 server->secmech.hmacsha256 = NULL;
65 return -ENOMEM;
66 }
67 server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
68 server->secmech.sdeschmacsha256->shash.flags = 0x0;
69
70 return 0;
71}
72
73static int
74smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
75{
76 unsigned int size;
77 int rc;
78
79 if (server->secmech.sdesccmacaes != NULL)
80 return 0; /* already allocated */
81
82 rc = smb2_crypto_shash_allocate(server);
83 if (rc)
84 return rc;
85
86 server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0);
87 if (IS_ERR(server->secmech.cmacaes)) {
88 cifs_dbg(VFS, "could not allocate crypto cmac-aes");
89 kfree(server->secmech.sdeschmacsha256);
90 server->secmech.sdeschmacsha256 = NULL;
91 crypto_free_shash(server->secmech.hmacsha256);
92 server->secmech.hmacsha256 = NULL;
ba482029
JL
93 rc = PTR_ERR(server->secmech.cmacaes);
94 server->secmech.cmacaes = NULL;
95 return rc;
95dc8dd1
SF
96 }
97
98 size = sizeof(struct shash_desc) +
99 crypto_shash_descsize(server->secmech.cmacaes);
100 server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL);
101 if (!server->secmech.sdesccmacaes) {
102 cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__);
103 kfree(server->secmech.sdeschmacsha256);
104 server->secmech.sdeschmacsha256 = NULL;
105 crypto_free_shash(server->secmech.hmacsha256);
106 crypto_free_shash(server->secmech.cmacaes);
107 server->secmech.hmacsha256 = NULL;
108 server->secmech.cmacaes = NULL;
109 return -ENOMEM;
110 }
111 server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes;
112 server->secmech.sdesccmacaes->shash.flags = 0x0;
113
114 return 0;
115}
116
32811d24 117static struct cifs_ses *
b6932a6a 118smb2_find_smb_ses(struct smb2_sync_hdr *shdr, struct TCP_Server_Info *server)
32811d24
SP
119{
120 struct cifs_ses *ses;
121
122 spin_lock(&cifs_tcp_ses_lock);
123 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
b6932a6a 124 if (ses->Suid != shdr->SessionId)
32811d24
SP
125 continue;
126 spin_unlock(&cifs_tcp_ses_lock);
127 return ses;
128 }
129 spin_unlock(&cifs_tcp_ses_lock);
130
131 return NULL;
132}
133
38107d45 134int
0b688cfc 135smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
3c1bf7e4 136{
16c568ef 137 int rc;
3c1bf7e4
PS
138 unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
139 unsigned char *sigptr = smb2_signature;
0b688cfc 140 struct kvec *iov = rqst->rq_iov;
27eefed6 141 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[1].iov_base;
32811d24
SP
142 struct cifs_ses *ses;
143
b6932a6a 144 ses = smb2_find_smb_ses(shdr, server);
32811d24
SP
145 if (!ses) {
146 cifs_dbg(VFS, "%s: Could not find session\n", __func__);
147 return 0;
148 }
3c1bf7e4
PS
149
150 memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
b6932a6a 151 memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
3c1bf7e4 152
95dc8dd1
SF
153 rc = smb2_crypto_shash_allocate(server);
154 if (rc) {
155 cifs_dbg(VFS, "%s: shah256 alloc failed\n", __func__);
156 return rc;
157 }
158
3c1bf7e4 159 rc = crypto_shash_setkey(server->secmech.hmacsha256,
32811d24 160 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
3c1bf7e4 161 if (rc) {
f96637be 162 cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
3c1bf7e4
PS
163 return rc;
164 }
165
166 rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
167 if (rc) {
95dc8dd1 168 cifs_dbg(VFS, "%s: Could not init sha256", __func__);
3c1bf7e4
PS
169 return rc;
170 }
171
16c568ef
AV
172 rc = __cifs_calc_signature(rqst, server, sigptr,
173 &server->secmech.sdeschmacsha256->shash);
3c1bf7e4 174
16c568ef 175 if (!rc)
b6932a6a 176 memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
3c1bf7e4
PS
177
178 return rc;
179}
180
373512ec
SF
181static int generate_key(struct cifs_ses *ses, struct kvec label,
182 struct kvec context, __u8 *key, unsigned int key_size)
429b46f4
SF
183{
184 unsigned char zero = 0x0;
185 __u8 i[4] = {0, 0, 0, 1};
186 __u8 L[4] = {0, 0, 0, 128};
187 int rc = 0;
188 unsigned char prfhash[SMB2_HMACSHA256_SIZE];
189 unsigned char *hashptr = prfhash;
190
191 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
373512ec 192 memset(key, 0x0, key_size);
429b46f4 193
32811d24 194 rc = smb3_crypto_shash_allocate(ses->server);
95dc8dd1
SF
195 if (rc) {
196 cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
197 goto smb3signkey_ret;
198 }
199
32811d24
SP
200 rc = crypto_shash_setkey(ses->server->secmech.hmacsha256,
201 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
429b46f4
SF
202 if (rc) {
203 cifs_dbg(VFS, "%s: Could not set with session key\n", __func__);
204 goto smb3signkey_ret;
205 }
206
32811d24 207 rc = crypto_shash_init(&ses->server->secmech.sdeschmacsha256->shash);
429b46f4
SF
208 if (rc) {
209 cifs_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
210 goto smb3signkey_ret;
211 }
212
32811d24 213 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
429b46f4
SF
214 i, 4);
215 if (rc) {
216 cifs_dbg(VFS, "%s: Could not update with n\n", __func__);
217 goto smb3signkey_ret;
218 }
219
32811d24 220 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
373512ec 221 label.iov_base, label.iov_len);
429b46f4
SF
222 if (rc) {
223 cifs_dbg(VFS, "%s: Could not update with label\n", __func__);
224 goto smb3signkey_ret;
225 }
226
32811d24 227 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
429b46f4
SF
228 &zero, 1);
229 if (rc) {
230 cifs_dbg(VFS, "%s: Could not update with zero\n", __func__);
231 goto smb3signkey_ret;
232 }
233
32811d24 234 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
373512ec 235 context.iov_base, context.iov_len);
429b46f4
SF
236 if (rc) {
237 cifs_dbg(VFS, "%s: Could not update with context\n", __func__);
238 goto smb3signkey_ret;
239 }
240
32811d24 241 rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
429b46f4
SF
242 L, 4);
243 if (rc) {
244 cifs_dbg(VFS, "%s: Could not update with L\n", __func__);
245 goto smb3signkey_ret;
246 }
247
32811d24 248 rc = crypto_shash_final(&ses->server->secmech.sdeschmacsha256->shash,
429b46f4
SF
249 hashptr);
250 if (rc) {
251 cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
252 goto smb3signkey_ret;
253 }
254
373512ec 255 memcpy(key, hashptr, key_size);
429b46f4
SF
256
257smb3signkey_ret:
32811d24 258 return rc;
429b46f4
SF
259}
260
373512ec
SF
261struct derivation {
262 struct kvec label;
263 struct kvec context;
264};
265
266struct derivation_triplet {
267 struct derivation signing;
268 struct derivation encryption;
269 struct derivation decryption;
270};
271
272static int
273generate_smb3signingkey(struct cifs_ses *ses,
274 const struct derivation_triplet *ptriplet)
275{
276 int rc;
277
278 rc = generate_key(ses, ptriplet->signing.label,
279 ptriplet->signing.context, ses->smb3signingkey,
280 SMB3_SIGN_KEY_SIZE);
281 if (rc)
282 return rc;
283
284 rc = generate_key(ses, ptriplet->encryption.label,
285 ptriplet->encryption.context, ses->smb3encryptionkey,
286 SMB3_SIGN_KEY_SIZE);
287 if (rc)
288 return rc;
289
290 return generate_key(ses, ptriplet->decryption.label,
291 ptriplet->decryption.context,
292 ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
293}
294
295int
296generate_smb30signingkey(struct cifs_ses *ses)
297
298{
299 struct derivation_triplet triplet;
300 struct derivation *d;
301
302 d = &triplet.signing;
303 d->label.iov_base = "SMB2AESCMAC";
304 d->label.iov_len = 12;
305 d->context.iov_base = "SmbSign";
306 d->context.iov_len = 8;
307
308 d = &triplet.encryption;
309 d->label.iov_base = "SMB2AESCCM";
310 d->label.iov_len = 11;
311 d->context.iov_base = "ServerIn ";
312 d->context.iov_len = 10;
313
314 d = &triplet.decryption;
315 d->label.iov_base = "SMB2AESCCM";
316 d->label.iov_len = 11;
317 d->context.iov_base = "ServerOut";
318 d->context.iov_len = 10;
319
320 return generate_smb3signingkey(ses, &triplet);
321}
322
323int
324generate_smb311signingkey(struct cifs_ses *ses)
325
326{
327 struct derivation_triplet triplet;
328 struct derivation *d;
329
330 d = &triplet.signing;
331 d->label.iov_base = "SMB2AESCMAC";
332 d->label.iov_len = 12;
333 d->context.iov_base = "SmbSign";
334 d->context.iov_len = 8;
335
336 d = &triplet.encryption;
337 d->label.iov_base = "SMB2AESCCM";
338 d->label.iov_len = 11;
339 d->context.iov_base = "ServerIn ";
340 d->context.iov_len = 10;
341
342 d = &triplet.decryption;
343 d->label.iov_base = "SMB2AESCCM";
344 d->label.iov_len = 11;
345 d->context.iov_base = "ServerOut";
346 d->context.iov_len = 10;
347
348 return generate_smb3signingkey(ses, &triplet);
349}
350
38107d45
SF
351int
352smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
353{
32811d24 354 int rc = 0;
429b46f4
SF
355 unsigned char smb3_signature[SMB2_CMACAES_SIZE];
356 unsigned char *sigptr = smb3_signature;
357 struct kvec *iov = rqst->rq_iov;
27eefed6 358 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[1].iov_base;
32811d24
SP
359 struct cifs_ses *ses;
360
b6932a6a 361 ses = smb2_find_smb_ses(shdr, server);
32811d24
SP
362 if (!ses) {
363 cifs_dbg(VFS, "%s: Could not find session\n", __func__);
364 return 0;
365 }
429b46f4
SF
366
367 memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
b6932a6a 368 memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
429b46f4
SF
369
370 rc = crypto_shash_setkey(server->secmech.cmacaes,
32811d24
SP
371 ses->smb3signingkey, SMB2_CMACAES_SIZE);
372
429b46f4
SF
373 if (rc) {
374 cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
375 return rc;
376 }
377
95dc8dd1
SF
378 /*
379 * we already allocate sdesccmacaes when we init smb3 signing key,
380 * so unlike smb2 case we do not have to check here if secmech are
381 * initialized
382 */
429b46f4
SF
383 rc = crypto_shash_init(&server->secmech.sdesccmacaes->shash);
384 if (rc) {
385 cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
386 return rc;
387 }
16c568ef
AV
388
389 rc = __cifs_calc_signature(rqst, server, sigptr,
390 &server->secmech.sdesccmacaes->shash);
429b46f4 391
16c568ef 392 if (!rc)
b6932a6a 393 memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
429b46f4
SF
394
395 return rc;
38107d45
SF
396}
397
3c1bf7e4
PS
398/* must be called with server->srv_mutex held */
399static int
0b688cfc 400smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
3c1bf7e4
PS
401{
402 int rc = 0;
27eefed6
PS
403 struct smb2_sync_hdr *shdr =
404 (struct smb2_sync_hdr *)rqst->rq_iov[1].iov_base;
3c1bf7e4 405
b6932a6a 406 if (!(shdr->Flags & SMB2_FLAGS_SIGNED) ||
3c1bf7e4
PS
407 server->tcpStatus == CifsNeedNegotiate)
408 return rc;
409
410 if (!server->session_estab) {
b6932a6a 411 strncpy(shdr->Signature, "BSRSPYL", 8);
3c1bf7e4
PS
412 return rc;
413 }
414
38107d45 415 rc = server->ops->calc_signature(rqst, server);
3c1bf7e4
PS
416
417 return rc;
418}
419
420int
0b688cfc 421smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
3c1bf7e4
PS
422{
423 unsigned int rc;
424 char server_response_sig[16];
27eefed6
PS
425 struct smb2_sync_hdr *shdr =
426 (struct smb2_sync_hdr *)rqst->rq_iov[1].iov_base;
3c1bf7e4 427
b6932a6a
PS
428 if ((shdr->Command == SMB2_NEGOTIATE) ||
429 (shdr->Command == SMB2_SESSION_SETUP) ||
430 (shdr->Command == SMB2_OPLOCK_BREAK) ||
3c1bf7e4
PS
431 (!server->session_estab))
432 return 0;
433
434 /*
435 * BB what if signatures are supposed to be on for session but
436 * server does not send one? BB
437 */
438
439 /* Do not need to verify session setups with signature "BSRSPYL " */
b6932a6a 440 if (memcmp(shdr->Signature, "BSRSPYL ", 8) == 0)
f96637be 441 cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
b6932a6a 442 shdr->Command);
3c1bf7e4
PS
443
444 /*
445 * Save off the origiginal signature so we can modify the smb and check
446 * our calculated signature against what the server sent.
447 */
b6932a6a 448 memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
3c1bf7e4 449
b6932a6a 450 memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
3c1bf7e4
PS
451
452 mutex_lock(&server->srv_mutex);
38107d45 453 rc = server->ops->calc_signature(rqst, server);
3c1bf7e4
PS
454 mutex_unlock(&server->srv_mutex);
455
456 if (rc)
457 return rc;
458
b6932a6a 459 if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE))
3c1bf7e4
PS
460 return -EACCES;
461 else
462 return 0;
463}
464
2dc7e1c0
PS
465/*
466 * Set message id for the request. Should be called after wait_for_free_request
467 * and when srv_mutex is held.
468 */
469static inline void
b6932a6a
PS
470smb2_seq_num_into_buf(struct TCP_Server_Info *server,
471 struct smb2_sync_hdr *shdr)
2dc7e1c0 472{
b6932a6a 473 unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
cb7e9eab 474
b6932a6a 475 shdr->MessageId = get_next_mid64(server);
cb7e9eab
PS
476 /* skip message numbers according to CreditCharge field */
477 for (i = 1; i < num; i++)
478 get_next_mid(server);
2dc7e1c0
PS
479}
480
481static struct mid_q_entry *
b6932a6a 482smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
2dc7e1c0
PS
483 struct TCP_Server_Info *server)
484{
485 struct mid_q_entry *temp;
486
487 if (server == NULL) {
f96637be 488 cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
2dc7e1c0
PS
489 return NULL;
490 }
491
492 temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
493 if (temp == NULL)
494 return temp;
495 else {
496 memset(temp, 0, sizeof(struct mid_q_entry));
b6932a6a 497 temp->mid = le64_to_cpu(shdr->MessageId);
2dc7e1c0 498 temp->pid = current->pid;
b6932a6a 499 temp->command = shdr->Command; /* Always LE */
2dc7e1c0
PS
500 temp->when_alloc = jiffies;
501 temp->server = server;
502
503 /*
504 * The default is for the mid to be synchronous, so the
505 * default callback just wakes up the current task.
506 */
507 temp->callback = cifs_wake_up_task;
508 temp->callback_data = current;
509 }
510
511 atomic_inc(&midCount);
512 temp->mid_state = MID_REQUEST_ALLOCATED;
513 return temp;
514}
515
516static int
b6932a6a 517smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_sync_hdr *shdr,
2dc7e1c0
PS
518 struct mid_q_entry **mid)
519{
520 if (ses->server->tcpStatus == CifsExiting)
521 return -ENOENT;
522
523 if (ses->server->tcpStatus == CifsNeedReconnect) {
f96637be 524 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
2dc7e1c0
PS
525 return -EAGAIN;
526 }
527
7f48558e 528 if (ses->status == CifsNew) {
b6932a6a
PS
529 if ((shdr->Command != SMB2_SESSION_SETUP) &&
530 (shdr->Command != SMB2_NEGOTIATE))
2dc7e1c0
PS
531 return -EAGAIN;
532 /* else ok - we are setting up session */
533 }
7f48558e
SP
534
535 if (ses->status == CifsExiting) {
b6932a6a 536 if (shdr->Command != SMB2_LOGOFF)
7f48558e
SP
537 return -EAGAIN;
538 /* else ok - we are shutting down the session */
539 }
540
b6932a6a 541 *mid = smb2_mid_entry_alloc(shdr, ses->server);
2dc7e1c0
PS
542 if (*mid == NULL)
543 return -ENOMEM;
544 spin_lock(&GlobalMid_Lock);
545 list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
546 spin_unlock(&GlobalMid_Lock);
547 return 0;
548}
549
550int
551smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
552 bool log_error)
553{
554 unsigned int len = get_rfc1002_length(mid->resp_buf);
27eefed6
PS
555 struct kvec iov[2];
556 struct smb_rqst rqst = { .rq_iov = iov,
557 .rq_nvec = 2 };
0b688cfc 558
27eefed6
PS
559 iov[0].iov_base = (char *)mid->resp_buf;
560 iov[0].iov_len = 4;
561 iov[1].iov_base = (char *)mid->resp_buf + 4;
562 iov[1].iov_len = len;
2dc7e1c0
PS
563
564 dump_smb(mid->resp_buf, min_t(u32, 80, len));
565 /* convert the length into a more usable form */
38d77c50 566 if (len > 24 && server->sign) {
3c1bf7e4
PS
567 int rc;
568
0b688cfc 569 rc = smb2_verify_signature(&rqst, server);
3c1bf7e4 570 if (rc)
f96637be
JP
571 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
572 rc);
3c1bf7e4 573 }
2dc7e1c0
PS
574
575 return map_smb2_to_linux_error(mid->resp_buf, log_error);
576}
577
fec344e3
JL
578struct mid_q_entry *
579smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
2dc7e1c0
PS
580{
581 int rc;
27eefed6
PS
582 struct smb2_sync_hdr *shdr =
583 (struct smb2_sync_hdr *)rqst->rq_iov[1].iov_base;
2dc7e1c0
PS
584 struct mid_q_entry *mid;
585
b6932a6a 586 smb2_seq_num_into_buf(ses->server, shdr);
2dc7e1c0 587
b6932a6a 588 rc = smb2_get_mid_entry(ses, shdr, &mid);
2dc7e1c0 589 if (rc)
fec344e3
JL
590 return ERR_PTR(rc);
591 rc = smb2_sign_rqst(rqst, ses->server);
592 if (rc) {
3c1bf7e4 593 cifs_delete_mid(mid);
fec344e3
JL
594 return ERR_PTR(rc);
595 }
596 return mid;
2dc7e1c0
PS
597}
598
fec344e3
JL
599struct mid_q_entry *
600smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
c95b8eed 601{
fec344e3 602 int rc;
27eefed6
PS
603 struct smb2_sync_hdr *shdr =
604 (struct smb2_sync_hdr *)rqst->rq_iov[1].iov_base;
c95b8eed
PS
605 struct mid_q_entry *mid;
606
b6932a6a 607 smb2_seq_num_into_buf(server, shdr);
c95b8eed 608
b6932a6a 609 mid = smb2_mid_entry_alloc(shdr, server);
c95b8eed 610 if (mid == NULL)
fec344e3 611 return ERR_PTR(-ENOMEM);
c95b8eed 612
fec344e3 613 rc = smb2_sign_rqst(rqst, server);
c95b8eed
PS
614 if (rc) {
615 DeleteMidQEntry(mid);
fec344e3 616 return ERR_PTR(rc);
3c1bf7e4
PS
617 }
618
fec344e3 619 return mid;
c95b8eed 620}