s3-auth Rename cryptic 'ptok' to security_token
[kai/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 "rpc_server/rpc_server.h"
22 #include "rpc_dce.h"
23 #include "librpc/gen_ndr/netlogon.h"
24 #include "librpc/gen_ndr/auth.h"
25 #include "registry/reg_parse_prs.h"
26 #include "lib/tsocket/tsocket.h"
27 #include "libcli/named_pipe_auth/npa_tstream.h"
28 #include "../auth/auth_sam_reply.h"
29
30 /* Creates a pipes_struct and initializes it with the information
31  * sent from the client */
32 static int make_server_pipes_struct(TALLOC_CTX *mem_ctx,
33                                     const char *pipe_name,
34                                     const struct ndr_syntax_id id,
35                                     const char *client_address,
36                                     struct auth_session_info_transport *session_info,
37                                     struct pipes_struct **_p,
38                                     int *perrno)
39 {
40         struct netr_SamInfo3 *info3;
41         struct auth_user_info_dc *auth_user_info_dc;
42         struct pipes_struct *p;
43         NTSTATUS status;
44         bool ok;
45
46         p = talloc_zero(mem_ctx, struct pipes_struct);
47         if (!p) {
48                 *perrno = ENOMEM;
49                 return -1;
50         }
51         p->syntax = id;
52
53         p->mem_ctx = talloc_named(p, 0, "pipe %s %p", pipe_name, p);
54         if (!p->mem_ctx) {
55                 TALLOC_FREE(p);
56                 *perrno = ENOMEM;
57                 return -1;
58         }
59
60         ok = init_pipe_handles(p, &id);
61         if (!ok) {
62                 DEBUG(1, ("Failed to init handles\n"));
63                 TALLOC_FREE(p);
64                 *perrno = EINVAL;
65                 return -1;
66         }
67
68
69         data_blob_free(&p->in_data.data);
70         data_blob_free(&p->in_data.pdu);
71
72         p->endian = RPC_LITTLE_ENDIAN;
73
74         /* Fake up an auth_user_info_dc for now, to make an info3, to make the server_info structure */
75         auth_user_info_dc = talloc_zero(p, struct auth_user_info_dc);
76         if (!auth_user_info_dc) {
77                 TALLOC_FREE(p);
78                 *perrno = ENOMEM;
79                 return -1;
80         }
81
82         auth_user_info_dc->num_sids = session_info->security_token->num_sids;
83         auth_user_info_dc->sids = session_info->security_token->sids;
84         auth_user_info_dc->info = session_info->info;
85         auth_user_info_dc->user_session_key = session_info->session_key;
86
87         /* This creates the input structure that make_server_info_info3 is looking for */
88         status = auth_convert_user_info_dc_saminfo3(p, auth_user_info_dc,
89                                                     &info3);
90
91         if (!NT_STATUS_IS_OK(status)) {
92                 DEBUG(1, ("Failed to convert auth_user_info_dc into netr_SamInfo3\n"));
93                 TALLOC_FREE(p);
94                 *perrno = EINVAL;
95                 return -1;
96         }
97
98         status = make_server_info_info3(p,
99                                         info3->base.account_name.string,
100                                         info3->base.domain.string,
101                                         &p->server_info, info3);
102         if (!NT_STATUS_IS_OK(status)) {
103                 DEBUG(1, ("Failed to init server info\n"));
104                 TALLOC_FREE(p);
105                 *perrno = EINVAL;
106                 return -1;
107         }
108
109         /*
110          * Some internal functions need a local token to determine access to
111          * resoutrces.
112          */
113         status = create_local_token(p->server_info);
114         if (!NT_STATUS_IS_OK(status)) {
115                 DEBUG(1, ("Failed to init local auth token\n"));
116                 TALLOC_FREE(p);
117                 *perrno = EINVAL;
118                 return -1;
119         }
120
121         /* Now override the server_info->security_token with the exact
122          * security_token we were given from the other side,
123          * regardless of what we just calculated */
124         p->server_info->security_token = talloc_move(p->server_info, &session_info->security_token);
125
126         /* Also set the session key to the correct value */
127         p->server_info->user_session_key = session_info->session_key;
128         p->server_info->user_session_key.data = talloc_move(p->server_info, &session_info->session_key.data);
129
130         p->client_id = talloc_zero(p, struct client_address);
131         if (!p->client_id) {
132                 TALLOC_FREE(p);
133                 *perrno = ENOMEM;
134                 return -1;
135         }
136         strlcpy(p->client_id->addr,
137                 client_address, sizeof(p->client_id->addr));
138         p->client_id->name = talloc_strdup(p->client_id, client_address);
139         if (p->client_id->name == NULL) {
140                 TALLOC_FREE(p);
141                 *perrno = ENOMEM;
142                 return -1;
143         }
144
145         talloc_set_destructor(p, close_internal_rpc_pipe_hnd);
146
147         *_p = p;
148         return 0;
149 }
150
151 /* Add some helper functions to wrap the common ncacn packet reading functions
152  * until we can share more dcerpc code */
153 struct named_pipe_read_packet_state {
154         struct ncacn_packet *pkt;
155         DATA_BLOB buffer;
156 };
157
158 static void named_pipe_read_packet_done(struct tevent_req *subreq);
159
160 static struct tevent_req *named_pipe_read_packet_send(TALLOC_CTX *mem_ctx,
161                                         struct tevent_context *ev,
162                                         struct tstream_context *tstream)
163 {
164         struct named_pipe_read_packet_state *state;
165         struct tevent_req *req, *subreq;
166
167         req = tevent_req_create(mem_ctx, &state,
168                                 struct named_pipe_read_packet_state);
169         if (!req) {
170                 return NULL;
171         }
172         ZERO_STRUCTP(state);
173
174         subreq = dcerpc_read_ncacn_packet_send(state, ev, tstream);
175         if (!subreq) {
176                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
177                 tevent_req_post(req, ev);
178                 return req;
179         }
180         tevent_req_set_callback(subreq, named_pipe_read_packet_done, req);
181
182         return req;
183 }
184
185 static void named_pipe_read_packet_done(struct tevent_req *subreq)
186 {
187         struct tevent_req *req =
188                 tevent_req_callback_data(subreq, struct tevent_req);
189         struct named_pipe_read_packet_state *state =
190                 tevent_req_data(req, struct named_pipe_read_packet_state);
191         NTSTATUS status;
192
193         status = dcerpc_read_ncacn_packet_recv(subreq, state,
194                                                 &state->pkt,
195                                                 &state->buffer);
196         TALLOC_FREE(subreq);
197         if (!NT_STATUS_IS_OK(status)) {
198                 DEBUG(3, ("Failed to receive dceprc packet!\n"));
199                 tevent_req_nterror(req, status);
200                 return;
201         }
202
203         tevent_req_done(req);
204 }
205
206 static NTSTATUS named_pipe_read_packet_recv(struct tevent_req *req,
207                                                 TALLOC_CTX *mem_ctx,
208                                                 DATA_BLOB *buffer)
209 {
210         struct named_pipe_read_packet_state *state =
211                 tevent_req_data(req, struct named_pipe_read_packet_state);
212         NTSTATUS status;
213
214         if (tevent_req_is_nterror(req, &status)) {
215                 tevent_req_received(req);
216                 return status;
217         }
218
219         buffer->data = talloc_move(mem_ctx, &state->buffer.data);
220         buffer->length = state->buffer.length;
221
222         tevent_req_received(req);
223         return NT_STATUS_OK;
224 }
225
226
227
228 /* Start listening on the appropriate unix socket and setup all is needed to
229  * dispatch requests to the pipes rpc implementation */
230
231 struct named_pipe_listen_state {
232         int fd;
233         char *name;
234 };
235
236 static void named_pipe_listener(struct tevent_context *ev,
237                                 struct tevent_fd *fde,
238                                 uint16_t flags,
239                                 void *private_data);
240
241 bool setup_named_pipe_socket(const char *pipe_name,
242                              struct tevent_context *ev_ctx)
243 {
244         struct named_pipe_listen_state *state;
245         struct tevent_fd *fde;
246         char *np_dir;
247
248         state = talloc(ev_ctx, struct named_pipe_listen_state);
249         if (!state) {
250                 DEBUG(0, ("Out of memory\n"));
251                 return false;
252         }
253         state->name = talloc_strdup(state, pipe_name);
254         if (!state->name) {
255                 DEBUG(0, ("Out of memory\n"));
256                 goto out;
257         }
258         state->fd = -1;
259
260         np_dir = talloc_asprintf(state, "%s/np", lp_ncalrpc_dir());
261         if (!np_dir) {
262                 DEBUG(0, ("Out of memory\n"));
263                 goto out;
264         }
265
266         if (!directory_create_or_exist(np_dir, geteuid(), 0700)) {
267                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
268                           np_dir, strerror(errno)));
269                 goto out;
270         }
271
272         state->fd = create_pipe_sock(np_dir, pipe_name, 0700);
273         if (state->fd == -1) {
274                 DEBUG(0, ("Failed to create pipe socket! [%s/%s]\n",
275                           np_dir, pipe_name));
276                 goto out;
277         }
278
279         DEBUG(10, ("Openened pipe socket fd %d for %s\n",
280                    state->fd, pipe_name));
281
282         fde = tevent_add_fd(ev_ctx,
283                             state, state->fd, TEVENT_FD_READ,
284                             named_pipe_listener, state);
285         if (!fde) {
286                 DEBUG(0, ("Failed to add event handler!\n"));
287                 goto out;
288         }
289
290         tevent_fd_set_auto_close(fde);
291         return true;
292
293 out:
294         if (state->fd != -1) {
295                 close(state->fd);
296         }
297         TALLOC_FREE(state);
298         return false;
299 }
300
301 static void named_pipe_accept_function(const char *pipe_name, int fd);
302
303 static void named_pipe_listener(struct tevent_context *ev,
304                                 struct tevent_fd *fde,
305                                 uint16_t flags,
306                                 void *private_data)
307 {
308         struct named_pipe_listen_state *state =
309                         talloc_get_type_abort(private_data,
310                                               struct named_pipe_listen_state);
311         struct sockaddr_un sunaddr;
312         socklen_t len;
313         int sd = -1;
314
315         /* TODO: should we have a limit to the number of clients ? */
316
317         len = sizeof(sunaddr);
318
319         while (sd == -1) {
320                 sd = accept(state->fd,
321                             (struct sockaddr *)(void *)&sunaddr, &len);
322                 if (errno != EINTR) break;
323         }
324
325         if (sd == -1) {
326                 DEBUG(6, ("Failed to get a valid socket [%s]\n",
327                           strerror(errno)));
328                 return;
329         }
330
331         DEBUG(6, ("Accepted socket %d\n", sd));
332
333         named_pipe_accept_function(state->name, sd);
334 }
335
336
337 /* This is the core of the rpc server.
338  * Accepts connections from clients and process requests using the appropriate
339  * dispatcher table. */
340
341 struct named_pipe_client {
342         const char *pipe_name;
343         struct ndr_syntax_id pipe_id;
344
345         struct tevent_context *ev;
346         struct messaging_context *msg_ctx;
347
348         uint16_t file_type;
349         uint16_t device_state;
350         uint64_t allocation_size;
351
352         struct tstream_context *tstream;
353
354         struct tsocket_address *client;
355         char *client_name;
356         struct tsocket_address *server;
357         char *server_name;
358         struct auth_session_info_transport *session_info;
359
360         struct pipes_struct *p;
361
362         struct tevent_queue *write_queue;
363
364         struct iovec *iov;
365         size_t count;
366 };
367
368 static void named_pipe_accept_done(struct tevent_req *subreq);
369
370 static void named_pipe_accept_function(const char *pipe_name, int fd)
371 {
372         struct ndr_syntax_id syntax;
373         struct named_pipe_client *npc;
374         struct tstream_context *plain;
375         struct tevent_req *subreq;
376         bool ok;
377         int ret;
378
379         ok = is_known_pipename(pipe_name, &syntax);
380         if (!ok) {
381                 DEBUG(1, ("Unknown pipe [%s]\n", pipe_name));
382                 close(fd);
383                 return;
384         }
385
386         npc = talloc_zero(NULL, struct named_pipe_client);
387         if (!npc) {
388                 DEBUG(0, ("Out of memory!\n"));
389                 close(fd);
390                 return;
391         }
392         npc->pipe_name = pipe_name;
393         npc->pipe_id = syntax;
394         npc->ev = server_event_context();
395         npc->msg_ctx = server_messaging_context();
396
397         /* make sure socket is in NON blocking state */
398         ret = set_blocking(fd, false);
399         if (ret != 0) {
400                 DEBUG(2, ("Failed to make socket non-blocking\n"));
401                 TALLOC_FREE(npc);
402                 close(fd);
403                 return;
404         }
405
406         ret = tstream_bsd_existing_socket(npc, fd, &plain);
407         if (ret != 0) {
408                 DEBUG(2, ("Failed to create tstream socket\n"));
409                 TALLOC_FREE(npc);
410                 close(fd);
411                 return;
412         }
413
414         npc->file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
415         npc->device_state = 0xff | 0x0400 | 0x0100;
416         npc->allocation_size = 4096;
417
418         subreq = tstream_npa_accept_existing_send(npc, npc->ev, plain,
419                                                   npc->file_type,
420                                                   npc->device_state,
421                                                   npc->allocation_size);
422         if (!subreq) {
423                 DEBUG(2, ("Failed to start async accept procedure\n"));
424                 TALLOC_FREE(npc);
425                 close(fd);
426                 return;
427         }
428         tevent_req_set_callback(subreq, named_pipe_accept_done, npc);
429 }
430
431 static void named_pipe_packet_process(struct tevent_req *subreq);
432 static void named_pipe_packet_done(struct tevent_req *subreq);
433
434 static void named_pipe_accept_done(struct tevent_req *subreq)
435 {
436         struct named_pipe_client *npc =
437                 tevent_req_callback_data(subreq, struct named_pipe_client);
438         const char *cli_addr;
439         int error;
440         int ret;
441
442         ret = tstream_npa_accept_existing_recv(subreq, &error, npc,
443                                                 &npc->tstream,
444                                                 &npc->client,
445                                                 &npc->client_name,
446                                                 &npc->server,
447                                                 &npc->server_name,
448                                                 &npc->session_info);
449         TALLOC_FREE(subreq);
450         if (ret != 0) {
451                 DEBUG(2, ("Failed to accept named pipe connection! (%s)\n",
452                           strerror(error)));
453                 TALLOC_FREE(npc);
454                 return;
455         }
456
457         if (tsocket_address_is_inet(npc->client, "ip")) {
458                 cli_addr = tsocket_address_inet_addr_string(npc->client,
459                                                             subreq);
460                 if (cli_addr == NULL) {
461                         TALLOC_FREE(npc);
462                         return;
463                 }
464         } else {
465                 cli_addr = "";
466         }
467
468         ret = make_server_pipes_struct(npc,
469                                         npc->pipe_name, npc->pipe_id,
470                                         cli_addr, npc->session_info,
471                                         &npc->p, &error);
472         if (ret != 0) {
473                 DEBUG(2, ("Failed to create pipes_struct! (%s)\n",
474                           strerror(error)));
475                 goto fail;
476         }
477         npc->p->msg_ctx = npc->msg_ctx;
478
479         npc->write_queue = tevent_queue_create(npc, "np_server_write_queue");
480         if (!npc->write_queue) {
481                 DEBUG(2, ("Failed to set up write queue!\n"));
482                 goto fail;
483         }
484
485         /* And now start receaving and processing packets */
486         subreq = named_pipe_read_packet_send(npc, npc->ev, npc->tstream);
487         if (!subreq) {
488                 DEBUG(2, ("Failed to start receving packets\n"));
489                 goto fail;
490         }
491         tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
492         return;
493
494 fail:
495         DEBUG(2, ("Fatal error. Terminating client(%s) connection!\n",
496                   npc->client_name));
497         /* terminate client connection */
498         talloc_free(npc);
499         return;
500 }
501
502 static void named_pipe_packet_process(struct tevent_req *subreq)
503 {
504         struct named_pipe_client *npc =
505                 tevent_req_callback_data(subreq, struct named_pipe_client);
506         struct _output_data *out = &npc->p->out_data;
507         DATA_BLOB recv_buffer = data_blob_null;
508         NTSTATUS status;
509         ssize_t data_left;
510         ssize_t data_used;
511         char *data;
512         uint32_t to_send;
513         bool ok;
514
515         status = named_pipe_read_packet_recv(subreq, npc, &recv_buffer);
516         TALLOC_FREE(subreq);
517         if (!NT_STATUS_IS_OK(status)) {
518                 goto fail;
519         }
520
521         data_left = recv_buffer.length;
522         data = (char *)recv_buffer.data;
523
524         while (data_left) {
525
526                 data_used = process_incoming_data(npc->p, data, data_left);
527                 if (data_used < 0) {
528                         DEBUG(3, ("Failed to process dceprc request!\n"));
529                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
530                         goto fail;
531                 }
532
533                 data_left -= data_used;
534                 data += data_used;
535         }
536
537         /* Do not leak this buffer, npc is a long lived context */
538         talloc_free(recv_buffer.data);
539
540         /* this is needed because of the way DCERPC Binds work in
541          * the RPC marshalling code */
542         to_send = out->frag.length - out->current_pdu_sent;
543         if (to_send > 0) {
544
545                 DEBUG(10, ("Current_pdu_len = %u, "
546                            "current_pdu_sent = %u "
547                            "Returning %u bytes\n",
548                            (unsigned int)out->frag.length,
549                            (unsigned int)out->current_pdu_sent,
550                            (unsigned int)to_send));
551
552                 npc->iov = talloc_zero(npc, struct iovec);
553                 if (!npc->iov) {
554                         status = NT_STATUS_NO_MEMORY;
555                         goto fail;
556                 }
557                 npc->count = 1;
558
559                 npc->iov[0].iov_base = out->frag.data
560                                         + out->current_pdu_sent;
561                 npc->iov[0].iov_len = to_send;
562
563                 out->current_pdu_sent += to_send;
564         }
565
566         /* this condition is false for bind packets, or when we haven't
567          * yet got a full request, and need to wait for more data from
568          * the client */
569         while (out->data_sent_length < out->rdata.length) {
570
571                 ok = create_next_pdu(npc->p);
572                 if (!ok) {
573                         DEBUG(3, ("Failed to create next PDU!\n"));
574                         status = NT_STATUS_UNEXPECTED_IO_ERROR;
575                         goto fail;
576                 }
577
578                 npc->iov = talloc_realloc(npc, npc->iov,
579                                             struct iovec, npc->count + 1);
580                 if (!npc->iov) {
581                         status = NT_STATUS_NO_MEMORY;
582                         goto fail;
583                 }
584
585                 npc->iov[npc->count].iov_base = out->frag.data;
586                 npc->iov[npc->count].iov_len = out->frag.length;
587
588                 DEBUG(10, ("PDU number: %d, PDU Length: %u\n",
589                            (unsigned int)npc->count,
590                            (unsigned int)npc->iov[npc->count].iov_len));
591                 dump_data(11, (const uint8_t *)npc->iov[npc->count].iov_base,
592                                 npc->iov[npc->count].iov_len);
593                 npc->count++;
594         }
595
596         /* we still don't have a complete request, go back and wait for more
597          * data */
598         if (npc->count == 0) {
599                 /* Wait for the next packet */
600                 subreq = named_pipe_read_packet_send(npc, npc->ev, npc->tstream);
601                 if (!subreq) {
602                         DEBUG(2, ("Failed to start receving packets\n"));
603                         status = NT_STATUS_NO_MEMORY;
604                         goto fail;
605                 }
606                 tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
607                 return;
608         }
609
610         DEBUG(10, ("Sending a total of %u bytes\n",
611                    (unsigned int)npc->p->out_data.data_sent_length));
612
613         subreq = tstream_writev_queue_send(npc, npc->ev,
614                                            npc->tstream,
615                                            npc->write_queue,
616                                            npc->iov, npc->count);
617         if (!subreq) {
618                 DEBUG(2, ("Failed to send packet\n"));
619                 status = NT_STATUS_NO_MEMORY;
620                 goto fail;
621         }
622         tevent_req_set_callback(subreq, named_pipe_packet_done, npc);
623         return;
624
625 fail:
626         DEBUG(2, ("Fatal error(%s). "
627                   "Terminating client(%s) connection!\n",
628                   nt_errstr(status), npc->client_name));
629         /* terminate client connection */
630         talloc_free(npc);
631         return;
632 }
633
634 static void named_pipe_packet_done(struct tevent_req *subreq)
635 {
636         struct named_pipe_client *npc =
637                 tevent_req_callback_data(subreq, struct named_pipe_client);
638         int sys_errno;
639         int ret;
640
641         ret = tstream_writev_queue_recv(subreq, &sys_errno);
642         TALLOC_FREE(subreq);
643         if (ret == -1) {
644                 DEBUG(2, ("Writev failed!\n"));
645                 goto fail;
646         }
647
648         /* clear out any data that may have been left around */
649         npc->count = 0;
650         TALLOC_FREE(npc->iov);
651         data_blob_free(&npc->p->in_data.data);
652         data_blob_free(&npc->p->out_data.frag);
653         data_blob_free(&npc->p->out_data.rdata);
654
655         /* Wait for the next packet */
656         subreq = named_pipe_read_packet_send(npc, npc->ev, npc->tstream);
657         if (!subreq) {
658                 DEBUG(2, ("Failed to start receving packets\n"));
659                 sys_errno = ENOMEM;
660                 goto fail;
661         }
662         tevent_req_set_callback(subreq, named_pipe_packet_process, npc);
663         return;
664
665 fail:
666         DEBUG(2, ("Fatal error(%s). "
667                   "Terminating client(%s) connection!\n",
668                   strerror(sys_errno), npc->client_name));
669         /* terminate client connection */
670         talloc_free(npc);
671         return;
672  }