docs:smbdotconf: fix type of "preferred master" parameter.
[Samba.git] / source3 / libsmb / unexpected.c
blob013d798dd03c341fb025024650733751f2310e38
1 /*
2 Unix SMB/CIFS implementation.
3 handle unexpected packets
4 Copyright (C) Andrew Tridgell 2000
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.
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.
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/>.
21 #include "includes.h"
22 #include "../lib/util/tevent_ntstatus.h"
23 #include "lib/tsocket/tsocket.h"
24 #include "libsmb/nmblib.h"
25 #include "lib/sys_rw.h"
27 static const char *nmbd_socket_dir(void)
29 return lp_parm_const_string(-1, "nmbd", "socket dir",
30 get_dyn_NMBDSOCKETDIR());
33 struct nb_packet_query {
34 enum packet_type type;
35 size_t mailslot_namelen;
36 int trn_id;
39 struct nb_packet_client;
41 struct nb_packet_server {
42 struct tevent_context *ev;
43 int listen_sock;
44 struct tevent_fd *listen_fde;
45 int max_clients;
46 int num_clients;
47 struct nb_packet_client *clients;
50 struct nb_packet_client {
51 struct nb_packet_client *prev, *next;
52 struct nb_packet_server *server;
54 enum packet_type type;
55 int trn_id;
56 char *mailslot_name;
58 struct {
59 uint8_t byte;
60 struct iovec iov[1];
61 } ack;
63 struct tstream_context *sock;
64 struct tevent_queue *out_queue;
67 static int nb_packet_server_destructor(struct nb_packet_server *s);
68 static void nb_packet_server_listener(struct tevent_context *ev,
69 struct tevent_fd *fde,
70 uint16_t flags,
71 void *private_data);
73 NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx,
74 struct tevent_context *ev,
75 int max_clients,
76 struct nb_packet_server **presult)
78 struct nb_packet_server *result;
79 NTSTATUS status;
80 int rc;
82 result = talloc_zero(mem_ctx, struct nb_packet_server);
83 if (result == NULL) {
84 status = NT_STATUS_NO_MEMORY;
85 goto fail;
87 result->ev = ev;
88 result->max_clients = max_clients;
90 result->listen_sock = create_pipe_sock(
91 nmbd_socket_dir(), "unexpected", 0755);
92 if (result->listen_sock == -1) {
93 status = map_nt_error_from_unix(errno);
94 goto fail;
96 rc = listen(result->listen_sock, 5);
97 if (rc < 0) {
98 status = map_nt_error_from_unix(errno);
99 goto fail;
101 talloc_set_destructor(result, nb_packet_server_destructor);
103 result->listen_fde = tevent_add_fd(ev, result,
104 result->listen_sock,
105 TEVENT_FD_READ,
106 nb_packet_server_listener,
107 result);
108 if (result->listen_fde == NULL) {
109 status = NT_STATUS_NO_MEMORY;
110 goto fail;
113 *presult = result;
114 return NT_STATUS_OK;
115 fail:
116 TALLOC_FREE(result);
117 return status;
120 static int nb_packet_server_destructor(struct nb_packet_server *s)
122 TALLOC_FREE(s->listen_fde);
124 if (s->listen_sock != -1) {
125 close(s->listen_sock);
126 s->listen_sock = -1;
128 return 0;
131 static int nb_packet_client_destructor(struct nb_packet_client *c);
132 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
133 void *private_data);
134 static void nb_packet_got_query(struct tevent_req *req);
135 static void nb_packet_client_ack_done(struct tevent_req *req);
136 static void nb_packet_client_read_done(struct tevent_req *req);
138 static void nb_packet_server_listener(struct tevent_context *ev,
139 struct tevent_fd *fde,
140 uint16_t flags,
141 void *private_data)
143 struct nb_packet_server *server = talloc_get_type_abort(
144 private_data, struct nb_packet_server);
145 struct nb_packet_client *client;
146 struct tevent_req *req;
147 struct sockaddr_un sunaddr;
148 socklen_t len;
149 int sock;
150 int ret;
152 len = sizeof(sunaddr);
154 sock = accept(server->listen_sock, (struct sockaddr *)(void *)&sunaddr,
155 &len);
156 if (sock == -1) {
157 return;
159 DEBUG(6,("accepted socket %d\n", sock));
161 client = talloc_zero(server, struct nb_packet_client);
162 if (client == NULL) {
163 DEBUG(10, ("talloc failed\n"));
164 close(sock);
165 return;
167 ret = tstream_bsd_existing_socket(client, sock, &client->sock);
168 if (ret != 0) {
169 DEBUG(10, ("tstream_bsd_existing_socket failed\n"));
170 close(sock);
171 return;
174 client->server = server;
175 talloc_set_destructor(client, nb_packet_client_destructor);
177 client->out_queue = tevent_queue_create(
178 client, "unexpected packet output");
179 if (client->out_queue == NULL) {
180 DEBUG(10, ("tevent_queue_create failed\n"));
181 TALLOC_FREE(client);
182 return;
185 req = tstream_read_packet_send(client, ev, client->sock,
186 sizeof(struct nb_packet_query),
187 nb_packet_client_more, NULL);
188 if (req == NULL) {
189 DEBUG(10, ("tstream_read_packet_send failed\n"));
190 TALLOC_FREE(client);
191 return;
193 tevent_req_set_callback(req, nb_packet_got_query, client);
195 DLIST_ADD(server->clients, client);
196 server->num_clients += 1;
198 if (server->num_clients > server->max_clients) {
199 DEBUG(10, ("Too many clients, dropping oldest\n"));
202 * no TALLOC_FREE here, don't mess with the list structs
204 talloc_free(server->clients->prev);
208 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
209 void *private_data)
211 struct nb_packet_query q;
212 if (buflen > sizeof(struct nb_packet_query)) {
213 return 0;
215 /* Take care of alignment */
216 memcpy(&q, buf, sizeof(q));
217 if (q.mailslot_namelen > 1024) {
218 DEBUG(10, ("Got invalid mailslot namelen %d\n",
219 (int)q.mailslot_namelen));
220 return -1;
222 return q.mailslot_namelen;
225 static int nb_packet_client_destructor(struct nb_packet_client *c)
227 tevent_queue_stop(c->out_queue);
228 TALLOC_FREE(c->sock);
230 DLIST_REMOVE(c->server->clients, c);
231 c->server->num_clients -= 1;
232 return 0;
235 static void nb_packet_got_query(struct tevent_req *req)
237 struct nb_packet_client *client = tevent_req_callback_data(
238 req, struct nb_packet_client);
239 struct nb_packet_query q;
240 uint8_t *buf;
241 ssize_t nread;
242 int err;
244 nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err);
245 TALLOC_FREE(req);
246 if (nread < (ssize_t)sizeof(struct nb_packet_query)) {
247 DEBUG(10, ("read_packet_recv returned %d (%s)\n",
248 (int)nread,
249 (nread == -1) ? strerror(err) : "wrong length"));
250 TALLOC_FREE(client);
251 return;
254 /* Take care of alignment */
255 memcpy(&q, buf, sizeof(q));
257 if (nread != sizeof(struct nb_packet_query) + q.mailslot_namelen) {
258 DEBUG(10, ("nb_packet_got_query: Invalid mailslot namelength\n"));
259 TALLOC_FREE(client);
260 return;
263 client->trn_id = q.trn_id;
264 client->type = q.type;
265 if (q.mailslot_namelen > 0) {
266 client->mailslot_name = talloc_strndup(
267 client, (char *)buf + sizeof(q),
268 q.mailslot_namelen);
269 if (client->mailslot_name == NULL) {
270 TALLOC_FREE(client);
271 return;
275 client->ack.byte = 0;
276 client->ack.iov[0].iov_base = &client->ack.byte;
277 client->ack.iov[0].iov_len = 1;
278 req = tstream_writev_queue_send(client, client->server->ev,
279 client->sock,
280 client->out_queue,
281 client->ack.iov, 1);
282 if (req == NULL) {
283 DEBUG(10, ("tstream_writev_queue_send failed\n"));
284 TALLOC_FREE(client);
285 return;
287 tevent_req_set_callback(req, nb_packet_client_ack_done, client);
289 req = tstream_read_packet_send(client, client->server->ev,
290 client->sock, 1, NULL, NULL);
291 if (req == NULL) {
292 DEBUG(10, ("Could not activate reader for client exit "
293 "detection\n"));
294 TALLOC_FREE(client);
295 return;
297 tevent_req_set_callback(req, nb_packet_client_read_done,
298 client);
301 static void nb_packet_client_ack_done(struct tevent_req *req)
303 struct nb_packet_client *client = tevent_req_callback_data(
304 req, struct nb_packet_client);
305 ssize_t nwritten;
306 int err;
308 nwritten = tstream_writev_queue_recv(req, &err);
310 TALLOC_FREE(req);
312 if (nwritten == -1) {
313 DEBUG(10, ("tstream_writev_queue_recv failed: %s\n",
314 strerror(err)));
315 TALLOC_FREE(client);
316 return;
320 static void nb_packet_client_read_done(struct tevent_req *req)
322 struct nb_packet_client *client = tevent_req_callback_data(
323 req, struct nb_packet_client);
324 ssize_t nread;
325 uint8_t *buf;
326 int err;
328 nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err);
329 TALLOC_FREE(req);
330 if (nread == 1) {
331 DEBUG(10, ("Protocol error, received data on write-only "
332 "unexpected socket: 0x%2.2x\n", (*buf)));
334 TALLOC_FREE(client);
337 static void nb_packet_client_send(struct nb_packet_client *client,
338 struct packet_struct *p);
340 void nb_packet_dispatch(struct nb_packet_server *server,
341 struct packet_struct *p)
343 struct nb_packet_client *c;
344 uint16_t trn_id;
346 switch (p->packet_type) {
347 case NMB_PACKET:
348 trn_id = p->packet.nmb.header.name_trn_id;
349 break;
350 case DGRAM_PACKET:
351 trn_id = p->packet.dgram.header.dgm_id;
352 break;
353 default:
354 DEBUG(10, ("Got invalid packet type %d\n",
355 (int)p->packet_type));
356 return;
358 for (c = server->clients; c != NULL; c = c->next) {
360 if (c->type != p->packet_type) {
361 DEBUG(10, ("client expects packet %d, got %d\n",
362 c->type, p->packet_type));
363 continue;
366 if (p->packet_type == NMB_PACKET) {
368 * See if the client specified transaction
369 * ID. Filter if it did.
371 if ((c->trn_id != -1) &&
372 (c->trn_id != trn_id)) {
373 DEBUG(10, ("client expects trn %d, got %d\n",
374 c->trn_id, trn_id));
375 continue;
377 } else {
379 * See if the client specified a mailslot
380 * name. Filter if it did.
382 if ((c->mailslot_name != NULL) &&
383 !match_mailslot_name(p, c->mailslot_name)) {
384 continue;
387 nb_packet_client_send(c, p);
391 struct nb_packet_client_header {
392 size_t len;
393 enum packet_type type;
394 time_t timestamp;
395 struct in_addr ip;
396 int port;
399 struct nb_packet_client_state {
400 struct nb_packet_client *client;
401 struct iovec iov[2];
402 struct nb_packet_client_header hdr;
403 char buf[1024];
406 static void nb_packet_client_send_done(struct tevent_req *req);
408 static void nb_packet_client_send(struct nb_packet_client *client,
409 struct packet_struct *p)
411 struct nb_packet_client_state *state;
412 struct tevent_req *req;
414 if (tevent_queue_length(client->out_queue) > 10) {
416 * Skip clients that don't listen anyway, some form of DoS
417 * protection
419 return;
422 state = talloc_zero(client, struct nb_packet_client_state);
423 if (state == NULL) {
424 DEBUG(10, ("talloc failed\n"));
425 return;
428 state->client = client;
430 state->hdr.ip = p->ip;
431 state->hdr.port = p->port;
432 state->hdr.timestamp = p->timestamp;
433 state->hdr.type = p->packet_type;
434 state->hdr.len = build_packet(state->buf, sizeof(state->buf), p);
436 state->iov[0].iov_base = (char *)&state->hdr;
437 state->iov[0].iov_len = sizeof(state->hdr);
438 state->iov[1].iov_base = state->buf;
439 state->iov[1].iov_len = state->hdr.len;
441 req = tstream_writev_queue_send(state, client->server->ev,
442 client->sock,
443 client->out_queue,
444 state->iov, 2);
445 if (req == NULL) {
446 DEBUG(10, ("tstream_writev_queue_send failed\n"));
447 return;
449 tevent_req_set_callback(req, nb_packet_client_send_done, state);
452 static void nb_packet_client_send_done(struct tevent_req *req)
454 struct nb_packet_client_state *state = tevent_req_callback_data(
455 req, struct nb_packet_client_state);
456 struct nb_packet_client *client = state->client;
457 ssize_t nwritten;
458 int err;
460 nwritten = tstream_writev_queue_recv(req, &err);
462 TALLOC_FREE(req);
463 TALLOC_FREE(state);
465 if (nwritten == -1) {
466 DEBUG(10, ("tstream_writev_queue failed: %s\n", strerror(err)));
467 TALLOC_FREE(client);
468 return;
472 struct nb_packet_reader {
473 struct tstream_context *sock;
476 struct nb_packet_reader_state {
477 struct tevent_context *ev;
478 struct nb_packet_query query;
479 const char *mailslot_name;
480 struct iovec iov[2];
481 char c;
482 struct nb_packet_reader *reader;
485 static void nb_packet_reader_connected(struct tevent_req *subreq);
486 static void nb_packet_reader_sent_query(struct tevent_req *subreq);
487 static void nb_packet_reader_got_ack(struct tevent_req *subreq);
489 struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx,
490 struct tevent_context *ev,
491 enum packet_type type,
492 int trn_id,
493 const char *mailslot_name)
495 struct tevent_req *req, *subreq;
496 struct nb_packet_reader_state *state;
497 struct tsocket_address *laddr;
498 char *rpath;
499 struct tsocket_address *raddr;
500 int ret;
502 req = tevent_req_create(mem_ctx, &state,
503 struct nb_packet_reader_state);
504 if (req == NULL) {
505 return NULL;
507 state->ev = ev;
508 state->query.trn_id = trn_id;
509 state->query.type = type;
510 state->mailslot_name = mailslot_name;
512 if (mailslot_name != NULL) {
513 state->query.mailslot_namelen = strlen(mailslot_name);
516 state->reader = talloc_zero(state, struct nb_packet_reader);
517 if (tevent_req_nomem(state->reader, req)) {
518 return tevent_req_post(req, ev);
521 ret = tsocket_address_unix_from_path(state, "", &laddr);
522 if (ret != 0) {
523 tevent_req_nterror(req, map_nt_error_from_unix(errno));
524 return tevent_req_post(req, ev);
526 rpath = talloc_asprintf(state, "%s/%s", nmbd_socket_dir(),
527 "unexpected");
528 if (tevent_req_nomem(rpath, req)) {
529 return tevent_req_post(req, ev);
531 ret = tsocket_address_unix_from_path(state, rpath, &raddr);
532 if (ret != 0) {
533 tevent_req_nterror(req, map_nt_error_from_unix(errno));
534 return tevent_req_post(req, ev);
537 subreq = tstream_unix_connect_send(state, ev, laddr, raddr);
538 if (tevent_req_nomem(subreq, req)) {
539 return tevent_req_post(req, ev);
541 tevent_req_set_callback(subreq, nb_packet_reader_connected, req);
542 return req;
545 static void nb_packet_reader_connected(struct tevent_req *subreq)
547 struct tevent_req *req = tevent_req_callback_data(
548 subreq, struct tevent_req);
549 struct nb_packet_reader_state *state = tevent_req_data(
550 req, struct nb_packet_reader_state);
551 int res, err;
552 int num_iovecs = 1;
554 res = tstream_unix_connect_recv(subreq, &err, state->reader,
555 &state->reader->sock);
556 TALLOC_FREE(subreq);
557 if (res == -1) {
558 DEBUG(10, ("tstream_unix_connect failed: %s\n", strerror(err)));
559 tevent_req_nterror(req, map_nt_error_from_unix(err));
560 return;
563 state->iov[0].iov_base = (char *)&state->query;
564 state->iov[0].iov_len = sizeof(state->query);
566 if (state->mailslot_name != NULL) {
567 num_iovecs = 2;
568 state->iov[1].iov_base = discard_const_p(
569 char, state->mailslot_name);
570 state->iov[1].iov_len = state->query.mailslot_namelen;
573 subreq = tstream_writev_send(state, state->ev, state->reader->sock,
574 state->iov, num_iovecs);
575 if (tevent_req_nomem(subreq, req)) {
576 return;
578 tevent_req_set_callback(subreq, nb_packet_reader_sent_query, req);
581 static void nb_packet_reader_sent_query(struct tevent_req *subreq)
583 struct tevent_req *req = tevent_req_callback_data(
584 subreq, struct tevent_req);
585 struct nb_packet_reader_state *state = tevent_req_data(
586 req, struct nb_packet_reader_state);
587 ssize_t written;
588 int err;
590 written = tstream_writev_recv(subreq, &err);
591 TALLOC_FREE(subreq);
592 if (written == -1) {
593 tevent_req_nterror(req, map_nt_error_from_unix(err));
594 return;
596 if (written != sizeof(state->query) + state->query.mailslot_namelen) {
597 tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR);
598 return;
600 subreq = tstream_read_packet_send(state, state->ev,
601 state->reader->sock,
602 sizeof(state->c), NULL, NULL);
603 if (tevent_req_nomem(subreq, req)) {
604 return;
606 tevent_req_set_callback(subreq, nb_packet_reader_got_ack, req);
609 static void nb_packet_reader_got_ack(struct tevent_req *subreq)
611 struct tevent_req *req = tevent_req_callback_data(
612 subreq, struct tevent_req);
613 struct nb_packet_reader_state *state = tevent_req_data(
614 req, struct nb_packet_reader_state);
615 ssize_t nread;
616 int err;
617 uint8_t *buf;
619 nread = tstream_read_packet_recv(subreq, state, &buf, &err);
620 TALLOC_FREE(subreq);
621 if (nread == -1) {
622 DEBUG(10, ("read_packet_recv returned %s\n",
623 strerror(err)));
624 tevent_req_nterror(req, map_nt_error_from_unix(err));
625 return;
627 if (nread != sizeof(state->c)) {
628 DEBUG(10, ("read = %d, expected %d\n", (int)nread,
629 (int)sizeof(state->c)));
630 tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR);
631 return;
633 tevent_req_done(req);
636 NTSTATUS nb_packet_reader_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
637 struct nb_packet_reader **preader)
639 struct nb_packet_reader_state *state = tevent_req_data(
640 req, struct nb_packet_reader_state);
641 NTSTATUS status;
643 if (tevent_req_is_nterror(req, &status)) {
644 tevent_req_received(req);
645 return status;
647 *preader = talloc_move(mem_ctx, &state->reader);
648 tevent_req_received(req);
649 return NT_STATUS_OK;
652 struct nb_packet_read_state {
653 struct nb_packet_client_header hdr;
654 uint8_t *buf;
655 size_t buflen;
658 static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p);
659 static void nb_packet_read_done(struct tevent_req *subreq);
661 struct tevent_req *nb_packet_read_send(TALLOC_CTX *mem_ctx,
662 struct tevent_context *ev,
663 struct nb_packet_reader *reader)
665 struct tevent_req *req, *subreq;
666 struct nb_packet_read_state *state;
668 req = tevent_req_create(mem_ctx, &state, struct nb_packet_read_state);
669 if (req == NULL) {
670 return NULL;
672 subreq = tstream_read_packet_send(state, ev, reader->sock,
673 sizeof(struct nb_packet_client_header),
674 nb_packet_read_more, state);
675 if (tevent_req_nomem(subreq, req)) {
676 return tevent_req_post(req, ev);
678 tevent_req_set_callback(subreq, nb_packet_read_done, req);
679 return req;
682 static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p)
684 struct nb_packet_read_state *state = talloc_get_type_abort(
685 p, struct nb_packet_read_state);
687 if (buflen > sizeof(struct nb_packet_client_header)) {
689 * Been here, done
691 return 0;
693 memcpy(&state->hdr, buf, sizeof(struct nb_packet_client_header));
694 return state->hdr.len;
697 static void nb_packet_read_done(struct tevent_req *subreq)
699 struct tevent_req *req = tevent_req_callback_data(
700 subreq, struct tevent_req);
701 struct nb_packet_read_state *state = tevent_req_data(
702 req, struct nb_packet_read_state);
703 ssize_t nread;
704 int err;
706 nread = tstream_read_packet_recv(subreq, state, &state->buf, &err);
707 if (nread == -1) {
708 tevent_req_nterror(req, map_nt_error_from_unix(err));
709 return;
711 state->buflen = nread;
712 tevent_req_done(req);
715 NTSTATUS nb_packet_read_recv(struct tevent_req *req,
716 struct packet_struct **ppacket)
718 struct nb_packet_read_state *state = tevent_req_data(
719 req, struct nb_packet_read_state);
720 struct nb_packet_client_header hdr;
721 struct packet_struct *packet;
722 NTSTATUS status;
724 if (tevent_req_is_nterror(req, &status)) {
725 tevent_req_received(req);
726 return status;
729 memcpy(&hdr, state->buf, sizeof(hdr));
731 packet = parse_packet(
732 (char *)state->buf + sizeof(struct nb_packet_client_header),
733 state->buflen - sizeof(struct nb_packet_client_header),
734 state->hdr.type, state->hdr.ip, state->hdr.port);
735 if (packet == NULL) {
736 tevent_req_received(req);
737 return NT_STATUS_INVALID_NETWORK_RESPONSE;
739 *ppacket = packet;
740 tevent_req_received(req);
741 return NT_STATUS_OK;