@@ -283,20 +283,121 @@ static int ksmbd_negotiate_smb_dialect(void *buf)
283
283
return BAD_PROT_ID ;
284
284
}
285
285
286
- int ksmbd_init_smb_server (struct ksmbd_work * work )
286
+ #define SMB_COM_NEGOTIATE_EX 0x0
287
+
288
+ /**
289
+ * get_smb1_cmd_val() - get smb command value from smb header
290
+ * @work: smb work containing smb header
291
+ *
292
+ * Return: smb command value
293
+ */
294
+ static u16 get_smb1_cmd_val (struct ksmbd_work * work )
287
295
{
288
- struct ksmbd_conn * conn = work -> conn ;
296
+ return SMB_COM_NEGOTIATE_EX ;
297
+ }
289
298
290
- if (conn -> need_neg == false)
299
+ /**
300
+ * init_smb1_rsp_hdr() - initialize smb negotiate response header
301
+ * @work: smb work containing smb request
302
+ *
303
+ * Return: 0 on success, otherwise -EINVAL
304
+ */
305
+ static int init_smb1_rsp_hdr (struct ksmbd_work * work )
306
+ {
307
+ struct smb_hdr * rsp_hdr = (struct smb_hdr * )work -> response_buf ;
308
+ struct smb_hdr * rcv_hdr = (struct smb_hdr * )work -> request_buf ;
309
+
310
+ /*
311
+ * Remove 4 byte direct TCP header.
312
+ */
313
+ * (__be32 * )work -> response_buf =
314
+ cpu_to_be32 (sizeof (struct smb_hdr ) - 4 );
315
+
316
+ rsp_hdr -> Command = SMB_COM_NEGOTIATE ;
317
+ * (__le32 * )rsp_hdr -> Protocol = SMB1_PROTO_NUMBER ;
318
+ rsp_hdr -> Flags = SMBFLG_RESPONSE ;
319
+ rsp_hdr -> Flags2 = SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS |
320
+ SMBFLG2_EXT_SEC | SMBFLG2_IS_LONG_NAME ;
321
+ rsp_hdr -> Pid = rcv_hdr -> Pid ;
322
+ rsp_hdr -> Mid = rcv_hdr -> Mid ;
323
+ return 0 ;
324
+ }
325
+
326
+ /**
327
+ * smb1_check_user_session() - check for valid session for a user
328
+ * @work: smb work containing smb request buffer
329
+ *
330
+ * Return: 0 on success, otherwise error
331
+ */
332
+ static int smb1_check_user_session (struct ksmbd_work * work )
333
+ {
334
+ unsigned int cmd = work -> conn -> ops -> get_cmd_val (work );
335
+
336
+ if (cmd == SMB_COM_NEGOTIATE_EX )
291
337
return 0 ;
292
338
293
- init_smb3_11_server (conn );
339
+ return - EINVAL ;
340
+ }
341
+
342
+ /**
343
+ * smb1_allocate_rsp_buf() - allocate response buffer for a command
344
+ * @work: smb work containing smb request
345
+ *
346
+ * Return: 0 on success, otherwise -ENOMEM
347
+ */
348
+ static int smb1_allocate_rsp_buf (struct ksmbd_work * work )
349
+ {
350
+ work -> response_buf = kmalloc (MAX_CIFS_SMALL_BUFFER_SIZE ,
351
+ GFP_KERNEL | __GFP_ZERO );
352
+ work -> response_sz = MAX_CIFS_SMALL_BUFFER_SIZE ;
353
+
354
+ if (!work -> response_buf ) {
355
+ pr_err ("Failed to allocate %u bytes buffer\n" ,
356
+ MAX_CIFS_SMALL_BUFFER_SIZE );
357
+ return - ENOMEM ;
358
+ }
294
359
295
- if (conn -> ops -> get_cmd_val (work ) != SMB_COM_NEGOTIATE )
296
- conn -> need_neg = false;
297
360
return 0 ;
298
361
}
299
362
363
+ static struct smb_version_ops smb1_server_ops = {
364
+ .get_cmd_val = get_smb1_cmd_val ,
365
+ .init_rsp_hdr = init_smb1_rsp_hdr ,
366
+ .allocate_rsp_buf = smb1_allocate_rsp_buf ,
367
+ .check_user_session = smb1_check_user_session ,
368
+ };
369
+
370
+ static int smb1_negotiate (struct ksmbd_work * work )
371
+ {
372
+ return ksmbd_smb_negotiate_common (work , SMB_COM_NEGOTIATE );
373
+ }
374
+
375
+ static struct smb_version_cmds smb1_server_cmds [1 ] = {
376
+ [SMB_COM_NEGOTIATE_EX ] = { .proc = smb1_negotiate , },
377
+ };
378
+
379
+ static void init_smb1_server (struct ksmbd_conn * conn )
380
+ {
381
+ conn -> ops = & smb1_server_ops ;
382
+ conn -> cmds = smb1_server_cmds ;
383
+ conn -> max_cmds = ARRAY_SIZE (smb1_server_cmds );
384
+ }
385
+
386
+ void ksmbd_init_smb_server (struct ksmbd_work * work )
387
+ {
388
+ struct ksmbd_conn * conn = work -> conn ;
389
+ __le32 proto ;
390
+
391
+ if (conn -> need_neg == false)
392
+ return ;
393
+
394
+ proto = * (__le32 * )((struct smb_hdr * )work -> request_buf )-> Protocol ;
395
+ if (proto == SMB1_PROTO_NUMBER )
396
+ init_smb1_server (conn );
397
+ else
398
+ init_smb3_11_server (conn );
399
+ }
400
+
300
401
int ksmbd_populate_dot_dotdot_entries (struct ksmbd_work * work , int info_level ,
301
402
struct ksmbd_file * dir ,
302
403
struct ksmbd_dir_info * d_info ,
@@ -444,20 +545,10 @@ static int smb_handle_negotiate(struct ksmbd_work *work)
444
545
445
546
ksmbd_debug (SMB , "Unsupported SMB1 protocol\n" );
446
547
447
- /*
448
- * Remove 4 byte direct TCP header, add 2 byte bcc and
449
- * 2 byte DialectIndex.
450
- */
451
- * (__be32 * )work -> response_buf =
452
- cpu_to_be32 (sizeof (struct smb_hdr ) - 4 + 2 + 2 );
548
+ /* Add 2 byte bcc and 2 byte DialectIndex. */
549
+ inc_rfc1001_len (work -> response_buf , 4 );
453
550
neg_rsp -> hdr .Status .CifsError = STATUS_SUCCESS ;
454
551
455
- neg_rsp -> hdr .Command = SMB_COM_NEGOTIATE ;
456
- * (__le32 * )neg_rsp -> hdr .Protocol = SMB1_PROTO_NUMBER ;
457
- neg_rsp -> hdr .Flags = SMBFLG_RESPONSE ;
458
- neg_rsp -> hdr .Flags2 = SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS |
459
- SMBFLG2_EXT_SEC | SMBFLG2_IS_LONG_NAME ;
460
-
461
552
neg_rsp -> hdr .WordCount = 1 ;
462
553
neg_rsp -> DialectIndex = cpu_to_le16 (work -> conn -> dialect );
463
554
neg_rsp -> ByteCount = 0 ;
@@ -473,24 +564,13 @@ int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command)
473
564
ksmbd_negotiate_smb_dialect (work -> request_buf );
474
565
ksmbd_debug (SMB , "conn->dialect 0x%x\n" , conn -> dialect );
475
566
476
- if (command == SMB2_NEGOTIATE_HE ) {
477
- struct smb2_hdr * smb2_hdr = smb2_get_msg (work -> request_buf );
478
-
479
- if (smb2_hdr -> ProtocolId != SMB2_PROTO_NUMBER ) {
480
- ksmbd_debug (SMB , "Downgrade to SMB1 negotiation\n" );
481
- command = SMB_COM_NEGOTIATE ;
482
- }
483
- }
484
-
485
567
if (command == SMB2_NEGOTIATE_HE ) {
486
568
ret = smb2_handle_negotiate (work );
487
- init_smb2_neg_rsp (work );
488
569
return ret ;
489
570
}
490
571
491
572
if (command == SMB_COM_NEGOTIATE ) {
492
573
if (__smb2_negotiate (conn )) {
493
- conn -> need_neg = true;
494
574
init_smb3_11_server (conn );
495
575
init_smb2_neg_rsp (work );
496
576
ksmbd_debug (SMB , "Upgrade to SMB2 negotiation\n" );
0 commit comments