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
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
       23 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
  24   24   */
  25   25  
  26   26  #include <smbsrv/smb_kproto.h>
  27   27  #include <smbsrv/smb_share.h>
  28   28  
  29   29  static void
  30   30  smb_tcon_puterror(smb_request_t *sr, uint32_t status)
  31   31  {
  32   32  
  33   33          switch (status) {
  34   34  
  35   35          case NT_STATUS_BAD_NETWORK_NAME:
  36   36                  /* Intentional status=0 */
  37   37                  smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
  38   38                  break;
  39   39  
  40   40          case NT_STATUS_ACCESS_DENIED:
  41   41                  smbsr_error(sr, status, ERRSRV, ERRaccess);
  42   42                  break;
  43   43  
  44   44          case NT_STATUS_BAD_DEVICE_TYPE:
  45   45                  smbsr_error(sr, status, ERRDOS, ERROR_BAD_DEV_TYPE);
  46   46                  break;
  47   47  
  48   48          default:
  49   49          case NT_STATUS_INTERNAL_ERROR:
  50   50                  /* Intentional status=0 */
  51   51                  smbsr_error(sr, 0, ERRSRV, ERRsrverror);
  52   52                  break;
  53   53          }
  54   54  }
  55   55  
  56   56  /*
  57   57   * SmbTreeConnect: Map a share to a tree and obtain a tree-id (TID).
  58   58   *
  59   59   * Client Request                     Description
  60   60   * ================================== =================================
  61   61   *
  62   62   * UCHAR WordCount;                   Count of parameter words = 0
  63   63   * USHORT ByteCount;                  Count of data bytes;    min = 4
  64   64   * UCHAR BufferFormat1;               0x04
  65   65   * STRING Path[];                     Server name and share name
  66   66   * UCHAR BufferFormat2;               0x04
  67   67   * STRING Password[];                 Password
  68   68   * UCHAR BufferFormat3;               0x04
  69   69   * STRING Service[];                  Service name
  70   70   *
  71   71   * The CIFS server responds with:
  72   72   *
  73   73   * Server Response                  Description
  74   74   * ================================ =================================
  75   75   *
  76   76   * UCHAR WordCount;                 Count of parameter words = 2
  77   77   * USHORT MaxBufferSize;            Max size message the server handles
  78   78   * USHORT Tid;                      Tree ID
  79   79   * USHORT ByteCount;                Count of data bytes = 0
  80   80   *
  81   81   * If the negotiated dialect is MICROSOFT NETWORKS 1.03 or earlier,
  82   82   * MaxBufferSize in the response message indicates the maximum size
  83   83   * message that the server can handle.  The client should not generate
  84   84   * messages, nor expect to receive responses, larger than this.  This
  85   85   * must be constant for a given server. For newer dialects, this field
  86   86   * is ignored.
  87   87   */
  88   88  smb_sdrc_t
  89   89  smb_pre_tree_connect(smb_request_t *sr)
  90   90  {
  91   91          smb_arg_tcon_t  *tcon = &sr->sr_tcon;
  92   92          int             rc;
  
    | 
      ↓ open down ↓ | 
    59 lines elided | 
    
      ↑ open up ↑ | 
  
  93   93  
  94   94          /*
  95   95           * Perhaps this should be "%A.sA" now that unicode is enabled.
  96   96           */
  97   97          rc = smbsr_decode_data(sr, "%AAA", sr, &tcon->path,
  98   98              &tcon->password, &tcon->service);
  99   99  
 100  100          tcon->flags = 0;
 101  101          tcon->optional_support = 0;
 102  102  
 103      -        DTRACE_SMB_2(op__TreeConnect__start, smb_request_t *, sr,
 104      -            smb_arg_tcon_t *, tcon);
      103 +        DTRACE_SMB_START(op__TreeConnect, smb_request_t *, sr);
 105  104  
 106  105          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 107  106  }
 108  107  
 109  108  void
 110  109  smb_post_tree_connect(smb_request_t *sr)
 111  110  {
 112      -        DTRACE_SMB_1(op__TreeConnect__done, smb_request_t *, sr);
      111 +        DTRACE_SMB_DONE(op__TreeConnect, smb_request_t *, sr);
 113  112  }
 114  113  
 115  114  smb_sdrc_t
 116  115  smb_com_tree_connect(smb_request_t *sr)
 117  116  {
 118  117          uint32_t status;
 119  118          int rc;
 120  119  
 121  120          status = smb_tree_connect(sr);
 122  121          if (status) {
 123  122                  smb_tcon_puterror(sr, status);
 124  123                  return (SDRC_ERROR);
 125  124          }
 126  125  
 127  126          rc = smbsr_encode_result(sr, 2, 0, "bwww",
 128  127              2,                          /* wct */
 129  128              (WORD)smb_maxbufsize,       /* MaxBufferSize */
 130  129              sr->smb_tid,                /* TID */
 131  130              0);                         /* bcc */
 132  131  
 133  132          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 134  133  }
 135  134  
 136  135  /*
 137  136   * SmbTreeConnectX: Map a share to a tree and obtain a tree-id (TID).
 138  137   *
 139  138   * Client Request                     Description
 140  139   * =================================  =================================
 141  140   *
 142  141   * UCHAR WordCount;                   Count of parameter words = 4
 143  142   * UCHAR AndXCommand;                 Secondary (X) command; 0xFF = none
 144  143   * UCHAR AndXReserved;                Reserved (must be 0)
 145  144   * USHORT AndXOffset;                 Offset to next command WordCount
 146  145   * USHORT Flags;                      Additional information
 147  146   *                                    bit 0 set = disconnect Tid
 148  147   * USHORT PasswordLength;             Length of Password[]
 149  148   * USHORT ByteCount;                  Count of data bytes;    min = 3
 150  149   * UCHAR Password[];                  Password
 151  150   * STRING Path[];                     Server name and share name
 152  151   * STRING Service[];                  Service name
 153  152   *
 154  153   * If the negotiated dialect is LANMAN1.0 or later, then it is a protocol
 155  154   * violation for the client to send this message prior to a successful
 156  155   * SMB_COM_SESSION_SETUP_ANDX, and the server ignores Password.
 157  156   *
 158  157   * If the negotiated dialect is prior to LANMAN1.0 and the client has not
 159  158   * sent a successful SMB_COM_SESSION_SETUP_ANDX request when the tree
 160  159   * connect arrives, a user level security mode server must nevertheless
 161  160   * validate the client's credentials.
 162  161   *
 163  162   * Flags (prefix with TREE_CONNECT_ANDX_):
 164  163   * ==========================  ========================================
 165  164   * 0x0001 DISCONECT_TID        The tree specified by TID in the SMB header
 166  165   *                             should be disconnected - disconnect errors
 167  166   *                             should be ignored.
 168  167   *
 169  168   * 0x0004 EXTENDED_SIGNATURES  Client request for signing key protection.
 170  169   *
 171  170   * 0x0008 EXTENDED_RESPONSE    Client request for extended information.
 172  171   *
 173  172   * Path follows UNC style syntax (\\server\share) and indicates the name
 174  173   * of the resource to which the client wishes to connect.
 175  174   *
 176  175   * Because Password may be an authentication response, it is a variable
 177  176   * length field with the length specified by PasswordLength.   If
 178  177   * authentication is not being used, Password should be a null terminated
 179  178   * ASCII string with PasswordLength set to the string size including the
 180  179   * terminating null.
 181  180   *
 182  181   * The server can enforce whatever policy it desires to govern share
 183  182   * access.  Administrative privilege is required for administrative
 184  183   * shares (C$, etc.).
 185  184   *
 186  185   * The Service component indicates the type of resource the client
 187  186   * intends to access.  Valid values are:
 188  187   *
 189  188   * Service   Description               Earliest Dialect Allowed
 190  189   * ========  ========================  ================================
 191  190   *
 192  191   * A:        disk share                PC NETWORK PROGRAM 1.0
 193  192   * LPT1:     printer                   PC NETWORK PROGRAM 1.0
 194  193   * IPC       named pipe                MICROSOFT NETWORKS 3.0
 195  194   * COMM      communications device     MICROSOFT NETWORKS 3.0
 196  195   * ?????     any type of device        MICROSOFT NETWORKS 3.0
 197  196   *
 198  197   * If the negotiated dialect is earlier than DOS LANMAN2.1, the response to
 199  198   * this SMB is:
 200  199   *
 201  200   * Server Response                  Description
 202  201   * ================================ ===================================
 203  202   *
 204  203   * UCHAR WordCount;                 Count of parameter words = 2
 205  204   * UCHAR AndXCommand;               Secondary (X) command;  0xFF = none
 206  205   * UCHAR AndXReserved;              Reserved (must be 0)
 207  206   * USHORT AndXOffset;               Offset to next command WordCount
 208  207   * USHORT ByteCount;                Count of data bytes;    min = 3
 209  208   *
 210  209   * If the negotiated is DOS LANMAN2.1 or later, the response to this SMB
 211  210   * is:
 212  211   *
 213  212   * Server Response                  Description
 214  213   * ================================ ===================================
 215  214   *
 216  215   * UCHAR WordCount;                 Count of parameter words = 3
 217  216   * UCHAR AndXCommand;               Secondary (X) command;  0xFF = none
 218  217   * UCHAR AndXReserved;              Reserved (must be 0)
 219  218   * USHORT AndXOffset;               Offset to next command WordCount
 220  219   * USHORT OptionalSupport;          Optional support bits
 221  220   * USHORT ByteCount;                Count of data bytes;    min = 3
 222  221   * UCHAR Service[];                 Service type connected to.  Always
 223  222   *                                   ANSII.
 224  223   * STRING NativeFileSystem[];       Native file system for this tree
 225  224   *
 226  225   * NativeFileSystem is the name of the filesystem; values to be expected
 227  226   * include FAT, NTFS, etc.
 228  227   *
 229  228   * OptionalSupport:
 230  229   * ==============================  ==========================
 231  230   * 0x0001 SMB_SUPPORT_SEARCH_BITS  The server supports the use of Search
 232  231   *                                 Attributes in client requests.
 233  232   * 0x0002 SMB_SHARE_IS_IN_DFS      The share is managed by DFS.
 234  233   * 0x000C SMB_CSC_MASK             Offline-caching mask - see CSC flags.
 235  234   * 0x0010 SMB_UNIQUE_FILE_NAME     The server uses long names and does not
 236  235   *                                 support short names.  Indicator for
 237  236   *                                 clients directory/name-space caching.
 238  237   * 0x0020 SMB_EXTENDED_SIGNATURES  The server will use signing key protection.
 239  238   *
 240  239   * Client-side caching (offline files):
 241  240   * ==============================  ==========================
 242  241   * 0x0000 SMB_CSC_CACHE_MANUAL_REINT Clients may cache files for offline use
 243  242   *                                 but automatic file-by-file reintegration
 244  243   *                                 is not allowed.
 245  244   * 0x0004 SMB_CSC_CACHE_AUTO_REINT Automatic file-by-file reintegration is
 246  245   *                                 allowed.
 247  246   * 0x0008 SMB_CSC_CACHE_VDO        File opens do not need to be flowed.
 248  247   * 0x000C SMB_CSC_CACHE_NONE       CSC is disabled for this share.
 249  248   *
 250  249   * Some servers negotiate "DOS LANMAN2.1" dialect or later and still send
 251  250   * the "downlevel" (i.e. wordcount==2) response.  Valid AndX following
 252  251   * commands are
 253  252   *
 254  253   * SMB_COM_OPEN              SMB_COM_OPEN_ANDX          SMB_COM_CREATE
 255  254   * SMB_COM_CREATE_NEW        SMB_COM_CREATE_DIRECTORY   SMB_COM_DELETE
 256  255   * SMB_COM_DELETE_DIRECTORY  SMB_COM_FIND               SMB_COM_COPY
 257  256   * SMB_COM_FIND_UNIQUE       SMB_COM_RENAME
 258  257   * SMB_COM_CHECK_DIRECTORY   SMB_COM_QUERY_INFORMATION
 259  258   * SMB_COM_GET_PRINT_QUEUE   SMB_COM_OPEN_PRINT_FILE
 260  259   * SMB_COM_TRANSACTION       SMB_COM_NO_ANDX_CMD
 261  260   * SMB_COM_SET_INFORMATION   SMB_COM_NT_RENAME
 262  261   *
 263  262   * Errors:
 264  263   * ERRDOS/ERRnomem
 265  264   * ERRDOS/ERRbadpath
 266  265   * ERRDOS/ERRinvdevice
 267  266   * ERRSRV/ERRaccess
 268  267   * ERRSRV/ERRbadpw
 269  268   * ERRSRV/ERRinvnetname
 270  269   */
 271  270  smb_sdrc_t
 272  271  smb_pre_tree_connect_andx(smb_request_t *sr)
 273  272  {
 274  273          smb_arg_tcon_t  *tcon = &sr->sr_tcon;
 275  274          uint8_t         *pwbuf = NULL;
 276  275          uint16_t        pwlen = 0;
 277  276          int             rc;
 278  277  
 279  278          rc = smbsr_decode_vwv(sr, "b.www", &sr->andx_com, &sr->andx_off,
 280  279              &tcon->flags, &pwlen);
 281  280          if (rc == 0) {
 282  281                  if (pwlen != 0)
 283  282                          pwbuf = smb_srm_zalloc(sr, pwlen);
  
    | 
      ↓ open down ↓ | 
    161 lines elided | 
    
      ↑ open up ↑ | 
  
 284  283  
 285  284                  rc = smbsr_decode_data(sr, "%#cus", sr, pwlen, pwbuf,
 286  285                      &tcon->path, &tcon->service);
 287  286  
 288  287                  tcon->pwdlen = pwlen;
 289  288                  tcon->password = (char *)pwbuf;
 290  289          }
 291  290  
 292  291          tcon->optional_support = 0;
 293  292  
 294      -        DTRACE_SMB_2(op__TreeConnectX__start, smb_request_t *, sr,
 295      -            smb_arg_tcon_t *, tcon);
      293 +        DTRACE_SMB_START(op__TreeConnectX, smb_request_t *, sr);
 296  294  
 297  295          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 298  296  }
 299  297  
 300  298  void
 301  299  smb_post_tree_connect_andx(smb_request_t *sr)
 302  300  {
 303      -        DTRACE_SMB_1(op__TreeConnectX__done, smb_request_t *, sr);
      301 +        DTRACE_SMB_DONE(op__TreeConnectX, smb_request_t *, sr);
 304  302  }
 305  303  
 306  304  smb_sdrc_t
 307  305  smb_com_tree_connect_andx(smb_request_t *sr)
 308  306  {
 309  307          smb_arg_tcon_t  *tcon = &sr->sr_tcon;
      308 +        smb_tree_t      *tree;
 310  309          char            *service;
 311  310          uint32_t        status;
 312  311          int             rc;
 313  312  
      313 +        if (tcon->flags & SMB_TCONX_DISCONECT_TID) {
      314 +                tree = smb_session_lookup_tree(sr->session, sr->smb_tid);
      315 +                if (tree != NULL) {
      316 +                        smb_tree_disconnect(tree, B_TRUE);
      317 +                        smb_session_cancel_requests(sr->session, tree, sr);
      318 +                }
      319 +        }
      320 +
 314  321          status = smb_tree_connect(sr);
 315  322          if (status) {
 316  323                  smb_tcon_puterror(sr, status);
 317  324                  return (SDRC_ERROR);
 318  325          }
      326 +        tree = sr->tid_tree;
 319  327  
 320      -        switch (sr->tid_tree->t_res_type & STYPE_MASK) {
      328 +        switch (tree->t_res_type & STYPE_MASK) {
 321  329          case STYPE_IPC:
 322  330                  service = "IPC";
 323  331                  break;
 324  332          case STYPE_PRINTQ:
 325  333                  service = "LPT1:";
 326  334                  break;
 327  335          case STYPE_DISKTREE:
 328  336          default:
 329  337                  service = "A:";
 330  338          }
 331  339  
 332  340          if (sr->session->dialect < NT_LM_0_12) {
 333      -                rc = smbsr_encode_result(sr, 2, VAR_BCC, "bb.wwss",
      341 +                rc = smbsr_encode_result(sr, 2, VAR_BCC, "bb.ww%ss",
 334  342                      (char)2,            /* wct */
 335  343                      sr->andx_com,
 336  344                      VAR_BCC,
 337  345                      VAR_BCC,
      346 +                    sr,
 338  347                      service,
 339      -                    sr->tid_tree->t_typename);
 340      -        } else {
 341      -                rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.wwws%u",
      348 +                    tree->t_typename);
      349 +        } else if ((tcon->flags & SMB_TCONX_EXTENDED_RESPONSE) == 0) {
      350 +                rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%su",
 342  351                      (char)3,            /* wct */
 343  352                      sr->andx_com,
 344  353                      (short)64,
 345  354                      tcon->optional_support,
 346  355                      VAR_BCC,
 347      -                    service,
 348  356                      sr,
 349      -                    sr->tid_tree->t_typename);
      357 +                    service,
      358 +                    tree->t_typename);
      359 +
      360 +        } else {
      361 +                rc = smbsr_encode_result(sr, 7, VAR_BCC, "bb.wwllw%su",
      362 +                    (char)7,            /* wct (b) */
      363 +                    sr->andx_com,       /* AndXcmd (b) */
      364 +                    (short)72,          /* AndXoff (w) */
      365 +                    tcon->optional_support,     /* (w) */
      366 +                    tree->t_access,             /* (l) */
      367 +                    0,          /*    guest_access (l) */
      368 +                    VAR_BCC,            /* (w) */
      369 +                    sr,                 /* (%) */
      370 +                    service,            /* (s) */
      371 +                    tree->t_typename);  /* (u) */
 350  372          }
 351  373  
 352  374          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 353  375  }
 354  376  
 355  377  /*
 356  378   * SmbTreeDisconnect: Disconnect a tree.
 357  379   *
 358  380   * Note: SDDF_SUPPRESS_UID is set for this operation, which means the sr
 359  381   * uid_user field will not be valid on entry to these functions.  Do not
 360  382   * use it until it is set up in smb_com_tree_disconnect() or the system
 361  383   * will panic.
 362  384   *
 363  385   * Note: there are scenarios in which the client does not send a tree
 364  386   * disconnect request, for example, when ERRbaduid is returned from
 365  387   * SmbReadX after a user has logged off.  Any open files will remain
 366  388   * around until the session is destroyed.
 367  389   *
 368  390   * Client Request                     Description
 369  391   * ================================== =================================
 370  392   *
 371  393   * UCHAR WordCount;                   Count of parameter words = 0
 372  394   * USHORT ByteCount;                  Count of data bytes = 0
 373  395   *
 374  396   * The resource sharing connection identified by Tid in the SMB header is
 375  397   * logically disconnected from the server. Tid is invalidated; it will not
 376  398   * be recognized if used by the client for subsequent requests. All locks,
 377  399   * open files, etc. created on behalf of Tid are released.
 378  400   *
 379  401   * Server Response                    Description
 380  402   * ================================== =================================
 381  403   *
 382  404   * UCHAR WordCount;                   Count of parameter words = 0
 383  405   * USHORT ByteCount;                  Count of data bytes = 0
 384  406   *
  
    | 
      ↓ open down ↓ | 
    25 lines elided | 
    
      ↑ open up ↑ | 
  
 385  407   * Errors:
 386  408   * ERRSRV/ERRinvnid
 387  409   * ERRSRV/ERRbaduid
 388  410   */
 389  411  smb_sdrc_t
 390  412  smb_pre_tree_disconnect(smb_request_t *sr)
 391  413  {
 392  414          sr->uid_user = smb_session_lookup_uid(sr->session, sr->smb_uid);
 393  415          sr->tid_tree = smb_session_lookup_tree(sr->session, sr->smb_tid);
 394  416  
 395      -        DTRACE_SMB_1(op__TreeDisconnect__start, smb_request_t *, sr);
      417 +        DTRACE_SMB_START(op__TreeDisconnect, smb_request_t *, sr);
 396  418          return (SDRC_SUCCESS);
 397  419  }
 398  420  
 399  421  void
 400  422  smb_post_tree_disconnect(smb_request_t *sr)
 401  423  {
 402      -        DTRACE_SMB_1(op__TreeDisconnect__done, smb_request_t *, sr);
      424 +        DTRACE_SMB_DONE(op__TreeDisconnect, smb_request_t *, sr);
 403  425  }
 404  426  
 405  427  /*
 406  428   * SmbTreeDisconnect requires a valid UID as well as a valid TID.  Some
 407  429   * clients logoff a user and then try to disconnect the trees connected
 408  430   * by the user who has just been logged off, which would normally fail
 409  431   * in the dispatch code with ERRbaduid but, unfortunately, ERRbaduid
 410  432   * causes a problem for some of those clients.  Windows returns ERRinvnid.
 411  433   *
 412  434   * To prevent ERRbaduid being returned, the UID and TID are looked up here
 413  435   * rather than prior to dispatching SmbTreeDisconnect requests.  If either
 414  436   * the UID or the TID is invalid, ERRinvnid is returned.
 415  437   */
  
    | 
      ↓ open down ↓ | 
    3 lines elided | 
    
      ↑ open up ↑ | 
  
 416  438  smb_sdrc_t
 417  439  smb_com_tree_disconnect(smb_request_t *sr)
 418  440  {
 419  441          if (sr->uid_user == NULL || sr->tid_tree == NULL) {
 420  442                  smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRinvnid);
 421  443                  return (SDRC_ERROR);
 422  444          }
 423  445  
 424  446          sr->user_cr = smb_user_getcred(sr->uid_user);
 425  447  
 426      -        smb_session_cancel_requests(sr->session, sr->tid_tree, sr);
 427  448          smb_tree_disconnect(sr->tid_tree, B_TRUE);
      449 +        smb_session_cancel_requests(sr->session, sr->tid_tree, sr);
 428  450  
 429  451          if (smbsr_encode_empty_result(sr))
 430  452                  return (SDRC_ERROR);
 431  453  
 432  454          return (SDRC_SUCCESS);
 433  455  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX