ncalrpc: Force ncalrpc dir to be mode 755 in all users
[samba.git] / source3 / rpc_server / rpc_server.c
1 /*
2    Unix SMB/Netbios implementation.
3    Generic infrstructure for RPC Daemons
4    Copyright (C) Simo Sorce 2010
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 "ntdomain.h"
22 #include "rpc_server/rpc_server.h"
23 #include "rpc_dce.h"
24 #include "librpc/gen_ndr/netlogon.h"
25 #include "librpc/gen_ndr/auth.h"
26 #include "lib/tsocket/tsocket.h"
27 #include "libcli/named_pipe_auth/npa_tstream.h"
28 #include "../auth/auth_sam_reply.h"
29 #include "auth.h"
30 #include "rpc_server/rpc_ncacn_np.h"
31 #include "rpc_server/srv_pipe_hnd.h"
32 #include "rpc_server/srv_pipe.h"
33
34 #define SERVER_TCP_LOW_PORT  1024
35 #define SERVER_TCP_HIGH_PORT 1300
36
37 static NTSTATUS auth_anonymous_session_info(TALLOC_CTX *mem_ctx,
38                                             struct auth_session_info **session_info)
39 {
40         struct auth_session_info *i;
41         struct auth_serversupplied_info *s;
42         struct auth_user_info_dc *u;
43         union netr_Validation val;
44         NTSTATUS status;
45
46         i = talloc_zero(mem_ctx, struct auth_session_info);
47         if (i == NULL) {
48                 return NT_STATUS_NO_MEMORY;
49         }
50
51         status = make_server_info_guest(i, &s);
52         if (!NT_STATUS_IS_OK(status)) {
53                 return status;
54         }
55
56         i->security_token = s->security_token;
57         i->session_key    = s->session_key;
58
59         val.sam3 = s->info3;
60
61         status = make_user_info_dc_netlogon_validation(mem_ctx,
62                                                        "",
63                                                        3,
64                                                        &val,
65                                                        &u);
66         if (!NT_STATUS_IS_OK(status)) {
67                 DEBUG(0, ("conversion of info3 into user_info_dc failed!\n"));
68                 return status;
69         }
70         i->info = talloc_move(i, &u->info);
71         talloc_free(u);
72
73         *session_info = i;
74
75         return NT_STATUS_OK;
76 }
77
78 /* Creates a pipes_struct and initializes it with the information
79  * sent from the client */
80 static int make_server_pipes_struct(TALLOC_CTX *mem_ctx,
81                                     const char *pipe_name,
82                                     const struct ndr_syntax_id id,
83                                     enum dcerpc_transport_t transport,
84                                     bool ncalrpc_as_system,
85                                     const char *client_address,
86                                     const char *server_address,
87                                     struct auth_session_info *session_info,
88                                     struct pipes_struct **_p,
89                                     int *perrno)
90 {
91         struct netr_SamInfo3 *info3;
92         struct auth_user_info_dc *auth_user_info_dc;
93         struct pipes_struct *p;
94         struct auth_serversupplied_info *server_info;
95         NTSTATUS status;
96         bool ok;
97
98         p = talloc_zero(mem_ctx, struct pipes_struct);
99         if (!p) {
100                 *perrno = ENOMEM;
101                 return -1;
102         }
103         p->syntax = id;
104         p->transport = transport;
105         p->ncalrpc_as_system = ncalrpc_as_system;
106
107         p->mem_ctx = talloc_named(p, 0, "pipe %s %p", pipe_name, p);
108         if (!p->mem_ctx) {
109                 TALLOC_FREE(p);
110                 *perrno = ENOMEM;
111                 return -1;
112         }
113
114         ok = init_pipe_handles(p, &id);
115         if (!ok) {
116                 DEBUG(1, ("Failed to init handles\n"));
117                 TALLOC_FREE(p);
118                 *perrno = EINVAL;
119                 return -1;
120         }
121
122
123         data_blob_free(&p->in_data.data);
124         data_blob_free(&p->in_data.pdu);
125
126         p->endian = RPC_LITTLE_ENDIAN;
127
128         /* Fake up an auth_user_info_dc for now, to make an info3, to make the session_info structure */
129         auth_user_info_dc = talloc_zero(p, struct auth_user_info_dc);
130         if (!auth_user_info_dc) {
131                 TALLOC_FREE(p);
132                 *perrno = ENOMEM;
133                 return -1;
134         }
135
136         auth_user_info_dc->num_sids = session_info->security_token->num_sids;
137         auth_user_info_dc->sids = session_info->security_token->sids;
138         auth_user_info_dc->info = session_info->info;
139         auth_user_info_dc->user_session_key = session_info->session_key;
140
141         /* This creates the input structure that make_server_info_info3 is looking for */
142         status = auth_convert_user_info_dc_saminfo3(p, auth_user_info_dc,
143                                                     &info3);
144
145         if (!NT_STATUS_IS_OK(status)) {
146                 DEBUG(1, ("Failed to convert auth_user_info_dc into netr_SamInfo3\n"));
147                 TALLOC_FREE(p);
148                 *perrno = EINVAL;
149                 return -1;
150         }
151
152         status = make_server_info_info3(p,
153                                         info3->base.account_name.string,
154                                         info3->base.domain.string,
155                                         &server_info, info3);
156         if (!NT_STATUS_IS_OK(status)) {
157                 DEBUG(1, ("Failed to init server info\n"));
158                 TALLOC_FREE(p);
159                 *perrno = EINVAL;
160                 return -1;
161         }
162
163         /*
164          * Some internal functions need a local token to determine access to
165          * resoutrces.
166          */
167         status = create_local_token(p, server_info, &session_info->session_key, &p->session_info);
168         talloc_free(server_info);
169         if (!NT_STATUS_IS_OK(status)) {
170                 DEBUG(1, ("Failed to init local auth token\n"));
171                 TALLOC_FREE(p);
172                 *perrno = EINVAL;
173                 return -1;
174         }
175
176         /* Now override the session_info->security_token with the exact
177          * security_token we were given from the other side,
178          * regardless of what we just calculated */
179         p->session_info->security_token = talloc_move(p->session_info, &session_info->security_token);
180
181         p->client_id = talloc_zero(p, struct client_address);
182         if (!p->client_id) {
183                 TALLOC_FREE(p);
184                 *perrno = ENOMEM;
185                 return -1;
186         }
187         strlcpy(p->client_id->addr,
188                 client_address, sizeof(p->client_id->addr));
189         p->client_id->name = talloc_strdup(p->client_id, client_address);
190         if (p->client_id->name == NULL) {
191                 TALLOC_FREE(p);
192                 *perrno = ENOMEM;
193                 return -1;
194         }
195
196         if (server_address != NULL) {
197                 p->server_id = talloc_zero(p, struct client_address);
198                 if (p->client_id == NULL) {
199                         TALLOC_FREE(p);
200                         *perrno = ENOMEM;
201                         return -1;
202                 }
203
204                 strlcpy(p->server_id->addr,
205                         server_address,
206                         sizeof(p->server_id->addr));
207
208                 p->server_id->name = talloc_strdup(p->server_id,
209                                                    server_address);
210                 if (p->server_id->name == NULL) {
211                         TALLOC_FREE(p);
212                         *perrno = ENOMEM;
213                         return -1;
214                 }
215         }
216
217         talloc_set_destructor(p, close_internal_rpc_pipe_hnd);
218
219         *_p = p;
220         return 0;
221 }
222
223 /* Start listening on the appropriate unix socket and setup all is needed to
224  * dispatch requests to the pipes rpc implementation */
225
226 struct dcerpc_ncacn_listen_state {
227         struct ndr_syntax_id syntax_id;
228
229         int fd;
230         union {
231                 char *name;
232                 uint16_t port;
233         } ep;
234
235         struct tevent_context *ev_ctx;
236         struct messaging_context *msg_ctx;
237         dcerpc_ncacn_disconnect_fn disconnect_fn;
238 };
239
240 static void named_pipe_listener(struct tevent_context *ev,
241                                 struct tevent_fd *fde,
242                                 uint16_t flags,
243                                 void *private_data);
244
245 bool setup_named_pipe_socket(const char *pipe_name,
246                              struct tevent_context *ev_ctx)
247 {
248         struct dcerpc_ncacn_listen_state *state;
249         struct tevent_fd *fde;
250         char *np_dir;
251
252         state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
253         if (!state) {
254                 DEBUG(0, ("Out of memory\n"));
255                 return false;
256         }
257         state->ep.name = talloc_strdup(state, pipe_name);
258         if (state->ep.name == NULL) {
259                 DEBUG(0, ("Out of memory\n"));
260                 goto out;
261         }
262         state->fd = -1;
263
264         np_dir = talloc_asprintf(state, "%s/np", lp_ncalrpc_dir());
265         if (!np_dir) {
266                 DEBUG(0, ("Out of memory\n"));
267                 goto out;
268         }
269
270         if (!directory_create_or_exist(np_dir, geteuid(), 0700)) {
271                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
272                           np_dir, strerror(errno)));
273                 goto out;
274         }
275
276         state->fd = create_pipe_sock(np_dir, pipe_name, 0700);
277         if (state->fd == -1) {
278                 DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
279                           np_dir, pipe_name));
280                 goto out;
281         }
282
283         DEBUG(10, ("Openened pipe socket fd %d for %s\n",
284                    state->fd, pipe_name));
285
286         fde = tevent_add_fd(ev_ctx,
287                             state, state->fd, TEVENT_FD_READ,
288                             named_pipe_listener, state);
289         if (!fde) {
290                 DEBUG(0, ("Failed to add event handler!\n"));
291                 goto out;
292         }
293
294         tevent_fd_set_auto_close(fde);
295         return true;
296
297 out:
298         if (state->fd != -1) {
299                 close(state->fd);
300         }
301         TALLOC_FREE(state);
302         return false;
303 }
304
305 static void named_pipe_accept_function(const char *pipe_name, int fd);
306
307 static void named_pipe_listener(struct tevent_context *ev,
308                                 struct tevent_fd *fde,
309                                 uint16_t flags,
310                                 void *private_data)
311 {
312         struct dcerpc_ncacn_listen_state *state =
313                         talloc_get_type_abort(private_data,
314                                               struct dcerpc_ncacn_listen_state);
315         struct sockaddr_un sunaddr;
316         socklen_t len;
317         int sd = -1;
318
319         /* TODO: should we have a limit to the number of clients ? */
320
321         len = sizeof(sunaddr);
322
323         sd = accept(state->fd,
324                     (struct sockaddr *)(void *)&sunaddr, &len);
325
326         if (sd == -1) {
327                 if (errno != EINTR) {
328                         DEBUG(6, ("Failed to get a valid socket [%s]\n",
329                                   strerror(errno)));
330                 }
331                 return;
332         }
333
334         DEBUG(6, ("Accepted socket %d\n", sd));
335
336         named_pipe_accept_function(state->ep.name, sd);
337 }
338
339
340 /* This is the core of the rpc server.
341  * Accepts connections from clients and process requests using the appropriate
342  * dispatcher table. */
343
344 struct named_pipe_client {
345         const char *pipe_name;
346         struct ndr_syntax_id pipe_id;
347
348         struct tevent_context *ev;
349         struct messaging_context *msg_ctx;
350
351         uint16_t file_type;
352         uint16_t device_state;
353         uint64_t allocation_size;
354
355         struct tstream_context *tstream;
356
357         struct tsocket_address *client;
358         char *client_name;
359         struct tsocket_address *server;
360         char *server_name;
361         struct auth_session_info *session_info;
362
363         struct pipes_struct *p;
364
365         struct tevent_queue *write_queue;
366
367         struct iovec *iov;
368         size_t count;
369 };
370
371 static void named_pipe_accept_done(struct tevent_req *subreq);
372
373 static void named_pipe_accept_function(const char *pipe_name, int fd)
374 {
375         struct ndr_syntax_id syntax;
376         struct named_pipe_client *npc;
377         struct tstream_context *plain;
378         struct tevent_req *subreq;
379         bool ok;
380         int ret;
381
382         ok = is_known_pipename(pipe_name, &syntax);
383         if (!ok) {
384                 DEBUG(1, ("Unknown pipe [%s]\n", pipe_name));
385                 close(fd);
386                 return;
387         }
388
389         npc = talloc_zero(NULL, struct named_pipe_client);
390         if (!npc) {
391                 DEBUG(0, ("Out of memory!\n"));
392                 close(fd);
393                 return;
394         }
395         npc->pipe_name = pipe_name;
396         npc->pipe_id = syntax;
397         npc->ev = server_event_context();
398         npc->msg_ctx = server_messaging_context();
399
400         /* make sure socket is in NON blocking state */
401         ret = set_blocking(fd, false);
402         if (ret != 0) {
403                 DEBUG(2, ("Failed to make socket non-blocking\n"));
404                 TALLOC_FREE(npc);
405                 close(fd);
406                 return;
407         }
408
409         ret = tstream_bsd_existing_socket(npc, fd, &plain);
410         if (ret != 0) {
411                 DEBUG(2, ("Failed to create tstream socket\n"));
412                 TALLOC_FREE(npc);
413                 close(fd);
414                 return;
415         }
416
417         npc->file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
418         npc->device_state = 0xff | 0x0400 | 0x0100;
419         npc->allocation_size = 4096;
420
421         subreq = tstream_npa_accept_existing_send(npc, npc->ev, plain,
422                                                   npc->file_type,
423                                                   npc->device_state,
424                                                   npc->allocation_size);
425         if (!subreq) {
426                 DEBUG(2, ("Failed to start async accept procedure\n"));
427                 TALLOC_FREE(npc);
428                 close(fd);
429                 return;
430         }
431         tevent_req_set_callback(subreq, named_pipe_accept_done, npc);
432 }
433
434 static void named_pipe_packet_process(struct tevent_req *subreq);
435 static void named_pipe_packet_done(struct tevent_req *subreq);
436
437 static void named_pipe_accept_done(struct tevent_req *subreq)
438 {
439         struct auth_session_info_transport *session_info_transport;
440         struct named_pipe_client *npc =
441                 tevent_req_callback_data(subreq, struct named_pipe_client);
442         const char *cli_addr;
443         int error;
444         int ret;
445
446         ret = tstream_npa_accept_existing_recv(subreq, &error, npc,
447                                                 &npc->tstream,
448                                                 &npc->client,
449                                                 &npc->client_name,
450                                                 &npc->server,
451                                                 &npc->server_name,
452                                                 &session_info_transport);
453
454         npc->session_info = talloc_move(npc, &session_info_transport->session_info);
455
456         TALLOC_FREE(subreq);
457         if (ret != 0) {
458                 DEBUG(2, ("Failed to accept named pipe connection! (%s)\n",
459                           strerror(error)));
460                 TALLOC_FREE(npc);
461                 return;
462         }
463
464         if (tsocket_address_is_inet(npc->client, "ip")) {
465                 cli_addr = tsocket_address_inet_addr_string(npc->client,
466                                                             subreq);
467                 if (cli_addr == NULL) {
468                         TALLOC_FREE(npc);
469                         return;
470                 }
471         } else {
472                 cli_addr = "";
473         }
474
475         ret = make_server_pipes_struct(npc,
476                                         npc->pipe_name, npc->pipe_id, NCACN_NP,
477                                         false, cli_addr, NULL, npc->session_info,
478                                         &npc->p, &error);
479         if (ret != 0) {
480                 DEBUG(2, ("Failed to create pipes_struct! (%s)\n",
481                           strerror(error)));
482                 goto fail;
483         }
484         npc->p->msg_ctx = npc->msg_ctx;
485
486         npc->write_queue = tevent_queue_create(npc, "np_server_write_queue");
487         if (!npc->write_queue) {
488                 DEBUG(2, ("Failed to set up write queue!\n"));
489                 goto fail;
490         }
491
492         /* And now start receiving and processing packets */
493         subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
494         if (!subreq) {
495                 DEBUG(2, ("Failed to start receving packets\n"));
496                 goto fail;
497         }
498         tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
499         return;
500
501 fail:
502         DEBUG(2, ("Fatal error. Terminating client(%s) connection!\n",
503                   npc->client_name));
504         /* terminate client connection */
505         talloc_free(npc);
506         return;
507 }
508
509 static void named_pipe_packet_process(struct tevent_req *subreq)
510 {
511         struct named_pipe_client *npc =
512                 tevent_req_callback_data(subreq, struct named_pipe_client);
513         struct _output_data *out = &npc->p->out_data;
514         DATA_BLOB recv_buffer = data_blob_null;
515         struct ncacn_packet *pkt;
516         NTSTATUS status;
517         ssize_t data_left;
518         ssize_t data_used;
519         char *data;
520         uint32_t to_send;
521         bool ok;
522
523         status = dcerpc_read_ncacn_packet_recv(subreq, npc, &pkt, &recv_buffer);
524         TALLOC_FREE(subreq);
525         if (!NT_STATUS_IS_OK(status)) {
526                 goto fail;
527         }
528
529         data_left = recv_buffer.length;
530         data = (char *)recv_buffer.data;
531
532         while (data_left) {
533
534                 data_used = process_incoming_data(npc->p, data, data_left);
535                 if (data_used < 0) {
536                         DEBUG(3, ("Failed to process dceprc request!\n"));
537                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
538                         goto fail;
539                 }
540
541                 data_left -= data_used;
542                 data += data_used;
543         }
544
545         /* Do not leak this buffer, npc is a long lived context */
546         talloc_free(recv_buffer.data);
547         talloc_free(pkt);
548
549         /* this is needed because of the way DCERPC Binds work in
550          * the RPC marshalling code */
551         to_send = out->frag.length - out->current_pdu_sent;
552         if (to_send > 0) {
553
554                 DEBUG(10, ("Current_pdu_len = %u, "
555                            "current_pdu_sent = %u "
556                            "Returning %u bytes\n",
557                            (unsigned int)out->frag.length,
558                            (unsigned int)out->current_pdu_sent,
559                            (unsigned int)to_send));
560
561                 npc->iov = talloc_zero(npc, struct iovec);
562                 if (!npc->iov) {
563                         status = NT_STATUS_NO_MEMORY;
564                         goto fail;
565                 }
566                 npc->count = 1;
567
568                 npc->iov[0].iov_base = out->frag.data
569                                         + out->current_pdu_sent;
570                 npc->iov[0].iov_len = to_send;
571
572                 out->current_pdu_sent += to_send;
573         }
574
575         /* this condition is false for bind packets, or when we haven't
576          * yet got a full request, and need to wait for more data from
577          * the client */
578         while (out->data_sent_length < out->rdata.length) {
579
580                 ok = create_next_pdu(npc->p);
581                 if (!ok) {
582                         DEBUG(3, ("Failed to create next PDU!\n"));
583                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
584                         goto fail;
585                 }
586
587                 npc->iov = talloc_realloc(npc, npc->iov,
588                                             struct iovec, npc->count + 1);
589                 if (!npc->iov) {
590                         status = NT_STATUS_NO_MEMORY;
591                         goto fail;
592                 }
593
594                 npc->iov[npc->count].iov_base = out->frag.data;
595                 npc->iov[npc->count].iov_len = out->frag.length;
596
597                 DEBUG(10, ("PDU number: %d, PDU Length: %u\n",
598                            (unsigned int)npc->count,
599                            (unsigned int)npc->iov[npc->count].iov_len));
600                 dump_data(11, (const uint8_t *)npc->iov[npc->count].iov_base,
601                                 npc->iov[npc->count].iov_len);
602                 npc->count++;
603         }
604
605         /* we still don't have a complete request, go back and wait for more
606          * data */
607         if (npc->count == 0) {
608                 /* Wait for the next packet */
609                 subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
610                 if (!subreq) {
611                         DEBUG(2, ("Failed to start receving packets\n"));
612                         status = NT_STATUS_NO_MEMORY;
613                         goto fail;
614                 }
615                 tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
616                 return;
617         }
618
619         DEBUG(10, ("Sending a total of %u bytes\n",
620                    (unsigned int)npc->p->out_data.data_sent_length));
621
622         subreq = tstream_writev_queue_send(npc, npc->ev,
623                                            npc->tstream,
624                                            npc->write_queue,
625                                            npc->iov, npc->count);
626         if (!subreq) {
627                 DEBUG(2, ("Failed to send packet\n"));
628                 status = NT_STATUS_NO_MEMORY;
629                 goto fail;
630         }
631         tevent_req_set_callback(subreq, named_pipe_packet_done, npc);
632         return;
633
634 fail:
635         DEBUG(2, ("Fatal error(%s). "
636                   "Terminating client(%s) connection!\n",
637                   nt_errstr(status), npc->client_name));
638         /* terminate client connection */
639         talloc_free(npc);
640         return;
641 }
642
643 static void named_pipe_packet_done(struct tevent_req *subreq)
644 {
645         struct named_pipe_client *npc =
646                 tevent_req_callback_data(subreq, struct named_pipe_client);
647         int sys_errno;
648         int ret;
649
650         ret = tstream_writev_queue_recv(subreq, &sys_errno);
651         TALLOC_FREE(subreq);
652         if (ret == -1) {
653                 DEBUG(2, ("Writev failed!\n"));
654                 goto fail;
655         }
656
657         /* clear out any data that may have been left around */
658         npc->count = 0;
659         TALLOC_FREE(npc->iov);
660         data_blob_free(&npc->p->in_data.data);
661         data_blob_free(&npc->p->out_data.frag);
662         data_blob_free(&npc->p->out_data.rdata);
663
664         /* Wait for the next packet */
665         subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
666         if (!subreq) {
667                 DEBUG(2, ("Failed to start receving packets\n"));
668                 sys_errno = ENOMEM;
669                 goto fail;
670         }
671         tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
672         return;
673
674 fail:
675         DEBUG(2, ("Fatal error(%s). "
676                   "Terminating client(%s) connection!\n",
677                   strerror(sys_errno), npc->client_name));
678         /* terminate client connection */
679         talloc_free(npc);
680         return;
681 }
682
683 static void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
684                                 struct messaging_context *msg_ctx,
685                                 struct ndr_syntax_id syntax_id,
686                                 enum dcerpc_transport_t transport,
687                                 const char *name,
688                                 uint16_t port,
689                                 struct tsocket_address *cli_addr,
690                                 struct tsocket_address *srv_addr,
691                                 int s,
692                                 dcerpc_ncacn_disconnect_fn fn);
693
694 /********************************************************************
695  * Start listening on the tcp/ip socket
696  ********************************************************************/
697
698 static void dcerpc_ncacn_tcpip_listener(struct tevent_context *ev,
699                                         struct tevent_fd *fde,
700                                         uint16_t flags,
701                                         void *private_data);
702
703 uint16_t setup_dcerpc_ncacn_tcpip_socket(struct tevent_context *ev_ctx,
704                                          struct messaging_context *msg_ctx,
705                                          struct ndr_syntax_id syntax_id,
706                                          const struct sockaddr_storage *ifss,
707                                          uint16_t port)
708 {
709         struct dcerpc_ncacn_listen_state *state;
710         struct tevent_fd *fde;
711         int rc;
712
713         state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
714         if (state == NULL) {
715                 DEBUG(0, ("setup_dcerpc_ncacn_tcpip_socket: Out of memory\n"));
716                 return 0;
717         }
718
719         state->syntax_id = syntax_id;
720         state->fd = -1;
721         state->ep.port = port;
722         state->disconnect_fn = NULL;
723
724         if (state->ep.port == 0) {
725                 uint16_t i;
726
727                 for (i = SERVER_TCP_LOW_PORT; i <= SERVER_TCP_HIGH_PORT; i++) {
728                         state->fd = open_socket_in(SOCK_STREAM,
729                                                    i,
730                                                    0,
731                                                    ifss,
732                                                    false);
733                         if (state->fd > 0) {
734                                 state->ep.port = i;
735                                 break;
736                         }
737                 }
738         } else {
739                 state->fd = open_socket_in(SOCK_STREAM,
740                                            state->ep.port,
741                                            0,
742                                            ifss,
743                                            true);
744         }
745         if (state->fd == -1) {
746                 DEBUG(0, ("setup_dcerpc_ncacn_tcpip_socket: Failed to create "
747                           "socket on port %u!\n", state->ep.port));
748                 goto out;
749         }
750
751         state->ev_ctx = ev_ctx;
752         state->msg_ctx = msg_ctx;
753
754         /* ready to listen */
755         set_socket_options(state->fd, "SO_KEEPALIVE");
756         set_socket_options(state->fd, lp_socket_options());
757
758         /* Set server socket to non-blocking for the accept. */
759         set_blocking(state->fd, false);
760
761         rc = listen(state->fd, SMBD_LISTEN_BACKLOG);
762         if (rc == -1) {
763                 DEBUG(0,("setup_tcpip_socket: listen - %s\n", strerror(errno)));
764                 goto out;
765         }
766
767         DEBUG(10, ("setup_tcpip_socket: openened socket fd %d for port %u\n",
768                    state->fd, state->ep.port));
769
770         fde = tevent_add_fd(state->ev_ctx,
771                             state,
772                             state->fd,
773                             TEVENT_FD_READ,
774                             dcerpc_ncacn_tcpip_listener,
775                             state);
776         if (fde == NULL) {
777                 DEBUG(0, ("setup_tcpip_socket: Failed to add event handler!\n"));
778                 goto out;
779         }
780
781         tevent_fd_set_auto_close(fde);
782
783         return state->ep.port;
784 out:
785         if (state->fd != -1) {
786                 close(state->fd);
787         }
788         TALLOC_FREE(state);
789
790         return 0;
791 }
792
793 static void dcerpc_ncacn_tcpip_listener(struct tevent_context *ev,
794                                         struct tevent_fd *fde,
795                                         uint16_t flags,
796                                         void *private_data)
797 {
798         struct dcerpc_ncacn_listen_state *state =
799                         talloc_get_type_abort(private_data,
800                                               struct dcerpc_ncacn_listen_state);
801         struct tsocket_address *cli_addr = NULL;
802         struct tsocket_address *srv_addr = NULL;
803         struct sockaddr_storage addr;
804         socklen_t in_addrlen = sizeof(addr);
805         int s = -1;
806         int rc;
807
808         s = accept(state->fd, (struct sockaddr *)(void *) &addr, &in_addrlen);
809         if (s == -1) {
810                 if (errno != EINTR) {
811                         DEBUG(0,("tcpip_listener accept: %s\n",
812                                  strerror(errno)));
813                 }
814                 return;
815         }
816
817         rc = tsocket_address_bsd_from_sockaddr(state,
818                                                (struct sockaddr *)(void *) &addr,
819                                                in_addrlen,
820                                                &cli_addr);
821         if (rc < 0) {
822                 close(s);
823                 return;
824         }
825
826         rc = getsockname(s, (struct sockaddr *)(void *) &addr, &in_addrlen);
827         if (rc < 0) {
828                 close(s);
829                 return;
830         }
831
832         rc = tsocket_address_bsd_from_sockaddr(state,
833                                                (struct sockaddr *)(void *) &addr,
834                                                in_addrlen,
835                                                &srv_addr);
836         if (rc < 0) {
837                 close(s);
838                 return;
839         }
840
841         DEBUG(6, ("tcpip_listener: Accepted socket %d\n", s));
842
843         dcerpc_ncacn_accept(state->ev_ctx,
844                             state->msg_ctx,
845                             state->syntax_id,
846                             NCACN_IP_TCP,
847                             NULL,
848                             state->ep.port,
849                             cli_addr,
850                             srv_addr,
851                             s,
852                             NULL);
853 }
854
855 /********************************************************************
856  * Start listening on the ncalrpc socket
857  ********************************************************************/
858
859 static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
860                                     struct tevent_fd *fde,
861                                     uint16_t flags,
862                                     void *private_data);
863
864 bool setup_dcerpc_ncalrpc_socket(struct tevent_context *ev_ctx,
865                                  struct messaging_context *msg_ctx,
866                                  struct ndr_syntax_id syntax_id,
867                                  const char *name,
868                                  dcerpc_ncacn_disconnect_fn fn)
869 {
870         struct dcerpc_ncacn_listen_state *state;
871         struct tevent_fd *fde;
872
873         state = talloc(ev_ctx, struct dcerpc_ncacn_listen_state);
874         if (state == NULL) {
875                 DEBUG(0, ("Out of memory\n"));
876                 return false;
877         }
878
879         state->syntax_id = syntax_id;
880         state->fd = -1;
881         state->disconnect_fn = fn;
882
883         if (name == NULL) {
884                 name = "DEFAULT";
885         }
886         state->ep.name = talloc_strdup(state, name);
887
888         if (state->ep.name == NULL) {
889                 DEBUG(0, ("Out of memory\n"));
890                 talloc_free(state);
891                 return false;
892         }
893
894         if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
895                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
896                           lp_ncalrpc_dir(), strerror(errno)));
897                 goto out;
898         }
899
900         state->fd = create_pipe_sock(lp_ncalrpc_dir(), name, 0755);
901         if (state->fd == -1) {
902                 DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
903                           lp_ncalrpc_dir(), name));
904                 goto out;
905         }
906
907         DEBUG(10, ("Openened pipe socket fd %d for %s\n", state->fd, name));
908
909         state->ev_ctx = ev_ctx;
910         state->msg_ctx = msg_ctx;
911
912         /* Set server socket to non-blocking for the accept. */
913         set_blocking(state->fd, false);
914
915         fde = tevent_add_fd(state->ev_ctx,
916                             state,
917                             state->fd,
918                             TEVENT_FD_READ,
919                             dcerpc_ncalrpc_listener,
920                             state);
921         if (fde == NULL) {
922                 DEBUG(0, ("Failed to add event handler for ncalrpc!\n"));
923                 goto out;
924         }
925
926         tevent_fd_set_auto_close(fde);
927
928         return true;
929 out:
930         if (state->fd != -1) {
931                 close(state->fd);
932         }
933         TALLOC_FREE(state);
934
935         return 0;
936 }
937
938 static void dcerpc_ncalrpc_listener(struct tevent_context *ev,
939                                         struct tevent_fd *fde,
940                                         uint16_t flags,
941                                         void *private_data)
942 {
943         struct dcerpc_ncacn_listen_state *state =
944                         talloc_get_type_abort(private_data,
945                                               struct dcerpc_ncacn_listen_state);
946         struct tsocket_address *cli_addr = NULL;
947         struct sockaddr_un sunaddr;
948         struct sockaddr *addr = (struct sockaddr *)(void *)&sunaddr;
949         socklen_t len = sizeof(sunaddr);
950         int sd = -1;
951         int rc;
952
953         ZERO_STRUCT(sunaddr);
954
955         sd = accept(state->fd, addr, &len);
956         if (sd == -1) {
957                 if (errno != EINTR) {
958                         DEBUG(0, ("ncalrpc accept() failed: %s\n", strerror(errno)));
959                 }
960                 return;
961         }
962
963         rc = tsocket_address_bsd_from_sockaddr(state,
964                                                addr, len,
965                                                &cli_addr);
966         if (rc < 0) {
967                 close(sd);
968                 return;
969         }
970
971         DEBUG(10, ("Accepted ncalrpc socket %d\n", sd));
972
973         dcerpc_ncacn_accept(state->ev_ctx,
974                             state->msg_ctx,
975                             state->syntax_id, NCALRPC,
976                             state->ep.name, 0,
977                             cli_addr, NULL, sd,
978                             state->disconnect_fn);
979 }
980
981 struct dcerpc_ncacn_conn {
982         struct ndr_syntax_id syntax_id;
983
984         enum dcerpc_transport_t transport;
985
986         union {
987                 const char *name;
988                 uint16_t port;
989         } ep;
990
991         int sock;
992
993         struct pipes_struct *p;
994         dcerpc_ncacn_disconnect_fn disconnect_fn;
995
996         struct tevent_context *ev_ctx;
997         struct messaging_context *msg_ctx;
998
999         struct tstream_context *tstream;
1000         struct tevent_queue *send_queue;
1001
1002         struct tsocket_address *client;
1003         char *client_name;
1004         struct tsocket_address *server;
1005         char *server_name;
1006         struct auth_session_info *session_info;
1007
1008         struct iovec *iov;
1009         size_t count;
1010 };
1011
1012 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq);
1013 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq);
1014
1015 static void dcerpc_ncacn_accept(struct tevent_context *ev_ctx,
1016                                 struct messaging_context *msg_ctx,
1017                                 struct ndr_syntax_id syntax_id,
1018                                 enum dcerpc_transport_t transport,
1019                                 const char *name,
1020                                 uint16_t port,
1021                                 struct tsocket_address *cli_addr,
1022                                 struct tsocket_address *srv_addr,
1023                                 int s,
1024                                 dcerpc_ncacn_disconnect_fn fn) {
1025         struct dcerpc_ncacn_conn *ncacn_conn;
1026         struct tevent_req *subreq;
1027         const char *cli_str;
1028         const char *srv_str = NULL;
1029         bool system_user = false;
1030         char *pipe_name;
1031         NTSTATUS status;
1032         int sys_errno;
1033         uid_t uid;
1034         int rc;
1035
1036         DEBUG(10, ("dcerpc_ncacn_accept\n"));
1037
1038         ncacn_conn = talloc_zero(ev_ctx, struct dcerpc_ncacn_conn);
1039         if (ncacn_conn == NULL) {
1040                 DEBUG(0, ("Out of memory!\n"));
1041                 close(s);
1042                 return;
1043         }
1044
1045         ncacn_conn->transport = transport;
1046         ncacn_conn->syntax_id = syntax_id;
1047         ncacn_conn->ev_ctx = ev_ctx;
1048         ncacn_conn->msg_ctx = msg_ctx;
1049         ncacn_conn->sock = s;
1050         ncacn_conn->disconnect_fn = fn;
1051
1052         ncacn_conn->client = talloc_move(ncacn_conn, &cli_addr);
1053         if (tsocket_address_is_inet(ncacn_conn->client, "ip")) {
1054                 ncacn_conn->client_name =
1055                         tsocket_address_inet_addr_string(ncacn_conn->client,
1056                                                          ncacn_conn);
1057         } else {
1058                 ncacn_conn->client_name =
1059                         tsocket_address_unix_path(ncacn_conn->client,
1060                                                   ncacn_conn);
1061         }
1062         if (ncacn_conn->client_name == NULL) {
1063                 DEBUG(0, ("Out of memory!\n"));
1064                 talloc_free(ncacn_conn);
1065                 close(s);
1066                 return;
1067         }
1068
1069         if (srv_addr != NULL) {
1070                 ncacn_conn->server = talloc_move(ncacn_conn, &srv_addr);
1071
1072                 ncacn_conn->server_name =
1073                         tsocket_address_inet_addr_string(ncacn_conn->server,
1074                                                          ncacn_conn);
1075                 if (ncacn_conn->server_name == NULL) {
1076                         DEBUG(0, ("Out of memory!\n"));
1077                         talloc_free(ncacn_conn);
1078                         close(s);
1079                         return;
1080                 }
1081         }
1082
1083         switch (transport) {
1084                 case NCACN_IP_TCP:
1085                         ncacn_conn->ep.port = port;
1086
1087                         pipe_name = tsocket_address_string(ncacn_conn->client,
1088                                                            ncacn_conn);
1089                         if (pipe_name == NULL) {
1090                                 close(s);
1091                                 talloc_free(ncacn_conn);
1092                                 return;
1093                         }
1094
1095                         break;
1096                 case NCALRPC:
1097                         rc = sys_getpeereid(s, &uid);
1098                         if (rc < 0) {
1099                                 DEBUG(2, ("Failed to get ncalrpc connecting uid!"));
1100                         } else {
1101                                 if (uid == sec_initial_uid()) {
1102                                         system_user = true;
1103                                 }
1104                         }
1105                 case NCACN_NP:
1106                         ncacn_conn->ep.name = talloc_strdup(ncacn_conn, name);
1107                         if (ncacn_conn->ep.name == NULL) {
1108                                 close(s);
1109                                 talloc_free(ncacn_conn);
1110                                 return;
1111                         }
1112
1113                         pipe_name = talloc_strdup(ncacn_conn,
1114                                                   name);
1115                         if (pipe_name == NULL) {
1116                                 close(s);
1117                                 talloc_free(ncacn_conn);
1118                                 return;
1119                         }
1120                         break;
1121                 default:
1122                         DEBUG(0, ("unknown dcerpc transport: %u!\n",
1123                                   transport));
1124                         talloc_free(ncacn_conn);
1125                         close(s);
1126                         return;
1127         }
1128
1129         rc = set_blocking(s, false);
1130         if (rc < 0) {
1131                 DEBUG(2, ("Failed to set dcerpc socket to non-blocking\n"));
1132                 talloc_free(ncacn_conn);
1133                 close(s);
1134                 return;
1135         }
1136
1137         /*
1138          * As soon as we have tstream_bsd_existing_socket set up it will
1139          * take care of closing the socket.
1140          */
1141         rc = tstream_bsd_existing_socket(ncacn_conn, s, &ncacn_conn->tstream);
1142         if (rc < 0) {
1143                 DEBUG(2, ("Failed to create tstream socket for dcerpc\n"));
1144                 talloc_free(ncacn_conn);
1145                 close(s);
1146                 return;
1147         }
1148
1149         if (tsocket_address_is_inet(ncacn_conn->client, "ip")) {
1150                 cli_str = ncacn_conn->client_name;
1151         } else {
1152                 cli_str = "";
1153         }
1154
1155         if (ncacn_conn->server != NULL) {
1156                 if (tsocket_address_is_inet(ncacn_conn->server, "ip")) {
1157                         srv_str = ncacn_conn->server_name;
1158                 } else {
1159                         srv_str = NULL;
1160                 }
1161         }
1162
1163         if (ncacn_conn->session_info == NULL) {
1164                 status = auth_anonymous_session_info(ncacn_conn,
1165                                                      &ncacn_conn->session_info);
1166                 if (!NT_STATUS_IS_OK(status)) {
1167                         DEBUG(2, ("Failed to create "
1168                                   "auth_anonymous_session_info - %s\n",
1169                                   nt_errstr(status)));
1170                         talloc_free(ncacn_conn);
1171                         return;
1172                 }
1173         }
1174
1175         rc = make_server_pipes_struct(ncacn_conn,
1176                                       pipe_name,
1177                                       ncacn_conn->syntax_id,
1178                                       ncacn_conn->transport,
1179                                       system_user,
1180                                       cli_str,
1181                                       srv_str,
1182                                       ncacn_conn->session_info,
1183                                       &ncacn_conn->p,
1184                                       &sys_errno);
1185         if (rc < 0) {
1186                 DEBUG(2, ("Failed to create pipe struct - %s",
1187                           strerror(sys_errno)));
1188                 talloc_free(ncacn_conn);
1189                 return;
1190         }
1191
1192         ncacn_conn->send_queue = tevent_queue_create(ncacn_conn,
1193                                                         "dcerpc send queue");
1194         if (ncacn_conn->send_queue == NULL) {
1195                 DEBUG(0, ("Out of memory!\n"));
1196                 talloc_free(ncacn_conn);
1197                 return;
1198         }
1199
1200         subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1201                                                ncacn_conn->ev_ctx,
1202                                                ncacn_conn->tstream);
1203         if (subreq == NULL) {
1204                 DEBUG(2, ("Failed to send ncacn packet\n"));
1205                 talloc_free(ncacn_conn);
1206                 return;
1207         }
1208
1209         tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1210
1211         DEBUG(10, ("dcerpc_ncacn_accept done\n"));
1212
1213         return;
1214 }
1215
1216 static void dcerpc_ncacn_packet_process(struct tevent_req *subreq)
1217 {
1218         struct dcerpc_ncacn_conn *ncacn_conn =
1219                 tevent_req_callback_data(subreq, struct dcerpc_ncacn_conn);
1220
1221         struct _output_data *out = &ncacn_conn->p->out_data;
1222         DATA_BLOB recv_buffer = data_blob_null;
1223         struct ncacn_packet *pkt;
1224         ssize_t data_left;
1225         ssize_t data_used;
1226         uint32_t to_send;
1227         char *data;
1228         NTSTATUS status;
1229         bool ok;
1230
1231         status = dcerpc_read_ncacn_packet_recv(subreq, ncacn_conn, &pkt, &recv_buffer);
1232         TALLOC_FREE(subreq);
1233         if (!NT_STATUS_IS_OK(status)) {
1234                 if (ncacn_conn->disconnect_fn != NULL) {
1235                         ok = ncacn_conn->disconnect_fn(ncacn_conn->p);
1236                         if (!ok) {
1237                                 DEBUG(3, ("Failed to call disconnect function\n"));
1238                         }
1239                 }
1240                 goto fail;
1241         }
1242
1243         data_left = recv_buffer.length;
1244         data = (char *) recv_buffer.data;
1245
1246         while (data_left) {
1247                 data_used = process_incoming_data(ncacn_conn->p, data, data_left);
1248                 if (data_used < 0) {
1249                         DEBUG(3, ("Failed to process dcerpc request!\n"));
1250                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
1251                         goto fail;
1252                 }
1253
1254                 data_left -= data_used;
1255                 data += data_used;
1256         }
1257
1258         /* Do not leak this buffer */
1259         talloc_free(recv_buffer.data);
1260         talloc_free(pkt);
1261
1262         /*
1263          * This is needed because of the way DCERPC binds work in the RPC
1264          * marshalling code
1265          */
1266         to_send = out->frag.length - out->current_pdu_sent;
1267         if (to_send > 0) {
1268
1269                 DEBUG(10, ("Current_pdu_len = %u, "
1270                            "current_pdu_sent = %u "
1271                            "Returning %u bytes\n",
1272                            (unsigned int)out->frag.length,
1273                            (unsigned int)out->current_pdu_sent,
1274                            (unsigned int)to_send));
1275
1276                 ncacn_conn->iov = talloc_zero(ncacn_conn, struct iovec);
1277                 if (ncacn_conn->iov == NULL) {
1278                         status = NT_STATUS_NO_MEMORY;
1279                         DEBUG(3, ("Out of memory!\n"));
1280                         goto fail;
1281                 }
1282                 ncacn_conn->count = 1;
1283
1284                 ncacn_conn->iov[0].iov_base = out->frag.data
1285                                             + out->current_pdu_sent;
1286                 ncacn_conn->iov[0].iov_len = to_send;
1287
1288                 out->current_pdu_sent += to_send;
1289         }
1290
1291         /*
1292          * This condition is false for bind packets, or when we haven't yet got
1293          * a full request, and need to wait for more data from the client
1294          */
1295         while (out->data_sent_length < out->rdata.length) {
1296                 ok = create_next_pdu(ncacn_conn->p);
1297                 if (!ok) {
1298                         DEBUG(3, ("Failed to create next PDU!\n"));
1299                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
1300                         goto fail;
1301                 }
1302
1303                 ncacn_conn->iov = talloc_realloc(ncacn_conn,
1304                                                  ncacn_conn->iov,
1305                                                  struct iovec,
1306                                                  ncacn_conn->count + 1);
1307                 if (ncacn_conn->iov == NULL) {
1308                         DEBUG(3, ("Out of memory!\n"));
1309                         status = NT_STATUS_NO_MEMORY;
1310                         goto fail;
1311                 }
1312
1313                 ncacn_conn->iov[ncacn_conn->count].iov_base = out->frag.data;
1314                 ncacn_conn->iov[ncacn_conn->count].iov_len = out->frag.length;
1315
1316                 DEBUG(10, ("PDU number: %d, PDU Length: %u\n",
1317                            (unsigned int) ncacn_conn->count,
1318                            (unsigned int) ncacn_conn->iov[ncacn_conn->count].iov_len));
1319                 dump_data(11, (const uint8_t *) ncacn_conn->iov[ncacn_conn->count].iov_base,
1320                               ncacn_conn->iov[ncacn_conn->count].iov_len);
1321                 ncacn_conn->count++;
1322         }
1323
1324         /*
1325          * We still don't have a complete request, go back and wait for more
1326          * data.
1327          */
1328         if (ncacn_conn->count == 0) {
1329                 /* Wait for the next packet */
1330                 subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1331                                                        ncacn_conn->ev_ctx,
1332                                                        ncacn_conn->tstream);
1333                 if (subreq == NULL) {
1334                         DEBUG(2, ("Failed to start receving packets\n"));
1335                         status = NT_STATUS_NO_MEMORY;
1336                         goto fail;
1337                 }
1338                 tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1339                 return;
1340         }
1341
1342         DEBUG(10, ("Sending a total of %u bytes\n",
1343                    (unsigned int)ncacn_conn->p->out_data.data_sent_length));
1344
1345         subreq = tstream_writev_queue_send(ncacn_conn,
1346                                            ncacn_conn->ev_ctx,
1347                                            ncacn_conn->tstream,
1348                                            ncacn_conn->send_queue,
1349                                            ncacn_conn->iov,
1350                                            ncacn_conn->count);
1351         if (subreq == NULL) {
1352                 DEBUG(2, ("Failed to send packet\n"));
1353                 status = NT_STATUS_NO_MEMORY;
1354                 goto fail;
1355         }
1356
1357         tevent_req_set_callback(subreq, dcerpc_ncacn_packet_done, ncacn_conn);
1358         return;
1359
1360 fail:
1361         DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1362                   ncacn_conn->client_name, nt_errstr(status)));
1363
1364         /* Terminate client connection */
1365         talloc_free(ncacn_conn);
1366         return;
1367 }
1368
1369 static void dcerpc_ncacn_packet_done(struct tevent_req *subreq)
1370 {
1371         struct dcerpc_ncacn_conn *ncacn_conn =
1372                 tevent_req_callback_data(subreq, struct dcerpc_ncacn_conn);
1373         NTSTATUS status = NT_STATUS_OK;
1374         int sys_errno;
1375         int rc;
1376
1377         rc = tstream_writev_queue_recv(subreq, &sys_errno);
1378         TALLOC_FREE(subreq);
1379         if (rc < 0) {
1380                 DEBUG(2, ("Writev failed!\n"));
1381                 status = map_nt_error_from_unix(sys_errno);
1382                 goto fail;
1383         }
1384
1385         /* clear out any data that may have been left around */
1386         ncacn_conn->count = 0;
1387         TALLOC_FREE(ncacn_conn->iov);
1388         data_blob_free(&ncacn_conn->p->in_data.data);
1389         data_blob_free(&ncacn_conn->p->out_data.frag);
1390         data_blob_free(&ncacn_conn->p->out_data.rdata);
1391
1392         /* Wait for the next packet */
1393         subreq = dcerpc_read_ncacn_packet_send(ncacn_conn,
1394                                                ncacn_conn->ev_ctx,
1395                                                ncacn_conn->tstream);
1396         if (subreq == NULL) {
1397                 DEBUG(2, ("Failed to start receving packets\n"));
1398                 status = NT_STATUS_NO_MEMORY;
1399                 goto fail;
1400         }
1401
1402         tevent_req_set_callback(subreq, dcerpc_ncacn_packet_process, ncacn_conn);
1403         return;
1404
1405 fail:
1406         DEBUG(3, ("Terminating client(%s) connection! - '%s'\n",
1407                   ncacn_conn->client_name, nt_errstr(status)));
1408
1409         /* Terminate client connection */
1410         talloc_free(ncacn_conn);
1411         return;
1412 }
1413
1414 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */