Changeset 745 for trunk/server/source3/smbd/conn.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/smbd/conn.c
r596 r745 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 Manage connections_struct structures 4 4 Copyright (C) Andrew Tridgell 1998 5 5 Copyright (C) Alexander Bokovoy 2002 6 6 Copyright (C) Jeremy Allison 2010 7 7 8 This program is free software; you can redistribute it and/or modify 8 9 it under the terms of the GNU General Public License as published by 9 10 the Free Software Foundation; either version 3 of the License, or 10 11 (at your option) any later version. 11 12 12 13 This program is distributed in the hope that it will be useful, 13 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 16 GNU General Public License for more details. 16 17 17 18 You should have received a copy of the GNU General Public License 18 19 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 20 21 21 22 #include "includes.h" 23 #include "smbd/smbd.h" 22 24 #include "smbd/globals.h" 25 #include "rpc_server/rpc_ncacn_np.h" 23 26 24 27 /* The connections bitmap is expanded in increments of BITMAP_BLOCK_SZ. The … … 26 29 * the "max connections" limit, looong before that. 27 30 */ 31 28 32 #define BITMAP_BLOCK_SZ 128 29 33 30 34 /**************************************************************************** 31 init the conn structures 32 ****************************************************************************/ 35 Init the conn structures. 36 ****************************************************************************/ 37 33 38 void conn_init(struct smbd_server_connection *sconn) 34 39 { 35 40 sconn->smb1.tcons.Connections = NULL; 36 sconn->smb1.tcons. num_open = 0;37 sconn->smb1.tcons.bmap = bitmap_allocate(BITMAP_BLOCK_SZ); 38 } 39 40 /**************************************************************************** 41 return the number of open connections 42 ****************************************************************************/ 41 sconn->smb1.tcons.bmap = bitmap_talloc(sconn, BITMAP_BLOCK_SZ); 42 } 43 44 /**************************************************************************** 45 Return the number of open connections. 46 ****************************************************************************/ 47 43 48 int conn_num_open(struct smbd_server_connection *sconn) 44 49 { 45 return sconn-> smb1.tcons.num_open;46 } 47 48 49 /**************************************************************************** 50 check if a snum is in use 51 ****************************************************************************/ 50 return sconn->num_tcons_open; 51 } 52 53 /**************************************************************************** 54 Check if a snum is in use. 55 ****************************************************************************/ 56 52 57 bool conn_snum_used(int snum) 53 58 { 54 59 struct smbd_server_connection *sconn = smbd_server_conn; 55 connection_struct *conn; 56 for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) { 57 if (conn->params->service == snum) { 58 return(True); 59 } 60 } 61 return(False); 60 61 if (sconn->using_smb2) { 62 /* SMB2 */ 63 struct smbd_smb2_session *sess; 64 for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) { 65 struct smbd_smb2_tcon *ptcon; 66 67 for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) { 68 if (ptcon->compat_conn && 69 ptcon->compat_conn->params && 70 (ptcon->compat_conn->params->service = snum)) { 71 return true; 72 } 73 } 74 } 75 } else { 76 /* SMB1 */ 77 connection_struct *conn; 78 for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) { 79 if (conn->params->service == snum) { 80 return true; 81 } 82 } 83 } 84 return false; 62 85 } 63 86 … … 68 91 connection_struct *conn_find(struct smbd_server_connection *sconn,unsigned cnum) 69 92 { 70 int count=0; 71 connection_struct *conn; 72 73 for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next,count++) { 74 if (conn->cnum == cnum) { 75 if (count > 10) { 76 DLIST_PROMOTE(sconn->smb1.tcons.Connections, 77 conn); 78 } 79 return conn; 93 if (sconn->using_smb2) { 94 /* SMB2 */ 95 struct smbd_smb2_session *sess; 96 for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) { 97 struct smbd_smb2_tcon *ptcon; 98 99 for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) { 100 if (ptcon->compat_conn && 101 ptcon->compat_conn->cnum == cnum) { 102 return ptcon->compat_conn; 103 } 104 } 105 } 106 } else { 107 /* SMB1 */ 108 int count=0; 109 connection_struct *conn; 110 for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next,count++) { 111 if (conn->cnum == cnum) { 112 if (count > 10) { 113 DLIST_PROMOTE(sconn->smb1.tcons.Connections, 114 conn); 115 } 116 return conn; 117 } 80 118 } 81 119 } … … 85 123 86 124 /**************************************************************************** 87 find first available connection slot, starting from a random position. 88 The randomisation stops problems with the server dieing and clients 89 thinking the server is still available. 90 ****************************************************************************/ 125 Find first available connection slot, starting from a random position. 126 The randomisation stops problems with the server dieing and clients 127 thinking the server is still available. 128 ****************************************************************************/ 129 91 130 connection_struct *conn_new(struct smbd_server_connection *sconn) 92 131 { … … 95 134 int find_offset = 1; 96 135 97 if (sconn->allow_smb2) { 136 if (sconn->using_smb2) { 137 /* SMB2 */ 98 138 if (!(conn=TALLOC_ZERO_P(NULL, connection_struct)) || 99 139 !(conn->params = TALLOC_P(conn, struct share_params))) { … … 106 146 } 107 147 148 /* SMB1 */ 108 149 find_again: 109 150 i = bitmap_find(sconn->smb1.tcons.bmap, find_offset); 110 151 111 152 if (i == -1) { 112 153 /* Expand the connections bitmap. */ … … 125 166 oldsz, newsz)); 126 167 127 nbmap = bitmap_ allocate(newsz);168 nbmap = bitmap_talloc(sconn, newsz); 128 169 if (!nbmap) { 129 170 DEBUG(0,("ERROR! malloc fail.\n")); … … 132 173 133 174 bitmap_copy(nbmap, sconn->smb1.tcons.bmap); 134 bitmap_free(sconn->smb1.tcons.bmap);175 TALLOC_FREE(sconn->smb1.tcons.bmap); 135 176 136 177 sconn->smb1.tcons.bmap = nbmap; … … 162 203 bitmap_set(sconn->smb1.tcons.bmap, i); 163 204 164 sconn-> smb1.tcons.num_open++;205 sconn->num_tcons_open++; 165 206 166 207 string_set(&conn->connectpath,""); 167 208 string_set(&conn->origpath,""); 168 209 169 210 DLIST_ADD(sconn->smb1.tcons.Connections, conn); 170 211 … … 174 215 /**************************************************************************** 175 216 Close all conn structures. 176 return true if any were closed 177 ****************************************************************************/ 217 Return true if any were closed. 218 ****************************************************************************/ 219 178 220 bool conn_close_all(struct smbd_server_connection *sconn) 179 221 { 180 connection_struct *conn, *next;181 222 bool ret = false; 182 for (conn=sconn->smb1.tcons.Connections;conn;conn=next) { 183 next=conn->next; 184 set_current_service(conn, 0, True); 185 close_cnum(conn, conn->vuid); 186 ret = true; 223 if (sconn->using_smb2) { 224 /* SMB2 */ 225 struct smbd_smb2_session *sess; 226 for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) { 227 struct smbd_smb2_tcon *tcon, *tc_next; 228 229 for (tcon = sess->tcons.list; tcon; tcon = tc_next) { 230 tc_next = tcon->next; 231 TALLOC_FREE(tcon); 232 ret = true; 233 } 234 } 235 } else { 236 /* SMB1 */ 237 connection_struct *conn, *next; 238 239 for (conn=sconn->smb1.tcons.Connections;conn;conn=next) { 240 next=conn->next; 241 set_current_service(conn, 0, True); 242 close_cnum(conn, conn->vuid); 243 ret = true; 244 } 187 245 } 188 246 return ret; … … 190 248 191 249 /**************************************************************************** 250 Update last used timestamps. 251 ****************************************************************************/ 252 253 static void conn_lastused_update(struct smbd_server_connection *sconn,time_t t) 254 { 255 if (sconn->using_smb2) { 256 /* SMB2 */ 257 struct smbd_smb2_session *sess; 258 for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) { 259 struct smbd_smb2_tcon *ptcon; 260 261 for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) { 262 connection_struct *conn = ptcon->compat_conn; 263 /* Update if connection wasn't idle. */ 264 if (conn && conn->lastused != conn->lastused_count) { 265 conn->lastused = t; 266 conn->lastused_count = t; 267 } 268 } 269 } 270 } else { 271 /* SMB1 */ 272 connection_struct *conn; 273 for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) { 274 /* Update if connection wasn't idle. */ 275 if (conn->lastused != conn->lastused_count) { 276 conn->lastused = t; 277 conn->lastused_count = t; 278 } 279 } 280 } 281 } 282 283 /**************************************************************************** 192 284 Idle inactive connections. 193 285 ****************************************************************************/ 194 286 195 bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)287 bool conn_idle_all(struct smbd_server_connection *sconn, time_t t) 196 288 { 197 289 int deadtime = lp_deadtime()*60; 198 pipes_struct *plist = NULL; 199 connection_struct *conn; 200 bool ret = true; 201 202 if (deadtime <= 0) 290 291 conn_lastused_update(sconn, t); 292 293 if (deadtime <= 0) { 203 294 deadtime = DEFAULT_SMBD_TIMEOUT; 204 205 for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) { 206 207 time_t age = t - conn->lastused; 208 209 /* Update if connection wasn't idle. */ 210 if (conn->lastused != conn->lastused_count) { 211 conn->lastused = t; 212 conn->lastused_count = t; 213 age = 0; 214 } 215 216 /* close dirptrs on connections that are idle */ 217 if (age > DPTR_IDLE_TIMEOUT) { 218 dptr_idlecnum(conn); 219 } 220 221 if (conn->num_files_open > 0 || age < deadtime) { 222 ret = false; 295 } 296 297 if (sconn->using_smb2) { 298 /* SMB2 */ 299 struct smbd_smb2_session *sess; 300 for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) { 301 struct smbd_smb2_tcon *ptcon; 302 303 for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) { 304 time_t age; 305 connection_struct *conn = ptcon->compat_conn; 306 307 if (conn == NULL) { 308 continue; 309 } 310 311 age = t - conn->lastused; 312 /* close dirptrs on connections that are idle */ 313 if (age > DPTR_IDLE_TIMEOUT) { 314 dptr_idlecnum(conn); 315 } 316 317 if (conn->num_files_open > 0 || age < deadtime) { 318 return false; 319 } 320 } 321 } 322 } else { 323 /* SMB1 */ 324 connection_struct *conn; 325 for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) { 326 time_t age = t - conn->lastused; 327 328 /* close dirptrs on connections that are idle */ 329 if (age > DPTR_IDLE_TIMEOUT) { 330 dptr_idlecnum(conn); 331 } 332 333 if (conn->num_files_open > 0 || age < deadtime) { 334 return false; 335 } 223 336 } 224 337 } … … 228 341 * idle with a handle open. 229 342 */ 230 231 for (plist = get_first_internal_pipe(); plist; 232 plist = get_next_internal_pipe(plist)) { 233 if (num_pipe_handles(plist->pipe_handles) != 0) { 234 ret = false; 235 break; 236 } 237 } 238 239 return ret; 343 if (check_open_pipes()) { 344 return false; 345 } 346 347 return true; 240 348 } 241 349 … … 248 356 connection_struct *conn; 249 357 250 for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) { 251 if (conn->vuid == vuid) { 252 conn->vuid = UID_FIELD_INVALID; 253 } 254 conn_clear_vuid_cache(conn, vuid); 358 if (sconn->using_smb2) { 359 /* SMB2 */ 360 struct smbd_smb2_session *sess; 361 for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) { 362 struct smbd_smb2_tcon *ptcon; 363 364 for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) { 365 if (ptcon->compat_conn) { 366 if (ptcon->compat_conn->vuid == vuid) { 367 ptcon->compat_conn->vuid = UID_FIELD_INVALID; 368 } 369 conn_clear_vuid_cache(ptcon->compat_conn, vuid); 370 } 371 } 372 } 373 } else { 374 /* SMB1 */ 375 for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) { 376 if (conn->vuid == vuid) { 377 conn->vuid = UID_FIELD_INVALID; 378 } 379 conn_clear_vuid_cache(conn, vuid); 380 } 255 381 } 256 382 } … … 286 412 free_namearray(conn->veto_oplock_list); 287 413 free_namearray(conn->aio_write_behind_list); 288 414 289 415 string_free(&conn->connectpath); 290 416 string_free(&conn->origpath); … … 305 431 } 306 432 307 if (conn->sconn->allow_smb2) { 433 if (conn->sconn->using_smb2) { 434 /* SMB2 */ 308 435 conn_free_internal(conn); 309 436 return; 310 437 } 311 438 439 /* SMB1 */ 312 440 DLIST_REMOVE(conn->sconn->smb1.tcons.Connections, conn); 313 441 314 bitmap_clear(conn->sconn->smb1.tcons.bmap, conn->cnum); 315 316 SMB_ASSERT(conn->sconn->smb1.tcons.num_open > 0); 317 conn->sconn->smb1.tcons.num_open--; 442 if (conn->sconn->smb1.tcons.bmap != NULL) { 443 /* 444 * Can be NULL for fake connections created by 445 * create_conn_struct() 446 */ 447 bitmap_clear(conn->sconn->smb1.tcons.bmap, conn->cnum); 448 } 449 450 SMB_ASSERT(conn->sconn->num_tcons_open > 0); 451 conn->sconn->num_tcons_open--; 318 452 319 453 conn_free_internal(conn); 320 454 } 321 322 /**************************************************************************** 323 receive a smbcontrol message to forcibly unmount a share 324 the message contains just a share name and all instances of that 325 share are unmounted 326 the special sharename '*' forces unmount of all shares 327 ****************************************************************************/ 455 456 /**************************************************************************** 457 Receive a smbcontrol message to forcibly unmount a share. 458 The message contains just a share name and all instances of that 459 share are unmounted. 460 The special sharename '*' forces unmount of all shares. 461 ****************************************************************************/ 462 328 463 void msg_force_tdis(struct messaging_context *msg, 329 464 void *private_data, … … 332 467 DATA_BLOB *data) 333 468 { 334 struct smbd_server_connection *sconn = smbd_server_conn;469 struct smbd_server_connection *sconn; 335 470 connection_struct *conn, *next; 336 471 fstring sharename; 472 473 sconn = msg_ctx_to_sconn(msg); 474 if (sconn == NULL) { 475 DEBUG(1, ("could not find sconn\n")); 476 return; 477 } 337 478 338 479 fstrcpy(sharename, (const char *)data->data); … … 344 485 } 345 486 346 for (conn=sconn->smb1.tcons.Connections;conn;conn=next) { 347 next=conn->next; 348 if (strequal(lp_servicename(SNUM(conn)), sharename)) { 349 DEBUG(1,("Forcing close of share %s cnum=%d\n", 350 sharename, conn->cnum)); 351 close_cnum(conn, (uint16)-1); 352 } 353 } 354 } 487 if (sconn->using_smb2) { 488 /* SMB2 */ 489 struct smbd_smb2_session *sess; 490 for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) { 491 struct smbd_smb2_tcon *tcon, *tc_next; 492 493 for (tcon = sess->tcons.list; tcon; tcon = tc_next) { 494 tc_next = tcon->next; 495 if (tcon->compat_conn && 496 strequal(lp_servicename(SNUM(tcon->compat_conn)), 497 sharename)) { 498 DEBUG(1,("Forcing close of share %s cnum=%d\n", 499 sharename, tcon->compat_conn->cnum)); 500 TALLOC_FREE(tcon); 501 } 502 } 503 } 504 } else { 505 /* SMB1 */ 506 for (conn=sconn->smb1.tcons.Connections;conn;conn=next) { 507 next=conn->next; 508 if (strequal(lp_servicename(SNUM(conn)), sharename)) { 509 DEBUG(1,("Forcing close of share %s cnum=%d\n", 510 sharename, conn->cnum)); 511 close_cnum(conn, (uint16)-1); 512 } 513 } 514 } 515 }
Note:
See TracChangeset
for help on using the changeset viewer.