Print this page
NEX-15580 SMB tree connect leaks memory
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15580 SMB tree connect leaks memory
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-1643 dtrace provider for smbsrv
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-6041 Should pass the smbtorture lock tests
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-4473 SMB1 tree connect missing some features
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
SMB-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients

@@ -18,11 +18,11 @@
  *
  * CDDL HEADER END
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
  */
 
 #include <smbsrv/smb_kproto.h>
 #include <smbsrv/smb_share.h>
 

@@ -98,20 +98,19 @@
             &tcon->password, &tcon->service);
 
         tcon->flags = 0;
         tcon->optional_support = 0;
 
-        DTRACE_SMB_2(op__TreeConnect__start, smb_request_t *, sr,
-            smb_arg_tcon_t *, tcon);
+        DTRACE_SMB_START(op__TreeConnect, smb_request_t *, sr);
 
         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 }
 
 void
 smb_post_tree_connect(smb_request_t *sr)
 {
-        DTRACE_SMB_1(op__TreeConnect__done, smb_request_t *, sr);
+        DTRACE_SMB_DONE(op__TreeConnect, smb_request_t *, sr);
 }
 
 smb_sdrc_t
 smb_com_tree_connect(smb_request_t *sr)
 {

@@ -289,37 +288,46 @@
                 tcon->password = (char *)pwbuf;
         }
 
         tcon->optional_support = 0;
 
-        DTRACE_SMB_2(op__TreeConnectX__start, smb_request_t *, sr,
-            smb_arg_tcon_t *, tcon);
+        DTRACE_SMB_START(op__TreeConnectX, smb_request_t *, sr);
 
         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 }
 
 void
 smb_post_tree_connect_andx(smb_request_t *sr)
 {
-        DTRACE_SMB_1(op__TreeConnectX__done, smb_request_t *, sr);
+        DTRACE_SMB_DONE(op__TreeConnectX, smb_request_t *, sr);
 }
 
 smb_sdrc_t
 smb_com_tree_connect_andx(smb_request_t *sr)
 {
         smb_arg_tcon_t  *tcon = &sr->sr_tcon;
+        smb_tree_t      *tree;
         char            *service;
         uint32_t        status;
         int             rc;
 
+        if (tcon->flags & SMB_TCONX_DISCONECT_TID) {
+                tree = smb_session_lookup_tree(sr->session, sr->smb_tid);
+                if (tree != NULL) {
+                        smb_tree_disconnect(tree, B_TRUE);
+                        smb_session_cancel_requests(sr->session, tree, sr);
+                }
+        }
+
         status = smb_tree_connect(sr);
         if (status) {
                 smb_tcon_puterror(sr, status);
                 return (SDRC_ERROR);
         }
+        tree = sr->tid_tree;
 
-        switch (sr->tid_tree->t_res_type & STYPE_MASK) {
+        switch (tree->t_res_type & STYPE_MASK) {
         case STYPE_IPC:
                 service = "IPC";
                 break;
         case STYPE_PRINTQ:
                 service = "LPT1:";

@@ -328,27 +336,41 @@
         default:
                 service = "A:";
         }
 
         if (sr->session->dialect < NT_LM_0_12) {
-                rc = smbsr_encode_result(sr, 2, VAR_BCC, "bb.wwss",
+                rc = smbsr_encode_result(sr, 2, VAR_BCC, "bb.ww%ss",
                     (char)2,            /* wct */
                     sr->andx_com,
                     VAR_BCC,
                     VAR_BCC,
+                    sr,
                     service,
-                    sr->tid_tree->t_typename);
-        } else {
-                rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.wwws%u",
+                    tree->t_typename);
+        } else if ((tcon->flags & SMB_TCONX_EXTENDED_RESPONSE) == 0) {
+                rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%su",
                     (char)3,            /* wct */
                     sr->andx_com,
                     (short)64,
                     tcon->optional_support,
                     VAR_BCC,
-                    service,
                     sr,
-                    sr->tid_tree->t_typename);
+                    service,
+                    tree->t_typename);
+
+        } else {
+                rc = smbsr_encode_result(sr, 7, VAR_BCC, "bb.wwllw%su",
+                    (char)7,            /* wct (b) */
+                    sr->andx_com,       /* AndXcmd (b) */
+                    (short)72,          /* AndXoff (w) */
+                    tcon->optional_support,     /* (w) */
+                    tree->t_access,             /* (l) */
+                    0,          /*    guest_access (l) */
+                    VAR_BCC,            /* (w) */
+                    sr,                 /* (%) */
+                    service,            /* (s) */
+                    tree->t_typename);  /* (u) */
         }
 
         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 }
 

@@ -390,18 +412,18 @@
 smb_pre_tree_disconnect(smb_request_t *sr)
 {
         sr->uid_user = smb_session_lookup_uid(sr->session, sr->smb_uid);
         sr->tid_tree = smb_session_lookup_tree(sr->session, sr->smb_tid);
 
-        DTRACE_SMB_1(op__TreeDisconnect__start, smb_request_t *, sr);
+        DTRACE_SMB_START(op__TreeDisconnect, smb_request_t *, sr);
         return (SDRC_SUCCESS);
 }
 
 void
 smb_post_tree_disconnect(smb_request_t *sr)
 {
-        DTRACE_SMB_1(op__TreeDisconnect__done, smb_request_t *, sr);
+        DTRACE_SMB_DONE(op__TreeDisconnect, smb_request_t *, sr);
 }
 
 /*
  * SmbTreeDisconnect requires a valid UID as well as a valid TID.  Some
  * clients logoff a user and then try to disconnect the trees connected

@@ -421,12 +443,12 @@
                 return (SDRC_ERROR);
         }
 
         sr->user_cr = smb_user_getcred(sr->uid_user);
 
-        smb_session_cancel_requests(sr->session, sr->tid_tree, sr);
         smb_tree_disconnect(sr->tid_tree, B_TRUE);
+        smb_session_cancel_requests(sr->session, sr->tid_tree, sr);
 
         if (smbsr_encode_empty_result(sr))
                 return (SDRC_ERROR);
 
         return (SDRC_SUCCESS);