@@ -283,20 +283,121 @@ static int ksmbd_negotiate_smb_dialect(void *buf)
283283 return BAD_PROT_ID ;
284284}
285285
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 )
287295{
288- struct ksmbd_conn * conn = work -> conn ;
296+ return SMB_COM_NEGOTIATE_EX ;
297+ }
289298
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 )
291337 return 0 ;
292338
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+ }
294359
295- if (conn -> ops -> get_cmd_val (work ) != SMB_COM_NEGOTIATE )
296- conn -> need_neg = false;
297360 return 0 ;
298361}
299362
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+
300401int ksmbd_populate_dot_dotdot_entries (struct ksmbd_work * work , int info_level ,
301402 struct ksmbd_file * dir ,
302403 struct ksmbd_dir_info * d_info ,
@@ -444,20 +545,10 @@ static int smb_handle_negotiate(struct ksmbd_work *work)
444545
445546 ksmbd_debug (SMB , "Unsupported SMB1 protocol\n" );
446547
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 );
453550 neg_rsp -> hdr .Status .CifsError = STATUS_SUCCESS ;
454551
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-
461552 neg_rsp -> hdr .WordCount = 1 ;
462553 neg_rsp -> DialectIndex = cpu_to_le16 (work -> conn -> dialect );
463554 neg_rsp -> ByteCount = 0 ;
@@ -473,24 +564,13 @@ int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command)
473564 ksmbd_negotiate_smb_dialect (work -> request_buf );
474565 ksmbd_debug (SMB , "conn->dialect 0x%x\n" , conn -> dialect );
475566
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-
485567 if (command == SMB2_NEGOTIATE_HE ) {
486568 ret = smb2_handle_negotiate (work );
487- init_smb2_neg_rsp (work );
488569 return ret ;
489570 }
490571
491572 if (command == SMB_COM_NEGOTIATE ) {
492573 if (__smb2_negotiate (conn )) {
493- conn -> need_neg = true;
494574 init_smb3_11_server (conn );
495575 init_smb2_neg_rsp (work );
496576 ksmbd_debug (SMB , "Upgrade to SMB2 negotiation\n" );
0 commit comments