21
21
#include "includes.h"
23
static TDB_CONTEXT *tdbd = NULL;
25
/* the key type used in the unexpected packet database */
26
struct unexpected_key {
27
enum packet_type packet_type;
22
#include "../lib/util/tevent_ntstatus.h"
23
#include "lib/async_req/async_sock.h"
24
#include "libsmb/nmblib.h"
26
static const char *nmbd_socket_dir(void)
28
return lp_parm_const_string(-1, "nmbd", "socket dir",
29
get_dyn_NMBDSOCKETDIR());
32
struct nb_packet_query {
33
enum packet_type type;
34
size_t mailslot_namelen;
38
struct nb_packet_client;
40
struct nb_packet_server {
41
struct tevent_context *ev;
45
struct nb_packet_client *clients;
48
struct nb_packet_client {
49
struct nb_packet_client *prev, *next;
50
struct nb_packet_server *server;
52
enum packet_type type;
57
struct tevent_req *read_req;
58
struct tevent_queue *out_queue;
61
static int nb_packet_server_destructor(struct nb_packet_server *s);
62
static void nb_packet_server_listener(struct tevent_context *ev,
63
struct tevent_fd *fde,
67
NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx,
68
struct tevent_context *ev,
70
struct nb_packet_server **presult)
72
struct nb_packet_server *result;
73
struct tevent_fd *fde;
76
result = TALLOC_ZERO_P(mem_ctx, struct nb_packet_server);
78
status = NT_STATUS_NO_MEMORY;
82
result->max_clients = max_clients;
84
result->listen_sock = create_pipe_sock(
85
nmbd_socket_dir(), "unexpected", 0755);
86
if (result->listen_sock == -1) {
87
status = map_nt_error_from_unix(errno);
90
talloc_set_destructor(result, nb_packet_server_destructor);
92
fde = tevent_add_fd(ev, result, result->listen_sock, TEVENT_FD_READ,
93
nb_packet_server_listener, result);
95
status = NT_STATUS_NO_MEMORY;
106
static int nb_packet_server_destructor(struct nb_packet_server *s)
108
if (s->listen_sock != -1) {
109
close(s->listen_sock);
115
static int nb_packet_client_destructor(struct nb_packet_client *c);
116
static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
118
static void nb_packet_got_query(struct tevent_req *req);
119
static void nb_packet_client_read_done(struct tevent_req *req);
121
static void nb_packet_server_listener(struct tevent_context *ev,
122
struct tevent_fd *fde,
126
struct nb_packet_server *server = talloc_get_type_abort(
127
private_data, struct nb_packet_server);
128
struct nb_packet_client *client;
129
struct tevent_req *req;
130
struct sockaddr_un sunaddr;
134
len = sizeof(sunaddr);
136
sock = accept(server->listen_sock, (struct sockaddr *)(void *)&sunaddr,
141
DEBUG(6,("accepted socket %d\n", sock));
143
client = TALLOC_ZERO_P(server, struct nb_packet_client);
144
if (client == NULL) {
145
DEBUG(10, ("talloc failed\n"));
150
client->server = server;
151
talloc_set_destructor(client, nb_packet_client_destructor);
153
client->out_queue = tevent_queue_create(
154
client, "unexpected packet output");
155
if (client->out_queue == NULL) {
156
DEBUG(10, ("tevent_queue_create failed\n"));
161
req = read_packet_send(client, ev, client->sock,
162
sizeof(struct nb_packet_query),
163
nb_packet_client_more, NULL);
165
DEBUG(10, ("read_packet_send failed\n"));
169
tevent_req_set_callback(req, nb_packet_got_query, client);
171
DLIST_ADD(server->clients, client);
172
server->num_clients += 1;
174
if (server->num_clients > server->max_clients) {
175
DEBUG(10, ("Too many clients, dropping oldest\n"));
178
* no TALLOC_FREE here, don't mess with the list structs
180
talloc_free(server->clients->prev);
184
static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
187
struct nb_packet_query q;
188
if (buflen > sizeof(struct nb_packet_query)) {
191
/* Take care of alignment */
192
memcpy(&q, buf, sizeof(q));
193
if (q.mailslot_namelen > 1024) {
194
DEBUG(10, ("Got invalid mailslot namelen %d\n",
195
(int)q.mailslot_namelen));
198
return q.mailslot_namelen;
201
static int nb_packet_client_destructor(struct nb_packet_client *c)
207
DLIST_REMOVE(c->server->clients, c);
208
c->server->num_clients -= 1;
212
static void nb_packet_got_query(struct tevent_req *req)
214
struct nb_packet_client *client = tevent_req_callback_data(
215
req, struct nb_packet_client);
216
struct nb_packet_query q;
218
ssize_t nread, nwritten;
222
nread = read_packet_recv(req, talloc_tos(), &buf, &err);
224
if (nread < (ssize_t)sizeof(struct nb_packet_query)) {
225
DEBUG(10, ("read_packet_recv returned %d (%s)\n",
227
(nread == -1) ? strerror(err) : "wrong length"));
232
/* Take care of alignment */
233
memcpy(&q, buf, sizeof(q));
235
if (nread != sizeof(struct nb_packet_query) + q.mailslot_namelen) {
236
DEBUG(10, ("nb_packet_got_query: Invalid mailslot namelength\n"));
241
client->trn_id = q.trn_id;
242
client->type = q.type;
243
if (q.mailslot_namelen > 0) {
244
client->mailslot_name = talloc_strndup(
245
client, (char *)buf + sizeof(q),
247
if (client->mailslot_name == NULL) {
254
* Yes, this is a blocking write of 1 byte into a unix
255
* domain socket that has never been written to. Highly
256
* unlikely that this actually blocks.
259
nwritten = sys_write(client->sock, &c, sizeof(c));
260
if (nwritten != sizeof(c)) {
261
DEBUG(10, ("Could not write success indicator to client: %s\n",
267
client->read_req = read_packet_send(client, client->server->ev,
268
client->sock, 1, NULL, NULL);
269
if (client->read_req == NULL) {
270
DEBUG(10, ("Could not activate reader for client exit "
275
tevent_req_set_callback(client->read_req, nb_packet_client_read_done,
279
static void nb_packet_client_read_done(struct tevent_req *req)
281
struct nb_packet_client *client = tevent_req_callback_data(
282
req, struct nb_packet_client);
287
nread = read_packet_recv(req, talloc_tos(), &buf, &err);
290
DEBUG(10, ("Protocol error, received data on write-only "
291
"unexpected socket: 0x%2.2x\n", (*buf)));
296
static void nb_packet_client_send(struct nb_packet_client *client,
297
struct packet_struct *p);
299
void nb_packet_dispatch(struct nb_packet_server *server,
300
struct packet_struct *p)
302
struct nb_packet_client *c;
305
switch (p->packet_type) {
307
trn_id = p->packet.nmb.header.name_trn_id;
310
trn_id = p->packet.dgram.header.dgm_id;
313
DEBUG(10, ("Got invalid packet type %d\n",
314
(int)p->packet_type));
317
for (c = server->clients; c != NULL; c = c->next) {
319
if (c->type != p->packet_type) {
320
DEBUG(10, ("client expects packet %d, got %d\n",
321
c->type, p->packet_type));
325
if (p->packet_type == NMB_PACKET) {
327
* See if the client specified transaction
328
* ID. Filter if it did.
330
if ((c->trn_id != -1) &&
331
(c->trn_id != trn_id)) {
332
DEBUG(10, ("client expects trn %d, got %d\n",
338
* See if the client specified a mailslot
339
* name. Filter if it did.
341
if ((c->mailslot_name != NULL) &&
342
!match_mailslot_name(p, c->mailslot_name)) {
346
nb_packet_client_send(c, p);
350
struct nb_packet_client_header {
352
enum packet_type type;
32
/****************************************************************************
33
All unexpected packets are passed in here, to be stored in a unexpected
34
packet database. This allows nmblookup and other tools to receive packets
35
erroneously sent to the wrong port by broken MS systems.
36
**************************************************************************/
38
void unexpected_packet(struct packet_struct *p)
42
struct unexpected_key key;
48
tdbd = tdb_open_log(lock_path("unexpected.tdb"), 0,
49
TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
50
O_RDWR | O_CREAT, 0644);
52
DEBUG(0,("Failed to open unexpected.tdb\n"));
57
memset(buf,'\0',sizeof(buf));
59
/* Encode the ip addr and port. */
60
enc_ip = ntohl(p->ip.s_addr);
64
len = build_packet(&buf[6], sizeof(buf)-6, p) + 6;
66
ZERO_STRUCT(key); /* needed for potential alignment */
68
key.packet_type = p->packet_type;
69
key.timestamp = p->timestamp;
72
kbuf.dptr = (uint8_t *)&key;
73
kbuf.dsize = sizeof(key);
74
dbuf.dptr = (uint8_t *)buf;
77
tdb_store(tdbd, kbuf, dbuf, TDB_REPLACE);
83
/****************************************************************************
84
Delete the record if it is too old.
85
**************************************************************************/
87
static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
89
struct unexpected_key key;
91
if (kbuf.dsize != sizeof(key)) {
92
tdb_delete(ttdb, kbuf);
95
memcpy(&key, kbuf.dptr, sizeof(key));
97
if (lastt - key.timestamp > NMBD_UNEXPECTED_TIMEOUT) {
98
tdb_delete(ttdb, kbuf);
105
/****************************************************************************
106
Delete all old unexpected packets.
107
**************************************************************************/
109
void clear_unexpected(time_t t)
113
if ((lastt != 0) && (t < lastt + NMBD_UNEXPECTED_TIMEOUT))
118
tdb_traverse(tdbd, traverse_fn, NULL);
121
struct receive_unexpected_state {
122
struct packet_struct *matched_packet;
124
enum packet_type match_type;
125
const char *match_name;
128
/****************************************************************************
129
tdb traversal fn to find a matching 137 packet.
130
**************************************************************************/
132
static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf,
135
struct receive_unexpected_state *state =
136
(struct receive_unexpected_state *)private_data;
137
struct unexpected_key key;
138
354
struct in_addr ip;
141
struct packet_struct *p;
143
if (kbuf.dsize != sizeof(key)) {
147
memcpy(&key, kbuf.dptr, sizeof(key));
149
if (key.packet_type != state->match_type) return 0;
151
if (dbuf.dsize < 6) {
155
/* Decode the ip addr and port. */
156
enc_ip = IVAL(dbuf.dptr,0);
157
ip.s_addr = htonl(enc_ip);
158
port = SVAL(dbuf.dptr,4);
160
p = parse_packet((char *)&dbuf.dptr[6],
168
if ((state->match_type == NMB_PACKET &&
169
p->packet.nmb.header.name_trn_id == state->match_id) ||
170
(state->match_type == DGRAM_PACKET &&
171
match_mailslot_name(p, state->match_name))) {
172
state->matched_packet = p;
181
/****************************************************************************
182
Check for a particular packet in the unexpected packet queue.
183
**************************************************************************/
185
struct packet_struct *receive_unexpected(enum packet_type packet_type, int id,
358
struct nb_packet_client_state {
359
struct nb_packet_client *client;
361
struct nb_packet_client_header hdr;
365
static void nb_packet_client_send_done(struct tevent_req *req);
367
static void nb_packet_client_send(struct nb_packet_client *client,
368
struct packet_struct *p)
370
struct nb_packet_client_state *state;
371
struct tevent_req *req;
373
if (tevent_queue_length(client->out_queue) > 10) {
375
* Skip clients that don't listen anyway, some form of DoS
381
state = TALLOC_ZERO_P(client, struct nb_packet_client_state);
383
DEBUG(10, ("talloc failed\n"));
387
state->client = client;
389
state->hdr.ip = p->ip;
390
state->hdr.port = p->port;
391
state->hdr.timestamp = p->timestamp;
392
state->hdr.type = p->packet_type;
393
state->hdr.len = build_packet(state->buf, sizeof(state->buf), p);
395
state->iov[0].iov_base = (char *)&state->hdr;
396
state->iov[0].iov_len = sizeof(state->hdr);
397
state->iov[1].iov_base = state->buf;
398
state->iov[1].iov_len = state->hdr.len;
400
TALLOC_FREE(client->read_req);
402
req = writev_send(client, client->server->ev, client->out_queue,
403
client->sock, true, state->iov, 2);
405
DEBUG(10, ("writev_send failed\n"));
408
tevent_req_set_callback(req, nb_packet_client_send_done, state);
411
static void nb_packet_client_send_done(struct tevent_req *req)
413
struct nb_packet_client_state *state = tevent_req_callback_data(
414
req, struct nb_packet_client_state);
415
struct nb_packet_client *client = state->client;
419
nwritten = writev_recv(req, &err);
424
if (nwritten == -1) {
425
DEBUG(10, ("writev failed: %s\n", strerror(err)));
429
if (tevent_queue_length(client->out_queue) == 0) {
430
client->read_req = read_packet_send(client, client->server->ev,
433
if (client->read_req == NULL) {
434
DEBUG(10, ("Could not activate reader for client exit "
439
tevent_req_set_callback(client->read_req,
440
nb_packet_client_read_done,
445
struct nb_packet_reader {
449
struct nb_packet_reader_state {
450
struct tevent_context *ev;
451
struct sockaddr_un addr;
452
struct nb_packet_query query;
453
const char *mailslot_name;
456
struct nb_packet_reader *reader;
459
static int nb_packet_reader_destructor(struct nb_packet_reader *r);
460
static void nb_packet_reader_connected(struct tevent_req *subreq);
461
static void nb_packet_reader_sent_query(struct tevent_req *subreq);
462
static void nb_packet_reader_got_ack(struct tevent_req *subreq);
464
struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx,
465
struct tevent_context *ev,
466
enum packet_type type,
186
468
const char *mailslot_name)
189
struct receive_unexpected_state state;
191
tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0);
192
if (!tdb2) return NULL;
194
state.matched_packet = NULL;
196
state.match_type = packet_type;
197
state.match_name = mailslot_name;
199
tdb_traverse(tdb2, traverse_match, &state);
203
return state.matched_packet;
470
struct tevent_req *req, *subreq;
471
struct nb_packet_reader_state *state;
474
req = tevent_req_create(mem_ctx, &state,
475
struct nb_packet_reader_state);
480
state->query.trn_id = trn_id;
481
state->query.type = type;
482
state->mailslot_name = mailslot_name;
484
if (mailslot_name != NULL) {
485
state->query.mailslot_namelen = strlen(mailslot_name);
488
state->reader = TALLOC_ZERO_P(state, struct nb_packet_reader);
489
if (tevent_req_nomem(state->reader, req)) {
490
return tevent_req_post(req, ev);
493
path = talloc_asprintf(talloc_tos(), "%s/%s", nmbd_socket_dir(),
495
if (tevent_req_nomem(path, req)) {
496
return tevent_req_post(req, ev);
498
state->addr.sun_family = AF_UNIX;
499
strlcpy(state->addr.sun_path, path, sizeof(state->addr.sun_path));
502
state->reader->sock = socket(AF_UNIX, SOCK_STREAM, 0);
503
if (state->reader->sock == -1) {
504
tevent_req_nterror(req, map_nt_error_from_unix(errno));
505
return tevent_req_post(req, ev);
507
talloc_set_destructor(state->reader, nb_packet_reader_destructor);
509
subreq = async_connect_send(state, ev, state->reader->sock,
510
(struct sockaddr *)(void *)&state->addr,
511
sizeof(state->addr));
512
if (tevent_req_nomem(subreq, req)) {
513
return tevent_req_post(req, ev);
515
tevent_req_set_callback(subreq, nb_packet_reader_connected, req);
519
static int nb_packet_reader_destructor(struct nb_packet_reader *r)
528
static void nb_packet_reader_connected(struct tevent_req *subreq)
530
struct tevent_req *req = tevent_req_callback_data(
531
subreq, struct tevent_req);
532
struct nb_packet_reader_state *state = tevent_req_data(
533
req, struct nb_packet_reader_state);
537
res = async_connect_recv(subreq, &err);
540
DEBUG(10, ("async_connect failed: %s\n", strerror(err)));
541
tevent_req_nterror(req, map_nt_error_from_unix(err));
545
state->iov[0].iov_base = (char *)&state->query;
546
state->iov[0].iov_len = sizeof(state->query);
548
if (state->mailslot_name != NULL) {
550
state->iov[1].iov_base = discard_const_p(
551
char, state->mailslot_name);
552
state->iov[1].iov_len = state->query.mailslot_namelen;
555
subreq = writev_send(state, state->ev, NULL, state->reader->sock,
556
true, state->iov, num_iovecs);
557
if (tevent_req_nomem(subreq, req)) {
560
tevent_req_set_callback(subreq, nb_packet_reader_sent_query, req);
563
static void nb_packet_reader_sent_query(struct tevent_req *subreq)
565
struct tevent_req *req = tevent_req_callback_data(
566
subreq, struct tevent_req);
567
struct nb_packet_reader_state *state = tevent_req_data(
568
req, struct nb_packet_reader_state);
572
written = writev_recv(subreq, &err);
575
tevent_req_nterror(req, map_nt_error_from_unix(err));
578
if (written != sizeof(state->query) + state->query.mailslot_namelen) {
579
tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR);
582
subreq = read_packet_send(state, state->ev, state->reader->sock,
583
sizeof(state->c), NULL, NULL);
584
if (tevent_req_nomem(subreq, req)) {
587
tevent_req_set_callback(subreq, nb_packet_reader_got_ack, req);
590
static void nb_packet_reader_got_ack(struct tevent_req *subreq)
592
struct tevent_req *req = tevent_req_callback_data(
593
subreq, struct tevent_req);
594
struct nb_packet_reader_state *state = tevent_req_data(
595
req, struct nb_packet_reader_state);
600
nread = read_packet_recv(subreq, state, &buf, &err);
603
DEBUG(10, ("read_packet_recv returned %s\n",
605
tevent_req_nterror(req, map_nt_error_from_unix(err));
608
if (nread != sizeof(state->c)) {
609
DEBUG(10, ("read = %d, expected %d\n", (int)nread,
610
(int)sizeof(state->c)));
611
tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR);
614
tevent_req_done(req);
617
NTSTATUS nb_packet_reader_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
618
struct nb_packet_reader **preader)
620
struct nb_packet_reader_state *state = tevent_req_data(
621
req, struct nb_packet_reader_state);
624
if (tevent_req_is_nterror(req, &status)) {
627
*preader = talloc_move(mem_ctx, &state->reader);
631
struct nb_packet_read_state {
632
struct nb_packet_client_header hdr;
637
static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p);
638
static void nb_packet_read_done(struct tevent_req *subreq);
640
struct tevent_req *nb_packet_read_send(TALLOC_CTX *mem_ctx,
641
struct tevent_context *ev,
642
struct nb_packet_reader *reader)
644
struct tevent_req *req, *subreq;
645
struct nb_packet_read_state *state;
647
req = tevent_req_create(mem_ctx, &state, struct nb_packet_read_state);
651
subreq = read_packet_send(state, ev, reader->sock,
652
sizeof(struct nb_packet_client_header),
653
nb_packet_read_more, state);
654
if (tevent_req_nomem(subreq, req)) {
655
return tevent_req_post(req, ev);
657
tevent_req_set_callback(subreq, nb_packet_read_done, req);
661
static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p)
663
struct nb_packet_read_state *state = talloc_get_type_abort(
664
p, struct nb_packet_read_state);
666
if (buflen > sizeof(struct nb_packet_client_header)) {
672
memcpy(&state->hdr, buf, sizeof(struct nb_packet_client_header));
673
return state->hdr.len;
676
static void nb_packet_read_done(struct tevent_req *subreq)
678
struct tevent_req *req = tevent_req_callback_data(
679
subreq, struct tevent_req);
680
struct nb_packet_read_state *state = tevent_req_data(
681
req, struct nb_packet_read_state);
685
nread = read_packet_recv(subreq, state, &state->buf, &err);
687
tevent_req_nterror(req, map_nt_error_from_unix(err));
690
state->buflen = nread;
691
tevent_req_done(req);
694
NTSTATUS nb_packet_read_recv(struct tevent_req *req,
695
struct packet_struct **ppacket)
697
struct nb_packet_read_state *state = tevent_req_data(
698
req, struct nb_packet_read_state);
699
struct nb_packet_client_header hdr;
700
struct packet_struct *packet;
703
if (tevent_req_is_nterror(req, &status)) {
707
memcpy(&hdr, state->buf, sizeof(hdr));
709
packet = parse_packet(
710
(char *)state->buf + sizeof(struct nb_packet_client_header),
711
state->buflen - sizeof(struct nb_packet_client_header),
712
state->hdr.type, state->hdr.ip, state->hdr.port);
713
if (packet == NULL) {
714
return NT_STATUS_INVALID_NETWORK_RESPONSE;