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,28 ****
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <smbsrv/smb_kproto.h>
#include <smbsrv/smb_share.h>
--- 18,28 ----
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
*/
#include <smbsrv/smb_kproto.h>
#include <smbsrv/smb_share.h>
*** 98,117 ****
&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);
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);
}
smb_sdrc_t
smb_com_tree_connect(smb_request_t *sr)
{
--- 98,116 ----
&tcon->password, &tcon->service);
tcon->flags = 0;
tcon->optional_support = 0;
! 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_DONE(op__TreeConnect, smb_request_t *, sr);
}
smb_sdrc_t
smb_com_tree_connect(smb_request_t *sr)
{
*** 289,325 ****
tcon->password = (char *)pwbuf;
}
tcon->optional_support = 0;
! DTRACE_SMB_2(op__TreeConnectX__start, smb_request_t *, sr,
! smb_arg_tcon_t *, tcon);
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);
}
smb_sdrc_t
smb_com_tree_connect_andx(smb_request_t *sr)
{
smb_arg_tcon_t *tcon = &sr->sr_tcon;
char *service;
uint32_t status;
int rc;
status = smb_tree_connect(sr);
if (status) {
smb_tcon_puterror(sr, status);
return (SDRC_ERROR);
}
! switch (sr->tid_tree->t_res_type & STYPE_MASK) {
case STYPE_IPC:
service = "IPC";
break;
case STYPE_PRINTQ:
service = "LPT1:";
--- 288,333 ----
tcon->password = (char *)pwbuf;
}
tcon->optional_support = 0;
! 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_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 (tree->t_res_type & STYPE_MASK) {
case STYPE_IPC:
service = "IPC";
break;
case STYPE_PRINTQ:
service = "LPT1:";
*** 328,354 ****
default:
service = "A:";
}
if (sr->session->dialect < NT_LM_0_12) {
! rc = smbsr_encode_result(sr, 2, VAR_BCC, "bb.wwss",
(char)2, /* wct */
sr->andx_com,
VAR_BCC,
VAR_BCC,
service,
! sr->tid_tree->t_typename);
! } else {
! rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.wwws%u",
(char)3, /* wct */
sr->andx_com,
(short)64,
tcon->optional_support,
VAR_BCC,
- service,
sr,
! sr->tid_tree->t_typename);
}
return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
}
--- 336,376 ----
default:
service = "A:";
}
if (sr->session->dialect < NT_LM_0_12) {
! rc = smbsr_encode_result(sr, 2, VAR_BCC, "bb.ww%ss",
(char)2, /* wct */
sr->andx_com,
VAR_BCC,
VAR_BCC,
+ sr,
service,
! 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,
sr,
! 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,407 ****
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);
return (SDRC_SUCCESS);
}
void
smb_post_tree_disconnect(smb_request_t *sr)
{
! DTRACE_SMB_1(op__TreeDisconnect__done, 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
--- 412,429 ----
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_START(op__TreeDisconnect, smb_request_t *, sr);
return (SDRC_SUCCESS);
}
void
smb_post_tree_disconnect(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,432 ****
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);
if (smbsr_encode_empty_result(sr))
return (SDRC_ERROR);
return (SDRC_SUCCESS);
--- 443,454 ----
return (SDRC_ERROR);
}
sr->user_cr = smb_user_getcred(sr->uid_user);
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);