summaryrefslogtreecommitdiffstats
path: root/source3/smbd/conn.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/conn.c')
-rw-r--r--source3/smbd/conn.c234
1 files changed, 41 insertions, 193 deletions
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index 16a0ee053e9..a3f66b36be7 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -53,10 +53,9 @@ int conn_num_open(struct smbd_server_connection *sconn)
Check if a snum is in use.
****************************************************************************/
-bool conn_snum_used(int snum)
+bool conn_snum_used(struct smbd_server_connection *sconn,
+ int snum)
{
- struct smbd_server_connection *sconn = smbd_server_conn;
-
if (sconn->using_smb2) {
/* SMB2 */
struct smbd_smb2_session *sess;
@@ -134,8 +133,8 @@ connection_struct *conn_new(struct smbd_server_connection *sconn)
if (sconn->using_smb2) {
/* SMB2 */
- if (!(conn=TALLOC_ZERO_P(NULL, connection_struct)) ||
- !(conn->params = TALLOC_P(conn, struct share_params))) {
+ if (!(conn=talloc_zero(NULL, connection_struct)) ||
+ !(conn->params = talloc(conn, struct share_params))) {
DEBUG(0,("TALLOC_ZERO() failed!\n"));
TALLOC_FREE(conn);
return NULL;
@@ -189,8 +188,8 @@ find_again:
return NULL;
}
- if (!(conn=TALLOC_ZERO_P(NULL, connection_struct)) ||
- !(conn->params = TALLOC_P(conn, struct share_params))) {
+ if (!(conn=talloc_zero(NULL, connection_struct)) ||
+ !(conn->params = talloc(conn, struct share_params))) {
DEBUG(0,("TALLOC_ZERO() failed!\n"));
TALLOC_FREE(conn);
return NULL;
@@ -212,142 +211,52 @@ find_again:
}
/****************************************************************************
- 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;
-}
-
-/****************************************************************************
- 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.
+ Clear a vuid out of the connection's vuid cache
****************************************************************************/
-bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
+static void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid)
{
- 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);
- }
- }
- }
-}