Merge Samba3 and Samba4 together
[kai/samba.git] / source4 / rpc_server / handles.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    server side dcerpc handle code
5
6    Copyright (C) Andrew Tridgell 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "lib/util/dlinklist.h"
24 #include "rpc_server/dcerpc_server.h"
25
26 /*
27   destroy a rpc handle
28 */
29 static int dcesrv_handle_destructor(struct dcesrv_handle *h)
30 {
31         DLIST_REMOVE(h->context->handles, h);
32         talloc_free(h);
33         return 0;
34 }
35
36
37 /*
38   allocate a new rpc handle
39 */
40 _PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_context *context, 
41                                         uint8_t handle_type)
42 {
43         struct dcesrv_handle *h;
44
45         h = talloc(context, struct dcesrv_handle);
46         if (!h) {
47                 return NULL;
48         }
49         h->data = NULL;
50         h->context = context;
51
52         h->wire_handle.handle_type = handle_type;
53         h->wire_handle.uuid = GUID_random();
54         
55         DLIST_ADD(context->handles, h);
56
57         talloc_set_destructor(h, dcesrv_handle_destructor);
58
59         return h;
60 }
61
62 /**
63   find an internal handle given a wire handle. If the wire handle is NULL then
64   allocate a new handle
65 */
66 _PUBLIC_ struct dcesrv_handle *dcesrv_handle_fetch(
67                                           struct dcesrv_connection_context *context, 
68                                           struct policy_handle *p,
69                                           uint8_t handle_type)
70 {
71         struct dcesrv_handle *h;
72
73         if (policy_handle_empty(p)) {
74                 return dcesrv_handle_new(context, handle_type);
75         }
76
77         for (h=context->handles; h; h=h->next) {
78                 if (h->wire_handle.handle_type == p->handle_type &&
79                     GUID_equal(&p->uuid, &h->wire_handle.uuid)) {
80                         if (handle_type != DCESRV_HANDLE_ANY &&
81                             p->handle_type != handle_type) {
82                                 DEBUG(0,("client gave us the wrong handle type (%d should be %d)\n",
83                                          p->handle_type, handle_type));
84                                 return NULL;
85                         }
86                         return h;
87                 }
88         }
89
90         return NULL;
91 }