diff options
Diffstat (limited to 'source4/smb_server/conn.c')
-rw-r--r-- | source4/smb_server/conn.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/source4/smb_server/conn.c b/source4/smb_server/conn.c index 5a5eeb3b0cd..6714b61e90f 100644 --- a/source4/smb_server/conn.c +++ b/source4/smb_server/conn.c @@ -29,19 +29,40 @@ /**************************************************************************** init the tcon structures ****************************************************************************/ -NTSTATUS smbsrv_init_tcons(struct smbsrv_connection *smb_conn) +NTSTATUS smbsrv_init_tcons(struct smbsrv_connection *smb_conn, uint32_t limit) { - smb_conn->tcons.idtree_tid = idr_init(smb_conn); + /* + * the idr_* functions take 'int' as limit, + * and only work with a max limit 0x00FFFFFF + */ + limit &= 0x00FFFFFF; + + smb_conn->tcons.idtree_tid = idr_init(smb_conn); NT_STATUS_HAVE_NO_MEMORY(smb_conn->tcons.idtree_tid); + smb_conn->tcons.idtree_limit = limit; + smb_conn->tcons.list = NULL; + return NT_STATUS_OK; } /**************************************************************************** find a tcon given a cnum ****************************************************************************/ -struct smbsrv_tcon *smbsrv_tcon_find(struct smbsrv_connection *smb_conn, uint_t tid) +struct smbsrv_tcon *smbsrv_tcon_find(struct smbsrv_connection *smb_conn, uint32_t tid) { - return idr_find(smb_conn->tcons.idtree_tid, tid); + void *p; + struct smbsrv_tcon *tcon; + + if (tid == 0) return NULL; + + if (tid > smb_conn->tcons.idtree_limit) return NULL; + + p = idr_find(smb_conn->tcons.idtree_tid, tid); + if (!p) return NULL; + + tcon = talloc_get_type(p, struct smbsrv_tcon); + + return tcon; } /* @@ -51,13 +72,14 @@ static int smbsrv_tcon_destructor(void *ptr) { struct smbsrv_tcon *tcon = ptr; - DEBUG(3,("%s closed connection to service %s\n", socket_get_peer_addr(tcon->smb_conn->connection->socket, tcon), lp_servicename(tcon->service))); /* tell the ntvfs backend that we are disconnecting */ - ntvfs_disconnect(tcon); + if (tcon->ntvfs_ctx) { + ntvfs_disconnect(tcon); + } idr_remove(tcon->smb_conn->tcons.idtree_tid, tcon->tid); DLIST_REMOVE(tcon->smb_conn->tcons.list, tcon); @@ -74,20 +96,20 @@ struct smbsrv_tcon *smbsrv_tcon_new(struct smbsrv_connection *smb_conn) tcon = talloc_zero(smb_conn, struct smbsrv_tcon); if (!tcon) return NULL; + tcon->smb_conn = smb_conn; - i = idr_get_new_random(smb_conn->tcons.idtree_tid, tcon, UINT16_MAX); + i = idr_get_new_random(smb_conn->tcons.idtree_tid, tcon, smb_conn->tcons.idtree_limit); if (i == -1) { DEBUG(1,("ERROR! Out of connection structures\n")); return NULL; } - tcon->tid = i; - tcon->smb_conn = smb_conn; - tcon->connect_time = timeval_current(); + DLIST_ADD(smb_conn->tcons.list, tcon); talloc_set_destructor(tcon, smbsrv_tcon_destructor); - DLIST_ADD(smb_conn->tcons.list, tcon); + /* now fill in some statistics */ + tcon->statistics.connect_time = timeval_current(); return tcon; } |