s3-rpc_server: Use talloc for pipe_rpc_fns
[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 int close_internal_rpc_pipe_hnd(struct pipes_struct *p)
111 {
112         if (!p) {
113                 DEBUG(0,("Invalid pipe in close_internal_rpc_pipe_hnd\n"));
114                 return False;
115         }
116
117         /* Free the handles database. */
118         close_policy_by_pipe(p);
119
120         DLIST_REMOVE(InternalPipes, p);
121
122         return 0;
123 }
124
125 /*
126  * Handle database - stored per pipe.
127  */
128
129 struct dcesrv_handle {
130         struct dcesrv_handle *prev, *next;
131         struct policy_handle wire_handle;
132         uint32_t access_granted;
133         void *data;
134 };
135
136 struct handle_list {
137         struct dcesrv_handle *handles;  /* List of pipe handles. */
138         size_t count;                   /* Current number of handles. */
139         size_t pipe_ref_count;          /* Number of pipe handles referring
140                                          * to this tree. */
141 };
142
143 /* This is the max handles across all instances of a pipe name. */
144 #ifndef MAX_OPEN_POLS
145 #define MAX_OPEN_POLS 2048
146 #endif
147
148 /****************************************************************************
149  Hack as handles need to be persisant over lsa pipe closes so long as a samr
150  pipe is open. JRA.
151 ****************************************************************************/
152
153 static bool is_samr_lsa_pipe(const struct ndr_syntax_id *syntax)
154 {
155         return (ndr_syntax_id_equal(syntax, &ndr_table_samr.syntax_id)
156                 || ndr_syntax_id_equal(syntax, &ndr_table_lsarpc.syntax_id));
157 }
158
159 size_t num_pipe_handles(struct pipes_struct *p)
160 {
161         if (p->pipe_handles == NULL) {
162                 return 0;
163         }
164         return p->pipe_handles->count;
165 }
166
167 /****************************************************************************
168  Initialise a policy handle list on a pipe. Handle list is shared between all
169  pipes of the same name.
170 ****************************************************************************/
171
172 bool init_pipe_handles(struct pipes_struct *p, const struct ndr_syntax_id *syntax)
173 {
174         struct pipes_struct *plist;
175         struct handle_list *hl;
176
177         for (plist = InternalPipes; plist; plist = plist->next) {
178                 struct pipe_rpc_fns *p_ctx;
179                 bool stop = false;
180
181                 for (p_ctx = plist->contexts;
182                      p_ctx != NULL;
183                      p_ctx = p_ctx->next) {
184                         if (ndr_syntax_id_equal(syntax, &p_ctx->syntax)) {
185                                 stop = true;
186                                 break;
187                         }
188                         if (is_samr_lsa_pipe(&p_ctx->syntax)
189                             && is_samr_lsa_pipe(syntax)) {
190                                 /*
191                                  * samr and lsa share a handle space (same process
192                                  * under Windows?)
193                                  */
194                                 stop = true;
195                                 break;
196                         }
197                 }
198
199                 if (stop) {
200                         break;
201                 }
202         }
203
204         if (plist != NULL) {
205                 hl = plist->pipe_handles;
206                 if (hl == NULL) {
207                         return false;
208                 }
209         } else {
210                 /*
211                  * First open, we have to create the handle list
212                  */
213                 hl = talloc_zero(NULL, struct handle_list);
214                 if (hl == NULL) {
215                         return false;
216                 }
217
218                 DEBUG(10,("init_pipe_handle_list: created handle list for "
219                           "pipe %s\n",
220                           get_pipe_name_from_syntax(talloc_tos(), syntax)));
221         }
222
223         /*
224          * One more pipe is using this list.
225          */
226
227         hl->pipe_ref_count++;
228
229         /*
230          * Point this pipe at this list.
231          */
232
233         p->pipe_handles = hl;
234
235         DEBUG(10,("init_pipe_handle_list: pipe_handles ref count = %lu for "
236                   "pipe %s\n", (unsigned long)p->pipe_handles->pipe_ref_count,
237                   get_pipe_name_from_syntax(talloc_tos(), syntax)));
238
239         return True;
240 }
241
242 /****************************************************************************
243   find first available policy slot.  creates a policy handle for you.
244
245   If "data_ptr" is given, this must be a talloc'ed object, create_policy_hnd
246   talloc_moves this into the handle. If the policy_hnd is closed,
247   data_ptr is TALLOC_FREE()'ed
248 ****************************************************************************/
249
250 static struct dcesrv_handle *create_rpc_handle_internal(struct pipes_struct *p,
251                                 struct policy_handle *hnd, void *data_ptr)
252 {
253         struct dcesrv_handle *rpc_hnd;
254         static uint32 pol_hnd_low  = 0;
255         static uint32 pol_hnd_high = 0;
256         time_t t = time(NULL);
257
258         if (p->pipe_handles->count > MAX_OPEN_POLS) {
259                 DEBUG(0,("create_policy_hnd: ERROR: too many handles (%d) on this pipe.\n",
260                                 (int)p->pipe_handles->count));
261                 return NULL;
262         }
263
264         rpc_hnd = talloc_zero(p->pipe_handles, struct dcesrv_handle);
265         if (!rpc_hnd) {
266                 DEBUG(0,("create_policy_hnd: ERROR: out of memory!\n"));
267                 return NULL;
268         }
269
270         if (data_ptr != NULL) {
271                 rpc_hnd->data = talloc_move(rpc_hnd, &data_ptr);
272         }
273
274         pol_hnd_low++;
275         if (pol_hnd_low == 0) {
276                 pol_hnd_high++;
277         }
278
279         /* first bit must be null */
280         SIVAL(&rpc_hnd->wire_handle.handle_type, 0 , 0);
281
282         /* second bit is incrementing */
283         SIVAL(&rpc_hnd->wire_handle.uuid.time_low, 0 , pol_hnd_low);
284         SSVAL(&rpc_hnd->wire_handle.uuid.time_mid, 0 , pol_hnd_high);
285         SSVAL(&rpc_hnd->wire_handle.uuid.time_hi_and_version, 0, (pol_hnd_high >> 16));
286
287         /* split the current time into two 16 bit values */
288
289         /* something random */
290         SSVAL(rpc_hnd->wire_handle.uuid.clock_seq, 0, (t >> 16));
291         /* something random */
292         SSVAL(rpc_hnd->wire_handle.uuid.node, 0, t);
293         /* something more random */
294         SIVAL(rpc_hnd->wire_handle.uuid.node, 2, sys_getpid());
295
296         DLIST_ADD(p->pipe_handles->handles, rpc_hnd);
297         p->pipe_handles->count++;
298
299         *hnd = rpc_hnd->wire_handle;
300
301         DEBUG(4, ("Opened policy hnd[%d] ", (int)p->pipe_handles->count));
302         dump_data(4, (uint8_t *)hnd, sizeof(*hnd));
303
304         return rpc_hnd;
305 }
306
307 bool create_policy_hnd(struct pipes_struct *p, struct policy_handle *hnd,
308                        void *data_ptr)
309 {
310         struct dcesrv_handle *rpc_hnd;
311
312         rpc_hnd = create_rpc_handle_internal(p, hnd, data_ptr);
313         if (rpc_hnd == NULL) {
314                 return false;
315         }
316         return true;
317 }
318
319 /****************************************************************************
320   find policy by handle - internal version.
321 ****************************************************************************/
322
323 static struct dcesrv_handle *find_policy_by_hnd_internal(struct pipes_struct *p,
324                                 const struct policy_handle *hnd, void **data_p)
325 {
326         struct dcesrv_handle *h;
327         unsigned int count;
328
329         if (data_p) {
330                 *data_p = NULL;
331         }
332
333         count = 0;
334         for (h = p->pipe_handles->handles; h != NULL; h = h->next) {
335                 if (memcmp(&h->wire_handle, hnd, sizeof(*hnd)) == 0) {
336                         DEBUG(4,("Found policy hnd[%u] ", count));
337                         dump_data(4, (const uint8 *)hnd, sizeof(*hnd));
338                         if (data_p) {
339                                 *data_p = h->data;
340                         }
341                         return h;
342                 }
343                 count++;
344         }
345
346         DEBUG(4,("Policy not found: "));
347         dump_data(4, (const uint8_t *)hnd, sizeof(*hnd));
348
349         p->bad_handle_fault_state = true;
350
351         return NULL;
352 }
353
354 /****************************************************************************
355   find policy by handle
356 ****************************************************************************/
357
358 bool find_policy_by_hnd(struct pipes_struct *p, const struct policy_handle *hnd,
359                         void **data_p)
360 {
361         struct dcesrv_handle *rpc_hnd;
362
363         rpc_hnd = find_policy_by_hnd_internal(p, hnd, data_p);
364         if (rpc_hnd == NULL) {
365                 return false;
366         }
367         return true;
368 }
369
370 /****************************************************************************
371   Close a policy.
372 ****************************************************************************/
373
374 bool close_policy_hnd(struct pipes_struct *p, struct policy_handle *hnd)
375 {
376         struct dcesrv_handle *rpc_hnd;
377
378         rpc_hnd = find_policy_by_hnd_internal(p, hnd, NULL);
379
380         if (rpc_hnd == NULL) {
381                 DEBUG(3, ("Error closing policy (policy not found)\n"));
382                 return false;
383         }
384
385         DEBUG(3,("Closed policy\n"));
386
387         p->pipe_handles->count--;
388
389         DLIST_REMOVE(p->pipe_handles->handles, rpc_hnd);
390         TALLOC_FREE(rpc_hnd);
391
392         return true;
393 }
394
395 /****************************************************************************
396  Close a pipe - free the handle set if it was the last pipe reference.
397 ****************************************************************************/
398
399 void close_policy_by_pipe(struct pipes_struct *p)
400 {
401         if (p->pipe_handles == NULL) {
402                 return;
403         }
404
405         p->pipe_handles->pipe_ref_count--;
406
407         if (p->pipe_handles->pipe_ref_count == 0) {
408                 /*
409                  * Last pipe open on this list - free the list.
410                  */
411                 TALLOC_FREE(p->pipe_handles);
412
413                 DEBUG(10,("Deleted handle list for RPC connection %s\n",
414                           get_pipe_name_from_syntax(talloc_tos(),
415                                                     &p->contexts->syntax)));
416         }
417 }
418
419 /*******************************************************************
420 Shall we allow access to this rpc?  Currently this function
421 implements the 'restrict anonymous' setting by denying access to
422 anonymous users if the restrict anonymous level is > 0.  Further work
423 will be checking a security descriptor to determine whether a user
424 token has enough access to access the pipe.
425 ********************************************************************/
426
427 bool pipe_access_check(struct pipes_struct *p)
428 {
429         /* Don't let anonymous users access this RPC if restrict
430            anonymous > 0 */
431
432         if (lp_restrict_anonymous() > 0) {
433
434                 /* schannel, so we must be ok */
435                 if (p->pipe_bound &&
436                     (p->auth.auth_type == DCERPC_AUTH_TYPE_SCHANNEL)) {
437                         return True;
438                 }
439
440                 if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
441                         return False;
442                 }
443         }
444
445         return True;
446 }
447
448 void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
449                             uint32_t access_granted, size_t data_size,
450                             const char *type, NTSTATUS *pstatus)
451 {
452         struct dcesrv_handle *rpc_hnd;
453         void *data;
454
455         if (p->pipe_handles->count > MAX_OPEN_POLS) {
456                 DEBUG(0, ("ERROR: Too many handles (%d) for RPC connection %s\n",
457                           (int) p->pipe_handles->count,
458                           get_pipe_name_from_syntax(talloc_tos(),
459                                                     &p->contexts->syntax)));
460                 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
461                 return NULL;
462         }
463
464         data = talloc_size(talloc_tos(), data_size);
465         if (data == NULL) {
466                 *pstatus = NT_STATUS_NO_MEMORY;
467                 return NULL;
468         }
469         talloc_set_name_const(data, type);
470
471         rpc_hnd = create_rpc_handle_internal(p, hnd, data);
472         if (rpc_hnd == NULL) {
473                 TALLOC_FREE(data);
474                 *pstatus = NT_STATUS_NO_MEMORY;
475                 return NULL;
476         }
477         rpc_hnd->access_granted = access_granted;
478         *pstatus = NT_STATUS_OK;
479         return data;
480 }
481
482 void *_policy_handle_find(struct pipes_struct *p,
483                           const struct policy_handle *hnd,
484                           uint32_t access_required,
485                           uint32_t *paccess_granted,
486                           const char *name, const char *location,
487                           NTSTATUS *pstatus)
488 {
489         struct dcesrv_handle *rpc_hnd;
490         void *data;
491
492         rpc_hnd = find_policy_by_hnd_internal(p, hnd, &data);
493         if (rpc_hnd == NULL) {
494                 *pstatus = NT_STATUS_INVALID_HANDLE;
495                 return NULL;
496         }
497         if (strcmp(name, talloc_get_name(data)) != 0) {
498                 DEBUG(10, ("expected %s, got %s\n", name,
499                            talloc_get_name(data)));
500                 *pstatus = NT_STATUS_INVALID_HANDLE;
501                 return NULL;
502         }
503         if ((access_required & rpc_hnd->access_granted) != access_required) {
504                 if (geteuid() == sec_initial_uid()) {
505                         DEBUG(4, ("%s: ACCESS should be DENIED (granted: "
506                                   "%#010x; required: %#010x)\n", location,
507                                   rpc_hnd->access_granted, access_required));
508                         DEBUGADD(4,("but overwritten by euid == 0\n"));
509                         goto okay;
510                 }
511                 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: "
512                          "%#010x)\n", location, rpc_hnd->access_granted,
513                          access_required));
514                 *pstatus = NT_STATUS_ACCESS_DENIED;
515                 return NULL;
516         }
517
518  okay:
519         DEBUG(10, ("found handle of type %s\n", talloc_get_name(data)));
520         if (paccess_granted != NULL) {
521                 *paccess_granted = rpc_hnd->access_granted;
522         }
523         *pstatus = NT_STATUS_OK;
524         return data;
525 }