source: vendor/3.6.0/source3/smbd/process.c

Last change on this file was 740, checked in by Silvan Scherrer, 13 years ago

Samba Server: update vendor to 3.6.0

File size: 86.8 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include "includes.h"
22#include "../lib/tsocket/tsocket.h"
23#include "system/filesys.h"
24#include "smbd/smbd.h"
25#include "smbd/globals.h"
26#include "librpc/gen_ndr/netlogon.h"
27#include "../lib/async_req/async_sock.h"
28#include "ctdbd_conn.h"
29#include "../lib/util/select.h"
30#include "printing/pcap.h"
31#include "system/select.h"
32#include "passdb.h"
33#include "auth.h"
34#include "messages.h"
35#include "smbprofile.h"
36#include "rpc_server/spoolss/srv_spoolss_nt.h"
37#include "libsmb/libsmb.h"
38
39extern bool global_machine_password_needs_changing;
40
41static void construct_reply_common(struct smb_request *req, const char *inbuf,
42 char *outbuf);
43static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
44
45static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
46{
47 bool ok;
48
49 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
50 return true;
51 }
52
53 sconn->smb1.echo_handler.ref_count++;
54
55 if (sconn->smb1.echo_handler.ref_count > 1) {
56 return true;
57 }
58
59 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
60
61 do {
62 ok = fcntl_lock(
63 sconn->smb1.echo_handler.socket_lock_fd,
64 SMB_F_SETLKW, 0, 0, F_WRLCK);
65 } while (!ok && (errno == EINTR));
66
67 if (!ok) {
68 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
69 return false;
70 }
71
72 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
73
74 return true;
75}
76
77void smbd_lock_socket(struct smbd_server_connection *sconn)
78{
79 if (!smbd_lock_socket_internal(sconn)) {
80 exit_server_cleanly("failed to lock socket");
81 }
82}
83
84static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
85{
86 bool ok;
87
88 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
89 return true;
90 }
91
92 sconn->smb1.echo_handler.ref_count--;
93
94 if (sconn->smb1.echo_handler.ref_count > 0) {
95 return true;
96 }
97
98 do {
99 ok = fcntl_lock(
100 sconn->smb1.echo_handler.socket_lock_fd,
101 SMB_F_SETLKW, 0, 0, F_UNLCK);
102 } while (!ok && (errno == EINTR));
103
104 if (!ok) {
105 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
106 return false;
107 }
108
109 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
110
111 return true;
112}
113
114void smbd_unlock_socket(struct smbd_server_connection *sconn)
115{
116 if (!smbd_unlock_socket_internal(sconn)) {
117 exit_server_cleanly("failed to unlock socket");
118 }
119}
120
121/* Accessor function for smb_read_error for smbd functions. */
122
123/****************************************************************************
124 Send an smb to a fd.
125****************************************************************************/
126
127bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
128 bool do_signing, uint32_t seqnum,
129 bool do_encrypt,
130 struct smb_perfcount_data *pcd)
131{
132 size_t len = 0;
133 size_t nwritten=0;
134 ssize_t ret;
135 char *buf_out = buffer;
136
137 smbd_lock_socket(sconn);
138
139 if (do_signing) {
140 /* Sign the outgoing packet if required. */
141 srv_calculate_sign_mac(sconn, buf_out, seqnum);
142 }
143
144 if (do_encrypt) {
145 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
146 if (!NT_STATUS_IS_OK(status)) {
147 DEBUG(0, ("send_smb: SMB encryption failed "
148 "on outgoing packet! Error %s\n",
149 nt_errstr(status) ));
150 goto out;
151 }
152 }
153
154 len = smb_len(buf_out) + 4;
155
156 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
157 if (ret <= 0) {
158
159 char addr[INET6_ADDRSTRLEN];
160 /*
161 * Try and give an error message saying what
162 * client failed.
163 */
164 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
165 (int)sys_getpid(), (int)len,
166 get_peer_addr(sconn->sock, addr, sizeof(addr)),
167 (int)ret, strerror(errno) ));
168
169 srv_free_enc_buffer(buf_out);
170 goto out;
171 }
172
173 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
174 srv_free_enc_buffer(buf_out);
175out:
176 SMB_PERFCOUNT_END(pcd);
177
178 smbd_unlock_socket(sconn);
179 return true;
180}
181
182/*******************************************************************
183 Setup the word count and byte count for a smb message.
184********************************************************************/
185
186int srv_set_message(char *buf,
187 int num_words,
188 int num_bytes,
189 bool zero)
190{
191 if (zero && (num_words || num_bytes)) {
192 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
193 }
194 SCVAL(buf,smb_wct,num_words);
195 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
196 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
197 return (smb_size + num_words*2 + num_bytes);
198}
199
200static bool valid_smb_header(const uint8_t *inbuf)
201{
202 if (is_encrypted_packet(inbuf)) {
203 return true;
204 }
205 /*
206 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
207 * but it just looks weird to call strncmp for this one.
208 */
209 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
210}
211
212/* Socket functions for smbd packet processing. */
213
214static bool valid_packet_size(size_t len)
215{
216 /*
217 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
218 * of header. Don't print the error if this fits.... JRA.
219 */
220
221 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
222 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
223 (unsigned long)len));
224 return false;
225 }
226 return true;
227}
228
229static NTSTATUS read_packet_remainder(int fd, char *buffer,
230 unsigned int timeout, ssize_t len)
231{
232 NTSTATUS status;
233
234 if (len <= 0) {
235 return NT_STATUS_OK;
236 }
237
238 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
239 if (!NT_STATUS_IS_OK(status)) {
240 char addr[INET6_ADDRSTRLEN];
241 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
242 "error = %s.\n",
243 get_peer_addr(fd, addr, sizeof(addr)),
244 nt_errstr(status)));
245 }
246 return status;
247}
248
249/****************************************************************************
250 Attempt a zerocopy writeX read. We know here that len > smb_size-4
251****************************************************************************/
252
253/*
254 * Unfortunately, earlier versions of smbclient/libsmbclient
255 * don't send this "standard" writeX header. I've fixed this
256 * for 3.2 but we'll use the old method with earlier versions.
257 * Windows and CIFSFS at least use this standard size. Not
258 * sure about MacOSX.
259 */
260
261#define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
262 (2*14) + /* word count (including bcc) */ \
263 1 /* pad byte */)
264
265static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
266 const char lenbuf[4],
267 struct smbd_server_connection *sconn,
268 int sock,
269 char **buffer,
270 unsigned int timeout,
271 size_t *p_unread,
272 size_t *len_ret)
273{
274 /* Size of a WRITEX call (+4 byte len). */
275 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
276 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
277 ssize_t toread;
278 NTSTATUS status;
279
280 memcpy(writeX_header, lenbuf, 4);
281
282 status = read_fd_with_timeout(
283 sock, writeX_header + 4,
284 STANDARD_WRITE_AND_X_HEADER_SIZE,
285 STANDARD_WRITE_AND_X_HEADER_SIZE,
286 timeout, NULL);
287
288 if (!NT_STATUS_IS_OK(status)) {
289 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
290 "error = %s.\n", sconn->client_id.addr,
291 nt_errstr(status)));
292 return status;
293 }
294
295 /*
296 * Ok - now try and see if this is a possible
297 * valid writeX call.
298 */
299
300 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
301 /*
302 * If the data offset is beyond what
303 * we've read, drain the extra bytes.
304 */
305 uint16_t doff = SVAL(writeX_header,smb_vwv11);
306 ssize_t newlen;
307
308 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
309 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
310 if (drain_socket(sock, drain) != drain) {
311 smb_panic("receive_smb_raw_talloc_partial_read:"
312 " failed to drain pending bytes");
313 }
314 } else {
315 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
316 }
317
318 /* Spoof down the length and null out the bcc. */
319 set_message_bcc(writeX_header, 0);
320 newlen = smb_len(writeX_header);
321
322 /* Copy the header we've written. */
323
324 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
325 writeX_header,
326 sizeof(writeX_header));
327
328 if (*buffer == NULL) {
329 DEBUG(0, ("Could not allocate inbuf of length %d\n",
330 (int)sizeof(writeX_header)));
331 return NT_STATUS_NO_MEMORY;
332 }
333
334 /* Work out the remaining bytes. */
335 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
336 *len_ret = newlen + 4;
337 return NT_STATUS_OK;
338 }
339
340 if (!valid_packet_size(len)) {
341 return NT_STATUS_INVALID_PARAMETER;
342 }
343
344 /*
345 * Not a valid writeX call. Just do the standard
346 * talloc and return.
347 */
348
349 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
350
351 if (*buffer == NULL) {
352 DEBUG(0, ("Could not allocate inbuf of length %d\n",
353 (int)len+4));
354 return NT_STATUS_NO_MEMORY;
355 }
356
357 /* Copy in what we already read. */
358 memcpy(*buffer,
359 writeX_header,
360 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
361 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
362
363 if(toread > 0) {
364 status = read_packet_remainder(
365 sock,
366 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
367 timeout, toread);
368
369 if (!NT_STATUS_IS_OK(status)) {
370 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
371 nt_errstr(status)));
372 return status;
373 }
374 }
375
376 *len_ret = len + 4;
377 return NT_STATUS_OK;
378}
379
380static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
381 struct smbd_server_connection *sconn,
382 int sock,
383 char **buffer, unsigned int timeout,
384 size_t *p_unread, size_t *plen)
385{
386 char lenbuf[4];
387 size_t len;
388 int min_recv_size = lp_min_receive_file_size();
389 NTSTATUS status;
390
391 *p_unread = 0;
392
393 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
394 &len);
395 if (!NT_STATUS_IS_OK(status)) {
396 return status;
397 }
398
399 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
400 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
401 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
402 !srv_is_signing_active(sconn) &&
403 sconn->smb1.echo_handler.trusted_fde == NULL) {
404
405 return receive_smb_raw_talloc_partial_read(
406 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
407 p_unread, plen);
408 }
409
410 if (!valid_packet_size(len)) {
411 return NT_STATUS_INVALID_PARAMETER;
412 }
413
414 /*
415 * The +4 here can't wrap, we've checked the length above already.
416 */
417
418 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
419
420 if (*buffer == NULL) {
421 DEBUG(0, ("Could not allocate inbuf of length %d\n",
422 (int)len+4));
423 return NT_STATUS_NO_MEMORY;
424 }
425
426 memcpy(*buffer, lenbuf, sizeof(lenbuf));
427
428 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
429 if (!NT_STATUS_IS_OK(status)) {
430 return status;
431 }
432
433 *plen = len + 4;
434 return NT_STATUS_OK;
435}
436
437static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
438 struct smbd_server_connection *sconn,
439 int sock,
440 char **buffer, unsigned int timeout,
441 size_t *p_unread, bool *p_encrypted,
442 size_t *p_len,
443 uint32_t *seqnum,
444 bool trusted_channel)
445{
446 size_t len = 0;
447 NTSTATUS status;
448
449 *p_encrypted = false;
450
451 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
452 p_unread, &len);
453 if (!NT_STATUS_IS_OK(status)) {
454 DEBUG(1, ("read_smb_length_return_keepalive failed for "
455 "client %s read error = %s.\n",
456 sconn->client_id.addr, nt_errstr(status)));
457 return status;
458 }
459
460 if (is_encrypted_packet((uint8_t *)*buffer)) {
461 status = srv_decrypt_buffer(*buffer);
462 if (!NT_STATUS_IS_OK(status)) {
463 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
464 "incoming packet! Error %s\n",
465 nt_errstr(status) ));
466 return status;
467 }
468 *p_encrypted = true;
469 }
470
471 /* Check the incoming SMB signature. */
472 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
473 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
474 "incoming packet!\n"));
475 return NT_STATUS_INVALID_NETWORK_RESPONSE;
476 }
477
478 *p_len = len;
479 return NT_STATUS_OK;
480}
481
482/*
483 * Initialize a struct smb_request from an inbuf
484 */
485
486static bool init_smb_request(struct smb_request *req,
487 struct smbd_server_connection *sconn,
488 const uint8 *inbuf,
489 size_t unread_bytes, bool encrypted,
490 uint32_t seqnum)
491{
492 size_t req_size = smb_len(inbuf) + 4;
493 /* Ensure we have at least smb_size bytes. */
494 if (req_size < smb_size) {
495 DEBUG(0,("init_smb_request: invalid request size %u\n",
496 (unsigned int)req_size ));
497 return false;
498 }
499 req->cmd = CVAL(inbuf, smb_com);
500 req->flags2 = SVAL(inbuf, smb_flg2);
501 req->smbpid = SVAL(inbuf, smb_pid);
502 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
503 req->seqnum = seqnum;
504 req->vuid = SVAL(inbuf, smb_uid);
505 req->tid = SVAL(inbuf, smb_tid);
506 req->wct = CVAL(inbuf, smb_wct);
507 req->vwv = (uint16_t *)(inbuf+smb_vwv);
508 req->buflen = smb_buflen(inbuf);
509 req->buf = (const uint8_t *)smb_buf(inbuf);
510 req->unread_bytes = unread_bytes;
511 req->encrypted = encrypted;
512 req->sconn = sconn;
513 req->conn = conn_find(sconn,req->tid);
514 req->chain_fsp = NULL;
515 req->chain_outbuf = NULL;
516 req->done = false;
517 req->smb2req = NULL;
518 smb_init_perfcount_data(&req->pcd);
519
520 /* Ensure we have at least wct words and 2 bytes of bcc. */
521 if (smb_size + req->wct*2 > req_size) {
522 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
523 (unsigned int)req->wct,
524 (unsigned int)req_size));
525 return false;
526 }
527 /* Ensure bcc is correct. */
528 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
529 DEBUG(0,("init_smb_request: invalid bcc number %u "
530 "(wct = %u, size %u)\n",
531 (unsigned int)req->buflen,
532 (unsigned int)req->wct,
533 (unsigned int)req_size));
534 return false;
535 }
536
537 req->outbuf = NULL;
538 return true;
539}
540
541static void process_smb(struct smbd_server_connection *conn,
542 uint8_t *inbuf, size_t nread, size_t unread_bytes,
543 uint32_t seqnum, bool encrypted,
544 struct smb_perfcount_data *deferred_pcd);
545
546static void smbd_deferred_open_timer(struct event_context *ev,
547 struct timed_event *te,
548 struct timeval _tval,
549 void *private_data)
550{
551 struct pending_message_list *msg = talloc_get_type(private_data,
552 struct pending_message_list);
553 TALLOC_CTX *mem_ctx = talloc_tos();
554 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
555 uint8_t *inbuf;
556
557 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
558 msg->buf.length);
559 if (inbuf == NULL) {
560 exit_server("smbd_deferred_open_timer: talloc failed\n");
561 return;
562 }
563
564 /* We leave this message on the queue so the open code can
565 know this is a retry. */
566 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
567 (unsigned long long)mid ));
568
569 /* Mark the message as processed so this is not
570 * re-processed in error. */
571 msg->processed = true;
572
573 process_smb(smbd_server_conn, inbuf,
574 msg->buf.length, 0,
575 msg->seqnum, msg->encrypted, &msg->pcd);
576
577 /* If it's still there and was processed, remove it. */
578 msg = get_deferred_open_message_smb(mid);
579 if (msg && msg->processed) {
580 remove_deferred_open_message_smb(mid);
581 }
582}
583
584/****************************************************************************
585 Function to push a message onto the tail of a linked list of smb messages ready
586 for processing.
587****************************************************************************/
588
589static bool push_queued_message(struct smb_request *req,
590 struct timeval request_time,
591 struct timeval end_time,
592 char *private_data, size_t private_len)
593{
594 int msg_len = smb_len(req->inbuf) + 4;
595 struct pending_message_list *msg;
596
597 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
598
599 if(msg == NULL) {
600 DEBUG(0,("push_message: malloc fail (1)\n"));
601 return False;
602 }
603
604 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
605 if(msg->buf.data == NULL) {
606 DEBUG(0,("push_message: malloc fail (2)\n"));
607 TALLOC_FREE(msg);
608 return False;
609 }
610
611 msg->request_time = request_time;
612 msg->seqnum = req->seqnum;
613 msg->encrypted = req->encrypted;
614 msg->processed = false;
615 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
616
617 if (private_data) {
618 msg->private_data = data_blob_talloc(msg, private_data,
619 private_len);
620 if (msg->private_data.data == NULL) {
621 DEBUG(0,("push_message: malloc fail (3)\n"));
622 TALLOC_FREE(msg);
623 return False;
624 }
625 }
626
627 msg->te = event_add_timed(smbd_event_context(),
628 msg,
629 end_time,
630 smbd_deferred_open_timer,
631 msg);
632 if (!msg->te) {
633 DEBUG(0,("push_message: event_add_timed failed\n"));
634 TALLOC_FREE(msg);
635 return false;
636 }
637
638 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
639
640 DEBUG(10,("push_message: pushed message length %u on "
641 "deferred_open_queue\n", (unsigned int)msg_len));
642
643 return True;
644}
645
646/****************************************************************************
647 Function to delete a sharing violation open message by mid.
648****************************************************************************/
649
650void remove_deferred_open_message_smb(uint64_t mid)
651{
652 struct pending_message_list *pml;
653
654 if (smbd_server_conn->using_smb2) {
655 remove_deferred_open_message_smb2(smbd_server_conn, mid);
656 return;
657 }
658
659 for (pml = deferred_open_queue; pml; pml = pml->next) {
660 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
661 DEBUG(10,("remove_deferred_open_message_smb: "
662 "deleting mid %llu len %u\n",
663 (unsigned long long)mid,
664 (unsigned int)pml->buf.length ));
665 DLIST_REMOVE(deferred_open_queue, pml);
666 TALLOC_FREE(pml);
667 return;
668 }
669 }
670}
671
672/****************************************************************************
673 Move a sharing violation open retry message to the front of the list and
674 schedule it for immediate processing.
675****************************************************************************/
676
677void schedule_deferred_open_message_smb(uint64_t mid)
678{
679 struct pending_message_list *pml;
680 int i = 0;
681
682 if (smbd_server_conn->using_smb2) {
683 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
684 return;
685 }
686
687 for (pml = deferred_open_queue; pml; pml = pml->next) {
688 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
689
690 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
691 "msg_mid = %llu\n",
692 i++,
693 (unsigned long long)msg_mid ));
694
695 if (mid == msg_mid) {
696 struct timed_event *te;
697
698 if (pml->processed) {
699 /* A processed message should not be
700 * rescheduled. */
701 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
702 "message mid %llu was already processed\n",
703 (unsigned long long)msg_mid ));
704 continue;
705 }
706
707 DEBUG(10,("schedule_deferred_open_message_smb: "
708 "scheduling mid %llu\n",
709 (unsigned long long)mid ));
710
711 te = event_add_timed(smbd_event_context(),
712 pml,
713 timeval_zero(),
714 smbd_deferred_open_timer,
715 pml);
716 if (!te) {
717 DEBUG(10,("schedule_deferred_open_message_smb: "
718 "event_add_timed() failed, "
719 "skipping mid %llu\n",
720 (unsigned long long)msg_mid ));
721 }
722
723 TALLOC_FREE(pml->te);
724 pml->te = te;
725 DLIST_PROMOTE(deferred_open_queue, pml);
726 return;
727 }
728 }
729
730 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
731 "find message mid %llu\n",
732 (unsigned long long)mid ));
733}
734
735/****************************************************************************
736 Return true if this mid is on the deferred queue and was not yet processed.
737****************************************************************************/
738
739bool open_was_deferred(uint64_t mid)
740{
741 struct pending_message_list *pml;
742
743 if (smbd_server_conn->using_smb2) {
744 return open_was_deferred_smb2(smbd_server_conn, mid);
745 }
746
747 for (pml = deferred_open_queue; pml; pml = pml->next) {
748 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
749 return True;
750 }
751 }
752 return False;
753}
754
755/****************************************************************************
756 Return the message queued by this mid.
757****************************************************************************/
758
759static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
760{
761 struct pending_message_list *pml;
762
763 for (pml = deferred_open_queue; pml; pml = pml->next) {
764 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
765 return pml;
766 }
767 }
768 return NULL;
769}
770
771/****************************************************************************
772 Get the state data queued by this mid.
773****************************************************************************/
774
775bool get_deferred_open_message_state(struct smb_request *smbreq,
776 struct timeval *p_request_time,
777 void **pp_state)
778{
779 struct pending_message_list *pml;
780
781 if (smbd_server_conn->using_smb2) {
782 return get_deferred_open_message_state_smb2(smbreq->smb2req,
783 p_request_time,
784 pp_state);
785 }
786
787 pml = get_deferred_open_message_smb(smbreq->mid);
788 if (!pml) {
789 return false;
790 }
791 if (p_request_time) {
792 *p_request_time = pml->request_time;
793 }
794 if (pp_state) {
795 *pp_state = (void *)pml->private_data.data;
796 }
797 return true;
798}
799
800/****************************************************************************
801 Function to push a deferred open smb message onto a linked list of local smb
802 messages ready for processing.
803****************************************************************************/
804
805bool push_deferred_open_message_smb(struct smb_request *req,
806 struct timeval request_time,
807 struct timeval timeout,
808 struct file_id id,
809 char *private_data, size_t priv_len)
810{
811 struct timeval end_time;
812
813 if (req->smb2req) {
814 return push_deferred_open_message_smb2(req->smb2req,
815 request_time,
816 timeout,
817 id,
818 private_data,
819 priv_len);
820 }
821
822 if (req->unread_bytes) {
823 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
824 "unread_bytes = %u\n",
825 (unsigned int)req->unread_bytes ));
826 smb_panic("push_deferred_open_message_smb: "
827 "logic error unread_bytes != 0" );
828 }
829
830 end_time = timeval_sum(&request_time, &timeout);
831
832 DEBUG(10,("push_deferred_open_message_smb: pushing message "
833 "len %u mid %llu timeout time [%u.%06u]\n",
834 (unsigned int) smb_len(req->inbuf)+4,
835 (unsigned long long)req->mid,
836 (unsigned int)end_time.tv_sec,
837 (unsigned int)end_time.tv_usec));
838
839 return push_queued_message(req, request_time, end_time,
840 private_data, priv_len);
841}
842
843struct idle_event {
844 struct timed_event *te;
845 struct timeval interval;
846 char *name;
847 bool (*handler)(const struct timeval *now, void *private_data);
848 void *private_data;
849};
850
851static void smbd_idle_event_handler(struct event_context *ctx,
852 struct timed_event *te,
853 struct timeval now,
854 void *private_data)
855{
856 struct idle_event *event =
857 talloc_get_type_abort(private_data, struct idle_event);
858
859 TALLOC_FREE(event->te);
860
861 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
862 event->name, event->te));
863
864 if (!event->handler(&now, event->private_data)) {
865 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
866 event->name, event->te));
867 /* Don't repeat, delete ourselves */
868 TALLOC_FREE(event);
869 return;
870 }
871
872 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
873 event->name, event->te));
874
875 event->te = event_add_timed(ctx, event,
876 timeval_sum(&now, &event->interval),
877 smbd_idle_event_handler, event);
878
879 /* We can't do much but fail here. */
880 SMB_ASSERT(event->te != NULL);
881}
882
883struct idle_event *event_add_idle(struct event_context *event_ctx,
884 TALLOC_CTX *mem_ctx,
885 struct timeval interval,
886 const char *name,
887 bool (*handler)(const struct timeval *now,
888 void *private_data),
889 void *private_data)
890{
891 struct idle_event *result;
892 struct timeval now = timeval_current();
893
894 result = TALLOC_P(mem_ctx, struct idle_event);
895 if (result == NULL) {
896 DEBUG(0, ("talloc failed\n"));
897 return NULL;
898 }
899
900 result->interval = interval;
901 result->handler = handler;
902 result->private_data = private_data;
903
904 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
905 DEBUG(0, ("talloc failed\n"));
906 TALLOC_FREE(result);
907 return NULL;
908 }
909
910 result->te = event_add_timed(event_ctx, result,
911 timeval_sum(&now, &interval),
912 smbd_idle_event_handler, result);
913 if (result->te == NULL) {
914 DEBUG(0, ("event_add_timed failed\n"));
915 TALLOC_FREE(result);
916 return NULL;
917 }
918
919 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
920 return result;
921}
922
923static void smbd_sig_term_handler(struct tevent_context *ev,
924 struct tevent_signal *se,
925 int signum,
926 int count,
927 void *siginfo,
928 void *private_data)
929{
930 exit_server_cleanly("termination signal");
931}
932
933void smbd_setup_sig_term_handler(void)
934{
935 struct tevent_signal *se;
936
937 se = tevent_add_signal(smbd_event_context(),
938 smbd_event_context(),
939 SIGTERM, 0,
940 smbd_sig_term_handler,
941 NULL);
942 if (!se) {
943 exit_server("failed to setup SIGTERM handler");
944 }
945}
946
947static void smbd_sig_hup_handler(struct tevent_context *ev,
948 struct tevent_signal *se,
949 int signum,
950 int count,
951 void *siginfo,
952 void *private_data)
953{
954 struct messaging_context *msg_ctx = talloc_get_type_abort(
955 private_data, struct messaging_context);
956 change_to_root_user();
957 DEBUG(1,("Reloading services after SIGHUP\n"));
958 reload_services(msg_ctx, smbd_server_conn->sock, False);
959 if (am_parent) {
960 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
961 }
962}
963
964void smbd_setup_sig_hup_handler(struct tevent_context *ev,
965 struct messaging_context *msg_ctx)
966{
967 struct tevent_signal *se;
968
969 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
970 msg_ctx);
971 if (!se) {
972 exit_server("failed to setup SIGHUP handler");
973 }
974}
975
976static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
977{
978 int timeout;
979 int num_pfds = 0;
980 int ret;
981 bool retry;
982
983 timeout = SMBD_SELECT_TIMEOUT * 1000;
984
985 /*
986 * Are there any timed events waiting ? If so, ensure we don't
987 * select for longer than it would take to wait for them.
988 */
989
990 event_add_to_poll_args(smbd_event_context(), conn,
991 &conn->pfds, &num_pfds, &timeout);
992
993 /* Process a signal and timed events now... */
994 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
995 return NT_STATUS_RETRY;
996 }
997
998 {
999 int sav;
1000 START_PROFILE(smbd_idle);
1001
1002 ret = sys_poll(conn->pfds, num_pfds, timeout);
1003 sav = errno;
1004
1005 END_PROFILE(smbd_idle);
1006 errno = sav;
1007 }
1008
1009 if (ret == -1) {
1010 if (errno == EINTR) {
1011 return NT_STATUS_RETRY;
1012 }
1013 return map_nt_error_from_unix(errno);
1014 }
1015
1016 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1017 num_pfds);
1018 if (retry) {
1019 return NT_STATUS_RETRY;
1020 }
1021
1022 /* Did we timeout ? */
1023 if (ret == 0) {
1024 return NT_STATUS_RETRY;
1025 }
1026
1027 /* should not be reached */
1028 return NT_STATUS_INTERNAL_ERROR;
1029}
1030
1031/*
1032 * Only allow 5 outstanding trans requests. We're allocating memory, so
1033 * prevent a DoS.
1034 */
1035
1036NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1037{
1038 int count = 0;
1039 for (; list != NULL; list = list->next) {
1040
1041 if (list->mid == mid) {
1042 return NT_STATUS_INVALID_PARAMETER;
1043 }
1044
1045 count += 1;
1046 }
1047 if (count > 5) {
1048 return NT_STATUS_INSUFFICIENT_RESOURCES;
1049 }
1050
1051 return NT_STATUS_OK;
1052}
1053
1054/*
1055These flags determine some of the permissions required to do an operation
1056
1057Note that I don't set NEED_WRITE on some write operations because they
1058are used by some brain-dead clients when printing, and I don't want to
1059force write permissions on print services.
1060*/
1061#define AS_USER (1<<0)
1062#define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1063#define TIME_INIT (1<<2)
1064#define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1065#define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1066#define DO_CHDIR (1<<6)
1067
1068/*
1069 define a list of possible SMB messages and their corresponding
1070 functions. Any message that has a NULL function is unimplemented -
1071 please feel free to contribute implementations!
1072*/
1073static const struct smb_message_struct {
1074 const char *name;
1075 void (*fn)(struct smb_request *req);
1076 int flags;
1077} smb_messages[256] = {
1078
1079/* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1080/* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1081/* 0x02 */ { "SMBopen",reply_open,AS_USER },
1082/* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1083/* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1084/* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1085/* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1086/* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1087/* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1088/* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1089/* 0x0a */ { "SMBread",reply_read,AS_USER},
1090/* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1091/* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1092/* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1093/* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1094/* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1095/* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1096/* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1097/* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1098/* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1099/* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1100/* 0x15 */ { NULL, NULL, 0 },
1101/* 0x16 */ { NULL, NULL, 0 },
1102/* 0x17 */ { NULL, NULL, 0 },
1103/* 0x18 */ { NULL, NULL, 0 },
1104/* 0x19 */ { NULL, NULL, 0 },
1105/* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1106/* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1107/* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1108/* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1109/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1110/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1111/* 0x20 */ { "SMBwritec", NULL,0},
1112/* 0x21 */ { NULL, NULL, 0 },
1113/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1114/* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1115/* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1116/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1117/* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1118/* 0x27 */ { "SMBioctl",reply_ioctl,0},
1119/* 0x28 */ { "SMBioctls", NULL,AS_USER},
1120/* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1121/* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1122/* 0x2b */ { "SMBecho",reply_echo,0},
1123/* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1124/* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1125/* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1126/* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1127/* 0x30 */ { NULL, NULL, 0 },
1128/* 0x31 */ { NULL, NULL, 0 },
1129/* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1130/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1131/* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1132/* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1133/* 0x36 */ { NULL, NULL, 0 },
1134/* 0x37 */ { NULL, NULL, 0 },
1135/* 0x38 */ { NULL, NULL, 0 },
1136/* 0x39 */ { NULL, NULL, 0 },
1137/* 0x3a */ { NULL, NULL, 0 },
1138/* 0x3b */ { NULL, NULL, 0 },
1139/* 0x3c */ { NULL, NULL, 0 },
1140/* 0x3d */ { NULL, NULL, 0 },
1141/* 0x3e */ { NULL, NULL, 0 },
1142/* 0x3f */ { NULL, NULL, 0 },
1143/* 0x40 */ { NULL, NULL, 0 },
1144/* 0x41 */ { NULL, NULL, 0 },
1145/* 0x42 */ { NULL, NULL, 0 },
1146/* 0x43 */ { NULL, NULL, 0 },
1147/* 0x44 */ { NULL, NULL, 0 },
1148/* 0x45 */ { NULL, NULL, 0 },
1149/* 0x46 */ { NULL, NULL, 0 },
1150/* 0x47 */ { NULL, NULL, 0 },
1151/* 0x48 */ { NULL, NULL, 0 },
1152/* 0x49 */ { NULL, NULL, 0 },
1153/* 0x4a */ { NULL, NULL, 0 },
1154/* 0x4b */ { NULL, NULL, 0 },
1155/* 0x4c */ { NULL, NULL, 0 },
1156/* 0x4d */ { NULL, NULL, 0 },
1157/* 0x4e */ { NULL, NULL, 0 },
1158/* 0x4f */ { NULL, NULL, 0 },
1159/* 0x50 */ { NULL, NULL, 0 },
1160/* 0x51 */ { NULL, NULL, 0 },
1161/* 0x52 */ { NULL, NULL, 0 },
1162/* 0x53 */ { NULL, NULL, 0 },
1163/* 0x54 */ { NULL, NULL, 0 },
1164/* 0x55 */ { NULL, NULL, 0 },
1165/* 0x56 */ { NULL, NULL, 0 },
1166/* 0x57 */ { NULL, NULL, 0 },
1167/* 0x58 */ { NULL, NULL, 0 },
1168/* 0x59 */ { NULL, NULL, 0 },
1169/* 0x5a */ { NULL, NULL, 0 },
1170/* 0x5b */ { NULL, NULL, 0 },
1171/* 0x5c */ { NULL, NULL, 0 },
1172/* 0x5d */ { NULL, NULL, 0 },
1173/* 0x5e */ { NULL, NULL, 0 },
1174/* 0x5f */ { NULL, NULL, 0 },
1175/* 0x60 */ { NULL, NULL, 0 },
1176/* 0x61 */ { NULL, NULL, 0 },
1177/* 0x62 */ { NULL, NULL, 0 },
1178/* 0x63 */ { NULL, NULL, 0 },
1179/* 0x64 */ { NULL, NULL, 0 },
1180/* 0x65 */ { NULL, NULL, 0 },
1181/* 0x66 */ { NULL, NULL, 0 },
1182/* 0x67 */ { NULL, NULL, 0 },
1183/* 0x68 */ { NULL, NULL, 0 },
1184/* 0x69 */ { NULL, NULL, 0 },
1185/* 0x6a */ { NULL, NULL, 0 },
1186/* 0x6b */ { NULL, NULL, 0 },
1187/* 0x6c */ { NULL, NULL, 0 },
1188/* 0x6d */ { NULL, NULL, 0 },
1189/* 0x6e */ { NULL, NULL, 0 },
1190/* 0x6f */ { NULL, NULL, 0 },
1191/* 0x70 */ { "SMBtcon",reply_tcon,0},
1192/* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1193/* 0x72 */ { "SMBnegprot",reply_negprot,0},
1194/* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1195/* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1196/* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1197/* 0x76 */ { NULL, NULL, 0 },
1198/* 0x77 */ { NULL, NULL, 0 },
1199/* 0x78 */ { NULL, NULL, 0 },
1200/* 0x79 */ { NULL, NULL, 0 },
1201/* 0x7a */ { NULL, NULL, 0 },
1202/* 0x7b */ { NULL, NULL, 0 },
1203/* 0x7c */ { NULL, NULL, 0 },
1204/* 0x7d */ { NULL, NULL, 0 },
1205/* 0x7e */ { NULL, NULL, 0 },
1206/* 0x7f */ { NULL, NULL, 0 },
1207/* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1208/* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1209/* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1210/* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1211/* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1212/* 0x85 */ { NULL, NULL, 0 },
1213/* 0x86 */ { NULL, NULL, 0 },
1214/* 0x87 */ { NULL, NULL, 0 },
1215/* 0x88 */ { NULL, NULL, 0 },
1216/* 0x89 */ { NULL, NULL, 0 },
1217/* 0x8a */ { NULL, NULL, 0 },
1218/* 0x8b */ { NULL, NULL, 0 },
1219/* 0x8c */ { NULL, NULL, 0 },
1220/* 0x8d */ { NULL, NULL, 0 },
1221/* 0x8e */ { NULL, NULL, 0 },
1222/* 0x8f */ { NULL, NULL, 0 },
1223/* 0x90 */ { NULL, NULL, 0 },
1224/* 0x91 */ { NULL, NULL, 0 },
1225/* 0x92 */ { NULL, NULL, 0 },
1226/* 0x93 */ { NULL, NULL, 0 },
1227/* 0x94 */ { NULL, NULL, 0 },
1228/* 0x95 */ { NULL, NULL, 0 },
1229/* 0x96 */ { NULL, NULL, 0 },
1230/* 0x97 */ { NULL, NULL, 0 },
1231/* 0x98 */ { NULL, NULL, 0 },
1232/* 0x99 */ { NULL, NULL, 0 },
1233/* 0x9a */ { NULL, NULL, 0 },
1234/* 0x9b */ { NULL, NULL, 0 },
1235/* 0x9c */ { NULL, NULL, 0 },
1236/* 0x9d */ { NULL, NULL, 0 },
1237/* 0x9e */ { NULL, NULL, 0 },
1238/* 0x9f */ { NULL, NULL, 0 },
1239/* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1240/* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1241/* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1242/* 0xa3 */ { NULL, NULL, 0 },
1243/* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1244/* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1245/* 0xa6 */ { NULL, NULL, 0 },
1246/* 0xa7 */ { NULL, NULL, 0 },
1247/* 0xa8 */ { NULL, NULL, 0 },
1248/* 0xa9 */ { NULL, NULL, 0 },
1249/* 0xaa */ { NULL, NULL, 0 },
1250/* 0xab */ { NULL, NULL, 0 },
1251/* 0xac */ { NULL, NULL, 0 },
1252/* 0xad */ { NULL, NULL, 0 },
1253/* 0xae */ { NULL, NULL, 0 },
1254/* 0xaf */ { NULL, NULL, 0 },
1255/* 0xb0 */ { NULL, NULL, 0 },
1256/* 0xb1 */ { NULL, NULL, 0 },
1257/* 0xb2 */ { NULL, NULL, 0 },
1258/* 0xb3 */ { NULL, NULL, 0 },
1259/* 0xb4 */ { NULL, NULL, 0 },
1260/* 0xb5 */ { NULL, NULL, 0 },
1261/* 0xb6 */ { NULL, NULL, 0 },
1262/* 0xb7 */ { NULL, NULL, 0 },
1263/* 0xb8 */ { NULL, NULL, 0 },
1264/* 0xb9 */ { NULL, NULL, 0 },
1265/* 0xba */ { NULL, NULL, 0 },
1266/* 0xbb */ { NULL, NULL, 0 },
1267/* 0xbc */ { NULL, NULL, 0 },
1268/* 0xbd */ { NULL, NULL, 0 },
1269/* 0xbe */ { NULL, NULL, 0 },
1270/* 0xbf */ { NULL, NULL, 0 },
1271/* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1272/* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1273/* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1274/* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1275/* 0xc4 */ { NULL, NULL, 0 },
1276/* 0xc5 */ { NULL, NULL, 0 },
1277/* 0xc6 */ { NULL, NULL, 0 },
1278/* 0xc7 */ { NULL, NULL, 0 },
1279/* 0xc8 */ { NULL, NULL, 0 },
1280/* 0xc9 */ { NULL, NULL, 0 },
1281/* 0xca */ { NULL, NULL, 0 },
1282/* 0xcb */ { NULL, NULL, 0 },
1283/* 0xcc */ { NULL, NULL, 0 },
1284/* 0xcd */ { NULL, NULL, 0 },
1285/* 0xce */ { NULL, NULL, 0 },
1286/* 0xcf */ { NULL, NULL, 0 },
1287/* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1288/* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1289/* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1290/* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1291/* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1292/* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1293/* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1294/* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1295/* 0xd8 */ { NULL, NULL, 0 },
1296/* 0xd9 */ { NULL, NULL, 0 },
1297/* 0xda */ { NULL, NULL, 0 },
1298/* 0xdb */ { NULL, NULL, 0 },
1299/* 0xdc */ { NULL, NULL, 0 },
1300/* 0xdd */ { NULL, NULL, 0 },
1301/* 0xde */ { NULL, NULL, 0 },
1302/* 0xdf */ { NULL, NULL, 0 },
1303/* 0xe0 */ { NULL, NULL, 0 },
1304/* 0xe1 */ { NULL, NULL, 0 },
1305/* 0xe2 */ { NULL, NULL, 0 },
1306/* 0xe3 */ { NULL, NULL, 0 },
1307/* 0xe4 */ { NULL, NULL, 0 },
1308/* 0xe5 */ { NULL, NULL, 0 },
1309/* 0xe6 */ { NULL, NULL, 0 },
1310/* 0xe7 */ { NULL, NULL, 0 },
1311/* 0xe8 */ { NULL, NULL, 0 },
1312/* 0xe9 */ { NULL, NULL, 0 },
1313/* 0xea */ { NULL, NULL, 0 },
1314/* 0xeb */ { NULL, NULL, 0 },
1315/* 0xec */ { NULL, NULL, 0 },
1316/* 0xed */ { NULL, NULL, 0 },
1317/* 0xee */ { NULL, NULL, 0 },
1318/* 0xef */ { NULL, NULL, 0 },
1319/* 0xf0 */ { NULL, NULL, 0 },
1320/* 0xf1 */ { NULL, NULL, 0 },
1321/* 0xf2 */ { NULL, NULL, 0 },
1322/* 0xf3 */ { NULL, NULL, 0 },
1323/* 0xf4 */ { NULL, NULL, 0 },
1324/* 0xf5 */ { NULL, NULL, 0 },
1325/* 0xf6 */ { NULL, NULL, 0 },
1326/* 0xf7 */ { NULL, NULL, 0 },
1327/* 0xf8 */ { NULL, NULL, 0 },
1328/* 0xf9 */ { NULL, NULL, 0 },
1329/* 0xfa */ { NULL, NULL, 0 },
1330/* 0xfb */ { NULL, NULL, 0 },
1331/* 0xfc */ { NULL, NULL, 0 },
1332/* 0xfd */ { NULL, NULL, 0 },
1333/* 0xfe */ { NULL, NULL, 0 },
1334/* 0xff */ { NULL, NULL, 0 }
1335
1336};
1337
1338/*******************************************************************
1339 allocate and initialize a reply packet
1340********************************************************************/
1341
1342static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1343 const char *inbuf, char **outbuf, uint8_t num_words,
1344 uint32_t num_bytes)
1345{
1346 /*
1347 * Protect against integer wrap
1348 */
1349 if ((num_bytes > 0xffffff)
1350 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1351 char *msg;
1352 if (asprintf(&msg, "num_bytes too large: %u",
1353 (unsigned)num_bytes) == -1) {
1354 msg = CONST_DISCARD(char *, "num_bytes too large");
1355 }
1356 smb_panic(msg);
1357 }
1358
1359 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1360 smb_size + num_words*2 + num_bytes);
1361 if (*outbuf == NULL) {
1362 return false;
1363 }
1364
1365 construct_reply_common(req, inbuf, *outbuf);
1366 srv_set_message(*outbuf, num_words, num_bytes, false);
1367 /*
1368 * Zero out the word area, the caller has to take care of the bcc area
1369 * himself
1370 */
1371 if (num_words != 0) {
1372 memset(*outbuf + smb_vwv0, 0, num_words*2);
1373 }
1374
1375 return true;
1376}
1377
1378void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1379{
1380 char *outbuf;
1381 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1382 num_bytes)) {
1383 smb_panic("could not allocate output buffer\n");
1384 }
1385 req->outbuf = (uint8_t *)outbuf;
1386}
1387
1388
1389/*******************************************************************
1390 Dump a packet to a file.
1391********************************************************************/
1392
1393static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1394{
1395 int fd, i;
1396 char *fname = NULL;
1397 if (DEBUGLEVEL < 50) {
1398 return;
1399 }
1400
1401 if (len < 4) len = smb_len(data)+4;
1402 for (i=1;i<100;i++) {
1403 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1404 type ? "req" : "resp") == -1) {
1405 return;
1406 }
1407 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1408 if (fd != -1 || errno != EEXIST) break;
1409 }
1410 if (fd != -1) {
1411 ssize_t ret = write(fd, data, len);
1412 if (ret != len)
1413 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1414 close(fd);
1415 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1416 }
1417 SAFE_FREE(fname);
1418}
1419
1420/****************************************************************************
1421 Prepare everything for calling the actual request function, and potentially
1422 call the request function via the "new" interface.
1423
1424 Return False if the "legacy" function needs to be called, everything is
1425 prepared.
1426
1427 Return True if we're done.
1428
1429 I know this API sucks, but it is the one with the least code change I could
1430 find.
1431****************************************************************************/
1432
1433static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1434{
1435 int flags;
1436 uint16 session_tag;
1437 connection_struct *conn = NULL;
1438 struct smbd_server_connection *sconn = req->sconn;
1439
1440 errno = 0;
1441
1442 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1443 * so subtract 4 from it. */
1444 if (!valid_smb_header(req->inbuf)
1445 || (size < (smb_size - 4))) {
1446 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1447 smb_len(req->inbuf)));
1448 exit_server_cleanly("Non-SMB packet");
1449 }
1450
1451 if (smb_messages[type].fn == NULL) {
1452 DEBUG(0,("Unknown message type %d!\n",type));
1453 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1454 reply_unknown_new(req, type);
1455 return NULL;
1456 }
1457
1458 flags = smb_messages[type].flags;
1459
1460 /* In share mode security we must ignore the vuid. */
1461 session_tag = (lp_security() == SEC_SHARE)
1462 ? UID_FIELD_INVALID : req->vuid;
1463 conn = req->conn;
1464
1465 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1466 (int)sys_getpid(), (unsigned long)conn));
1467
1468 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1469
1470 /* Ensure this value is replaced in the incoming packet. */
1471 SSVAL(req->inbuf,smb_uid,session_tag);
1472
1473 /*
1474 * Ensure the correct username is in current_user_info. This is a
1475 * really ugly bugfix for problems with multiple session_setup_and_X's
1476 * being done and allowing %U and %G substitutions to work correctly.
1477 * There is a reason this code is done here, don't move it unless you
1478 * know what you're doing... :-).
1479 * JRA.
1480 */
1481
1482 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1483 user_struct *vuser = NULL;
1484
1485 sconn->smb1.sessions.last_session_tag = session_tag;
1486 if(session_tag != UID_FIELD_INVALID) {
1487 vuser = get_valid_user_struct(sconn, session_tag);
1488 if (vuser) {
1489 set_current_user_info(
1490 vuser->session_info->sanitized_username,
1491 vuser->session_info->unix_name,
1492 vuser->session_info->info3->base.domain.string);
1493 }
1494 }
1495 }
1496
1497 /* Does this call need to be run as the connected user? */
1498 if (flags & AS_USER) {
1499
1500 /* Does this call need a valid tree connection? */
1501 if (!conn) {
1502 /*
1503 * Amazingly, the error code depends on the command
1504 * (from Samba4).
1505 */
1506 if (type == SMBntcreateX) {
1507 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1508 } else {
1509 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1510 }
1511 return NULL;
1512 }
1513
1514 if (!change_to_user(conn,session_tag)) {
1515 DEBUG(0, ("Error: Could not change to user. Removing "
1516 "deferred open, mid=%llu.\n",
1517 (unsigned long long)req->mid));
1518 reply_force_doserror(req, ERRSRV, ERRbaduid);
1519 return conn;
1520 }
1521
1522 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1523
1524 /* Does it need write permission? */
1525 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1526 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1527 return conn;
1528 }
1529
1530 /* IPC services are limited */
1531 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1532 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1533 return conn;
1534 }
1535 } else {
1536 /* This call needs to be run as root */
1537 change_to_root_user();
1538 }
1539
1540 /* load service specific parameters */
1541 if (conn) {
1542 if (req->encrypted) {
1543 conn->encrypted_tid = true;
1544 /* encrypted required from now on. */
1545 conn->encrypt_level = Required;
1546 } else if (ENCRYPTION_REQUIRED(conn)) {
1547 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1548 exit_server_cleanly("encryption required "
1549 "on connection");
1550 return conn;
1551 }
1552 }
1553
1554 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1555 (flags & (AS_USER|DO_CHDIR)
1556 ?True:False))) {
1557 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1558 return conn;
1559 }
1560 conn->num_smb_operations++;
1561 }
1562
1563 /* does this protocol need to be run as guest? */
1564 if ((flags & AS_GUEST)
1565 && (!change_to_guest() ||
1566 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1567 sconn->client_id.name,
1568 sconn->client_id.addr))) {
1569 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1570 return conn;
1571 }
1572
1573 smb_messages[type].fn(req);
1574 return req->conn;
1575}
1576
1577/****************************************************************************
1578 Construct a reply to the incoming packet.
1579****************************************************************************/
1580
1581static void construct_reply(struct smbd_server_connection *sconn,
1582 char *inbuf, int size, size_t unread_bytes,
1583 uint32_t seqnum, bool encrypted,
1584 struct smb_perfcount_data *deferred_pcd)
1585{
1586 connection_struct *conn;
1587 struct smb_request *req;
1588
1589 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1590 smb_panic("could not allocate smb_request");
1591 }
1592
1593 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1594 encrypted, seqnum)) {
1595 exit_server_cleanly("Invalid SMB request");
1596 }
1597
1598 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1599
1600 /* we popped this message off the queue - keep original perf data */
1601 if (deferred_pcd)
1602 req->pcd = *deferred_pcd;
1603 else {
1604 SMB_PERFCOUNT_START(&req->pcd);
1605 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1606 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1607 }
1608
1609 conn = switch_message(req->cmd, req, size);
1610
1611 if (req->unread_bytes) {
1612 /* writeX failed. drain socket. */
1613 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1614 req->unread_bytes) {
1615 smb_panic("failed to drain pending bytes");
1616 }
1617 req->unread_bytes = 0;
1618 }
1619
1620 if (req->done) {
1621 TALLOC_FREE(req);
1622 return;
1623 }
1624
1625 if (req->outbuf == NULL) {
1626 return;
1627 }
1628
1629 if (CVAL(req->outbuf,0) == 0) {
1630 show_msg((char *)req->outbuf);
1631 }
1632
1633 if (!srv_send_smb(req->sconn,
1634 (char *)req->outbuf,
1635 true, req->seqnum+1,
1636 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1637 &req->pcd)) {
1638 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1639 }
1640
1641 TALLOC_FREE(req);
1642
1643 return;
1644}
1645
1646/****************************************************************************
1647 Process an smb from the client
1648****************************************************************************/
1649static void process_smb(struct smbd_server_connection *sconn,
1650 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1651 uint32_t seqnum, bool encrypted,
1652 struct smb_perfcount_data *deferred_pcd)
1653{
1654 int msg_type = CVAL(inbuf,0);
1655
1656 DO_PROFILE_INC(smb_count);
1657
1658 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1659 smb_len(inbuf) ) );
1660 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1661 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1662
1663 if (msg_type != 0) {
1664 /*
1665 * NetBIOS session request, keepalive, etc.
1666 */
1667 reply_special(sconn, (char *)inbuf, nread);
1668 goto done;
1669 }
1670
1671 if (sconn->using_smb2) {
1672 /* At this point we're not really using smb2,
1673 * we make the decision here.. */
1674 if (smbd_is_smb2_header(inbuf, nread)) {
1675 smbd_smb2_first_negprot(sconn, inbuf, nread);
1676 return;
1677 } else if (nread >= smb_size && valid_smb_header(inbuf)
1678 && CVAL(inbuf, smb_com) != 0x72) {
1679 /* This is a non-negprot SMB1 packet.
1680 Disable SMB2 from now on. */
1681 sconn->using_smb2 = false;
1682 }
1683 }
1684
1685 show_msg((char *)inbuf);
1686
1687 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1688 encrypted, deferred_pcd);
1689 sconn->trans_num++;
1690
1691done:
1692 sconn->num_requests++;
1693
1694 /* The timeout_processing function isn't run nearly
1695 often enough to implement 'max log size' without
1696 overrunning the size of the file by many megabytes.
1697 This is especially true if we are running at debug
1698 level 10. Checking every 50 SMBs is a nice
1699 tradeoff of performance vs log file size overrun. */
1700
1701 if ((sconn->num_requests % 50) == 0 &&
1702 need_to_check_log_size()) {
1703 change_to_root_user();
1704 check_log_size();
1705 }
1706}
1707
1708/****************************************************************************
1709 Return a string containing the function name of a SMB command.
1710****************************************************************************/
1711
1712const char *smb_fn_name(int type)
1713{
1714 const char *unknown_name = "SMBunknown";
1715
1716 if (smb_messages[type].name == NULL)
1717 return(unknown_name);
1718
1719 return(smb_messages[type].name);
1720}
1721
1722/****************************************************************************
1723 Helper functions for contruct_reply.
1724****************************************************************************/
1725
1726void add_to_common_flags2(uint32 v)
1727{
1728 common_flags2 |= v;
1729}
1730
1731void remove_from_common_flags2(uint32 v)
1732{
1733 common_flags2 &= ~v;
1734}
1735
1736static void construct_reply_common(struct smb_request *req, const char *inbuf,
1737 char *outbuf)
1738{
1739 srv_set_message(outbuf,0,0,false);
1740
1741 SCVAL(outbuf, smb_com, req->cmd);
1742 SIVAL(outbuf,smb_rcls,0);
1743 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1744 SSVAL(outbuf,smb_flg2,
1745 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1746 common_flags2);
1747 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1748
1749 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1750 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1751 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1752 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1753}
1754
1755void construct_reply_common_req(struct smb_request *req, char *outbuf)
1756{
1757 construct_reply_common(req, (char *)req->inbuf, outbuf);
1758}
1759
1760/*
1761 * How many bytes have we already accumulated up to the current wct field
1762 * offset?
1763 */
1764
1765size_t req_wct_ofs(struct smb_request *req)
1766{
1767 size_t buf_size;
1768
1769 if (req->chain_outbuf == NULL) {
1770 return smb_wct - 4;
1771 }
1772 buf_size = talloc_get_size(req->chain_outbuf);
1773 if ((buf_size % 4) != 0) {
1774 buf_size += (4 - (buf_size % 4));
1775 }
1776 return buf_size - 4;
1777}
1778
1779/*
1780 * Hack around reply_nterror & friends not being aware of chained requests,
1781 * generating illegal (i.e. wct==0) chain replies.
1782 */
1783
1784static void fixup_chain_error_packet(struct smb_request *req)
1785{
1786 uint8_t *outbuf = req->outbuf;
1787 req->outbuf = NULL;
1788 reply_outbuf(req, 2, 0);
1789 memcpy(req->outbuf, outbuf, smb_wct);
1790 TALLOC_FREE(outbuf);
1791 SCVAL(req->outbuf, smb_vwv0, 0xff);
1792}
1793
1794/**
1795 * @brief Find the smb_cmd offset of the last command pushed
1796 * @param[in] buf The buffer we're building up
1797 * @retval Where can we put our next andx cmd?
1798 *
1799 * While chaining requests, the "next" request we're looking at needs to put
1800 * its SMB_Command before the data the previous request already built up added
1801 * to the chain. Find the offset to the place where we have to put our cmd.
1802 */
1803
1804static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1805{
1806 uint8_t cmd;
1807 size_t ofs;
1808
1809 cmd = CVAL(buf, smb_com);
1810
1811 SMB_ASSERT(is_andx_req(cmd));
1812
1813 ofs = smb_vwv0;
1814
1815 while (CVAL(buf, ofs) != 0xff) {
1816
1817 if (!is_andx_req(CVAL(buf, ofs))) {
1818 return false;
1819 }
1820
1821 /*
1822 * ofs is from start of smb header, so add the 4 length
1823 * bytes. The next cmd is right after the wct field.
1824 */
1825 ofs = SVAL(buf, ofs+2) + 4 + 1;
1826
1827 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1828 }
1829
1830 *pofs = ofs;
1831 return true;
1832}
1833
1834/**
1835 * @brief Do the smb chaining at a buffer level
1836 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1837 * @param[in] smb_command The command that we want to issue
1838 * @param[in] wct How many words?
1839 * @param[in] vwv The words, already in network order
1840 * @param[in] bytes_alignment How shall we align "bytes"?
1841 * @param[in] num_bytes How many bytes?
1842 * @param[in] bytes The data the request ships
1843 *
1844 * smb_splice_chain() adds the vwv and bytes to the request already present in
1845 * *poutbuf.
1846 */
1847
1848static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1849 uint8_t wct, const uint16_t *vwv,
1850 size_t bytes_alignment,
1851 uint32_t num_bytes, const uint8_t *bytes)
1852{
1853 uint8_t *outbuf;
1854 size_t old_size, new_size;
1855 size_t ofs;
1856 size_t chain_padding = 0;
1857 size_t bytes_padding = 0;
1858 bool first_request;
1859
1860 old_size = talloc_get_size(*poutbuf);
1861
1862 /*
1863 * old_size == smb_wct means we're pushing the first request in for
1864 * libsmb/
1865 */
1866
1867 first_request = (old_size == smb_wct);
1868
1869 if (!first_request && ((old_size % 4) != 0)) {
1870 /*
1871 * Align the wct field of subsequent requests to a 4-byte
1872 * boundary
1873 */
1874 chain_padding = 4 - (old_size % 4);
1875 }
1876
1877 /*
1878 * After the old request comes the new wct field (1 byte), the vwv's
1879 * and the num_bytes field. After at we might need to align the bytes
1880 * given to us to "bytes_alignment", increasing the num_bytes value.
1881 */
1882
1883 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1884
1885 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1886 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1887 }
1888
1889 new_size += bytes_padding + num_bytes;
1890
1891 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1892 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1893 (unsigned)new_size));
1894 return false;
1895 }
1896
1897 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1898 if (outbuf == NULL) {
1899 DEBUG(0, ("talloc failed\n"));
1900 return false;
1901 }
1902 *poutbuf = outbuf;
1903
1904 if (first_request) {
1905 SCVAL(outbuf, smb_com, smb_command);
1906 } else {
1907 size_t andx_cmd_ofs;
1908
1909 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1910 DEBUG(1, ("invalid command chain\n"));
1911 *poutbuf = TALLOC_REALLOC_ARRAY(
1912 NULL, *poutbuf, uint8_t, old_size);
1913 return false;
1914 }
1915
1916 if (chain_padding != 0) {
1917 memset(outbuf + old_size, 0, chain_padding);
1918 old_size += chain_padding;
1919 }
1920
1921 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1922 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1923 }
1924
1925 ofs = old_size;
1926
1927 /*
1928 * Push the chained request:
1929 *
1930 * wct field
1931 */
1932
1933 SCVAL(outbuf, ofs, wct);
1934 ofs += 1;
1935
1936 /*
1937 * vwv array
1938 */
1939
1940 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1941 ofs += sizeof(uint16_t) * wct;
1942
1943 /*
1944 * bcc (byte count)
1945 */
1946
1947 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1948 ofs += sizeof(uint16_t);
1949
1950 /*
1951 * padding
1952 */
1953
1954 if (bytes_padding != 0) {
1955 memset(outbuf + ofs, 0, bytes_padding);
1956 ofs += bytes_padding;
1957 }
1958
1959 /*
1960 * The bytes field
1961 */
1962
1963 memcpy(outbuf + ofs, bytes, num_bytes);
1964
1965 return true;
1966}
1967
1968/****************************************************************************
1969 Construct a chained reply and add it to the already made reply
1970****************************************************************************/
1971
1972void chain_reply(struct smb_request *req)
1973{
1974 size_t smblen = smb_len(req->inbuf);
1975 size_t already_used, length_needed;
1976 uint8_t chain_cmd;
1977 uint32_t chain_offset; /* uint32_t to avoid overflow */
1978
1979 uint8_t wct;
1980 uint16_t *vwv;
1981 uint16_t buflen;
1982 uint8_t *buf;
1983
1984 if (IVAL(req->outbuf, smb_rcls) != 0) {
1985 fixup_chain_error_packet(req);
1986 }
1987
1988 /*
1989 * Any of the AndX requests and replies have at least a wct of
1990 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1991 * beginning of the SMB header to the next wct field.
1992 *
1993 * None of the AndX requests put anything valuable in vwv[0] and [1],
1994 * so we can overwrite it here to form the chain.
1995 */
1996
1997 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1998 if (req->chain_outbuf == NULL) {
1999 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2000 req, req->outbuf, uint8_t,
2001 smb_len(req->outbuf) + 4);
2002 if (req->chain_outbuf == NULL) {
2003 smb_panic("talloc failed");
2004 }
2005 }
2006 req->outbuf = NULL;
2007 goto error;
2008 }
2009
2010 /*
2011 * Here we assume that this is the end of the chain. For that we need
2012 * to set "next command" to 0xff and the offset to 0. If we later find
2013 * more commands in the chain, this will be overwritten again.
2014 */
2015
2016 SCVAL(req->outbuf, smb_vwv0, 0xff);
2017 SCVAL(req->outbuf, smb_vwv0+1, 0);
2018 SSVAL(req->outbuf, smb_vwv1, 0);
2019
2020 if (req->chain_outbuf == NULL) {
2021 /*
2022 * In req->chain_outbuf we collect all the replies. Start the
2023 * chain by copying in the first reply.
2024 *
2025 * We do the realloc because later on we depend on
2026 * talloc_get_size to determine the length of
2027 * chain_outbuf. The reply_xxx routines might have
2028 * over-allocated (reply_pipe_read_and_X used to be such an
2029 * example).
2030 */
2031 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2032 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2033 if (req->chain_outbuf == NULL) {
2034 smb_panic("talloc failed");
2035 }
2036 req->outbuf = NULL;
2037 } else {
2038 /*
2039 * Update smb headers where subsequent chained commands
2040 * may have updated them.
2041 */
2042 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2043 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2044
2045 if (!smb_splice_chain(&req->chain_outbuf,
2046 CVAL(req->outbuf, smb_com),
2047 CVAL(req->outbuf, smb_wct),
2048 (uint16_t *)(req->outbuf + smb_vwv),
2049 0, smb_buflen(req->outbuf),
2050 (uint8_t *)smb_buf(req->outbuf))) {
2051 goto error;
2052 }
2053 TALLOC_FREE(req->outbuf);
2054 }
2055
2056 /*
2057 * We use the old request's vwv field to grab the next chained command
2058 * and offset into the chained fields.
2059 */
2060
2061 chain_cmd = CVAL(req->vwv+0, 0);
2062 chain_offset = SVAL(req->vwv+1, 0);
2063
2064 if (chain_cmd == 0xff) {
2065 /*
2066 * End of chain, no more requests from the client. So ship the
2067 * replies.
2068 */
2069 smb_setlen((char *)(req->chain_outbuf),
2070 talloc_get_size(req->chain_outbuf) - 4);
2071
2072 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2073 true, req->seqnum+1,
2074 IS_CONN_ENCRYPTED(req->conn)
2075 ||req->encrypted,
2076 &req->pcd)) {
2077 exit_server_cleanly("chain_reply: srv_send_smb "
2078 "failed.");
2079 }
2080 TALLOC_FREE(req->chain_outbuf);
2081 req->done = true;
2082 return;
2083 }
2084
2085 /* add a new perfcounter for this element of chain */
2086 SMB_PERFCOUNT_ADD(&req->pcd);
2087 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2088 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2089
2090 /*
2091 * Check if the client tries to fool us. The request so far uses the
2092 * space to the end of the byte buffer in the request just
2093 * processed. The chain_offset can't point into that area. If that was
2094 * the case, we could end up with an endless processing of the chain,
2095 * we would always handle the same request.
2096 */
2097
2098 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2099 if (chain_offset < already_used) {
2100 goto error;
2101 }
2102
2103 /*
2104 * Next check: Make sure the chain offset does not point beyond the
2105 * overall smb request length.
2106 */
2107
2108 length_needed = chain_offset+1; /* wct */
2109 if (length_needed > smblen) {
2110 goto error;
2111 }
2112
2113 /*
2114 * Now comes the pointer magic. Goal here is to set up req->vwv and
2115 * req->buf correctly again to be able to call the subsequent
2116 * switch_message(). The chain offset (the former vwv[1]) points at
2117 * the new wct field.
2118 */
2119
2120 wct = CVAL(smb_base(req->inbuf), chain_offset);
2121
2122 /*
2123 * Next consistency check: Make the new vwv array fits in the overall
2124 * smb request.
2125 */
2126
2127 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2128 if (length_needed > smblen) {
2129 goto error;
2130 }
2131 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2132
2133 /*
2134 * Now grab the new byte buffer....
2135 */
2136
2137 buflen = SVAL(vwv+wct, 0);
2138
2139 /*
2140 * .. and check that it fits.
2141 */
2142
2143 length_needed += buflen;
2144 if (length_needed > smblen) {
2145 goto error;
2146 }
2147 buf = (uint8_t *)(vwv+wct+1);
2148
2149 req->cmd = chain_cmd;
2150 req->wct = wct;
2151 req->vwv = vwv;
2152 req->buflen = buflen;
2153 req->buf = buf;
2154
2155 switch_message(chain_cmd, req, smblen);
2156
2157 if (req->outbuf == NULL) {
2158 /*
2159 * This happens if the chained command has suspended itself or
2160 * if it has called srv_send_smb() itself.
2161 */
2162 return;
2163 }
2164
2165 /*
2166 * We end up here if the chained command was not itself chained or
2167 * suspended, but for example a close() command. We now need to splice
2168 * the chained commands' outbuf into the already built up chain_outbuf
2169 * and ship the result.
2170 */
2171 goto done;
2172
2173 error:
2174 /*
2175 * We end up here if there's any error in the chain syntax. Report a
2176 * DOS error, just like Windows does.
2177 */
2178 reply_force_doserror(req, ERRSRV, ERRerror);
2179 fixup_chain_error_packet(req);
2180
2181 done:
2182 /*
2183 * This scary statement intends to set the
2184 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2185 * to the value req->outbuf carries
2186 */
2187 SSVAL(req->chain_outbuf, smb_flg2,
2188 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2189 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2190
2191 /*
2192 * Transfer the error codes from the subrequest to the main one
2193 */
2194 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2195 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2196
2197 if (!smb_splice_chain(&req->chain_outbuf,
2198 CVAL(req->outbuf, smb_com),
2199 CVAL(req->outbuf, smb_wct),
2200 (uint16_t *)(req->outbuf + smb_vwv),
2201 0, smb_buflen(req->outbuf),
2202 (uint8_t *)smb_buf(req->outbuf))) {
2203 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2204 }
2205 TALLOC_FREE(req->outbuf);
2206
2207 smb_setlen((char *)(req->chain_outbuf),
2208 talloc_get_size(req->chain_outbuf) - 4);
2209
2210 show_msg((char *)(req->chain_outbuf));
2211
2212 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2213 true, req->seqnum+1,
2214 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2215 &req->pcd)) {
2216 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2217 }
2218 TALLOC_FREE(req->chain_outbuf);
2219 req->done = true;
2220}
2221
2222/****************************************************************************
2223 Check if services need reloading.
2224****************************************************************************/
2225
2226static void check_reload(struct smbd_server_connection *sconn, time_t t)
2227{
2228
2229 if (last_smb_conf_reload_time == 0) {
2230 last_smb_conf_reload_time = t;
2231 }
2232
2233 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2234 reload_services(sconn->msg_ctx, sconn->sock, True);
2235 last_smb_conf_reload_time = t;
2236 }
2237}
2238
2239static bool fd_is_readable(int fd)
2240{
2241 int ret, revents;
2242
2243 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2244
2245 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2246
2247}
2248
2249static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2250{
2251 /* TODO: make write nonblocking */
2252}
2253
2254static void smbd_server_connection_read_handler(
2255 struct smbd_server_connection *conn, int fd)
2256{
2257 uint8_t *inbuf = NULL;
2258 size_t inbuf_len = 0;
2259 size_t unread_bytes = 0;
2260 bool encrypted = false;
2261 TALLOC_CTX *mem_ctx = talloc_tos();
2262 NTSTATUS status;
2263 uint32_t seqnum;
2264
2265 bool from_client = (conn->sock == fd);
2266
2267 if (from_client) {
2268 smbd_lock_socket(conn);
2269
2270 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2271 DEBUG(10,("the echo listener was faster\n"));
2272 smbd_unlock_socket(conn);
2273 return;
2274 }
2275
2276 /* TODO: make this completely nonblocking */
2277 status = receive_smb_talloc(mem_ctx, conn, fd,
2278 (char **)(void *)&inbuf,
2279 0, /* timeout */
2280 &unread_bytes,
2281 &encrypted,
2282 &inbuf_len, &seqnum,
2283 false /* trusted channel */);
2284 smbd_unlock_socket(conn);
2285 } else {
2286 /* TODO: make this completely nonblocking */
2287 status = receive_smb_talloc(mem_ctx, conn, fd,
2288 (char **)(void *)&inbuf,
2289 0, /* timeout */
2290 &unread_bytes,
2291 &encrypted,
2292 &inbuf_len, &seqnum,
2293 true /* trusted channel */);
2294 }
2295
2296 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2297 goto process;
2298 }
2299 if (NT_STATUS_IS_ERR(status)) {
2300 exit_server_cleanly("failed to receive smb request");
2301 }
2302 if (!NT_STATUS_IS_OK(status)) {
2303 return;
2304 }
2305
2306process:
2307 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2308 seqnum, encrypted, NULL);
2309}
2310
2311static void smbd_server_connection_handler(struct event_context *ev,
2312 struct fd_event *fde,
2313 uint16_t flags,
2314 void *private_data)
2315{
2316 struct smbd_server_connection *conn = talloc_get_type(private_data,
2317 struct smbd_server_connection);
2318
2319 if (flags & EVENT_FD_WRITE) {
2320 smbd_server_connection_write_handler(conn);
2321 return;
2322 }
2323 if (flags & EVENT_FD_READ) {
2324 smbd_server_connection_read_handler(conn, conn->sock);
2325 return;
2326 }
2327}
2328
2329static void smbd_server_echo_handler(struct event_context *ev,
2330 struct fd_event *fde,
2331 uint16_t flags,
2332 void *private_data)
2333{
2334 struct smbd_server_connection *conn = talloc_get_type(private_data,
2335 struct smbd_server_connection);
2336
2337 if (flags & EVENT_FD_WRITE) {
2338 smbd_server_connection_write_handler(conn);
2339 return;
2340 }
2341 if (flags & EVENT_FD_READ) {
2342 smbd_server_connection_read_handler(
2343 conn, conn->smb1.echo_handler.trusted_fd);
2344 return;
2345 }
2346}
2347
2348/****************************************************************************
2349received when we should release a specific IP
2350****************************************************************************/
2351static void release_ip(const char *ip, void *priv)
2352{
2353 const char *addr = (const char *)priv;
2354 const char *p = addr;
2355
2356 if (strncmp("::ffff:", addr, 7) == 0) {
2357 p = addr + 7;
2358 }
2359
2360 DEBUG(10, ("Got release IP message for %s, "
2361 "our address is %s\n", ip, p));
2362
2363 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2364 /* we can't afford to do a clean exit - that involves
2365 database writes, which would potentially mean we
2366 are still running after the failover has finished -
2367 we have to get rid of this process ID straight
2368 away */
2369 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2370 ip));
2371 /* note we must exit with non-zero status so the unclean handler gets
2372 called in the parent, so that the brl database is tickled */
2373 _exit(1);
2374 }
2375}
2376
2377static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2378 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2379{
2380 struct smbd_server_connection *sconn = talloc_get_type_abort(
2381 private_data, struct smbd_server_connection);
2382
2383 release_ip((char *)data->data, sconn->client_id.addr);
2384}
2385
2386#ifdef CLUSTER_SUPPORT
2387static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2388 struct sockaddr_storage *client)
2389{
2390 socklen_t length;
2391 length = sizeof(*server);
2392 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2393 return -1;
2394 }
2395 length = sizeof(*client);
2396 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2397 return -1;
2398 }
2399 return 0;
2400}
2401#endif
2402
2403/*
2404 * Send keepalive packets to our client
2405 */
2406static bool keepalive_fn(const struct timeval *now, void *private_data)
2407{
2408 struct smbd_server_connection *sconn = smbd_server_conn;
2409 bool ret;
2410
2411 if (sconn->using_smb2) {
2412 /* Don't do keepalives on an SMB2 connection. */
2413 return false;
2414 }
2415
2416 smbd_lock_socket(smbd_server_conn);
2417 ret = send_keepalive(sconn->sock);
2418 smbd_unlock_socket(smbd_server_conn);
2419
2420 if (!ret) {
2421 char addr[INET6_ADDRSTRLEN];
2422 /*
2423 * Try and give an error message saying what
2424 * client failed.
2425 */
2426 DEBUG(0, ("send_keepalive failed for client %s. "
2427 "Error %s - exiting\n",
2428 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2429 strerror(errno)));
2430 return False;
2431 }
2432 return True;
2433}
2434
2435/*
2436 * Do the recurring check if we're idle
2437 */
2438static bool deadtime_fn(const struct timeval *now, void *private_data)
2439{
2440 struct smbd_server_connection *sconn =
2441 (struct smbd_server_connection *)private_data;
2442
2443 if ((conn_num_open(sconn) == 0)
2444 || (conn_idle_all(sconn, now->tv_sec))) {
2445 DEBUG( 2, ( "Closing idle connection\n" ) );
2446 messaging_send(sconn->msg_ctx,
2447 messaging_server_id(sconn->msg_ctx),
2448 MSG_SHUTDOWN, &data_blob_null);
2449 return False;
2450 }
2451
2452 return True;
2453}
2454
2455/*
2456 * Do the recurring log file and smb.conf reload checks.
2457 */
2458
2459static bool housekeeping_fn(const struct timeval *now, void *private_data)
2460{
2461 struct smbd_server_connection *sconn = talloc_get_type_abort(
2462 private_data, struct smbd_server_connection);
2463
2464 DEBUG(5, ("housekeeping\n"));
2465
2466 change_to_root_user();
2467
2468 /* update printer queue caches if necessary */
2469 update_monitored_printq_cache(sconn->msg_ctx);
2470
2471 /* check if we need to reload services */
2472 check_reload(sconn, time_mono(NULL));
2473
2474 /* Change machine password if neccessary. */
2475 attempt_machine_password_change();
2476
2477 /*
2478 * Force a log file check.
2479 */
2480 force_check_log_size();
2481 check_log_size();
2482 return true;
2483}
2484
2485static int create_unlink_tmp(const char *dir)
2486{
2487 char *fname;
2488 int fd;
2489
2490 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2491 if (fname == NULL) {
2492 errno = ENOMEM;
2493 return -1;
2494 }
2495 fd = mkstemp(fname);
2496 if (fd == -1) {
2497 TALLOC_FREE(fname);
2498 return -1;
2499 }
2500 if (unlink(fname) == -1) {
2501 int sys_errno = errno;
2502 close(fd);
2503 TALLOC_FREE(fname);
2504 errno = sys_errno;
2505 return -1;
2506 }
2507 TALLOC_FREE(fname);
2508 return fd;
2509}
2510
2511struct smbd_echo_state {
2512 struct tevent_context *ev;
2513 struct iovec *pending;
2514 struct smbd_server_connection *sconn;
2515 int parent_pipe;
2516
2517 struct tevent_fd *parent_fde;
2518
2519 struct tevent_fd *read_fde;
2520 struct tevent_req *write_req;
2521};
2522
2523static void smbd_echo_writer_done(struct tevent_req *req);
2524
2525static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2526{
2527 int num_pending;
2528
2529 if (state->write_req != NULL) {
2530 return;
2531 }
2532
2533 num_pending = talloc_array_length(state->pending);
2534 if (num_pending == 0) {
2535 return;
2536 }
2537
2538 state->write_req = writev_send(state, state->ev, NULL,
2539 state->parent_pipe, false,
2540 state->pending, num_pending);
2541 if (state->write_req == NULL) {
2542 DEBUG(1, ("writev_send failed\n"));
2543 exit(1);
2544 }
2545
2546 talloc_steal(state->write_req, state->pending);
2547 state->pending = NULL;
2548
2549 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2550 state);
2551}
2552
2553static void smbd_echo_writer_done(struct tevent_req *req)
2554{
2555 struct smbd_echo_state *state = tevent_req_callback_data(
2556 req, struct smbd_echo_state);
2557 ssize_t written;
2558 int err;
2559
2560 written = writev_recv(req, &err);
2561 TALLOC_FREE(req);
2562 state->write_req = NULL;
2563 if (written == -1) {
2564 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2565 exit(1);
2566 }
2567 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2568 smbd_echo_activate_writer(state);
2569}
2570
2571static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2572 uint32_t seqnum)
2573{
2574 struct smb_request req;
2575 uint16_t num_replies;
2576 size_t out_len;
2577 char *outbuf;
2578 bool ok;
2579
2580 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2581 DEBUG(10, ("Got netbios keepalive\n"));
2582 /*
2583 * Just swallow it
2584 */
2585 return true;
2586 }
2587
2588 if (inbuf_len < smb_size) {
2589 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2590 return false;
2591 }
2592 if (!valid_smb_header(inbuf)) {
2593 DEBUG(10, ("Got invalid SMB header\n"));
2594 return false;
2595 }
2596
2597 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2598 seqnum)) {
2599 return false;
2600 }
2601 req.inbuf = inbuf;
2602
2603 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2604 smb_messages[req.cmd].name
2605 ? smb_messages[req.cmd].name : "unknown"));
2606
2607 if (req.cmd != SMBecho) {
2608 return false;
2609 }
2610 if (req.wct < 1) {
2611 return false;
2612 }
2613
2614 num_replies = SVAL(req.vwv+0, 0);
2615 if (num_replies != 1) {
2616 /* Not a Windows "Hey, you're still there?" request */
2617 return false;
2618 }
2619
2620 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2621 1, req.buflen)) {
2622 DEBUG(10, ("create_outbuf failed\n"));
2623 return false;
2624 }
2625 req.outbuf = (uint8_t *)outbuf;
2626
2627 SSVAL(req.outbuf, smb_vwv0, num_replies);
2628
2629 if (req.buflen > 0) {
2630 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2631 }
2632
2633 out_len = smb_len(req.outbuf) + 4;
2634
2635 ok = srv_send_smb(req.sconn,
2636 (char *)outbuf,
2637 true, seqnum+1,
2638 false, &req.pcd);
2639 TALLOC_FREE(outbuf);
2640 if (!ok) {
2641 exit(1);
2642 }
2643
2644 return true;
2645}
2646
2647static void smbd_echo_exit(struct tevent_context *ev,
2648 struct tevent_fd *fde, uint16_t flags,
2649 void *private_data)
2650{
2651 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2652 exit(0);
2653}
2654
2655static void smbd_echo_reader(struct tevent_context *ev,
2656 struct tevent_fd *fde, uint16_t flags,
2657 void *private_data)
2658{
2659 struct smbd_echo_state *state = talloc_get_type_abort(
2660 private_data, struct smbd_echo_state);
2661 struct smbd_server_connection *sconn = state->sconn;
2662 size_t unread, num_pending;
2663 NTSTATUS status;
2664 struct iovec *tmp;
2665 size_t iov_len;
2666 uint32_t seqnum = 0;
2667 bool reply;
2668 bool ok;
2669 bool encrypted = false;
2670
2671 smb_msleep(1000);
2672
2673 ok = smbd_lock_socket_internal(sconn);
2674 if (!ok) {
2675 DEBUG(0, ("%s: failed to lock socket\n",
2676 __location__));
2677 exit(1);
2678 }
2679
2680 if (!fd_is_readable(sconn->sock)) {
2681 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2682 (int)sys_getpid()));
2683 ok = smbd_unlock_socket_internal(sconn);
2684 if (!ok) {
2685 DEBUG(1, ("%s: failed to unlock socket in\n",
2686 __location__));
2687 exit(1);
2688 }
2689 return;
2690 }
2691
2692 num_pending = talloc_array_length(state->pending);
2693 tmp = talloc_realloc(state, state->pending, struct iovec,
2694 num_pending+1);
2695 if (tmp == NULL) {
2696 DEBUG(1, ("talloc_realloc failed\n"));
2697 exit(1);
2698 }
2699 state->pending = tmp;
2700
2701 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2702
2703 status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2704 (char **)(void *)&state->pending[num_pending].iov_base,
2705 0 /* timeout */,
2706 &unread,
2707 &encrypted,
2708 &iov_len,
2709 &seqnum,
2710 false /* trusted_channel*/);
2711 if (!NT_STATUS_IS_OK(status)) {
2712 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2713 (int)sys_getpid(), nt_errstr(status)));
2714 exit(1);
2715 }
2716 state->pending[num_pending].iov_len = iov_len;
2717
2718 ok = smbd_unlock_socket_internal(sconn);
2719 if (!ok) {
2720 DEBUG(1, ("%s: failed to unlock socket in\n",
2721 __location__));
2722 exit(1);
2723 }
2724
2725 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2726 state->pending[num_pending].iov_len,
2727 seqnum);
2728 if (reply) {
2729 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2730 /* no check, shrinking by some bytes does not fail */
2731 state->pending = talloc_realloc(state, state->pending,
2732 struct iovec,
2733 num_pending);
2734 return;
2735 }
2736
2737 if (state->pending[num_pending].iov_len >= smb_size) {
2738 /*
2739 * place the seqnum in the packet so that the main process
2740 * can reply with signing
2741 */
2742 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2743 smb_ss_field, seqnum);
2744 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2745 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2746 }
2747
2748 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2749 smbd_echo_activate_writer(state);
2750}
2751
2752static void smbd_echo_loop(struct smbd_server_connection *sconn,
2753 int parent_pipe)
2754{
2755 struct smbd_echo_state *state;
2756
2757 state = talloc_zero(sconn, struct smbd_echo_state);
2758 if (state == NULL) {
2759 DEBUG(1, ("talloc failed\n"));
2760 return;
2761 }
2762 state->sconn = sconn;
2763 state->parent_pipe = parent_pipe;
2764 state->ev = s3_tevent_context_init(state);
2765 if (state->ev == NULL) {
2766 DEBUG(1, ("tevent_context_init failed\n"));
2767 TALLOC_FREE(state);
2768 return;
2769 }
2770 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2771 TEVENT_FD_READ, smbd_echo_exit,
2772 state);
2773 if (state->parent_fde == NULL) {
2774 DEBUG(1, ("tevent_add_fd failed\n"));
2775 TALLOC_FREE(state);
2776 return;
2777 }
2778 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2779 TEVENT_FD_READ, smbd_echo_reader,
2780 state);
2781 if (state->read_fde == NULL) {
2782 DEBUG(1, ("tevent_add_fd failed\n"));
2783 TALLOC_FREE(state);
2784 return;
2785 }
2786
2787 while (true) {
2788 if (tevent_loop_once(state->ev) == -1) {
2789 DEBUG(1, ("tevent_loop_once failed: %s\n",
2790 strerror(errno)));
2791 break;
2792 }
2793 }
2794 TALLOC_FREE(state);
2795}
2796
2797/*
2798 * Handle SMBecho requests in a forked child process
2799 */
2800static bool fork_echo_handler(struct smbd_server_connection *sconn)
2801{
2802 int listener_pipe[2];
2803 int res;
2804 pid_t child;
2805
2806 res = pipe(listener_pipe);
2807 if (res == -1) {
2808 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2809 return false;
2810 }
2811 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2812 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2813 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2814 goto fail;
2815 }
2816
2817 child = sys_fork();
2818 if (child == 0) {
2819 NTSTATUS status;
2820
2821 close(listener_pipe[0]);
2822 set_blocking(listener_pipe[1], false);
2823
2824 status = reinit_after_fork(sconn->msg_ctx,
2825 smbd_event_context(),
2826 procid_self(), false);
2827 if (!NT_STATUS_IS_OK(status)) {
2828 DEBUG(1, ("reinit_after_fork failed: %s\n",
2829 nt_errstr(status)));
2830 exit(1);
2831 }
2832 smbd_echo_loop(sconn, listener_pipe[1]);
2833 exit(0);
2834 }
2835 close(listener_pipe[1]);
2836 listener_pipe[1] = -1;
2837 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2838
2839 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2840
2841 /*
2842 * Without smb signing this is the same as the normal smbd
2843 * listener. This needs to change once signing comes in.
2844 */
2845 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2846 sconn,
2847 sconn->smb1.echo_handler.trusted_fd,
2848 EVENT_FD_READ,
2849 smbd_server_echo_handler,
2850 sconn);
2851 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2852 DEBUG(1, ("event_add_fd failed\n"));
2853 goto fail;
2854 }
2855
2856 return true;
2857
2858fail:
2859 if (listener_pipe[0] != -1) {
2860 close(listener_pipe[0]);
2861 }
2862 if (listener_pipe[1] != -1) {
2863 close(listener_pipe[1]);
2864 }
2865 sconn->smb1.echo_handler.trusted_fd = -1;
2866 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2867 close(sconn->smb1.echo_handler.socket_lock_fd);
2868 }
2869 sconn->smb1.echo_handler.trusted_fd = -1;
2870 sconn->smb1.echo_handler.socket_lock_fd = -1;
2871 return false;
2872}
2873
2874#if CLUSTER_SUPPORT
2875
2876static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2877 struct sockaddr_storage *srv,
2878 struct sockaddr_storage *clnt)
2879{
2880 struct ctdbd_connection *cconn;
2881 char tmp_addr[INET6_ADDRSTRLEN];
2882 char *addr;
2883
2884 cconn = messaging_ctdbd_connection();
2885 if (cconn == NULL) {
2886 return NT_STATUS_NO_MEMORY;
2887 }
2888
2889 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2890 addr = talloc_strdup(cconn, tmp_addr);
2891 if (addr == NULL) {
2892 return NT_STATUS_NO_MEMORY;
2893 }
2894 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2895}
2896
2897#endif
2898
2899/****************************************************************************
2900 Process commands from the client
2901****************************************************************************/
2902
2903void smbd_process(struct smbd_server_connection *sconn)
2904{
2905 TALLOC_CTX *frame = talloc_stackframe();
2906 struct sockaddr_storage ss;
2907 struct sockaddr *sa = NULL;
2908 socklen_t sa_socklen;
2909 struct tsocket_address *local_address = NULL;
2910 struct tsocket_address *remote_address = NULL;
2911 const char *remaddr = NULL;
2912 int ret;
2913
2914 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2915 !lp_async_smb_echo_handler()) {
2916 /*
2917 * We're not making the decision here,
2918 * we're just allowing the client
2919 * to decide between SMB1 and SMB2
2920 * with the first negprot
2921 * packet.
2922 */
2923 sconn->using_smb2 = true;
2924 }
2925
2926 /* Ensure child is set to blocking mode */
2927 set_blocking(sconn->sock,True);
2928
2929 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2930 set_socket_options(sconn->sock, lp_socket_options());
2931
2932 sa = (struct sockaddr *)(void *)&ss;
2933 sa_socklen = sizeof(ss);
2934 ret = getpeername(sconn->sock, sa, &sa_socklen);
2935 if (ret != 0) {
2936 int level = (errno == ENOTCONN)?2:0;
2937 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2938 exit_server_cleanly("getpeername() failed.\n");
2939 }
2940 ret = tsocket_address_bsd_from_sockaddr(sconn,
2941 sa, sa_socklen,
2942 &remote_address);
2943 if (ret != 0) {
2944 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2945 __location__, strerror(errno)));
2946 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2947 }
2948
2949 sa = (struct sockaddr *)(void *)&ss;
2950 sa_socklen = sizeof(ss);
2951 ret = getsockname(sconn->sock, sa, &sa_socklen);
2952 if (ret != 0) {
2953 int level = (errno == ENOTCONN)?2:0;
2954 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2955 exit_server_cleanly("getsockname() failed.\n");
2956 }
2957 ret = tsocket_address_bsd_from_sockaddr(sconn,
2958 sa, sa_socklen,
2959 &local_address);
2960 if (ret != 0) {
2961 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2962 __location__, strerror(errno)));
2963 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2964 }
2965
2966 sconn->local_address = local_address;
2967 sconn->remote_address = remote_address;
2968
2969 if (tsocket_address_is_inet(remote_address, "ip")) {
2970 remaddr = tsocket_address_inet_addr_string(
2971 sconn->remote_address,
2972 talloc_tos());
2973 if (remaddr == NULL) {
2974
2975 }
2976 } else {
2977 remaddr = "0.0.0.0";
2978 }
2979
2980 /* this is needed so that we get decent entries
2981 in smbstatus for port 445 connects */
2982 set_remote_machine_name(remaddr, false);
2983 reload_services(sconn->msg_ctx, sconn->sock, true);
2984
2985 /*
2986 * Before the first packet, check the global hosts allow/ hosts deny
2987 * parameters before doing any parsing of packets passed to us by the
2988 * client. This prevents attacks on our parsing code from hosts not in
2989 * the hosts allow list.
2990 */
2991
2992 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2993 sconn->client_id.name,
2994 sconn->client_id.addr)) {
2995 /*
2996 * send a negative session response "not listening on calling
2997 * name"
2998 */
2999 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3000 DEBUG( 1, ("Connection denied from %s to %s\n",
3001 tsocket_address_string(remote_address, talloc_tos()),
3002 tsocket_address_string(local_address, talloc_tos())));
3003 (void)srv_send_smb(sconn,(char *)buf, false,
3004 0, false, NULL);
3005 exit_server_cleanly("connection denied");
3006 }
3007
3008 DEBUG(10, ("Connection allowed from %s to %s\n",
3009 tsocket_address_string(remote_address, talloc_tos()),
3010 tsocket_address_string(local_address, talloc_tos())));
3011
3012 init_modules();
3013
3014 smb_perfcount_init();
3015
3016 if (!init_account_policy()) {
3017 exit_server("Could not open account policy tdb.\n");
3018 }
3019
3020 if (*lp_rootdir()) {
3021 if (chroot(lp_rootdir()) != 0) {
3022 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3023 exit_server("Failed to chroot()");
3024 }
3025 if (chdir("/") == -1) {
3026 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3027 exit_server("Failed to chroot()");
3028 }
3029 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3030 }
3031
3032 if (!srv_init_signing(sconn)) {
3033 exit_server("Failed to init smb_signing");
3034 }
3035
3036 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3037 exit_server("Failed to fork echo handler");
3038 }
3039
3040 /* Setup oplocks */
3041 if (!init_oplocks(sconn->msg_ctx))
3042 exit_server("Failed to init oplocks");
3043
3044 /* register our message handlers */
3045 messaging_register(sconn->msg_ctx, NULL,
3046 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3047 messaging_register(sconn->msg_ctx, sconn,
3048 MSG_SMB_RELEASE_IP, msg_release_ip);
3049 messaging_register(sconn->msg_ctx, NULL,
3050 MSG_SMB_CLOSE_FILE, msg_close_file);
3051
3052 /*
3053 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3054 * MSGs to all child processes
3055 */
3056 messaging_deregister(sconn->msg_ctx,
3057 MSG_DEBUG, NULL);
3058 messaging_register(sconn->msg_ctx, NULL,
3059 MSG_DEBUG, debug_message);
3060
3061 if ((lp_keepalive() != 0)
3062 && !(event_add_idle(smbd_event_context(), NULL,
3063 timeval_set(lp_keepalive(), 0),
3064 "keepalive", keepalive_fn,
3065 NULL))) {
3066 DEBUG(0, ("Could not add keepalive event\n"));
3067 exit(1);
3068 }
3069
3070 if (!(event_add_idle(smbd_event_context(), NULL,
3071 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3072 "deadtime", deadtime_fn, sconn))) {
3073 DEBUG(0, ("Could not add deadtime event\n"));
3074 exit(1);
3075 }
3076
3077 if (!(event_add_idle(smbd_event_context(), NULL,
3078 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3079 "housekeeping", housekeeping_fn, sconn))) {
3080 DEBUG(0, ("Could not add housekeeping event\n"));
3081 exit(1);
3082 }
3083
3084#ifdef CLUSTER_SUPPORT
3085
3086 if (lp_clustering()) {
3087 /*
3088 * We need to tell ctdb about our client's TCP
3089 * connection, so that for failover ctdbd can send
3090 * tickle acks, triggering a reconnection by the
3091 * client.
3092 */
3093
3094 struct sockaddr_storage srv, clnt;
3095
3096 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3097 NTSTATUS status;
3098 status = smbd_register_ips(sconn, &srv, &clnt);
3099 if (!NT_STATUS_IS_OK(status)) {
3100 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3101 nt_errstr(status)));
3102 }
3103 } else
3104 {
3105 DEBUG(0,("Unable to get tcp info for "
3106 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3107 strerror(errno)));
3108 }
3109 }
3110
3111#endif
3112
3113 sconn->nbt.got_session = false;
3114
3115 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3116
3117 sconn->smb1.sessions.done_sesssetup = false;
3118 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3119 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3120 /* users from session setup */
3121 sconn->smb1.sessions.session_userlist = NULL;
3122 /* workgroup from session setup. */
3123 sconn->smb1.sessions.session_workgroup = NULL;
3124 /* this holds info on user ids that are already validated for this VC */
3125 sconn->smb1.sessions.validated_users = NULL;
3126 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3127 sconn->smb1.sessions.num_validated_vuids = 0;
3128
3129 conn_init(sconn);
3130 if (!init_dptrs(sconn)) {
3131 exit_server("init_dptrs() failed");
3132 }
3133
3134 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3135 sconn,
3136 sconn->sock,
3137 EVENT_FD_READ,
3138 smbd_server_connection_handler,
3139 sconn);
3140 if (!sconn->smb1.fde) {
3141 exit_server("failed to create smbd_server_connection fde");
3142 }
3143
3144 TALLOC_FREE(frame);
3145
3146 while (True) {
3147 NTSTATUS status;
3148
3149 frame = talloc_stackframe_pool(8192);
3150
3151 errno = 0;
3152
3153 status = smbd_server_connection_loop_once(sconn);
3154 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3155 !NT_STATUS_IS_OK(status)) {
3156 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3157 " exiting\n", nt_errstr(status)));
3158 break;
3159 }
3160
3161 TALLOC_FREE(frame);
3162 }
3163
3164 exit_server_cleanly(NULL);
3165}
3166
3167bool req_is_in_chain(struct smb_request *req)
3168{
3169 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3170 /*
3171 * We're right now handling a subsequent request, so we must
3172 * be in a chain
3173 */
3174 return true;
3175 }
3176
3177 if (!is_andx_req(req->cmd)) {
3178 return false;
3179 }
3180
3181 if (req->wct < 2) {
3182 /*
3183 * Okay, an illegal request, but definitely not chained :-)
3184 */
3185 return false;
3186 }
3187
3188 return (CVAL(req->vwv+0, 0) != 0xFF);
3189}
Note: See TracBrowser for help on using the repository browser.