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