1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00
samba-mirror/source3/smbd/conn_idle.c
Simo Sorce 759a04e58a s3-rpc_server: Move pipe/handles functions
Put InternalPipes related functions in rpc_handles.c and out of rpc_ncacn_np.c
rpc_handles.c is the only file that really uses them after all and ncacn_np.c
is the wrong place for that stuff.
While ther remove unnecessary wrapper functions now that the InternalPipes
static variable is directly accessible.

Also move all pipes_struct related header stuff in its own rpc_pipes.h header.

Signed-off-by: Andreas Schneider <asn@samba.org>
2011-07-21 18:40:23 +02:00

208 lines
5.5 KiB
C

/*
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_pipes.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);
}
}
}
}