s3-talloc Change TALLOC_ZERO_P() to talloc_zero()
[nivanova/samba-autobuild/.git] / source3 / libsmb / unexpected.c
1 /*
2    Unix SMB/CIFS implementation.
3    handle unexpected packets
4    Copyright (C) Andrew Tridgell 2000
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
21 #include "includes.h"
22 #include "../lib/util/tevent_ntstatus.h"
23 #include "lib/async_req/async_sock.h"
24 #include "libsmb/nmblib.h"
25
26 static const char *nmbd_socket_dir(void)
27 {
28         return lp_parm_const_string(-1, "nmbd", "socket dir",
29                                     get_dyn_NMBDSOCKETDIR());
30 }
31
32 struct nb_packet_query {
33         enum packet_type type;
34         size_t mailslot_namelen;
35         int trn_id;
36 };
37
38 struct nb_packet_client;
39
40 struct nb_packet_server {
41         struct tevent_context *ev;
42         int listen_sock;
43         int max_clients;
44         int num_clients;
45         struct nb_packet_client *clients;
46 };
47
48 struct nb_packet_client {
49         struct nb_packet_client *prev, *next;
50         struct nb_packet_server *server;
51
52         enum packet_type type;
53         int trn_id;
54         char *mailslot_name;
55
56         int sock;
57         struct tevent_req *read_req;
58         struct tevent_queue *out_queue;
59 };
60
61 static int nb_packet_server_destructor(struct nb_packet_server *s);
62 static void nb_packet_server_listener(struct tevent_context *ev,
63                                       struct tevent_fd *fde,
64                                       uint16_t flags,
65                                       void *private_data);
66
67 NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx,
68                                  struct tevent_context *ev,
69                                  int max_clients,
70                                  struct nb_packet_server **presult)
71 {
72         struct nb_packet_server *result;
73         struct tevent_fd *fde;
74         NTSTATUS status;
75
76         result = talloc_zero(mem_ctx, struct nb_packet_server);
77         if (result == NULL) {
78                 status = NT_STATUS_NO_MEMORY;
79                 goto fail;
80         }
81         result->ev = ev;
82         result->max_clients = max_clients;
83
84         result->listen_sock = create_pipe_sock(
85                 nmbd_socket_dir(), "unexpected", 0755);
86         if (result->listen_sock == -1) {
87                 status = map_nt_error_from_unix(errno);
88                 goto fail;
89         }
90         talloc_set_destructor(result, nb_packet_server_destructor);
91
92         fde = tevent_add_fd(ev, result, result->listen_sock, TEVENT_FD_READ,
93                             nb_packet_server_listener, result);
94         if (fde == NULL) {
95                 status = NT_STATUS_NO_MEMORY;
96                 goto fail;
97         }
98
99         *presult = result;
100         return NT_STATUS_OK;
101 fail:
102         TALLOC_FREE(result);
103         return status;
104 }
105
106 static int nb_packet_server_destructor(struct nb_packet_server *s)
107 {
108         if (s->listen_sock != -1) {
109                 close(s->listen_sock);
110                 s->listen_sock = -1;
111         }
112         return 0;
113 }
114
115 static int nb_packet_client_destructor(struct nb_packet_client *c);
116 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
117                                      void *private_data);
118 static void nb_packet_got_query(struct tevent_req *req);
119 static void nb_packet_client_read_done(struct tevent_req *req);
120
121 static void nb_packet_server_listener(struct tevent_context *ev,
122                                       struct tevent_fd *fde,
123                                       uint16_t flags,
124                                       void *private_data)
125 {
126         struct nb_packet_server *server = talloc_get_type_abort(
127                 private_data, struct nb_packet_server);
128         struct nb_packet_client *client;
129         struct tevent_req *req;
130         struct sockaddr_un sunaddr;
131         socklen_t len;
132         int sock;
133
134         len = sizeof(sunaddr);
135
136         sock = accept(server->listen_sock, (struct sockaddr *)(void *)&sunaddr,
137                       &len);
138         if (sock == -1) {
139                 return;
140         }
141         DEBUG(6,("accepted socket %d\n", sock));
142
143         client = talloc_zero(server, struct nb_packet_client);
144         if (client == NULL) {
145                 DEBUG(10, ("talloc failed\n"));
146                 close(sock);
147                 return;
148         }
149         client->sock = sock;
150         client->server = server;
151         talloc_set_destructor(client, nb_packet_client_destructor);
152
153         client->out_queue = tevent_queue_create(
154                 client, "unexpected packet output");
155         if (client->out_queue == NULL) {
156                 DEBUG(10, ("tevent_queue_create failed\n"));
157                 TALLOC_FREE(client);
158                 return;
159         }
160
161         req = read_packet_send(client, ev, client->sock,
162                                sizeof(struct nb_packet_query),
163                                nb_packet_client_more, NULL);
164         if (req == NULL) {
165                 DEBUG(10, ("read_packet_send failed\n"));
166                 TALLOC_FREE(client);
167                 return;
168         }
169         tevent_req_set_callback(req, nb_packet_got_query, client);
170
171         DLIST_ADD(server->clients, client);
172         server->num_clients += 1;
173
174         if (server->num_clients > server->max_clients) {
175                 DEBUG(10, ("Too many clients, dropping oldest\n"));
176
177                 /*
178                  * no TALLOC_FREE here, don't mess with the list structs
179                  */
180                 talloc_free(server->clients->prev);
181         }
182 }
183
184 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
185                                      void *private_data)
186 {
187         struct nb_packet_query q;
188         if (buflen > sizeof(struct nb_packet_query)) {
189                 return 0;
190         }
191         /* Take care of alignment */
192         memcpy(&q, buf, sizeof(q));
193         if (q.mailslot_namelen > 1024) {
194                 DEBUG(10, ("Got invalid mailslot namelen %d\n",
195                            (int)q.mailslot_namelen));
196                 return -1;
197         }
198         return q.mailslot_namelen;
199 }
200
201 static int nb_packet_client_destructor(struct nb_packet_client *c)
202 {
203         if (c->sock != -1) {
204                 close(c->sock);
205                 c->sock = -1;
206         }
207         DLIST_REMOVE(c->server->clients, c);
208         c->server->num_clients -= 1;
209         return 0;
210 }
211
212 static void nb_packet_got_query(struct tevent_req *req)
213 {
214         struct nb_packet_client *client = tevent_req_callback_data(
215                 req, struct nb_packet_client);
216         struct nb_packet_query q;
217         uint8_t *buf;
218         ssize_t nread, nwritten;
219         int err;
220         char c;
221
222         nread = read_packet_recv(req, talloc_tos(), &buf, &err);
223         TALLOC_FREE(req);
224         if (nread < sizeof(struct nb_packet_query)) {
225                 DEBUG(10, ("read_packet_recv returned %d (%s)\n",
226                            (int)nread,
227                            (nread == -1) ? strerror(err) : "wrong length"));
228                 TALLOC_FREE(client);
229                 return;
230         }
231
232         /* Take care of alignment */
233         memcpy(&q, buf, sizeof(q));
234
235         if (nread != sizeof(struct nb_packet_query) + q.mailslot_namelen) {
236                 DEBUG(10, ("nb_packet_got_query: Invalid mailslot namelength\n"));
237                 TALLOC_FREE(client);
238                 return;
239         }
240
241         client->trn_id = q.trn_id;
242         client->type = q.type;
243         if (q.mailslot_namelen > 0) {
244                 client->mailslot_name = talloc_strndup(
245                         client, (char *)buf + sizeof(q),
246                         q.mailslot_namelen);
247                 if (client->mailslot_name == NULL) {
248                         TALLOC_FREE(client);
249                         return;
250                 }
251         }
252
253         /*
254          * Yes, this is a blocking write of 1 byte into a unix
255          * domain socket that has never been written to. Highly
256          * unlikely that this actually blocks.
257          */
258         c = 0;
259         nwritten = sys_write(client->sock, &c, sizeof(c));
260         if (nwritten != sizeof(c)) {
261                 DEBUG(10, ("Could not write success indicator to client: %s\n",
262                            strerror(errno)));
263                 TALLOC_FREE(client);
264                 return;
265         }
266
267         client->read_req = read_packet_send(client, client->server->ev,
268                                             client->sock, 1, NULL, NULL);
269         if (client->read_req == NULL) {
270                 DEBUG(10, ("Could not activate reader for client exit "
271                            "detection\n"));
272                 TALLOC_FREE(client);
273                 return;
274         }
275         tevent_req_set_callback(client->read_req, nb_packet_client_read_done,
276                                 client);
277 }
278
279 static void nb_packet_client_read_done(struct tevent_req *req)
280 {
281         struct nb_packet_client *client = tevent_req_callback_data(
282                 req, struct nb_packet_client);
283         ssize_t nread;
284         uint8_t *buf;
285         int err;
286
287         nread = read_packet_recv(req, talloc_tos(), &buf, &err);
288         TALLOC_FREE(req);
289         if (nread == 1) {
290                 DEBUG(10, ("Protocol error, received data on write-only "
291                            "unexpected socket: 0x%2.2x\n", (*buf)));
292         }
293         TALLOC_FREE(client);
294 }
295
296 static void nb_packet_client_send(struct nb_packet_client *client,
297                                   struct packet_struct *p);
298
299 void nb_packet_dispatch(struct nb_packet_server *server,
300                         struct packet_struct *p)
301 {
302         struct nb_packet_client *c;
303         uint16_t trn_id;
304
305         switch (p->packet_type) {
306         case NMB_PACKET:
307                 trn_id = p->packet.nmb.header.name_trn_id;
308                 break;
309         case DGRAM_PACKET:
310                 trn_id = p->packet.dgram.header.dgm_id;
311                 break;
312         default:
313                 DEBUG(10, ("Got invalid packet type %d\n",
314                            (int)p->packet_type));
315                 return;
316         }
317         for (c = server->clients; c != NULL; c = c->next) {
318
319                 if (c->type != p->packet_type) {
320                         DEBUG(10, ("client expects packet %d, got %d\n",
321                                    c->type, p->packet_type));
322                         continue;
323                 }
324
325                 if (p->packet_type == NMB_PACKET) {
326                         /*
327                          * See if the client specified transaction
328                          * ID. Filter if it did.
329                          */
330                         if ((c->trn_id != -1) &&
331                             (c->trn_id != trn_id)) {
332                                 DEBUG(10, ("client expects trn %d, got %d\n",
333                                            c->trn_id, trn_id));
334                                 continue;
335                         }
336                 } else {
337                         /*
338                          * See if the client specified a mailslot
339                          * name. Filter if it did.
340                          */
341                         if ((c->mailslot_name != NULL) &&
342                             !match_mailslot_name(p, c->mailslot_name)) {
343                                 continue;
344                         }
345                 }
346                 nb_packet_client_send(c, p);
347         }
348 }
349
350 struct nb_packet_client_header {
351         size_t len;
352         enum packet_type type;
353         time_t timestamp;
354         struct in_addr ip;
355         int port;
356 };
357
358 struct nb_packet_client_state {
359         struct nb_packet_client *client;
360         struct iovec iov[2];
361         struct nb_packet_client_header hdr;
362         char buf[1024];
363 };
364
365 static void nb_packet_client_send_done(struct tevent_req *req);
366
367 static void nb_packet_client_send(struct nb_packet_client *client,
368                                   struct packet_struct *p)
369 {
370         struct nb_packet_client_state *state;
371         struct tevent_req *req;
372
373         if (tevent_queue_length(client->out_queue) > 10) {
374                 /*
375                  * Skip clients that don't listen anyway, some form of DoS
376                  * protection
377                  */
378                 return;
379         }
380
381         state = talloc_zero(client, struct nb_packet_client_state);
382         if (state == NULL) {
383                 DEBUG(10, ("talloc failed\n"));
384                 return;
385         }
386
387         state->client = client;
388
389         state->hdr.ip = p->ip;
390         state->hdr.port = p->port;
391         state->hdr.timestamp = p->timestamp;
392         state->hdr.type = p->packet_type;
393         state->hdr.len = build_packet(state->buf, sizeof(state->buf), p);
394
395         state->iov[0].iov_base = (char *)&state->hdr;
396         state->iov[0].iov_len = sizeof(state->hdr);
397         state->iov[1].iov_base = state->buf;
398         state->iov[1].iov_len = state->hdr.len;
399
400         TALLOC_FREE(client->read_req);
401
402         req = writev_send(client, client->server->ev, client->out_queue,
403                           client->sock, true, state->iov, 2);
404         if (req == NULL) {
405                 DEBUG(10, ("writev_send failed\n"));
406                 return;
407         }
408         tevent_req_set_callback(req, nb_packet_client_send_done, state);
409 }
410
411 static void nb_packet_client_send_done(struct tevent_req *req)
412 {
413         struct nb_packet_client_state *state = tevent_req_callback_data(
414                 req, struct nb_packet_client_state);
415         struct nb_packet_client *client = state->client;
416         ssize_t nwritten;
417         int err;
418
419         nwritten = writev_recv(req, &err);
420
421         TALLOC_FREE(req);
422         TALLOC_FREE(state);
423
424         if (nwritten == -1) {
425                 DEBUG(10, ("writev failed: %s\n", strerror(err)));
426                 TALLOC_FREE(client);
427         }
428
429         if (tevent_queue_length(client->out_queue) == 0) {
430                 client->read_req = read_packet_send(client, client->server->ev,
431                                                     client->sock, 1,
432                                                     NULL, NULL);
433                 if (client->read_req == NULL) {
434                         DEBUG(10, ("Could not activate reader for client exit "
435                                    "detection\n"));
436                         TALLOC_FREE(client);
437                         return;
438                 }
439                 tevent_req_set_callback(client->read_req,
440                                         nb_packet_client_read_done,
441                                         client);
442         }
443 }
444
445 struct nb_packet_reader {
446         int sock;
447 };
448
449 struct nb_packet_reader_state {
450         struct tevent_context *ev;
451         struct sockaddr_un addr;
452         struct nb_packet_query query;
453         const char *mailslot_name;
454         struct iovec iov[2];
455         char c;
456         struct nb_packet_reader *reader;
457 };
458
459 static int nb_packet_reader_destructor(struct nb_packet_reader *r);
460 static void nb_packet_reader_connected(struct tevent_req *subreq);
461 static void nb_packet_reader_sent_query(struct tevent_req *subreq);
462 static void nb_packet_reader_got_ack(struct tevent_req *subreq);
463
464 struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx,
465                                          struct tevent_context *ev,
466                                          enum packet_type type,
467                                          int trn_id,
468                                          const char *mailslot_name)
469 {
470         struct tevent_req *req, *subreq;
471         struct nb_packet_reader_state *state;
472         char *path;
473
474         req = tevent_req_create(mem_ctx, &state,
475                                 struct nb_packet_reader_state);
476         if (req == NULL) {
477                 return NULL;
478         }
479         state->ev = ev;
480         state->query.trn_id = trn_id;
481         state->query.type = type;
482         state->mailslot_name = mailslot_name;
483
484         if (mailslot_name != NULL) {
485                 state->query.mailslot_namelen = strlen(mailslot_name);
486         }
487
488         state->reader = talloc_zero(state, struct nb_packet_reader);
489         if (tevent_req_nomem(state->reader, req)) {
490                 return tevent_req_post(req, ev);
491         }
492
493         path = talloc_asprintf(talloc_tos(), "%s/%s", nmbd_socket_dir(),
494                                "unexpected");
495         if (tevent_req_nomem(path, req)) {
496                 return tevent_req_post(req, ev);
497         }
498         state->addr.sun_family = AF_UNIX;
499         strlcpy(state->addr.sun_path, path, sizeof(state->addr.sun_path));
500         TALLOC_FREE(path);
501
502         state->reader->sock = socket(AF_UNIX, SOCK_STREAM, 0);
503         if (state->reader->sock == -1) {
504                 tevent_req_nterror(req, map_nt_error_from_unix(errno));
505                 return tevent_req_post(req, ev);
506         }
507         talloc_set_destructor(state->reader, nb_packet_reader_destructor);
508
509         subreq = async_connect_send(state, ev, state->reader->sock,
510                                     (struct sockaddr *)(void *)&state->addr,
511                                     sizeof(state->addr));
512         if (tevent_req_nomem(subreq, req)) {
513                 return tevent_req_post(req, ev);
514         }
515         tevent_req_set_callback(subreq, nb_packet_reader_connected, req);
516         return req;
517 }
518
519 static int nb_packet_reader_destructor(struct nb_packet_reader *r)
520 {
521         if (r->sock != -1) {
522                 close(r->sock);
523                 r->sock = -1;
524         }
525         return 0;
526 }
527
528 static void nb_packet_reader_connected(struct tevent_req *subreq)
529 {
530         struct tevent_req *req = tevent_req_callback_data(
531                 subreq, struct tevent_req);
532         struct nb_packet_reader_state *state = tevent_req_data(
533                 req, struct nb_packet_reader_state);
534         int res, err;
535         int num_iovecs = 1;
536
537         res = async_connect_recv(subreq, &err);
538         TALLOC_FREE(subreq);
539         if (res == -1) {
540                 DEBUG(10, ("async_connect failed: %s\n", strerror(err)));
541                 tevent_req_nterror(req, map_nt_error_from_unix(err));
542                 return;
543         }
544
545         state->iov[0].iov_base = (char *)&state->query;
546         state->iov[0].iov_len = sizeof(state->query);
547
548         if (state->mailslot_name != NULL) {
549                 num_iovecs = 2;
550                 state->iov[1].iov_base = discard_const_p(
551                         char, state->mailslot_name);
552                 state->iov[1].iov_len = state->query.mailslot_namelen;
553         }
554
555         subreq = writev_send(state, state->ev, NULL, state->reader->sock,
556                              true, state->iov, num_iovecs);
557         if (tevent_req_nomem(subreq, req)) {
558                 return;
559         }
560         tevent_req_set_callback(subreq, nb_packet_reader_sent_query, req);
561 }
562
563 static void nb_packet_reader_sent_query(struct tevent_req *subreq)
564 {
565         struct tevent_req *req = tevent_req_callback_data(
566                 subreq, struct tevent_req);
567         struct nb_packet_reader_state *state = tevent_req_data(
568                 req, struct nb_packet_reader_state);
569         ssize_t written;
570         int err;
571
572         written = writev_recv(subreq, &err);
573         TALLOC_FREE(subreq);
574         if (written == -1) {
575                 tevent_req_nterror(req, map_nt_error_from_unix(err));
576                 return;
577         }
578         if (written != sizeof(state->query) + state->query.mailslot_namelen) {
579                 tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR);
580                 return;
581         }
582         subreq = read_packet_send(state, state->ev, state->reader->sock,
583                                   sizeof(state->c), NULL, NULL);
584         if (tevent_req_nomem(subreq, req)) {
585                 return;
586         }
587         tevent_req_set_callback(subreq, nb_packet_reader_got_ack, req);
588 }
589
590 static void nb_packet_reader_got_ack(struct tevent_req *subreq)
591 {
592         struct tevent_req *req = tevent_req_callback_data(
593                 subreq, struct tevent_req);
594         struct nb_packet_reader_state *state = tevent_req_data(
595                 req, struct nb_packet_reader_state);
596         ssize_t nread;
597         int err;
598         uint8_t *buf;
599
600         nread = read_packet_recv(subreq, state, &buf, &err);
601         TALLOC_FREE(subreq);
602         if (nread == -1) {
603                 DEBUG(10, ("read_packet_recv returned %s\n",
604                            strerror(err)));
605                 tevent_req_nterror(req, map_nt_error_from_unix(err));
606                 return;
607         }
608         if (nread != sizeof(state->c)) {
609                 DEBUG(10, ("read = %d, expected %d\n", (int)nread,
610                            (int)sizeof(state->c)));
611                 tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR);
612                 return;
613         }
614         tevent_req_done(req);
615 }
616
617 NTSTATUS nb_packet_reader_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
618                                struct nb_packet_reader **preader)
619 {
620         struct nb_packet_reader_state *state = tevent_req_data(
621                 req, struct nb_packet_reader_state);
622         NTSTATUS status;
623
624         if (tevent_req_is_nterror(req, &status)) {
625                 return status;
626         }
627         *preader = talloc_move(mem_ctx, &state->reader);
628         return NT_STATUS_OK;
629 }
630
631 struct nb_packet_read_state {
632         struct nb_packet_client_header hdr;
633         uint8_t *buf;
634         size_t buflen;
635 };
636
637 static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p);
638 static void nb_packet_read_done(struct tevent_req *subreq);
639
640 struct tevent_req *nb_packet_read_send(TALLOC_CTX *mem_ctx,
641                                        struct tevent_context *ev,
642                                        struct nb_packet_reader *reader)
643 {
644         struct tevent_req *req, *subreq;
645         struct nb_packet_read_state *state;
646
647         req = tevent_req_create(mem_ctx, &state, struct nb_packet_read_state);
648         if (req == NULL) {
649                 return NULL;
650         }
651         subreq = read_packet_send(state, ev, reader->sock,
652                                   sizeof(struct nb_packet_client_header),
653                                   nb_packet_read_more, state);
654         if (tevent_req_nomem(subreq, req)) {
655                 return tevent_req_post(req, ev);
656         }
657         tevent_req_set_callback(subreq, nb_packet_read_done, req);
658         return req;
659 }
660
661 static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p)
662 {
663         struct nb_packet_read_state *state = talloc_get_type_abort(
664                 p, struct nb_packet_read_state);
665
666         if (buflen > sizeof(struct nb_packet_client_header)) {
667                 /*
668                  * Been here, done
669                  */
670                 return 0;
671         }
672         memcpy(&state->hdr, buf, sizeof(struct nb_packet_client_header));
673         return state->hdr.len;
674 }
675
676 static void nb_packet_read_done(struct tevent_req *subreq)
677 {
678         struct tevent_req *req = tevent_req_callback_data(
679                 subreq, struct tevent_req);
680         struct nb_packet_read_state *state = tevent_req_data(
681                 req, struct nb_packet_read_state);
682         ssize_t nread;
683         int err;
684
685         nread = read_packet_recv(subreq, state, &state->buf, &err);
686         if (nread == -1) {
687                 tevent_req_nterror(req, map_nt_error_from_unix(err));
688                 return;
689         }
690         state->buflen = nread;
691         tevent_req_done(req);
692 }
693
694 NTSTATUS nb_packet_read_recv(struct tevent_req *req,
695                              struct packet_struct **ppacket)
696 {
697         struct nb_packet_read_state *state = tevent_req_data(
698                 req, struct nb_packet_read_state);
699         struct nb_packet_client_header hdr;
700         struct packet_struct *packet;
701         NTSTATUS status;
702
703         if (tevent_req_is_nterror(req, &status)) {
704                 return status;
705         }
706
707         memcpy(&hdr, state->buf, sizeof(hdr));
708
709         packet = parse_packet(
710                 (char *)state->buf + sizeof(struct nb_packet_client_header),
711                 state->buflen - sizeof(struct nb_packet_client_header),
712                 state->hdr.type, state->hdr.ip, state->hdr.port);
713         if (packet == NULL) {
714                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
715         }
716         *ppacket = packet;
717         return NT_STATUS_OK;
718 }