s3-id_cache: Use better names for id cache management ops
[idra/samba.git] / source3 / smbd / conn_idle.c
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
7
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.
12
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.
17
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/>.
20 */
21
22 #include "includes.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "rpc_server/rpc_pipes.h"
26
27 /****************************************************************************
28  Update last used timestamps.
29 ****************************************************************************/
30
31 static void conn_lastused_update(struct smbd_server_connection *sconn,time_t t)
32 {
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;
38
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;
45                                 }
46                         }
47                 }
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;
56                         }
57                 }
58         }
59 }
60
61 /****************************************************************************
62  Idle inactive connections.
63 ****************************************************************************/
64
65 bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
66 {
67         int deadtime = lp_deadtime()*60;
68
69         conn_lastused_update(sconn, t);
70
71         if (deadtime <= 0) {
72                 deadtime = DEFAULT_SMBD_TIMEOUT;
73         }
74
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;
80
81                         for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
82                                 time_t age;
83                                 connection_struct *conn = ptcon->compat_conn;
84
85                                 if (conn == NULL) {
86                                         continue;
87                                 }
88
89                                 age = t - conn->lastused;
90                                 /* close dirptrs on connections that are idle */
91                                 if (age > DPTR_IDLE_TIMEOUT) {
92                                         dptr_idlecnum(conn);
93                                 }
94
95                                 if (conn->num_files_open > 0 || age < deadtime) {
96                                         return false;
97                                 }
98                         }
99                 }
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;
105
106                         /* close dirptrs on connections that are idle */
107                         if (age > DPTR_IDLE_TIMEOUT) {
108                                 dptr_idlecnum(conn);
109                         }
110
111                         if (conn->num_files_open > 0 || age < deadtime) {
112                                 return false;
113                         }
114                 }
115         }
116
117         /*
118          * Check all pipes for any open handles. We cannot
119          * idle with a handle open.
120          */
121         if (check_open_pipes()) {
122                 return false;
123         }
124
125         return true;
126 }
127
128 /****************************************************************************
129  Close all conn structures.
130  Return true if any were closed.
131 ****************************************************************************/
132
133 bool conn_close_all(struct smbd_server_connection *sconn)
134 {
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;
141
142                         for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
143                                 tc_next = tcon->next;
144                                 TALLOC_FREE(tcon);
145                                 ret = true;
146                         }
147                 }
148         } else {
149                 /* SMB1 */
150                 connection_struct *conn, *next;
151
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;
157                 }
158         }
159         return ret;
160 }
161
162
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 ****************************************************************************/
168
169 void conn_force_tdis(struct smbd_server_connection *sconn, const char *sharename)
170 {
171         connection_struct *conn, *next;
172
173         if (strcmp(sharename, "*") == 0) {
174                 DEBUG(1,("Forcing close of all shares\n"));
175                 conn_close_all(sconn);
176                 return;
177         }
178
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;
184
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);
193                                 }
194                         }
195                 }
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);
204                         }
205                 }
206         }
207 }