summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2011-05-25 14:58:24 +1000
committerAndrew Bartlett <abartlet@samba.org>2011-05-31 00:32:07 +0200
commitade01f083c502ecf7cba19303eb16d3c9a4be52a (patch)
tree8fe090925a70c9ed4f5de4efa344ea4a79a80216 /source3/smbd
parent4e374d167992195b7a0e0f8c82aab755fd3d8379 (diff)
downloadsamba-ade01f083c502ecf7cba19303eb16d3c9a4be52a.tar.gz
samba-ade01f083c502ecf7cba19303eb16d3c9a4be52a.tar.bz2
samba-ade01f083c502ecf7cba19303eb16d3c9a4be52a.zip
s3-smbd Split conn.c into 3 files
The idea with this split is to make it easier to handle dependencies, avoiding having the loadparm code depend on the global server variables, without resorting to dummy functions and linker tricks. conn_clear_vuid_cache() is brought in from uid.c to make it static Andrew Bartlett
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/conn.c222
-rw-r--r--source3/smbd/conn_idle.c207
-rw-r--r--source3/smbd/conn_msg.c49
-rw-r--r--source3/smbd/proto.h2
-rw-r--r--source3/smbd/uid.c44
5 files changed, 292 insertions, 232 deletions
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index c4ab5c1793..da4ed9966c 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -22,7 +22,6 @@
#include "includes.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
-#include "rpc_server/rpc_ncacn_np.h"
/* The connections bitmap is expanded in increments of BITMAP_BLOCK_SZ. The
* maximum size of the bitmap is the largest positive integer, but you will hit
@@ -212,142 +211,52 @@ find_again:
}
/****************************************************************************
- Close all conn structures.
- Return true if any were closed.
+ Clear a vuid out of the connection's vuid cache
****************************************************************************/
-bool conn_close_all(struct smbd_server_connection *sconn)
+static void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid)
{
- bool ret = false;
- 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;
- TALLOC_FREE(tcon);
- ret = true;
- }
- }
- } else {
- /* SMB1 */
- connection_struct *conn, *next;
-
- for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
- next=conn->next;
- set_current_service(conn, 0, True);
- close_cnum(conn, conn->vuid);
- ret = true;
- }
- }
- 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;
- }
- }
- }
-}
-
-/****************************************************************************
- Idle inactive connections.
-****************************************************************************/
-
-bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
-{
- int deadtime = lp_deadtime()*60;
-
- conn_lastused_update(sconn, t);
-
- if (deadtime <= 0) {
- deadtime = DEFAULT_SMBD_TIMEOUT;
- }
-
- 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);
- }
+ int i;
- if (conn->num_files_open > 0 || age < deadtime) {
- return false;
+ for (i=0; i<VUID_CACHE_SIZE; i++) {
+ struct vuid_cache_entry *ent;
+
+ ent = &conn->vuid_cache.array[i];
+
+ if (ent->vuid == vuid) {
+ ent->vuid = UID_FIELD_INVALID;
+ /*
+ * We need to keep conn->session_info around
+ * if it's equal to ent->session_info as a SMBulogoff
+ * is often followed by a SMBtdis (with an invalid
+ * vuid). The debug code (or regular code in
+ * vfs_full_audit) wants to refer to the
+ * conn->session_info pointer to print debug
+ * statements. Theoretically this is a bug,
+ * as once the vuid is gone the session_info
+ * on the conn struct isn't valid any more,
+ * but there's enough code that assumes
+ * conn->session_info is never null that
+ * it's easier to hold onto the old pointer
+ * until we get a new sessionsetupX.
+ * As everything is hung off the
+ * conn pointer as a talloc context we're not
+ * leaking memory here. See bug #6315. JRA.
+ */
+ if (conn->session_info == ent->session_info) {
+ ent->session_info = NULL;
+ } else {
+ TALLOC_FREE(ent->session_info);
}
+ ent->read_only = False;
}
}
-
- /*
- * Check all pipes for any open handles. We cannot
- * idle with a handle open.
- */
- if (check_open_pipes()) {
- return false;
- }
-
- return true;
}
/****************************************************************************
Clear a vuid out of the validity cache, and as the 'owner' of a connection.
+
+ Called from invalidate_vuid()
****************************************************************************/
void conn_clear_vuid_caches(struct smbd_server_connection *sconn,uint16_t vuid)
@@ -451,64 +360,3 @@ void conn_free(connection_struct *conn)
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.
-****************************************************************************/
-
-void msg_force_tdis(struct messaging_context *msg,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
-{
- struct smbd_server_connection *sconn;
- connection_struct *conn, *next;
- fstring sharename;
-
- sconn = msg_ctx_to_sconn(msg);
- if (sconn == NULL) {
- DEBUG(1, ("could not find sconn\n"));
- return;
- }
-
- fstrcpy(sharename, (const char *)data->data);
-
- if (strcmp(sharename, "*") == 0) {
- DEBUG(1,("Forcing close of all shares\n"));
- conn_close_all(sconn);
- return;
- }
-
- 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/conn_idle.c b/source3/smbd/conn_idle.c
new file mode 100644
index 0000000000..46f5b7b111
--- /dev/null
+++ b/source3/smbd/conn_idle.c
@@ -0,0 +1,207 @@
+/*
+ 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/>.
+*/
+
+#include "includes.h"
+#include "smbd/smbd.h"
+#include "smbd/globals.h"
+#include "rpc_server/rpc_ncacn_np.h"
+
+/****************************************************************************
+ 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;
+ }
+ }
+ }
+}
+
+/****************************************************************************
+ Idle inactive connections.
+****************************************************************************/
+
+bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
+{
+ int deadtime = lp_deadtime()*60;
+
+ conn_lastused_update(sconn, t);
+
+ if (deadtime <= 0) {
+ deadtime = DEFAULT_SMBD_TIMEOUT;
+ }
+
+ 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);
+ }
+
+ if (conn->num_files_open > 0 || age < deadtime) {
+ return false;
+ }
+ }
+ }
+
+ /*
+ * Check all pipes for any open handles. We cannot
+ * idle with a handle open.
+ */
+ if (check_open_pipes()) {
+ return false;
+ }
+
+ return true;
+}
+
+/****************************************************************************
+ Close all conn structures.
+ Return true if any were closed.
+****************************************************************************/
+
+bool conn_close_all(struct smbd_server_connection *sconn)
+{
+ bool ret = false;
+ 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;
+ TALLOC_FREE(tcon);
+ ret = true;
+ }
+ }
+ } else {
+ /* SMB1 */
+ connection_struct *conn, *next;
+
+ for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
+ next=conn->next;
+ set_current_service(conn, 0, True);
+ close_cnum(conn, conn->vuid);
+ ret = true;
+ }
+ }
+ return ret;
+}
+
+
+/****************************************************************************
+ Forcibly unmount a share.
+ All instances of the parameter 'sharename' share are unmounted.
+ The special sharename '*' forces unmount of all shares.
+****************************************************************************/
+
+void conn_force_tdis(struct smbd_server_connection *sconn, const char *sharename)
+{
+ connection_struct *conn, *next;
+
+ if (strcmp(sharename, "*") == 0) {
+ DEBUG(1,("Forcing close of all shares\n"));
+ conn_close_all(sconn);
+ return;
+ }
+
+ 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/conn_msg.c b/source3/smbd/conn_msg.c
new file mode 100644
index 0000000000..ba03823667
--- /dev/null
+++ b/source3/smbd/conn_msg.c
@@ -0,0 +1,49 @@
+/*
+ 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/>.
+*/
+
+#include "includes.h"
+#include "smbd/smbd.h"
+#include "smbd/globals.h"
+
+/****************************************************************************
+ 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,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ struct smbd_server_connection *sconn;
+ const char *sharename = (const char *)data->data;
+
+ sconn = msg_ctx_to_sconn(msg);
+ if (sconn == NULL) {
+ DEBUG(1, ("could not find sconn\n"));
+ return;
+ }
+
+ return conn_force_tdis(sconn, sharename);
+}
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 5b45574bc5..b1ebf994cf 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -102,6 +102,7 @@ bool conn_close_all(struct smbd_server_connection *sconn);
bool conn_idle_all(struct smbd_server_connection *sconn, time_t t);
void conn_clear_vuid_caches(struct smbd_server_connection *sconn, uint16 vuid);
void conn_free(connection_struct *conn);
+void conn_force_tdis(struct smbd_server_connection *sconn, const char *sharename);
void msg_force_tdis(struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
@@ -1049,7 +1050,6 @@ void reply_transs2(struct smb_request *req);
/* The following definitions come from smbd/uid.c */
bool change_to_guest(void);
-void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid);
bool change_to_user(connection_struct *conn, uint16 vuid);
bool change_to_user_by_session(connection_struct *conn,
const struct auth_serversupplied_info *session_info);
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 7b04713bab..fb05a6ce98 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -182,50 +182,6 @@ static bool check_user_ok(connection_struct *conn,
}
/****************************************************************************
- Clear a vuid out of the connection's vuid cache
- This is only called on SMBulogoff.
-****************************************************************************/
-
-void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid)
-{
- int i;
-
- for (i=0; i<VUID_CACHE_SIZE; i++) {
- struct vuid_cache_entry *ent;
-
- ent = &conn->vuid_cache.array[i];
-
- if (ent->vuid == vuid) {
- ent->vuid = UID_FIELD_INVALID;
- /*
- * We need to keep conn->session_info around
- * if it's equal to ent->session_info as a SMBulogoff
- * is often followed by a SMBtdis (with an invalid
- * vuid). The debug code (or regular code in
- * vfs_full_audit) wants to refer to the
- * conn->session_info pointer to print debug
- * statements. Theoretically this is a bug,
- * as once the vuid is gone the session_info
- * on the conn struct isn't valid any more,
- * but there's enough code that assumes
- * conn->session_info is never null that
- * it's easier to hold onto the old pointer
- * until we get a new sessionsetupX.
- * As everything is hung off the
- * conn pointer as a talloc context we're not
- * leaking memory here. See bug #6315. JRA.
- */
- if (conn->session_info == ent->session_info) {
- ent->session_info = NULL;
- } else {
- TALLOC_FREE(ent->session_info);
- }
- ent->read_only = False;
- }
- }
-}
-
-/****************************************************************************
Become the user of a connection number without changing the security context
stack, but modify the current_user entries.
****************************************************************************/