s3-utils/net_rpc_printer.c: print more info on write error
[Samba/gebeck_regimport.git] / source3 / smbd / conn_idle.c
blobc1949d334ed7b375ce352dabcf880ad196b12441
1 /*
2 Unix SMB/CIFS implementation.
3 Manage connections_struct structures
4 Copyright (C) Andrew Tridgell 1998
5 Copyright (C) Alexander Bokovoy 2002
6 Copyright (C) Jeremy Allison 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "rpc_server/rpc_pipes.h"
27 /****************************************************************************
28 Update last used timestamps.
29 ****************************************************************************/
31 static void conn_lastused_update(struct smbd_server_connection *sconn,time_t t)
33 if (sconn->using_smb2) {
34 /* SMB2 */
35 struct smbd_smb2_session *sess;
36 for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
37 struct smbd_smb2_tcon *ptcon;
39 for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
40 connection_struct *conn = ptcon->compat_conn;
41 /* Update if connection wasn't idle. */
42 if (conn && conn->lastused != conn->lastused_count) {
43 conn->lastused = t;
44 conn->lastused_count = t;
48 } else {
49 /* SMB1 */
50 connection_struct *conn;
51 for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
52 /* Update if connection wasn't idle. */
53 if (conn->lastused != conn->lastused_count) {
54 conn->lastused = t;
55 conn->lastused_count = t;
61 /****************************************************************************
62 Idle inactive connections.
63 ****************************************************************************/
65 bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
67 int deadtime = lp_deadtime()*60;
69 conn_lastused_update(sconn, t);
71 if (deadtime <= 0) {
72 deadtime = DEFAULT_SMBD_TIMEOUT;
75 if (sconn->using_smb2) {
76 /* SMB2 */
77 struct smbd_smb2_session *sess;
78 for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
79 struct smbd_smb2_tcon *ptcon;
81 for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
82 time_t age;
83 connection_struct *conn = ptcon->compat_conn;
85 if (conn == NULL) {
86 continue;
89 age = t - conn->lastused;
90 /* close dirptrs on connections that are idle */
91 if (age > DPTR_IDLE_TIMEOUT) {
92 dptr_idlecnum(conn);
95 if (conn->num_files_open > 0 || age < deadtime) {
96 return false;
100 } else {
101 /* SMB1 */
102 connection_struct *conn;
103 for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
104 time_t age = t - conn->lastused;
106 /* close dirptrs on connections that are idle */
107 if (age > DPTR_IDLE_TIMEOUT) {
108 dptr_idlecnum(conn);
111 if (conn->num_files_open > 0 || age < deadtime) {
112 return false;
118 * Check all pipes for any open handles. We cannot
119 * idle with a handle open.
121 if (check_open_pipes()) {
122 return false;
125 return true;
128 /****************************************************************************
129 Close all conn structures.
130 Return true if any were closed.
131 ****************************************************************************/
133 bool conn_close_all(struct smbd_server_connection *sconn)
135 bool ret = false;
136 if (sconn->using_smb2) {
137 /* SMB2 */
138 struct smbd_smb2_session *sess;
139 for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
140 struct smbd_smb2_tcon *tcon, *tc_next;
142 for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
143 tc_next = tcon->next;
144 TALLOC_FREE(tcon);
145 ret = true;
148 } else {
149 /* SMB1 */
150 connection_struct *conn, *next;
152 for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
153 next=conn->next;
154 set_current_service(conn, 0, True);
155 close_cnum(conn, conn->vuid);
156 ret = true;
159 return ret;
163 /****************************************************************************
164 Forcibly unmount a share.
165 All instances of the parameter 'sharename' share are unmounted.
166 The special sharename '*' forces unmount of all shares.
167 ****************************************************************************/
169 void conn_force_tdis(struct smbd_server_connection *sconn, const char *sharename)
171 connection_struct *conn, *next;
173 if (strcmp(sharename, "*") == 0) {
174 DEBUG(1,("Forcing close of all shares\n"));
175 conn_close_all(sconn);
176 return;
179 if (sconn->using_smb2) {
180 /* SMB2 */
181 struct smbd_smb2_session *sess;
182 for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
183 struct smbd_smb2_tcon *tcon, *tc_next;
185 for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
186 tc_next = tcon->next;
187 if (tcon->compat_conn &&
188 strequal(lp_servicename(SNUM(tcon->compat_conn)),
189 sharename)) {
190 DEBUG(1,("Forcing close of share %s cnum=%d\n",
191 sharename, tcon->compat_conn->cnum));
192 TALLOC_FREE(tcon);
196 } else {
197 /* SMB1 */
198 for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
199 next=conn->next;
200 if (strequal(lp_servicename(SNUM(conn)), sharename)) {
201 DEBUG(1,("Forcing close of share %s cnum=%d\n",
202 sharename, conn->cnum));
203 close_cnum(conn, (uint16)-1);