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
↓ 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) {
↓ 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) {
↓ 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
↓ 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
↓ 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