summaryrefslogtreecommitdiff
path: root/source4/smb_server/handle.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2006-05-20 08:15:22 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:08:10 -0500
commit9ef33f5f5c786b83311ca088357fb2f0aa72fc9e (patch)
tree66335dced1641119f94e6c656dd1ccc673218d0c /source4/smb_server/handle.c
parent0dcecc314899b6f36e9215e0b3881220062ba4f9 (diff)
downloadsamba-9ef33f5f5c786b83311ca088357fb2f0aa72fc9e.tar.gz
samba-9ef33f5f5c786b83311ca088357fb2f0aa72fc9e.tar.bz2
samba-9ef33f5f5c786b83311ca088357fb2f0aa72fc9e.zip
r15734: This is a major change to the NTVFS subsystem:
- to use a struct ntvfs_handle instead of a uint16_t fnum. (to make it independend from the frontend protocol) - the allocation of handles now is provided by the frontend (smbsrv_*) via callbacks and not by each backend module - this also makes sure that file handles are only passed to the ntvfs subsystem when the tcon and session matches, so modules can rely on this and need to check this. - this allows multiple modules in the ntvfs module chain to allocate file handles. This can be used for virtual files like "\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION"... - also this will make SMB2 with 128 bit file handles possible metze (This used to be commit 287fc1c22d670f6e568014b420f7f4cb31dc7958)
Diffstat (limited to 'source4/smb_server/handle.c')
-rw-r--r--source4/smb_server/handle.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/source4/smb_server/handle.c b/source4/smb_server/handle.c
new file mode 100644
index 0000000000..c2fea9e91c
--- /dev/null
+++ b/source4/smb_server/handle.c
@@ -0,0 +1,137 @@
+/*
+ Unix SMB/CIFS implementation.
+ Manage smbsrv_handle structures
+ Copyright (C) Stefan Metzmacher 2006
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "dlinklist.h"
+#include "smb_server/smb_server.h"
+#include "ntvfs/ntvfs.h"
+
+
+/****************************************************************************
+init the handle structures
+****************************************************************************/
+NTSTATUS smbsrv_init_handles(struct smbsrv_tcon *tcon, uint64_t limit)
+{
+ /*
+ * the idr_* functions take 'int' as limit,
+ * and only work with a max limit 0x00FFFFFF
+ */
+ limit &= 0x00FFFFFF;
+
+ tcon->handles.idtree_hid = idr_init(tcon);
+ NT_STATUS_HAVE_NO_MEMORY(tcon->handles.idtree_hid);
+ tcon->handles.idtree_limit = limit;
+ tcon->handles.list = NULL;
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+find a handle given a handle id
+****************************************************************************/
+static struct smbsrv_handle *smbsrv_handle_find(struct smbsrv_handles_context *handles_ctx,
+ uint64_t hid, struct timeval request_time)
+{
+ void *p;
+ struct smbsrv_handle *handle;
+
+ if (hid == 0) return NULL;
+
+ if (hid > handles_ctx->idtree_limit) return NULL;
+
+ p = idr_find(handles_ctx->idtree_hid, hid);
+ if (!p) return NULL;
+
+ handle = talloc_get_type(p, struct smbsrv_handle);
+ if (!handle) return NULL;
+
+ /* only give it away when the ntvfs subsystem has made the handle valid */
+ if (!handle->ntvfs) return NULL;
+
+ handle->statistics.last_use_time = request_time;
+
+ return handle;
+}
+
+struct smbsrv_handle *smbsrv_smb_handle_find(struct smbsrv_tcon *smb_tcon,
+ uint16_t fnum, struct timeval request_time)
+{
+ return smbsrv_handle_find(&smb_tcon->handles, fnum, request_time);
+}
+
+/*
+ destroy a connection structure
+*/
+static int smbsrv_handle_destructor(void *ptr)
+{
+ struct smbsrv_handle *handle = talloc_get_type(ptr, struct smbsrv_handle);
+ struct smbsrv_handles_context *handles_ctx;
+
+ handles_ctx = &handle->tcon->handles;
+
+ idr_remove(handles_ctx->idtree_hid, handle->hid);
+ DLIST_REMOVE(handles_ctx->list, handle);
+ DLIST_REMOVE(handle->session->handles, &handle->session_item);
+
+ /* tell the ntvfs backend that we are disconnecting */
+ if (handle->ntvfs) {
+ talloc_free(handle->ntvfs);
+ handle->ntvfs = NULL;
+ }
+
+ return 0;
+}
+
+/*
+ find first available handle slot
+*/
+struct smbsrv_handle *smbsrv_handle_new(struct smbsrv_request *req)
+{
+ struct smbsrv_handles_context *handles_ctx = &req->tcon->handles;
+ struct smbsrv_handle *handle;
+ int i;
+
+ handle = talloc_zero(req, struct smbsrv_handle);
+ if (!handle) return NULL;
+ handle->tcon = req->tcon;
+ handle->session = req->session;
+
+ i = idr_get_new_above(handles_ctx->idtree_hid, handle, 1, handles_ctx->idtree_limit);
+ if (i == -1) {
+ DEBUG(1,("ERROR! Out of handle structures\n"));
+ goto failed;
+ }
+ handle->hid = i;
+ handle->session_item.handle = handle;
+
+ DLIST_ADD(handles_ctx->list, handle);
+ DLIST_ADD(handle->session->handles, &handle->session_item);
+ talloc_set_destructor(handle, smbsrv_handle_destructor);
+
+ /* now fill in some statistics */
+ handle->statistics.open_time = req->request_time;
+ handle->statistics.last_use_time = req->request_time;
+
+ return handle;
+
+failed:
+ talloc_free(handle);
+ return NULL;
+}