summaryrefslogtreecommitdiffstats
path: root/source4/smb_server/conn.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/smb_server/conn.c')
-rw-r--r--source4/smb_server/conn.c44
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;
}