auth/credentials: don't ignore "client use kerberos" and --use-kerberos for machine...
[Samba.git] / source3 / libsmb / unexpected.c
blob10ceac774478196267b7ca6281e117edc1a576d0
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 "libsmb/unexpected.h"
23 #include "../lib/util/tevent_ntstatus.h"
24 #include "lib/util_tsock.h"
25 #include "libsmb/nmblib.h"
26 #include "lib/tsocket/tsocket.h"
27 #include "lib/util/sys_rw.h"
29 struct nb_packet_query {
30 enum packet_type type;
31 size_t mailslot_namelen;
32 int trn_id;
35 struct nb_packet_client;
37 struct nb_packet_server {
38 struct tevent_context *ev;
39 int listen_sock;
40 struct tevent_fd *listen_fde;
41 int max_clients;
42 int num_clients;
43 struct nb_packet_client *clients;
46 struct nb_packet_client {
47 struct nb_packet_client *prev, *next;
48 struct nb_packet_server *server;
50 enum packet_type type;
51 int trn_id;
52 char *mailslot_name;
54 struct {
55 uint8_t byte;
56 struct iovec iov[1];
57 } ack;
59 struct tstream_context *sock;
60 struct tevent_queue *out_queue;
63 static int nb_packet_server_destructor(struct nb_packet_server *s);
64 static void nb_packet_server_listener(struct tevent_context *ev,
65 struct tevent_fd *fde,
66 uint16_t flags,
67 void *private_data);
69 NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx,
70 struct tevent_context *ev,
71 const char *nmbd_socket_dir,
72 int max_clients,
73 struct nb_packet_server **presult)
75 struct nb_packet_server *result;
76 NTSTATUS status;
77 int rc;
79 result = talloc_zero(mem_ctx, struct nb_packet_server);
80 if (result == NULL) {
81 status = NT_STATUS_NO_MEMORY;
82 goto fail;
84 result->ev = ev;
85 result->max_clients = max_clients;
87 result->listen_sock = create_pipe_sock(
88 nmbd_socket_dir, "unexpected", 0755);
89 if (result->listen_sock == -1) {
90 status = map_nt_error_from_unix(errno);
91 goto fail;
93 rc = listen(result->listen_sock, 5);
94 if (rc < 0) {
95 status = map_nt_error_from_unix(errno);
96 goto fail;
98 talloc_set_destructor(result, nb_packet_server_destructor);
100 result->listen_fde = tevent_add_fd(ev, result,
101 result->listen_sock,
102 TEVENT_FD_READ,
103 nb_packet_server_listener,
104 result);
105 if (result->listen_fde == NULL) {
106 status = NT_STATUS_NO_MEMORY;
107 goto fail;
110 *presult = result;
111 return NT_STATUS_OK;
112 fail:
113 TALLOC_FREE(result);
114 return status;
117 static int nb_packet_server_destructor(struct nb_packet_server *s)
119 TALLOC_FREE(s->listen_fde);
121 if (s->listen_sock != -1) {
122 close(s->listen_sock);
123 s->listen_sock = -1;
125 return 0;
128 static int nb_packet_client_destructor(struct nb_packet_client *c);
129 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
130 void *private_data);
131 static void nb_packet_got_query(struct tevent_req *req);
132 static void nb_packet_client_ack_done(struct tevent_req *req);
133 static void nb_packet_client_read_done(struct tevent_req *req);
135 static void nb_packet_server_listener(struct tevent_context *ev,
136 struct tevent_fd *fde,
137 uint16_t flags,
138 void *private_data)
140 struct nb_packet_server *server = talloc_get_type_abort(
141 private_data, struct nb_packet_server);
142 struct nb_packet_client *client;
143 struct tevent_req *req;
144 struct sockaddr_un sunaddr;
145 socklen_t len;
146 int sock;
147 int ret;
149 len = sizeof(sunaddr);
151 sock = accept(server->listen_sock, (struct sockaddr *)(void *)&sunaddr,
152 &len);
153 if (sock == -1) {
154 return;
156 smb_set_close_on_exec(sock);
157 DEBUG(6,("accepted socket %d\n", sock));
159 client = talloc_zero(server, struct nb_packet_client);
160 if (client == NULL) {
161 DEBUG(10, ("talloc failed\n"));
162 close(sock);
163 return;
165 ret = tstream_bsd_existing_socket(client, sock, &client->sock);
166 if (ret != 0) {
167 DEBUG(10, ("tstream_bsd_existing_socket failed\n"));
168 TALLOC_FREE(client);
169 close(sock);
170 return;
172 /* as server we want to fail early */
173 tstream_bsd_fail_readv_first_error(client->sock, true);
175 client->server = server;
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 talloc_set_destructor(client, nb_packet_client_destructor);
200 if (server->num_clients > server->max_clients) {
201 DEBUG(10, ("Too many clients, dropping oldest\n"));
204 * no TALLOC_FREE here, don't mess with the list structs
206 talloc_free(server->clients->prev);
210 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
211 void *private_data)
213 struct nb_packet_query q;
214 if (buflen > sizeof(struct nb_packet_query)) {
215 return 0;
217 /* Take care of alignment */
218 memcpy(&q, buf, sizeof(q));
219 if (q.mailslot_namelen > 1024) {
220 DEBUG(10, ("Got invalid mailslot namelen %d\n",
221 (int)q.mailslot_namelen));
222 return -1;
224 return q.mailslot_namelen;
227 static int nb_packet_client_destructor(struct nb_packet_client *c)
229 tevent_queue_stop(c->out_queue);
230 TALLOC_FREE(c->sock);
232 DLIST_REMOVE(c->server->clients, c);
233 c->server->num_clients -= 1;
234 return 0;
237 static void nb_packet_got_query(struct tevent_req *req)
239 struct nb_packet_client *client = tevent_req_callback_data(
240 req, struct nb_packet_client);
241 struct nb_packet_query q;
242 uint8_t *buf;
243 ssize_t nread;
244 int err;
246 nread = tstream_read_packet_recv(req, client, &buf, &err);
247 TALLOC_FREE(req);
248 if (nread < (ssize_t)sizeof(struct nb_packet_query)) {
249 DEBUG(10, ("read_packet_recv returned %d (%s)\n",
250 (int)nread,
251 (nread == -1) ? strerror(err) : "wrong length"));
252 TALLOC_FREE(client);
253 return;
256 /* Take care of alignment */
257 memcpy(&q, buf, sizeof(q));
259 if ((size_t)nread !=
260 sizeof(struct nb_packet_query) + q.mailslot_namelen) {
261 DEBUG(10, ("nb_packet_got_query: Invalid mailslot namelength\n"));
262 TALLOC_FREE(client);
263 return;
266 client->trn_id = q.trn_id;
267 client->type = q.type;
268 if (q.mailslot_namelen > 0) {
269 client->mailslot_name = talloc_strndup(
270 client, (char *)buf + sizeof(q),
271 q.mailslot_namelen);
272 if (client->mailslot_name == NULL) {
273 TALLOC_FREE(client);
274 return;
278 TALLOC_FREE(buf);
280 client->ack.byte = 0;
281 client->ack.iov[0].iov_base = &client->ack.byte;
282 client->ack.iov[0].iov_len = 1;
283 req = tstream_writev_queue_send(client, client->server->ev,
284 client->sock,
285 client->out_queue,
286 client->ack.iov, 1);
287 if (req == NULL) {
288 DEBUG(10, ("tstream_writev_queue_send failed\n"));
289 TALLOC_FREE(client);
290 return;
292 tevent_req_set_callback(req, nb_packet_client_ack_done, client);
294 req = tstream_read_packet_send(client, client->server->ev,
295 client->sock, 1, NULL, NULL);
296 if (req == NULL) {
297 DEBUG(10, ("Could not activate reader for client exit "
298 "detection\n"));
299 TALLOC_FREE(client);
300 return;
302 tevent_req_set_callback(req, nb_packet_client_read_done,
303 client);
306 static void nb_packet_client_ack_done(struct tevent_req *req)
308 struct nb_packet_client *client = tevent_req_callback_data(
309 req, struct nb_packet_client);
310 ssize_t nwritten;
311 int err;
313 nwritten = tstream_writev_queue_recv(req, &err);
315 TALLOC_FREE(req);
317 if (nwritten == -1) {
318 DEBUG(10, ("tstream_writev_queue_recv failed: %s\n",
319 strerror(err)));
320 TALLOC_FREE(client);
321 return;
325 static void nb_packet_client_read_done(struct tevent_req *req)
327 struct nb_packet_client *client = tevent_req_callback_data(
328 req, struct nb_packet_client);
329 ssize_t nread;
330 uint8_t *buf;
331 int err;
333 nread = tstream_read_packet_recv(req, client, &buf, &err);
334 TALLOC_FREE(req);
335 if (nread == 1) {
336 DEBUG(10, ("Protocol error, received data on write-only "
337 "unexpected socket: 0x%2.2x\n", (*buf)));
339 TALLOC_FREE(client);
342 static void nb_packet_client_send(struct nb_packet_client *client,
343 struct packet_struct *p);
345 void nb_packet_dispatch(struct nb_packet_server *server,
346 struct packet_struct *p)
348 struct nb_packet_client *c;
349 uint16_t trn_id;
351 switch (p->packet_type) {
352 case NMB_PACKET:
353 trn_id = p->packet.nmb.header.name_trn_id;
354 break;
355 case DGRAM_PACKET:
356 trn_id = p->packet.dgram.header.dgm_id;
357 break;
358 default:
359 DEBUG(10, ("Got invalid packet type %d\n",
360 (int)p->packet_type));
361 return;
363 for (c = server->clients; c != NULL; c = c->next) {
365 if (c->type != p->packet_type) {
366 DEBUG(10, ("client expects packet %d, got %d\n",
367 c->type, p->packet_type));
368 continue;
371 if (p->packet_type == NMB_PACKET) {
373 * See if the client specified transaction
374 * ID. Filter if it did.
376 if ((c->trn_id != -1) &&
377 (c->trn_id != trn_id)) {
378 DEBUG(10, ("client expects trn %d, got %d\n",
379 c->trn_id, trn_id));
380 continue;
382 } else {
384 * See if the client specified a mailslot
385 * name. Filter if it did.
387 if ((c->mailslot_name != NULL) &&
388 !match_mailslot_name(p, c->mailslot_name)) {
389 continue;
392 nb_packet_client_send(c, p);
396 struct nb_packet_client_header {
397 size_t len;
398 enum packet_type type;
399 time_t timestamp;
400 struct in_addr ip;
401 int port;
404 struct nb_packet_client_state {
405 struct nb_packet_client *client;
406 struct iovec iov[2];
407 struct nb_packet_client_header hdr;
408 char buf[1024];
411 static void nb_packet_client_send_done(struct tevent_req *req);
413 static void nb_packet_client_send(struct nb_packet_client *client,
414 struct packet_struct *p)
416 struct nb_packet_client_state *state;
417 struct tevent_req *req;
419 if (tevent_queue_length(client->out_queue) > 10) {
421 * Skip clients that don't listen anyway, some form of DoS
422 * protection
424 return;
427 state = talloc_zero(client, struct nb_packet_client_state);
428 if (state == NULL) {
429 DEBUG(10, ("talloc failed\n"));
430 return;
433 state->client = client;
435 state->hdr.ip = p->ip;
436 state->hdr.port = p->port;
437 state->hdr.timestamp = p->timestamp;
438 state->hdr.type = p->packet_type;
439 state->hdr.len = build_packet(state->buf, sizeof(state->buf), p);
441 state->iov[0].iov_base = (char *)&state->hdr;
442 state->iov[0].iov_len = sizeof(state->hdr);
443 state->iov[1].iov_base = state->buf;
444 state->iov[1].iov_len = state->hdr.len;
446 req = tstream_writev_queue_send(state, client->server->ev,
447 client->sock,
448 client->out_queue,
449 state->iov, 2);
450 if (req == NULL) {
451 DEBUG(10, ("tstream_writev_queue_send failed\n"));
452 return;
454 tevent_req_set_callback(req, nb_packet_client_send_done, state);
457 static void nb_packet_client_send_done(struct tevent_req *req)
459 struct nb_packet_client_state *state = tevent_req_callback_data(
460 req, struct nb_packet_client_state);
461 struct nb_packet_client *client = state->client;
462 ssize_t nwritten;
463 int err;
465 nwritten = tstream_writev_queue_recv(req, &err);
467 TALLOC_FREE(req);
468 TALLOC_FREE(state);
470 if (nwritten == -1) {
471 DEBUG(10, ("tstream_writev_queue failed: %s\n", strerror(err)));
472 TALLOC_FREE(client);
473 return;
477 struct nb_packet_reader {
478 struct tstream_context *sock;
481 struct nb_packet_reader_state {
482 struct tevent_context *ev;
483 struct nb_packet_query query;
484 const char *mailslot_name;
485 struct iovec iov[2];
486 struct nb_packet_reader *reader;
489 static void nb_packet_reader_connected(struct tevent_req *subreq);
490 static void nb_packet_reader_sent_query(struct tevent_req *subreq);
491 static void nb_packet_reader_got_ack(struct tevent_req *subreq);
493 struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx,
494 struct tevent_context *ev,
495 const char *nmbd_socket_dir,
496 enum packet_type type,
497 int trn_id,
498 const char *mailslot_name)
500 struct tevent_req *req, *subreq;
501 struct nb_packet_reader_state *state;
502 struct tsocket_address *laddr;
503 char *rpath;
504 struct tsocket_address *raddr;
505 int ret;
507 req = tevent_req_create(mem_ctx, &state,
508 struct nb_packet_reader_state);
509 if (req == NULL) {
510 return NULL;
512 state->ev = ev;
513 state->query.trn_id = trn_id;
514 state->query.type = type;
515 state->mailslot_name = mailslot_name;
517 if (mailslot_name != NULL) {
518 state->query.mailslot_namelen = strlen(mailslot_name);
521 state->reader = talloc_zero(state, struct nb_packet_reader);
522 if (tevent_req_nomem(state->reader, req)) {
523 return tevent_req_post(req, ev);
526 ret = tsocket_address_unix_from_path(state, NULL, &laddr);
527 if (ret != 0) {
528 tevent_req_nterror(req, map_nt_error_from_unix(errno));
529 return tevent_req_post(req, ev);
531 rpath = talloc_asprintf(state, "%s/%s", nmbd_socket_dir,
532 "unexpected");
533 if (tevent_req_nomem(rpath, req)) {
534 return tevent_req_post(req, ev);
536 ret = tsocket_address_unix_from_path(state, rpath, &raddr);
537 if (ret != 0) {
538 tevent_req_nterror(req, map_nt_error_from_unix(errno));
539 return tevent_req_post(req, ev);
542 subreq = tstream_unix_connect_send(state, ev, laddr, raddr);
543 if (tevent_req_nomem(subreq, req)) {
544 return tevent_req_post(req, ev);
546 tevent_req_set_callback(subreq, nb_packet_reader_connected, req);
547 return req;
550 static void nb_packet_reader_connected(struct tevent_req *subreq)
552 struct tevent_req *req = tevent_req_callback_data(
553 subreq, struct tevent_req);
554 struct nb_packet_reader_state *state = tevent_req_data(
555 req, struct nb_packet_reader_state);
556 int res, err;
557 int num_iovecs = 1;
559 res = tstream_unix_connect_recv(subreq, &err, state->reader,
560 &state->reader->sock);
561 TALLOC_FREE(subreq);
562 if (res == -1) {
563 DEBUG(10, ("tstream_unix_connect failed: %s\n", strerror(err)));
564 tevent_req_nterror(req, map_nt_error_from_unix(err));
565 return;
568 state->iov[0].iov_base = (char *)&state->query;
569 state->iov[0].iov_len = sizeof(state->query);
571 if (state->mailslot_name != NULL) {
572 num_iovecs = 2;
573 state->iov[1].iov_base = discard_const_p(
574 char, state->mailslot_name);
575 state->iov[1].iov_len = state->query.mailslot_namelen;
578 subreq = tstream_writev_send(state, state->ev, state->reader->sock,
579 state->iov, num_iovecs);
580 if (tevent_req_nomem(subreq, req)) {
581 return;
583 tevent_req_set_callback(subreq, nb_packet_reader_sent_query, req);
586 static void nb_packet_reader_sent_query(struct tevent_req *subreq)
588 struct tevent_req *req = tevent_req_callback_data(
589 subreq, struct tevent_req);
590 struct nb_packet_reader_state *state = tevent_req_data(
591 req, struct nb_packet_reader_state);
592 ssize_t written;
593 int err;
595 written = tstream_writev_recv(subreq, &err);
596 TALLOC_FREE(subreq);
597 if (written == -1) {
598 tevent_req_nterror(req, map_nt_error_from_unix(err));
599 return;
601 if ((size_t)written !=
602 sizeof(state->query) + state->query.mailslot_namelen) {
603 tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR);
604 return;
606 subreq = tstream_read_packet_send(state, state->ev,
607 state->reader->sock,
608 1, NULL, NULL);
609 if (tevent_req_nomem(subreq, req)) {
610 return;
612 tevent_req_set_callback(subreq, nb_packet_reader_got_ack, req);
615 static void nb_packet_reader_got_ack(struct tevent_req *subreq)
617 struct tevent_req *req = tevent_req_callback_data(
618 subreq, struct tevent_req);
619 struct nb_packet_reader_state *state = tevent_req_data(
620 req, struct nb_packet_reader_state);
621 ssize_t nread;
622 int err;
623 uint8_t *buf;
625 nread = tstream_read_packet_recv(subreq, state, &buf, &err);
626 TALLOC_FREE(subreq);
627 if (nread == -1) {
628 DEBUG(10, ("read_packet_recv returned %s\n",
629 strerror(err)));
630 tevent_req_nterror(req, map_nt_error_from_unix(err));
631 return;
633 if (nread != 1) {
634 DBG_DEBUG("read = %zd, expected 1\n", nread);
635 tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR);
636 return;
638 tevent_req_done(req);
641 NTSTATUS nb_packet_reader_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
642 struct nb_packet_reader **preader)
644 struct nb_packet_reader_state *state = tevent_req_data(
645 req, struct nb_packet_reader_state);
646 NTSTATUS status;
648 if (tevent_req_is_nterror(req, &status)) {
649 tevent_req_received(req);
650 return status;
652 *preader = talloc_move(mem_ctx, &state->reader);
653 tevent_req_received(req);
654 return NT_STATUS_OK;
657 struct nb_packet_read_state {
658 struct nb_packet_client_header hdr;
659 uint8_t *buf;
660 size_t buflen;
663 static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p);
664 static void nb_packet_read_done(struct tevent_req *subreq);
666 struct tevent_req *nb_packet_read_send(TALLOC_CTX *mem_ctx,
667 struct tevent_context *ev,
668 struct nb_packet_reader *reader)
670 struct tevent_req *req, *subreq;
671 struct nb_packet_read_state *state;
673 req = tevent_req_create(mem_ctx, &state, struct nb_packet_read_state);
674 if (req == NULL) {
675 return NULL;
677 subreq = tstream_read_packet_send(state, ev, reader->sock,
678 sizeof(struct nb_packet_client_header),
679 nb_packet_read_more, state);
680 if (tevent_req_nomem(subreq, req)) {
681 return tevent_req_post(req, ev);
683 tevent_req_set_callback(subreq, nb_packet_read_done, req);
684 return req;
687 static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p)
689 struct nb_packet_read_state *state = talloc_get_type_abort(
690 p, struct nb_packet_read_state);
692 if (buflen > sizeof(struct nb_packet_client_header)) {
694 * Been here, done
696 return 0;
698 memcpy(&state->hdr, buf, sizeof(struct nb_packet_client_header));
699 return state->hdr.len;
702 static void nb_packet_read_done(struct tevent_req *subreq)
704 struct tevent_req *req = tevent_req_callback_data(
705 subreq, struct tevent_req);
706 struct nb_packet_read_state *state = tevent_req_data(
707 req, struct nb_packet_read_state);
708 ssize_t nread;
709 int err;
711 nread = tstream_read_packet_recv(subreq, state, &state->buf, &err);
712 if (nread == -1) {
713 tevent_req_nterror(req, map_nt_error_from_unix(err));
714 return;
716 state->buflen = nread;
717 tevent_req_done(req);
720 NTSTATUS nb_packet_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
721 struct packet_struct **ppacket)
723 struct nb_packet_read_state *state = tevent_req_data(
724 req, struct nb_packet_read_state);
725 struct nb_packet_client_header hdr;
726 struct packet_struct *packet;
727 NTSTATUS status;
729 if (tevent_req_is_nterror(req, &status)) {
730 tevent_req_received(req);
731 return status;
734 memcpy(&hdr, state->buf, sizeof(hdr));
736 packet = parse_packet_talloc(
737 mem_ctx,
738 (char *)state->buf + sizeof(struct nb_packet_client_header),
739 state->buflen - sizeof(struct nb_packet_client_header),
740 state->hdr.type, state->hdr.ip, state->hdr.port);
741 if (packet == NULL) {
742 tevent_req_received(req);
743 return NT_STATUS_INVALID_NETWORK_RESPONSE;
746 *ppacket = packet;
747 tevent_req_received(req);
748 return NT_STATUS_OK;