summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/idl/irpc.idl2
-rw-r--r--source4/smb_server/conn.c44
-rw-r--r--source4/smb_server/management.c2
-rw-r--r--source4/smb_server/receive.c2
-rw-r--r--source4/smb_server/smb_server.h17
5 files changed, 50 insertions, 17 deletions
diff --git a/source4/librpc/idl/irpc.idl b/source4/librpc/idl/irpc.idl
index 27eccf9a33..6ca853d642 100644
--- a/source4/librpc/idl/irpc.idl
+++ b/source4/librpc/idl/irpc.idl
@@ -83,7 +83,7 @@
} smbsrv_sessions;
typedef struct {
- uint16 tid;
+ uint32 tid;
astring share_name;
astring client_ip;
NTTIME connect_time;
diff --git a/source4/smb_server/conn.c b/source4/smb_server/conn.c
index 5a5eeb3b0c..6714b61e90 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;
}
diff --git a/source4/smb_server/management.c b/source4/smb_server/management.c
index 23680be112..9f22ee94e8 100644
--- a/source4/smb_server/management.c
+++ b/source4/smb_server/management.c
@@ -82,7 +82,7 @@ static NTSTATUS smbsrv_tcon_information(struct irpc_message *msg,
struct smbsrv_tcon_info *info = &r->out.info.tcons.tcons[i];
info->tid = tcon->tid;
info->share_name = lp_servicename(tcon->service);
- info->connect_time = timeval_to_nttime(&tcon->connect_time);
+ info->connect_time = timeval_to_nttime(&tcon->statistics.connect_time);
info->client_ip = socket_get_peer_addr(smb_conn->connection->socket, r);
i++;
}
diff --git a/source4/smb_server/receive.c b/source4/smb_server/receive.c
index aa54d9867e..3ecd111af6 100644
--- a/source4/smb_server/receive.c
+++ b/source4/smb_server/receive.c
@@ -648,7 +648,7 @@ NTSTATUS smbsrv_init_smb_connection(struct smbsrv_connection *smb_conn)
status = smbsrv_init_sessions(smb_conn);
NT_STATUS_NOT_OK_RETURN(status);
- status = smbsrv_init_tcons(smb_conn);
+ status = smbsrv_init_tcons(smb_conn, UINT16_MAX);
NT_STATUS_NOT_OK_RETURN(status);
srv_init_signing(smb_conn);
diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h
index ddf4a2b627..46a10c74bb 100644
--- a/source4/smb_server/smb_server.h
+++ b/source4/smb_server/smb_server.h
@@ -3,7 +3,7 @@
Copyright (C) Andrew Tridgell 2003
Copyright (C) James J Myers 2003 <myersjj@samba.org>
- Copyright (C) Stefan Metzmacher 2004
+ Copyright (C) Stefan Metzmacher 2004-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -65,7 +65,12 @@ struct smbsrv_tcon {
/* the server context that this was created on */
struct smbsrv_connection *smb_conn;
- uint16_t tid; /* an index passed over the wire (the TID) */
+ /*
+ * an index passed over the wire:
+ * - 16 bit for smb
+ * - 32 bit for smb2
+ */
+ uint32_t tid; /* an index passed over the wire (the TID) */
int service;
BOOL read_only;
@@ -86,7 +91,10 @@ struct smbsrv_tcon {
struct smbsrv_session *session;
} sec_share;
- struct timeval connect_time;
+ /* some statictics for the management tools */
+ struct {
+ struct timeval connect_time;
+ } statistics;
};
/* a set of flags to control handling of request structures */
@@ -225,6 +233,9 @@ struct smbsrv_connection {
/* an id tree used to allocate tids */
struct idr_context *idtree_tid;
+ /* this is the limit of vuid values for this connection */
+ uint32_t idtree_limit;
+
/* list of open tree connects */
struct smbsrv_tcon *list;
} tcons;