Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : Manage smbsrv_handle structures 4 : Copyright (C) Stefan Metzmacher 2006 5 : 6 : This program is free software; you can redistribute it and/or modify 7 : it under the terms of the GNU General Public License as published by 8 : the Free Software Foundation; either version 3 of the License, or 9 : (at your option) any later version. 10 : 11 : This program is distributed in the hope that it will be useful, 12 : but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : GNU General Public License for more details. 15 : 16 : You should have received a copy of the GNU General Public License 17 : along with this program. If not, see <http://www.gnu.org/licenses/>. 18 : */ 19 : 20 : #include "includes.h" 21 : #include "smb_server/smb_server.h" 22 : #include "lib/util/idtree.h" 23 : 24 : /**************************************************************************** 25 : init the handle structures 26 : ****************************************************************************/ 27 2555 : NTSTATUS smbsrv_init_handles(struct smbsrv_tcon *tcon, uint32_t limit) 28 : { 29 : /* 30 : * the idr_* functions take 'int' as limit, 31 : * and only work with a max limit 0x00FFFFFF 32 : */ 33 2555 : limit &= 0x00FFFFFF; 34 : 35 2555 : tcon->handles.idtree_hid = idr_init(tcon); 36 2555 : NT_STATUS_HAVE_NO_MEMORY(tcon->handles.idtree_hid); 37 2555 : tcon->handles.idtree_limit = limit; 38 2555 : tcon->handles.list = NULL; 39 : 40 2555 : return NT_STATUS_OK; 41 : } 42 : 43 : /**************************************************************************** 44 : find a handle given a handle id 45 : ****************************************************************************/ 46 517199 : static struct smbsrv_handle *smbsrv_handle_find(struct smbsrv_handles_context *handles_ctx, 47 : uint32_t hid, struct timeval request_time) 48 : { 49 0 : void *p; 50 0 : struct smbsrv_handle *handle; 51 : 52 517199 : if (hid == 0) return NULL; 53 : 54 467091 : if (hid > handles_ctx->idtree_limit) return NULL; 55 : 56 464920 : p = idr_find(handles_ctx->idtree_hid, hid); 57 464920 : if (!p) return NULL; 58 : 59 464486 : handle = talloc_get_type(p, struct smbsrv_handle); 60 464486 : if (!handle) return NULL; 61 : 62 : /* only give it away when the ntvfs subsystem has made the handle valid */ 63 464486 : if (!handle->ntvfs) return NULL; 64 : 65 464486 : handle->statistics.last_use_time = request_time; 66 : 67 464486 : return handle; 68 : } 69 : 70 320796 : struct smbsrv_handle *smbsrv_smb_handle_find(struct smbsrv_tcon *smb_tcon, 71 : uint16_t fnum, struct timeval request_time) 72 : { 73 320796 : return smbsrv_handle_find(&smb_tcon->handles, fnum, request_time); 74 : } 75 : 76 196403 : struct smbsrv_handle *smbsrv_smb2_handle_find(struct smbsrv_tcon *smb_tcon, 77 : uint32_t hid, struct timeval request_time) 78 : { 79 196403 : return smbsrv_handle_find(&smb_tcon->handles, hid, request_time); 80 : } 81 : 82 : /* 83 : destroy a connection structure 84 : */ 85 220947 : static int smbsrv_handle_destructor(struct smbsrv_handle *handle) 86 : { 87 0 : struct smbsrv_handles_context *handles_ctx; 88 : 89 220947 : handles_ctx = &handle->tcon->handles; 90 : 91 220947 : idr_remove(handles_ctx->idtree_hid, handle->hid); 92 220947 : DLIST_REMOVE(handles_ctx->list, handle); 93 220947 : DLIST_REMOVE(handle->session->handles, &handle->session_item); 94 : 95 : /* tell the ntvfs backend that we are disconnecting */ 96 220947 : if (handle->ntvfs) { 97 216370 : talloc_free(handle->ntvfs); 98 216370 : handle->ntvfs = NULL; 99 : } 100 : 101 220947 : return 0; 102 : } 103 : 104 : /* 105 : find first available handle slot 106 : */ 107 220947 : struct smbsrv_handle *smbsrv_handle_new(struct smbsrv_session *session, 108 : struct smbsrv_tcon *tcon, 109 : TALLOC_CTX *mem_ctx, 110 : struct timeval request_time) 111 : { 112 220947 : struct smbsrv_handles_context *handles_ctx = &tcon->handles; 113 0 : struct smbsrv_handle *handle; 114 0 : int i; 115 : 116 220947 : handle = talloc_zero(mem_ctx, struct smbsrv_handle); 117 220947 : if (!handle) return NULL; 118 220947 : handle->tcon = tcon; 119 220947 : handle->session = session; 120 : 121 220947 : i = idr_get_new_above(handles_ctx->idtree_hid, handle, 1, handles_ctx->idtree_limit); 122 220947 : if (i == -1) { 123 0 : DEBUG(1,("ERROR! Out of handle structures\n")); 124 0 : goto failed; 125 : } 126 220947 : handle->hid = i; 127 220947 : handle->session_item.handle = handle; 128 : 129 220947 : DLIST_ADD(handles_ctx->list, handle); 130 220947 : DLIST_ADD(session->handles, &handle->session_item); 131 220947 : talloc_set_destructor(handle, smbsrv_handle_destructor); 132 : 133 : /* now fill in some statistics */ 134 220947 : handle->statistics.open_time = request_time; 135 220947 : handle->statistics.last_use_time = request_time; 136 : 137 220947 : return handle; 138 : 139 0 : failed: 140 0 : talloc_free(handle); 141 0 : return NULL; 142 : }