[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Tue Oct 19 16:54:02 MDT 2010
The branch, master has been updated
via 45794dd Fix shadow warning for "access" variable.
via e7d0f47 Add deadtime detection for SMB2. Correctly update lastused timestamp across all active tcons. Should fix dfree cache not updating bug.
via d7f4bea Add SMB2 paths to smbd/conn.c. Except for conn_idle_all(), to be cleaned up next.
via 1bd6faa Copyright/whitespace/comment cleanup in preparation for adding SMB2 paths.
via edefaf5 Move tcons.num_open from smb1 to sconn->num_tcons_open as this is needed for SMB2 also.
from 492ab4d s3-waf Use LIBSECRUITY subsystem from the common wscript_build
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 45794dd30a7717aafba40864c1843e47098a4502
Author: Jeremy Allison <jra at samba.org>
Date: Tue Oct 19 13:32:53 2010 -0700
Fix shadow warning for "access" variable.
Autobuild-User: Jeremy Allison <jra at samba.org>
Autobuild-Date: Tue Oct 19 22:53:38 UTC 2010 on sn-devel-104
commit e7d0f478ee529500461f80f2fd51987c9255d345
Author: Jeremy Allison <jra at samba.org>
Date: Tue Oct 19 11:11:56 2010 -0700
Add deadtime detection for SMB2. Correctly update lastused timestamp across all active tcons. Should fix dfree cache not updating bug.
commit d7f4bea39455c5d0a9b36cfa731d10c96a1c1405
Author: Jeremy Allison <jra at samba.org>
Date: Tue Oct 19 10:12:42 2010 -0700
Add SMB2 paths to smbd/conn.c. Except for conn_idle_all(), to be cleaned up next.
commit 1bd6faa8fa9143f526f9438c6b126b68820d29f8
Author: Jeremy Allison <jra at samba.org>
Date: Tue Oct 19 10:04:27 2010 -0700
Copyright/whitespace/comment cleanup in preparation for adding SMB2 paths.
commit edefaf5bed75fd315b1ca9a3da096419a7a6cec3
Author: Jeremy Allison <jra at samba.org>
Date: Tue Oct 19 13:25:51 2010 -0700
Move tcons.num_open from smb1 to sconn->num_tcons_open as this is needed for SMB2 also.
-----------------------------------------------------------------------
Summary of changes:
libcli/security/object_tree.c | 6 +-
source3/smbd/conn.c | 289 ++++++++++++++++++++++++++++++-----------
source3/smbd/globals.h | 4 +-
source3/smbd/msdfs.c | 2 +-
source3/smbd/process.c | 14 +--
source3/smbd/smb2_tcon.c | 3 +
6 files changed, 224 insertions(+), 94 deletions(-)
Changeset truncated at 500 lines:
diff --git a/libcli/security/object_tree.c b/libcli/security/object_tree.c
index 7c7d644..6fa9585 100644
--- a/libcli/security/object_tree.c
+++ b/libcli/security/object_tree.c
@@ -109,13 +109,13 @@ struct object_tree *get_object_tree_by_GUID(struct object_tree *root,
/* Change the granted access per each ACE */
void object_tree_modify_access(struct object_tree *root,
- uint32_t access)
+ uint32_t access_mask)
{
- root->remaining_access &= ~access;
+ root->remaining_access &= ~access_mask;
if (root->num_of_children > 0) {
int i;
for (i = 0; i < root->num_of_children; i++) {
- object_tree_modify_access(&root->children[i], access);
+ object_tree_modify_access(&root->children[i], access_mask);
}
}
}
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index d12495b..8de8ce2 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -1,19 +1,20 @@
-/*
+/*
Unix SMB/CIFS implementation.
Manage connections_struct structures
Copyright (C) Andrew Tridgell 1998
Copyright (C) Alexander Bokovoy 2002
-
+ Copyright (C) Jeremy Allison 2010
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -25,40 +26,60 @@
* maximum size of the bitmap is the largest positive integer, but you will hit
* the "max connections" limit, looong before that.
*/
+
#define BITMAP_BLOCK_SZ 128
/****************************************************************************
-init the conn structures
+ Init the conn structures.
****************************************************************************/
+
void conn_init(struct smbd_server_connection *sconn)
{
sconn->smb1.tcons.Connections = NULL;
- sconn->smb1.tcons.num_open = 0;
sconn->smb1.tcons.bmap = bitmap_talloc(sconn, BITMAP_BLOCK_SZ);
}
/****************************************************************************
-return the number of open connections
+ Return the number of open connections.
****************************************************************************/
+
int conn_num_open(struct smbd_server_connection *sconn)
{
- return sconn->smb1.tcons.num_open;
+ return sconn->num_tcons_open;
}
-
/****************************************************************************
-check if a snum is in use
+ Check if a snum is in use.
****************************************************************************/
+
bool conn_snum_used(int snum)
{
struct smbd_server_connection *sconn = smbd_server_conn;
- connection_struct *conn;
- for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
- if (conn->params->service == snum) {
- return(True);
+
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *ptcon;
+
+ for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
+ if (ptcon->compat_conn &&
+ ptcon->compat_conn->params &&
+ (ptcon->compat_conn->params->service = snum)) {
+ return true;
+ }
+ }
+ }
+ } else {
+ /* SMB1 */
+ connection_struct *conn;
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+ if (conn->params->service == snum) {
+ return true;
+ }
}
}
- return(False);
+ return false;
}
/****************************************************************************
@@ -67,16 +88,31 @@ bool conn_snum_used(int snum)
connection_struct *conn_find(struct smbd_server_connection *sconn,unsigned cnum)
{
- int count=0;
- connection_struct *conn;
-
- for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next,count++) {
- if (conn->cnum == cnum) {
- if (count > 10) {
- DLIST_PROMOTE(sconn->smb1.tcons.Connections,
- conn);
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *ptcon;
+
+ for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
+ if (ptcon->compat_conn &&
+ ptcon->compat_conn->cnum == cnum) {
+ return ptcon->compat_conn;
+ }
+ }
+ }
+ } else {
+ /* SMB1 */
+ int count=0;
+ connection_struct *conn;
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next,count++) {
+ if (conn->cnum == cnum) {
+ if (count > 10) {
+ DLIST_PROMOTE(sconn->smb1.tcons.Connections,
+ conn);
+ }
+ return conn;
}
- return conn;
}
}
@@ -84,10 +120,11 @@ connection_struct *conn_find(struct smbd_server_connection *sconn,unsigned cnum)
}
/****************************************************************************
- find first available connection slot, starting from a random position.
-The randomisation stops problems with the server dieing and clients
-thinking the server is still available.
+ Find first available connection slot, starting from a random position.
+ The randomisation stops problems with the server dieing and clients
+ thinking the server is still available.
****************************************************************************/
+
connection_struct *conn_new(struct smbd_server_connection *sconn)
{
connection_struct *conn;
@@ -95,6 +132,7 @@ connection_struct *conn_new(struct smbd_server_connection *sconn)
int find_offset = 1;
if (sconn->using_smb2) {
+ /* SMB2 */
if (!(conn=TALLOC_ZERO_P(NULL, connection_struct)) ||
!(conn->params = TALLOC_P(conn, struct share_params))) {
DEBUG(0,("TALLOC_ZERO() failed!\n"));
@@ -105,9 +143,10 @@ connection_struct *conn_new(struct smbd_server_connection *sconn)
return conn;
}
+ /* SMB1 */
find_again:
i = bitmap_find(sconn->smb1.tcons.bmap, find_offset);
-
+
if (i == -1) {
/* Expand the connections bitmap. */
int oldsz = sconn->smb1.tcons.bmap->n;
@@ -161,11 +200,11 @@ find_again:
bitmap_set(sconn->smb1.tcons.bmap, i);
- sconn->smb1.tcons.num_open++;
+ sconn->num_tcons_open++;
string_set(&conn->connectpath,"");
string_set(&conn->origpath,"");
-
+
DLIST_ADD(sconn->smb1.tcons.Connections, conn);
return conn;
@@ -173,28 +212,27 @@ find_again:
/****************************************************************************
Close all conn structures.
-return true if any were closed
+ Return true if any were closed.
****************************************************************************/
+
bool conn_close_all(struct smbd_server_connection *sconn)
{
+ bool ret = false;
if (sconn->using_smb2) {
/* SMB2 */
- if (sconn->smb2.sessions.list &&
- sconn->smb2.sessions.list->tcons.list) {
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
struct smbd_smb2_tcon *tcon, *tc_next;
- for (tcon = sconn->smb2.sessions.list->tcons.list;
- tcon; tcon = tc_next) {
+ for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
tc_next = tcon->next;
TALLOC_FREE(tcon);
+ ret = true;
}
- return true;
}
- return false;
} else {
/* SMB1 */
connection_struct *conn, *next;
- bool ret = false;
for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
next=conn->next;
@@ -202,7 +240,41 @@ bool conn_close_all(struct smbd_server_connection *sconn)
close_cnum(conn, conn->vuid);
ret = true;
}
- return ret;
+ }
+ return ret;
+}
+
+/****************************************************************************
+ Update last used timestamps.
+****************************************************************************/
+
+static void conn_lastused_update(struct smbd_server_connection *sconn,time_t t)
+{
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *ptcon;
+
+ for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
+ connection_struct *conn = ptcon->compat_conn;
+ /* Update if connection wasn't idle. */
+ if (conn && conn->lastused != conn->lastused_count) {
+ conn->lastused = t;
+ conn->lastused_count = t;
+ }
+ }
+ }
+ } else {
+ /* SMB1 */
+ connection_struct *conn;
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+ /* Update if connection wasn't idle. */
+ if (conn->lastused != conn->lastused_count) {
+ conn->lastused = t;
+ conn->lastused_count = t;
+ }
+ }
}
}
@@ -210,31 +282,55 @@ bool conn_close_all(struct smbd_server_connection *sconn)
Idle inactive connections.
****************************************************************************/
-bool conn_idle_all(struct smbd_server_connection *sconn,time_t t)
+bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
{
int deadtime = lp_deadtime()*60;
- connection_struct *conn;
- if (deadtime <= 0)
- deadtime = DEFAULT_SMBD_TIMEOUT;
+ conn_lastused_update(sconn, t);
- for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
-
- time_t age = t - conn->lastused;
+ if (deadtime <= 0) {
+ deadtime = DEFAULT_SMBD_TIMEOUT;
+ }
- /* Update if connection wasn't idle. */
- if (conn->lastused != conn->lastused_count) {
- conn->lastused = t;
- conn->lastused_count = t;
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *ptcon;
+
+ for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
+ time_t age;
+ connection_struct *conn = ptcon->compat_conn;
+
+ if (conn == NULL) {
+ continue;
+ }
+
+ age = t - conn->lastused;
+ /* close dirptrs on connections that are idle */
+ if (age > DPTR_IDLE_TIMEOUT) {
+ dptr_idlecnum(conn);
+ }
+
+ if (conn->num_files_open > 0 || age < deadtime) {
+ return false;
+ }
+ }
}
+ } else {
+ /* SMB1 */
+ connection_struct *conn;
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+ time_t age = t - conn->lastused;
- /* close dirptrs on connections that are idle */
- if (age > DPTR_IDLE_TIMEOUT) {
- dptr_idlecnum(conn);
- }
+ /* close dirptrs on connections that are idle */
+ if (age > DPTR_IDLE_TIMEOUT) {
+ dptr_idlecnum(conn);
+ }
- if (conn->num_files_open > 0 || age < deadtime) {
- return False;
+ if (conn->num_files_open > 0 || age < deadtime) {
+ return false;
+ }
}
}
@@ -243,10 +339,10 @@ bool conn_idle_all(struct smbd_server_connection *sconn,time_t t)
* idle with a handle open.
*/
if (check_open_pipes()) {
- return False;
+ return false;
}
- return True;
+ return true;
}
/****************************************************************************
@@ -257,11 +353,29 @@ void conn_clear_vuid_caches(struct smbd_server_connection *sconn,uint16_t vuid)
{
connection_struct *conn;
- for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
- if (conn->vuid == vuid) {
- conn->vuid = UID_FIELD_INVALID;
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *ptcon;
+
+ for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
+ if (ptcon->compat_conn) {
+ if (ptcon->compat_conn->vuid == vuid) {
+ ptcon->compat_conn->vuid = UID_FIELD_INVALID;
+ }
+ conn_clear_vuid_cache(ptcon->compat_conn, vuid);
+ }
+ }
+ }
+ } else {
+ /* SMB1 */
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+ if (conn->vuid == vuid) {
+ conn->vuid = UID_FIELD_INVALID;
+ }
+ conn_clear_vuid_cache(conn, vuid);
}
- conn_clear_vuid_cache(conn, vuid);
}
}
@@ -295,7 +409,7 @@ static void conn_free_internal(connection_struct *conn)
free_namearray(conn->hide_list);
free_namearray(conn->veto_oplock_list);
free_namearray(conn->aio_write_behind_list);
-
+
string_free(&conn->connectpath);
string_free(&conn->origpath);
@@ -315,10 +429,12 @@ void conn_free(connection_struct *conn)
}
if (conn->sconn->using_smb2) {
+ /* SMB2 */
conn_free_internal(conn);
return;
}
+ /* SMB1 */
DLIST_REMOVE(conn->sconn->smb1.tcons.Connections, conn);
if (conn->sconn->smb1.tcons.bmap != NULL) {
@@ -329,18 +445,19 @@ void conn_free(connection_struct *conn)
bitmap_clear(conn->sconn->smb1.tcons.bmap, conn->cnum);
}
- SMB_ASSERT(conn->sconn->smb1.tcons.num_open > 0);
- conn->sconn->smb1.tcons.num_open--;
+ SMB_ASSERT(conn->sconn->num_tcons_open > 0);
+ conn->sconn->num_tcons_open--;
conn_free_internal(conn);
}
-
+
/****************************************************************************
-receive a smbcontrol message to forcibly unmount a share
-the message contains just a share name and all instances of that
-share are unmounted
-the special sharename '*' forces unmount of all shares
+ Receive a smbcontrol message to forcibly unmount a share.
+ The message contains just a share name and all instances of that
+ share are unmounted.
+ The special sharename '*' forces unmount of all shares.
****************************************************************************/
+
void msg_force_tdis(struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
@@ -365,12 +482,32 @@ void msg_force_tdis(struct messaging_context *msg,
return;
}
- for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
- next=conn->next;
- if (strequal(lp_servicename(SNUM(conn)), sharename)) {
- DEBUG(1,("Forcing close of share %s cnum=%d\n",
- sharename, conn->cnum));
- close_cnum(conn, (uint16)-1);
+ if (sconn->using_smb2) {
+ /* SMB2 */
+ struct smbd_smb2_session *sess;
+ for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+ struct smbd_smb2_tcon *tcon, *tc_next;
+
+ for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
+ tc_next = tcon->next;
+ if (tcon->compat_conn &&
+ strequal(lp_servicename(SNUM(tcon->compat_conn)),
+ sharename)) {
+ DEBUG(1,("Forcing close of share %s cnum=%d\n",
+ sharename, tcon->compat_conn->cnum));
+ TALLOC_FREE(tcon);
+ }
+ }
+ }
+ } else {
+ /* SMB1 */
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
+ next=conn->next;
+ if (strequal(lp_servicename(SNUM(conn)), sharename)) {
+ DEBUG(1,("Forcing close of share %s cnum=%d\n",
+ sharename, conn->cnum));
+ close_cnum(conn, (uint16)-1);
+ }
}
}
}
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
--
Samba Shared Repository
More information about the samba-cvs
mailing list