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