[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