s3-rpc_server: remove unnecessary talloc_free
[kai/samba.git] / source3 / rpc_server / rpc_handles.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Jeremy Allison                           2001.
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 "../librpc/gen_ndr/ndr_lsa.h"
24 #include "../librpc/gen_ndr/ndr_samr.h"
25 #include "auth.h"
26 #include "rpc_server/rpc_pipes.h"
27 #include "../libcli/security/security.h"
28 #include "lib/tsocket/tsocket.h"
29
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_RPC_SRV
32
33 static struct pipes_struct *InternalPipes;
34
35 /* TODO
36  * the following prototypes are declared here to avoid
37  * code being moved about too much for a patch to be
38  * disrupted / less obvious.
39  *
40  * these functions, and associated functions that they
41  * call, should be moved behind a .so module-loading
42  * system _anyway_.  so that's the next step...
43  */
44
45 int make_base_pipes_struct(TALLOC_CTX *mem_ctx,
46                            struct messaging_context *msg_ctx,
47                            const char *pipe_name,
48                            enum dcerpc_transport_t transport,
49                            bool endian, bool ncalrpc_as_system,
50                            const struct tsocket_address *remote_address,
51                            const struct tsocket_address *local_address,
52                            struct pipes_struct **_p)
53 {
54         struct pipes_struct *p;
55
56         p = talloc_zero(mem_ctx, struct pipes_struct);
57         if (!p) {
58                 return ENOMEM;
59         }
60
61         p->mem_ctx = talloc_named(p, 0, "pipe %s %p", pipe_name, p);
62         if (!p->mem_ctx) {
63                 talloc_free(p);
64                 return ENOMEM;
65         }
66
67         p->msg_ctx = msg_ctx;
68         p->transport = transport;
69         p->endian = endian;
70         p->ncalrpc_as_system = ncalrpc_as_system;
71
72         p->remote_address = tsocket_address_copy(remote_address, p);
73         if (p->remote_address == NULL) {
74                 talloc_free(p);
75                 return ENOMEM;
76         }
77
78         if (local_address) {
79                 p->local_address = tsocket_address_copy(local_address, p);
80                 if (p->local_address == NULL) {
81                         talloc_free(p);
82                         return ENOMEM;
83                 }
84         }
85
86         DLIST_ADD(InternalPipes, p);
87         talloc_set_destructor(p, close_internal_rpc_pipe_hnd);
88
89         *_p = p;
90         return 0;
91 }
92
93
94 bool check_open_pipes(void)
95 {
96         struct pipes_struct *p;
97
98         for (p = InternalPipes; p != NULL; p = p->next) {
99                 if (num_pipe_handles(p) != 0) {
100                         return true;
101                 }
102         }
103         return false;
104 }
105
106 /****************************************************************************
107  Close an rpc pipe.
108 ****************************************************************************/
109
110 static void free_pipe_rpc_context_internal(struct pipe_rpc_fns *list)
111 {
112         struct pipe_rpc_fns *tmp = list;
113         struct pipe_rpc_fns *tmp2;
114
115         while (tmp) {
116                 tmp2 = tmp->next;
117                 SAFE_FREE(tmp);
118                 tmp = tmp2;
119         }
120
121         return;
122 }
123
124 int close_internal_rpc_pipe_hnd(struct pipes_struct *p)
125 {
126         if (!p) {
127                 DEBUG(0,("Invalid pipe in close_internal_rpc_pipe_hnd\n"));
128                 return False;
129         }
130
131         /* Free the handles database. */
132         close_policy_by_pipe(p);
133
134         free_pipe_rpc_context_internal( p->contexts );
135
136         DLIST_REMOVE(InternalPipes, p);
137
138         ZERO_STRUCTP(p);
139
140         return 0;
141 }
142
143 /*
144  * Handle database - stored per pipe.
145  */
146
147 struct dcesrv_handle {
148         struct dcesrv_handle *prev, *next;
149         struct policy_handle wire_handle;
150         uint32_t access_granted;
151         void *data;
152 };
153
154 struct handle_list {
155         struct dcesrv_handle *handles;  /* List of pipe handles. */
156         size_t count;                   /* Current number of handles. */
157         size_t pipe_ref_count;          /* Number of pipe handles referring
158                                          * to this tree. */
159 };
160
161 /* This is the max handles across all instances of a pipe name. */
162 #ifndef MAX_OPEN_POLS
163 #define MAX_OPEN_POLS 2048
164 #endif
165
166 /****************************************************************************
167  Hack as handles need to be persisant over lsa pipe closes so long as a samr
168  pipe is open. JRA.
169 ****************************************************************************/
170
171 static bool is_samr_lsa_pipe(const struct ndr_syntax_id *syntax)
172 {
173         return (ndr_syntax_id_equal(syntax, &ndr_table_samr.syntax_id)
174                 || ndr_syntax_id_equal(syntax, &ndr_table_lsarpc.syntax_id));
175 }
176
177 size_t num_pipe_handles(struct pipes_struct *p)
178 {
179         if (p->pipe_handles == NULL) {
180                 return 0;
181         }
182         return p->pipe_handles->count;
183 }
184
185 /****************************************************************************
186  Initialise a policy handle list on a pipe. Handle list is shared between all
187  pipes of the same name.
188 ****************************************************************************/
189
190 bool init_pipe_handles(struct pipes_struct *p, const struct ndr_syntax_id *syntax)
191 {
192         struct pipes_struct *plist;
193         struct handle_list *hl;
194
195         for (plist = InternalPipes; plist; plist = plist->next) {
196                 struct pipe_rpc_fns *p_ctx;
197                 bool stop = false;
198
199                 for (p_ctx = plist->contexts;
200                      p_ctx != NULL;
201                      p_ctx = p_ctx->next) {
202                         if (ndr_syntax_id_equal(syntax, &p_ctx->syntax)) {
203                                 stop = true;
204                                 break;
205                         }
206                         if (is_samr_lsa_pipe(&p_ctx->syntax)
207                             && is_samr_lsa_pipe(syntax)) {
208                                 /*
209                                  * samr and lsa share a handle space (same process
210                                  * under Windows?)
211                                  */
212                                 stop = true;
213                                 break;
214                         }
215                 }
216
217                 if (stop) {
218                         break;
219                 }
220         }
221
222         if (plist != NULL) {
223                 hl = plist->pipe_handles;
224                 if (hl == NULL) {
225                         return false;
226                 }
227         } else {
228                 /*
229                  * First open, we have to create the handle list
230                  */
231                 hl = talloc_zero(NULL, struct handle_list);
232                 if (hl == NULL) {
233                         return false;
234                 }
235
236                 DEBUG(10,("init_pipe_handle_list: created handle list for "
237                           "pipe %s\n",
238                           get_pipe_name_from_syntax(talloc_tos(), syntax)));
239         }
240
241         /*
242          * One more pipe is using this list.
243          */
244
245         hl->pipe_ref_count++;
246
247         /*
248          * Point this pipe at this list.
249          */
250
251         p->pipe_handles = hl;
252
253         DEBUG(10,("init_pipe_handle_list: pipe_handles ref count = %lu for "
254                   "pipe %s\n", (unsigned long)p->pipe_handles->pipe_ref_count,
255                   get_pipe_name_from_syntax(talloc_tos(), syntax)));
256
257         return True;
258 }
259
260 /****************************************************************************
261   find first available policy slot.  creates a policy handle for you.
262
263   If "data_ptr" is given, this must be a talloc'ed object, create_policy_hnd
264   talloc_moves this into the handle. If the policy_hnd is closed,
265   data_ptr is TALLOC_FREE()'ed
266 ****************************************************************************/
267
268 static struct dcesrv_handle *create_rpc_handle_internal(struct pipes_struct *p,
269                                 struct policy_handle *hnd, void *data_ptr)
270 {
271         struct dcesrv_handle *rpc_hnd;
272         static uint32 pol_hnd_low  = 0;
273         static uint32 pol_hnd_high = 0;
274         time_t t = time(NULL);
275
276         if (p->pipe_handles->count > MAX_OPEN_POLS) {
277                 DEBUG(0,("create_policy_hnd: ERROR: too many handles (%d) on this pipe.\n",
278                                 (int)p->pipe_handles->count));
279                 return NULL;
280         }
281
282         rpc_hnd = talloc_zero(p->pipe_handles, struct dcesrv_handle);
283         if (!rpc_hnd) {
284                 DEBUG(0,("create_policy_hnd: ERROR: out of memory!\n"));
285                 return NULL;
286         }
287
288         if (data_ptr != NULL) {
289                 rpc_hnd->data = talloc_move(rpc_hnd, &data_ptr);
290         }
291
292         pol_hnd_low++;
293         if (pol_hnd_low == 0) {
294                 pol_hnd_high++;
295         }
296
297         /* first bit must be null */
298         SIVAL(&rpc_hnd->wire_handle.handle_type, 0 , 0);
299
300         /* second bit is incrementing */
301         SIVAL(&rpc_hnd->wire_handle.uuid.time_low, 0 , pol_hnd_low);
302         SSVAL(&rpc_hnd->wire_handle.uuid.time_mid, 0 , pol_hnd_high);
303         SSVAL(&rpc_hnd->wire_handle.uuid.time_hi_and_version, 0, (pol_hnd_high >> 16));
304
305         /* split the current time into two 16 bit values */
306
307         /* something random */
308         SSVAL(rpc_hnd->wire_handle.uuid.clock_seq, 0, (t >> 16));
309         /* something random */
310         SSVAL(rpc_hnd->wire_handle.uuid.node, 0, t);
311         /* something more random */
312         SIVAL(rpc_hnd->wire_handle.uuid.node, 2, sys_getpid());
313
314         DLIST_ADD(p->pipe_handles->handles, rpc_hnd);
315         p->pipe_handles->count++;
316
317         *hnd = rpc_hnd->wire_handle;
318
319         DEBUG(4, ("Opened policy hnd[%d] ", (int)p->pipe_handles->count));
320         dump_data(4, (uint8_t *)hnd, sizeof(*hnd));
321
322         return rpc_hnd;
323 }
324
325 bool create_policy_hnd(struct pipes_struct *p, struct policy_handle *hnd,
326                        void *data_ptr)
327 {
328         struct dcesrv_handle *rpc_hnd;
329
330         rpc_hnd = create_rpc_handle_internal(p, hnd, data_ptr);
331         if (rpc_hnd == NULL) {
332                 return false;
333         }
334         return true;
335 }
336
337 /****************************************************************************
338   find policy by handle - internal version.
339 ****************************************************************************/
340
341 static struct dcesrv_handle *find_policy_by_hnd_internal(struct pipes_struct *p,
342                                 const struct policy_handle *hnd, void **data_p)
343 {
344         struct dcesrv_handle *h;
345         unsigned int count;
346
347         if (data_p) {
348                 *data_p = NULL;
349         }
350
351         count = 0;
352         for (h = p->pipe_handles->handles; h != NULL; h = h->next) {
353                 if (memcmp(&h->wire_handle, hnd, sizeof(*hnd)) == 0) {
354                         DEBUG(4,("Found policy hnd[%u] ", count));
355                         dump_data(4, (const uint8 *)hnd, sizeof(*hnd));
356                         if (data_p) {
357                                 *data_p = h->data;
358                         }
359                         return h;
360                 }
361                 count++;
362         }
363
364         DEBUG(4,("Policy not found: "));
365         dump_data(4, (const uint8_t *)hnd, sizeof(*hnd));
366
367         p->bad_handle_fault_state = true;
368
369         return NULL;
370 }
371
372 /****************************************************************************
373   find policy by handle
374 ****************************************************************************/
375
376 bool find_policy_by_hnd(struct pipes_struct *p, const struct policy_handle *hnd,
377                         void **data_p)
378 {
379         struct dcesrv_handle *rpc_hnd;
380
381         rpc_hnd = find_policy_by_hnd_internal(p, hnd, data_p);
382         if (rpc_hnd == NULL) {
383                 return false;
384         }
385         return true;
386 }
387
388 /****************************************************************************
389   Close a policy.
390 ****************************************************************************/
391
392 bool close_policy_hnd(struct pipes_struct *p, struct policy_handle *hnd)
393 {
394         struct dcesrv_handle *rpc_hnd;
395
396         rpc_hnd = find_policy_by_hnd_internal(p, hnd, NULL);
397
398         if (rpc_hnd == NULL) {
399                 DEBUG(3, ("Error closing policy (policy not found)\n"));
400                 return false;
401         }
402
403         DEBUG(3,("Closed policy\n"));
404
405         p->pipe_handles->count--;
406
407         DLIST_REMOVE(p->pipe_handles->handles, rpc_hnd);
408         TALLOC_FREE(rpc_hnd);
409
410         return true;
411 }
412
413 /****************************************************************************
414  Close a pipe - free the handle set if it was the last pipe reference.
415 ****************************************************************************/
416
417 void close_policy_by_pipe(struct pipes_struct *p)
418 {
419         if (p->pipe_handles == NULL) {
420                 return;
421         }
422
423         p->pipe_handles->pipe_ref_count--;
424
425         if (p->pipe_handles->pipe_ref_count == 0) {
426                 /*
427                  * Last pipe open on this list - free the list.
428                  */
429                 TALLOC_FREE(p->pipe_handles);
430
431                 DEBUG(10,("Deleted handle list for RPC connection %s\n",
432                           get_pipe_name_from_syntax(talloc_tos(),
433                                                     &p->contexts->syntax)));
434         }
435 }
436
437 /*******************************************************************
438 Shall we allow access to this rpc?  Currently this function
439 implements the 'restrict anonymous' setting by denying access to
440 anonymous users if the restrict anonymous level is > 0.  Further work
441 will be checking a security descriptor to determine whether a user
442 token has enough access to access the pipe.
443 ********************************************************************/
444
445 bool pipe_access_check(struct pipes_struct *p)
446 {
447         /* Don't let anonymous users access this RPC if restrict
448            anonymous > 0 */
449
450         if (lp_restrict_anonymous() > 0) {
451
452                 /* schannel, so we must be ok */
453                 if (p->pipe_bound &&
454                     (p->auth.auth_type == DCERPC_AUTH_TYPE_SCHANNEL)) {
455                         return True;
456                 }
457
458                 if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
459                         return False;
460                 }
461         }
462
463         return True;
464 }
465
466 void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
467                             uint32_t access_granted, size_t data_size,
468                             const char *type, NTSTATUS *pstatus)
469 {
470         struct dcesrv_handle *rpc_hnd;
471         void *data;
472
473         if (p->pipe_handles->count > MAX_OPEN_POLS) {
474                 DEBUG(0, ("ERROR: Too many handles (%d) for RPC connection %s\n",
475                           (int) p->pipe_handles->count,
476                           get_pipe_name_from_syntax(talloc_tos(),
477                                                     &p->contexts->syntax)));
478                 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
479                 return NULL;
480         }
481
482         data = talloc_size(talloc_tos(), data_size);
483         if (data == NULL) {
484                 *pstatus = NT_STATUS_NO_MEMORY;
485                 return NULL;
486         }
487         talloc_set_name_const(data, type);
488
489         rpc_hnd = create_rpc_handle_internal(p, hnd, data);
490         if (rpc_hnd == NULL) {
491                 TALLOC_FREE(data);
492                 *pstatus = NT_STATUS_NO_MEMORY;
493                 return NULL;
494         }
495         rpc_hnd->access_granted = access_granted;
496         *pstatus = NT_STATUS_OK;
497         return data;
498 }
499
500 void *_policy_handle_find(struct pipes_struct *p,
501                           const struct policy_handle *hnd,
502                           uint32_t access_required,
503                           uint32_t *paccess_granted,
504                           const char *name, const char *location,
505                           NTSTATUS *pstatus)
506 {
507         struct dcesrv_handle *rpc_hnd;
508         void *data;
509
510         rpc_hnd = find_policy_by_hnd_internal(p, hnd, &data);
511         if (rpc_hnd == NULL) {
512                 *pstatus = NT_STATUS_INVALID_HANDLE;
513                 return NULL;
514         }
515         if (strcmp(name, talloc_get_name(data)) != 0) {
516                 DEBUG(10, ("expected %s, got %s\n", name,
517                            talloc_get_name(data)));
518                 *pstatus = NT_STATUS_INVALID_HANDLE;
519                 return NULL;
520         }
521         if ((access_required & rpc_hnd->access_granted) != access_required) {
522                 if (geteuid() == sec_initial_uid()) {
523                         DEBUG(4, ("%s: ACCESS should be DENIED (granted: "
524                                   "%#010x; required: %#010x)\n", location,
525                                   rpc_hnd->access_granted, access_required));
526                         DEBUGADD(4,("but overwritten by euid == 0\n"));
527                         goto okay;
528                 }
529                 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: "
530                          "%#010x)\n", location, rpc_hnd->access_granted,
531                          access_required));
532                 *pstatus = NT_STATUS_ACCESS_DENIED;
533                 return NULL;
534         }
535
536  okay:
537         DEBUG(10, ("found handle of type %s\n", talloc_get_name(data)));
538         if (paccess_granted != NULL) {
539                 *paccess_granted = rpc_hnd->access_granted;
540         }
541         *pstatus = NT_STATUS_OK;
542         return data;
543 }