s3: Avoid a race with the async echo handler
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
blob82dd51048e4bf02a9e5d48edb2e57124c96cd595
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
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.
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.
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/>.
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/queue_process.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 #include "../lib/util/tevent_ntstatus.h"
40 extern bool global_machine_password_needs_changing;
42 static void construct_reply_common(struct smb_request *req, const char *inbuf,
43 char *outbuf);
44 static struct pending_message_list *get_deferred_open_message_smb(
45 struct smbd_server_connection *sconn, uint64_t mid);
47 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
49 bool ok;
51 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
52 return true;
55 sconn->smb1.echo_handler.ref_count++;
57 if (sconn->smb1.echo_handler.ref_count > 1) {
58 return true;
61 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
63 do {
64 ok = fcntl_lock(
65 sconn->smb1.echo_handler.socket_lock_fd,
66 SMB_F_SETLKW, 0, 0, F_WRLCK);
67 } while (!ok && (errno == EINTR));
69 if (!ok) {
70 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
71 return false;
74 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
76 return true;
79 void smbd_lock_socket(struct smbd_server_connection *sconn)
81 if (!smbd_lock_socket_internal(sconn)) {
82 exit_server_cleanly("failed to lock socket");
86 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
88 bool ok;
90 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
91 return true;
94 sconn->smb1.echo_handler.ref_count--;
96 if (sconn->smb1.echo_handler.ref_count > 0) {
97 return true;
100 do {
101 ok = fcntl_lock(
102 sconn->smb1.echo_handler.socket_lock_fd,
103 SMB_F_SETLKW, 0, 0, F_UNLCK);
104 } while (!ok && (errno == EINTR));
106 if (!ok) {
107 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
108 return false;
111 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
113 return true;
116 void smbd_unlock_socket(struct smbd_server_connection *sconn)
118 if (!smbd_unlock_socket_internal(sconn)) {
119 exit_server_cleanly("failed to unlock socket");
123 /* Accessor function for smb_read_error for smbd functions. */
125 /****************************************************************************
126 Send an smb to a fd.
127 ****************************************************************************/
129 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
130 bool do_signing, uint32_t seqnum,
131 bool do_encrypt,
132 struct smb_perfcount_data *pcd)
134 size_t len = 0;
135 size_t nwritten=0;
136 ssize_t ret;
137 char *buf_out = buffer;
139 smbd_lock_socket(sconn);
141 if (do_signing) {
142 /* Sign the outgoing packet if required. */
143 srv_calculate_sign_mac(sconn, buf_out, seqnum);
146 if (do_encrypt) {
147 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
148 if (!NT_STATUS_IS_OK(status)) {
149 DEBUG(0, ("send_smb: SMB encryption failed "
150 "on outgoing packet! Error %s\n",
151 nt_errstr(status) ));
152 goto out;
156 len = smb_len(buf_out) + 4;
158 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
159 if (ret <= 0) {
161 char addr[INET6_ADDRSTRLEN];
163 * Try and give an error message saying what
164 * client failed.
166 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
167 (int)sys_getpid(), (int)len,
168 get_peer_addr(sconn->sock, addr, sizeof(addr)),
169 (int)ret, strerror(errno) ));
171 srv_free_enc_buffer(sconn, buf_out);
172 goto out;
175 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
176 srv_free_enc_buffer(sconn, buf_out);
177 out:
178 SMB_PERFCOUNT_END(pcd);
180 smbd_unlock_socket(sconn);
181 return true;
184 /*******************************************************************
185 Setup the word count and byte count for a smb message.
186 ********************************************************************/
188 int srv_set_message(char *buf,
189 int num_words,
190 int num_bytes,
191 bool zero)
193 if (zero && (num_words || num_bytes)) {
194 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
196 SCVAL(buf,smb_wct,num_words);
197 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
198 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
199 return (smb_size + num_words*2 + num_bytes);
202 static bool valid_smb_header(struct smbd_server_connection *sconn,
203 const uint8_t *inbuf)
205 if (is_encrypted_packet(sconn, inbuf)) {
206 return true;
209 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
210 * but it just looks weird to call strncmp for this one.
212 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
215 /* Socket functions for smbd packet processing. */
217 static bool valid_packet_size(size_t len)
220 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
221 * of header. Don't print the error if this fits.... JRA.
224 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
225 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
226 (unsigned long)len));
227 return false;
229 return true;
232 static NTSTATUS read_packet_remainder(int fd, char *buffer,
233 unsigned int timeout, ssize_t len)
235 NTSTATUS status;
237 if (len <= 0) {
238 return NT_STATUS_OK;
241 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
242 if (!NT_STATUS_IS_OK(status)) {
243 char addr[INET6_ADDRSTRLEN];
244 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
245 "error = %s.\n",
246 get_peer_addr(fd, addr, sizeof(addr)),
247 nt_errstr(status)));
249 return status;
252 /****************************************************************************
253 Attempt a zerocopy writeX read. We know here that len > smb_size-4
254 ****************************************************************************/
257 * Unfortunately, earlier versions of smbclient/libsmbclient
258 * don't send this "standard" writeX header. I've fixed this
259 * for 3.2 but we'll use the old method with earlier versions.
260 * Windows and CIFSFS at least use this standard size. Not
261 * sure about MacOSX.
264 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
265 (2*14) + /* word count (including bcc) */ \
266 1 /* pad byte */)
268 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
269 const char lenbuf[4],
270 struct smbd_server_connection *sconn,
271 int sock,
272 char **buffer,
273 unsigned int timeout,
274 size_t *p_unread,
275 size_t *len_ret)
277 /* Size of a WRITEX call (+4 byte len). */
278 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
279 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
280 ssize_t toread;
281 NTSTATUS status;
283 memcpy(writeX_header, lenbuf, 4);
285 status = read_fd_with_timeout(
286 sock, writeX_header + 4,
287 STANDARD_WRITE_AND_X_HEADER_SIZE,
288 STANDARD_WRITE_AND_X_HEADER_SIZE,
289 timeout, NULL);
291 if (!NT_STATUS_IS_OK(status)) {
292 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
293 "error = %s.\n",
294 tsocket_address_string(sconn->remote_address,
295 talloc_tos()),
296 nt_errstr(status)));
297 return status;
301 * Ok - now try and see if this is a possible
302 * valid writeX call.
305 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
307 * If the data offset is beyond what
308 * we've read, drain the extra bytes.
310 uint16_t doff = SVAL(writeX_header,smb_vwv11);
311 ssize_t newlen;
313 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
314 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
315 if (drain_socket(sock, drain) != drain) {
316 smb_panic("receive_smb_raw_talloc_partial_read:"
317 " failed to drain pending bytes");
319 } else {
320 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
323 /* Spoof down the length and null out the bcc. */
324 set_message_bcc(writeX_header, 0);
325 newlen = smb_len(writeX_header);
327 /* Copy the header we've written. */
329 *buffer = (char *)talloc_memdup(mem_ctx,
330 writeX_header,
331 sizeof(writeX_header));
333 if (*buffer == NULL) {
334 DEBUG(0, ("Could not allocate inbuf of length %d\n",
335 (int)sizeof(writeX_header)));
336 return NT_STATUS_NO_MEMORY;
339 /* Work out the remaining bytes. */
340 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
341 *len_ret = newlen + 4;
342 return NT_STATUS_OK;
345 if (!valid_packet_size(len)) {
346 return NT_STATUS_INVALID_PARAMETER;
350 * Not a valid writeX call. Just do the standard
351 * talloc and return.
354 *buffer = talloc_array(mem_ctx, char, len+4);
356 if (*buffer == NULL) {
357 DEBUG(0, ("Could not allocate inbuf of length %d\n",
358 (int)len+4));
359 return NT_STATUS_NO_MEMORY;
362 /* Copy in what we already read. */
363 memcpy(*buffer,
364 writeX_header,
365 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
366 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
368 if(toread > 0) {
369 status = read_packet_remainder(
370 sock,
371 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
372 timeout, toread);
374 if (!NT_STATUS_IS_OK(status)) {
375 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
376 nt_errstr(status)));
377 return status;
381 *len_ret = len + 4;
382 return NT_STATUS_OK;
385 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
386 struct smbd_server_connection *sconn,
387 int sock,
388 char **buffer, unsigned int timeout,
389 size_t *p_unread, size_t *plen)
391 char lenbuf[4];
392 size_t len;
393 int min_recv_size = lp_min_receive_file_size();
394 NTSTATUS status;
396 *p_unread = 0;
398 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
399 &len);
400 if (!NT_STATUS_IS_OK(status)) {
401 return status;
404 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
405 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
406 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
407 !srv_is_signing_active(sconn) &&
408 sconn->smb1.echo_handler.trusted_fde == NULL) {
410 return receive_smb_raw_talloc_partial_read(
411 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
412 p_unread, plen);
415 if (!valid_packet_size(len)) {
416 return NT_STATUS_INVALID_PARAMETER;
420 * The +4 here can't wrap, we've checked the length above already.
423 *buffer = talloc_array(mem_ctx, char, len+4);
425 if (*buffer == NULL) {
426 DEBUG(0, ("Could not allocate inbuf of length %d\n",
427 (int)len+4));
428 return NT_STATUS_NO_MEMORY;
431 memcpy(*buffer, lenbuf, sizeof(lenbuf));
433 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
434 if (!NT_STATUS_IS_OK(status)) {
435 return status;
438 *plen = len + 4;
439 return NT_STATUS_OK;
442 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
443 struct smbd_server_connection *sconn,
444 int sock,
445 char **buffer, unsigned int timeout,
446 size_t *p_unread, bool *p_encrypted,
447 size_t *p_len,
448 uint32_t *seqnum,
449 bool trusted_channel)
451 size_t len = 0;
452 NTSTATUS status;
454 *p_encrypted = false;
456 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
457 p_unread, &len);
458 if (!NT_STATUS_IS_OK(status)) {
459 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
460 ("receive_smb_raw_talloc failed for client %s "
461 "read error = %s.\n",
462 tsocket_address_string(sconn->remote_address,
463 talloc_tos()),
464 nt_errstr(status)) );
465 return status;
468 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
469 status = srv_decrypt_buffer(sconn, *buffer);
470 if (!NT_STATUS_IS_OK(status)) {
471 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
472 "incoming packet! Error %s\n",
473 nt_errstr(status) ));
474 return status;
476 *p_encrypted = true;
479 /* Check the incoming SMB signature. */
480 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
481 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
482 "incoming packet!\n"));
483 return NT_STATUS_INVALID_NETWORK_RESPONSE;
486 *p_len = len;
487 return NT_STATUS_OK;
491 * Initialize a struct smb_request from an inbuf
494 static bool init_smb_request(struct smb_request *req,
495 struct smbd_server_connection *sconn,
496 const uint8 *inbuf,
497 size_t unread_bytes, bool encrypted,
498 uint32_t seqnum)
500 size_t req_size = smb_len(inbuf) + 4;
501 /* Ensure we have at least smb_size bytes. */
502 if (req_size < smb_size) {
503 DEBUG(0,("init_smb_request: invalid request size %u\n",
504 (unsigned int)req_size ));
505 return false;
507 req->cmd = CVAL(inbuf, smb_com);
508 req->flags2 = SVAL(inbuf, smb_flg2);
509 req->smbpid = SVAL(inbuf, smb_pid);
510 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
511 req->seqnum = seqnum;
512 req->vuid = SVAL(inbuf, smb_uid);
513 req->tid = SVAL(inbuf, smb_tid);
514 req->wct = CVAL(inbuf, smb_wct);
515 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
516 req->buflen = smb_buflen(inbuf);
517 req->buf = (const uint8_t *)smb_buf_const(inbuf);
518 req->unread_bytes = unread_bytes;
519 req->encrypted = encrypted;
520 req->sconn = sconn;
521 req->conn = conn_find(sconn,req->tid);
522 req->chain_fsp = NULL;
523 req->chain_outbuf = NULL;
524 req->done = false;
525 req->smb2req = NULL;
526 smb_init_perfcount_data(&req->pcd);
528 /* Ensure we have at least wct words and 2 bytes of bcc. */
529 if (smb_size + req->wct*2 > req_size) {
530 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
531 (unsigned int)req->wct,
532 (unsigned int)req_size));
533 return false;
535 /* Ensure bcc is correct. */
536 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
537 DEBUG(0,("init_smb_request: invalid bcc number %u "
538 "(wct = %u, size %u)\n",
539 (unsigned int)req->buflen,
540 (unsigned int)req->wct,
541 (unsigned int)req_size));
542 return false;
545 req->outbuf = NULL;
546 return true;
549 static void process_smb(struct smbd_server_connection *conn,
550 uint8_t *inbuf, size_t nread, size_t unread_bytes,
551 uint32_t seqnum, bool encrypted,
552 struct smb_perfcount_data *deferred_pcd);
554 static void smbd_deferred_open_timer(struct event_context *ev,
555 struct timed_event *te,
556 struct timeval _tval,
557 void *private_data)
559 struct pending_message_list *msg = talloc_get_type(private_data,
560 struct pending_message_list);
561 TALLOC_CTX *mem_ctx = talloc_tos();
562 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
563 uint8_t *inbuf;
565 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
566 msg->buf.length);
567 if (inbuf == NULL) {
568 exit_server("smbd_deferred_open_timer: talloc failed\n");
569 return;
572 /* We leave this message on the queue so the open code can
573 know this is a retry. */
574 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
575 (unsigned long long)mid ));
577 /* Mark the message as processed so this is not
578 * re-processed in error. */
579 msg->processed = true;
581 process_smb(smbd_server_conn, inbuf,
582 msg->buf.length, 0,
583 msg->seqnum, msg->encrypted, &msg->pcd);
585 /* If it's still there and was processed, remove it. */
586 msg = get_deferred_open_message_smb(smbd_server_conn, mid);
587 if (msg && msg->processed) {
588 remove_deferred_open_message_smb(smbd_server_conn, mid);
592 /****************************************************************************
593 Function to push a message onto the tail of a linked list of smb messages ready
594 for processing.
595 ****************************************************************************/
597 static bool push_queued_message(struct smb_request *req,
598 struct timeval request_time,
599 struct timeval end_time,
600 char *private_data, size_t private_len)
602 int msg_len = smb_len(req->inbuf) + 4;
603 struct pending_message_list *msg;
605 msg = talloc_zero(NULL, struct pending_message_list);
607 if(msg == NULL) {
608 DEBUG(0,("push_message: malloc fail (1)\n"));
609 return False;
612 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
613 if(msg->buf.data == NULL) {
614 DEBUG(0,("push_message: malloc fail (2)\n"));
615 TALLOC_FREE(msg);
616 return False;
619 msg->request_time = request_time;
620 msg->seqnum = req->seqnum;
621 msg->encrypted = req->encrypted;
622 msg->processed = false;
623 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
625 if (private_data) {
626 msg->private_data = data_blob_talloc(msg, private_data,
627 private_len);
628 if (msg->private_data.data == NULL) {
629 DEBUG(0,("push_message: malloc fail (3)\n"));
630 TALLOC_FREE(msg);
631 return False;
635 msg->te = event_add_timed(server_event_context(),
636 msg,
637 end_time,
638 smbd_deferred_open_timer,
639 msg);
640 if (!msg->te) {
641 DEBUG(0,("push_message: event_add_timed failed\n"));
642 TALLOC_FREE(msg);
643 return false;
646 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
647 struct pending_message_list *);
649 DEBUG(10,("push_message: pushed message length %u on "
650 "deferred_open_queue\n", (unsigned int)msg_len));
652 return True;
655 /****************************************************************************
656 Function to delete a sharing violation open message by mid.
657 ****************************************************************************/
659 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
660 uint64_t mid)
662 struct pending_message_list *pml;
664 if (sconn->using_smb2) {
665 remove_deferred_open_message_smb2(sconn, mid);
666 return;
669 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
670 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
671 DEBUG(10,("remove_deferred_open_message_smb: "
672 "deleting mid %llu len %u\n",
673 (unsigned long long)mid,
674 (unsigned int)pml->buf.length ));
675 DLIST_REMOVE(sconn->deferred_open_queue, pml);
676 TALLOC_FREE(pml);
677 return;
682 /****************************************************************************
683 Move a sharing violation open retry message to the front of the list and
684 schedule it for immediate processing.
685 ****************************************************************************/
687 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
688 uint64_t mid)
690 struct pending_message_list *pml;
691 int i = 0;
693 if (sconn->using_smb2) {
694 schedule_deferred_open_message_smb2(sconn, mid);
695 return;
698 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
699 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
701 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
702 "msg_mid = %llu\n",
703 i++,
704 (unsigned long long)msg_mid ));
706 if (mid == msg_mid) {
707 struct timed_event *te;
709 if (pml->processed) {
710 /* A processed message should not be
711 * rescheduled. */
712 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
713 "message mid %llu was already processed\n",
714 (unsigned long long)msg_mid ));
715 continue;
718 DEBUG(10,("schedule_deferred_open_message_smb: "
719 "scheduling mid %llu\n",
720 (unsigned long long)mid ));
722 te = event_add_timed(server_event_context(),
723 pml,
724 timeval_zero(),
725 smbd_deferred_open_timer,
726 pml);
727 if (!te) {
728 DEBUG(10,("schedule_deferred_open_message_smb: "
729 "event_add_timed() failed, "
730 "skipping mid %llu\n",
731 (unsigned long long)msg_mid ));
734 TALLOC_FREE(pml->te);
735 pml->te = te;
736 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
737 return;
741 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
742 "find message mid %llu\n",
743 (unsigned long long)mid ));
746 /****************************************************************************
747 Return true if this mid is on the deferred queue and was not yet processed.
748 ****************************************************************************/
750 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
752 struct pending_message_list *pml;
754 if (sconn->using_smb2) {
755 return open_was_deferred_smb2(sconn, mid);
758 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
759 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
760 return True;
763 return False;
766 /****************************************************************************
767 Return the message queued by this mid.
768 ****************************************************************************/
770 static struct pending_message_list *get_deferred_open_message_smb(
771 struct smbd_server_connection *sconn, uint64_t mid)
773 struct pending_message_list *pml;
775 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
776 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
777 return pml;
780 return NULL;
783 /****************************************************************************
784 Get the state data queued by this mid.
785 ****************************************************************************/
787 bool get_deferred_open_message_state(struct smb_request *smbreq,
788 struct timeval *p_request_time,
789 void **pp_state)
791 struct pending_message_list *pml;
793 if (smbd_server_conn->using_smb2) {
794 return get_deferred_open_message_state_smb2(smbreq->smb2req,
795 p_request_time,
796 pp_state);
799 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
800 if (!pml) {
801 return false;
803 if (p_request_time) {
804 *p_request_time = pml->request_time;
806 if (pp_state) {
807 *pp_state = (void *)pml->private_data.data;
809 return true;
812 /****************************************************************************
813 Function to push a deferred open smb message onto a linked list of local smb
814 messages ready for processing.
815 ****************************************************************************/
817 bool push_deferred_open_message_smb(struct smb_request *req,
818 struct timeval request_time,
819 struct timeval timeout,
820 struct file_id id,
821 char *private_data, size_t priv_len)
823 struct timeval end_time;
825 if (req->smb2req) {
826 return push_deferred_open_message_smb2(req->smb2req,
827 request_time,
828 timeout,
830 private_data,
831 priv_len);
834 if (req->unread_bytes) {
835 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
836 "unread_bytes = %u\n",
837 (unsigned int)req->unread_bytes ));
838 smb_panic("push_deferred_open_message_smb: "
839 "logic error unread_bytes != 0" );
842 end_time = timeval_sum(&request_time, &timeout);
844 DEBUG(10,("push_deferred_open_message_smb: pushing message "
845 "len %u mid %llu timeout time [%u.%06u]\n",
846 (unsigned int) smb_len(req->inbuf)+4,
847 (unsigned long long)req->mid,
848 (unsigned int)end_time.tv_sec,
849 (unsigned int)end_time.tv_usec));
851 return push_queued_message(req, request_time, end_time,
852 private_data, priv_len);
855 static void smbd_sig_term_handler(struct tevent_context *ev,
856 struct tevent_signal *se,
857 int signum,
858 int count,
859 void *siginfo,
860 void *private_data)
862 exit_server_cleanly("termination signal");
865 void smbd_setup_sig_term_handler(void)
867 struct tevent_signal *se;
869 se = tevent_add_signal(server_event_context(),
870 server_event_context(),
871 SIGTERM, 0,
872 smbd_sig_term_handler,
873 NULL);
874 if (!se) {
875 exit_server("failed to setup SIGTERM handler");
879 static void smbd_sig_hup_handler(struct tevent_context *ev,
880 struct tevent_signal *se,
881 int signum,
882 int count,
883 void *siginfo,
884 void *private_data)
886 struct messaging_context *msg_ctx = talloc_get_type_abort(
887 private_data, struct messaging_context);
888 change_to_root_user();
889 DEBUG(1,("Reloading services after SIGHUP\n"));
890 reload_services(msg_ctx, smbd_server_conn->sock, False);
891 if (am_parent) {
892 printing_subsystem_update(ev, msg_ctx, true);
896 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
897 struct messaging_context *msg_ctx)
899 struct tevent_signal *se;
901 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
902 msg_ctx);
903 if (!se) {
904 exit_server("failed to setup SIGHUP handler");
908 static NTSTATUS smbd_server_connection_loop_once(struct tevent_context *ev_ctx,
909 struct smbd_server_connection *conn)
911 int timeout;
912 int num_pfds = 0;
913 int ret;
914 bool retry;
916 timeout = SMBD_SELECT_TIMEOUT * 1000;
919 * Are there any timed events waiting ? If so, ensure we don't
920 * select for longer than it would take to wait for them.
923 event_add_to_poll_args(ev_ctx, conn, &conn->pfds, &num_pfds, &timeout);
925 /* Process a signal and timed events now... */
926 if (run_events_poll(ev_ctx, 0, NULL, 0)) {
927 return NT_STATUS_RETRY;
931 int sav;
932 START_PROFILE(smbd_idle);
934 ret = sys_poll(conn->pfds, num_pfds, timeout);
935 sav = errno;
937 END_PROFILE(smbd_idle);
938 errno = sav;
941 if (ret == -1) {
942 if (errno == EINTR) {
943 return NT_STATUS_RETRY;
945 return map_nt_error_from_unix(errno);
948 retry = run_events_poll(ev_ctx, ret, conn->pfds, num_pfds);
949 if (retry) {
950 return NT_STATUS_RETRY;
953 /* Did we timeout ? */
954 if (ret == 0) {
955 return NT_STATUS_RETRY;
958 /* should not be reached */
959 return NT_STATUS_INTERNAL_ERROR;
963 * Only allow 5 outstanding trans requests. We're allocating memory, so
964 * prevent a DoS.
967 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
969 int count = 0;
970 for (; list != NULL; list = list->next) {
972 if (list->mid == mid) {
973 return NT_STATUS_INVALID_PARAMETER;
976 count += 1;
978 if (count > 5) {
979 return NT_STATUS_INSUFFICIENT_RESOURCES;
982 return NT_STATUS_OK;
986 These flags determine some of the permissions required to do an operation
988 Note that I don't set NEED_WRITE on some write operations because they
989 are used by some brain-dead clients when printing, and I don't want to
990 force write permissions on print services.
992 #define AS_USER (1<<0)
993 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
994 #define TIME_INIT (1<<2)
995 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
996 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
997 #define DO_CHDIR (1<<6)
1000 define a list of possible SMB messages and their corresponding
1001 functions. Any message that has a NULL function is unimplemented -
1002 please feel free to contribute implementations!
1004 static const struct smb_message_struct {
1005 const char *name;
1006 void (*fn)(struct smb_request *req);
1007 int flags;
1008 } smb_messages[256] = {
1010 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1011 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1012 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1013 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1014 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1015 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1016 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1017 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1018 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1019 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1020 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1021 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1022 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1023 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1024 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1025 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1026 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1027 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1028 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1029 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1030 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1031 /* 0x15 */ { NULL, NULL, 0 },
1032 /* 0x16 */ { NULL, NULL, 0 },
1033 /* 0x17 */ { NULL, NULL, 0 },
1034 /* 0x18 */ { NULL, NULL, 0 },
1035 /* 0x19 */ { NULL, NULL, 0 },
1036 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1037 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1038 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1039 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1040 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1041 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1042 /* 0x20 */ { "SMBwritec", NULL,0},
1043 /* 0x21 */ { NULL, NULL, 0 },
1044 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1045 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1046 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1047 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1048 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1049 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1050 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1051 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1052 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1053 /* 0x2b */ { "SMBecho",reply_echo,0},
1054 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1055 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1056 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1057 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1058 /* 0x30 */ { NULL, NULL, 0 },
1059 /* 0x31 */ { NULL, NULL, 0 },
1060 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1061 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1062 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1063 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1064 /* 0x36 */ { NULL, NULL, 0 },
1065 /* 0x37 */ { NULL, NULL, 0 },
1066 /* 0x38 */ { NULL, NULL, 0 },
1067 /* 0x39 */ { NULL, NULL, 0 },
1068 /* 0x3a */ { NULL, NULL, 0 },
1069 /* 0x3b */ { NULL, NULL, 0 },
1070 /* 0x3c */ { NULL, NULL, 0 },
1071 /* 0x3d */ { NULL, NULL, 0 },
1072 /* 0x3e */ { NULL, NULL, 0 },
1073 /* 0x3f */ { NULL, NULL, 0 },
1074 /* 0x40 */ { NULL, NULL, 0 },
1075 /* 0x41 */ { NULL, NULL, 0 },
1076 /* 0x42 */ { NULL, NULL, 0 },
1077 /* 0x43 */ { NULL, NULL, 0 },
1078 /* 0x44 */ { NULL, NULL, 0 },
1079 /* 0x45 */ { NULL, NULL, 0 },
1080 /* 0x46 */ { NULL, NULL, 0 },
1081 /* 0x47 */ { NULL, NULL, 0 },
1082 /* 0x48 */ { NULL, NULL, 0 },
1083 /* 0x49 */ { NULL, NULL, 0 },
1084 /* 0x4a */ { NULL, NULL, 0 },
1085 /* 0x4b */ { NULL, NULL, 0 },
1086 /* 0x4c */ { NULL, NULL, 0 },
1087 /* 0x4d */ { NULL, NULL, 0 },
1088 /* 0x4e */ { NULL, NULL, 0 },
1089 /* 0x4f */ { NULL, NULL, 0 },
1090 /* 0x50 */ { NULL, NULL, 0 },
1091 /* 0x51 */ { NULL, NULL, 0 },
1092 /* 0x52 */ { NULL, NULL, 0 },
1093 /* 0x53 */ { NULL, NULL, 0 },
1094 /* 0x54 */ { NULL, NULL, 0 },
1095 /* 0x55 */ { NULL, NULL, 0 },
1096 /* 0x56 */ { NULL, NULL, 0 },
1097 /* 0x57 */ { NULL, NULL, 0 },
1098 /* 0x58 */ { NULL, NULL, 0 },
1099 /* 0x59 */ { NULL, NULL, 0 },
1100 /* 0x5a */ { NULL, NULL, 0 },
1101 /* 0x5b */ { NULL, NULL, 0 },
1102 /* 0x5c */ { NULL, NULL, 0 },
1103 /* 0x5d */ { NULL, NULL, 0 },
1104 /* 0x5e */ { NULL, NULL, 0 },
1105 /* 0x5f */ { NULL, NULL, 0 },
1106 /* 0x60 */ { NULL, NULL, 0 },
1107 /* 0x61 */ { NULL, NULL, 0 },
1108 /* 0x62 */ { NULL, NULL, 0 },
1109 /* 0x63 */ { NULL, NULL, 0 },
1110 /* 0x64 */ { NULL, NULL, 0 },
1111 /* 0x65 */ { NULL, NULL, 0 },
1112 /* 0x66 */ { NULL, NULL, 0 },
1113 /* 0x67 */ { NULL, NULL, 0 },
1114 /* 0x68 */ { NULL, NULL, 0 },
1115 /* 0x69 */ { NULL, NULL, 0 },
1116 /* 0x6a */ { NULL, NULL, 0 },
1117 /* 0x6b */ { NULL, NULL, 0 },
1118 /* 0x6c */ { NULL, NULL, 0 },
1119 /* 0x6d */ { NULL, NULL, 0 },
1120 /* 0x6e */ { NULL, NULL, 0 },
1121 /* 0x6f */ { NULL, NULL, 0 },
1122 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1123 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1124 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1125 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1126 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1127 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1128 /* 0x76 */ { NULL, NULL, 0 },
1129 /* 0x77 */ { NULL, NULL, 0 },
1130 /* 0x78 */ { NULL, NULL, 0 },
1131 /* 0x79 */ { NULL, NULL, 0 },
1132 /* 0x7a */ { NULL, NULL, 0 },
1133 /* 0x7b */ { NULL, NULL, 0 },
1134 /* 0x7c */ { NULL, NULL, 0 },
1135 /* 0x7d */ { NULL, NULL, 0 },
1136 /* 0x7e */ { NULL, NULL, 0 },
1137 /* 0x7f */ { NULL, NULL, 0 },
1138 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1139 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1140 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1141 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1142 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1143 /* 0x85 */ { NULL, NULL, 0 },
1144 /* 0x86 */ { NULL, NULL, 0 },
1145 /* 0x87 */ { NULL, NULL, 0 },
1146 /* 0x88 */ { NULL, NULL, 0 },
1147 /* 0x89 */ { NULL, NULL, 0 },
1148 /* 0x8a */ { NULL, NULL, 0 },
1149 /* 0x8b */ { NULL, NULL, 0 },
1150 /* 0x8c */ { NULL, NULL, 0 },
1151 /* 0x8d */ { NULL, NULL, 0 },
1152 /* 0x8e */ { NULL, NULL, 0 },
1153 /* 0x8f */ { NULL, NULL, 0 },
1154 /* 0x90 */ { NULL, NULL, 0 },
1155 /* 0x91 */ { NULL, NULL, 0 },
1156 /* 0x92 */ { NULL, NULL, 0 },
1157 /* 0x93 */ { NULL, NULL, 0 },
1158 /* 0x94 */ { NULL, NULL, 0 },
1159 /* 0x95 */ { NULL, NULL, 0 },
1160 /* 0x96 */ { NULL, NULL, 0 },
1161 /* 0x97 */ { NULL, NULL, 0 },
1162 /* 0x98 */ { NULL, NULL, 0 },
1163 /* 0x99 */ { NULL, NULL, 0 },
1164 /* 0x9a */ { NULL, NULL, 0 },
1165 /* 0x9b */ { NULL, NULL, 0 },
1166 /* 0x9c */ { NULL, NULL, 0 },
1167 /* 0x9d */ { NULL, NULL, 0 },
1168 /* 0x9e */ { NULL, NULL, 0 },
1169 /* 0x9f */ { NULL, NULL, 0 },
1170 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1171 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1172 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1173 /* 0xa3 */ { NULL, NULL, 0 },
1174 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1175 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1176 /* 0xa6 */ { NULL, NULL, 0 },
1177 /* 0xa7 */ { NULL, NULL, 0 },
1178 /* 0xa8 */ { NULL, NULL, 0 },
1179 /* 0xa9 */ { NULL, NULL, 0 },
1180 /* 0xaa */ { NULL, NULL, 0 },
1181 /* 0xab */ { NULL, NULL, 0 },
1182 /* 0xac */ { NULL, NULL, 0 },
1183 /* 0xad */ { NULL, NULL, 0 },
1184 /* 0xae */ { NULL, NULL, 0 },
1185 /* 0xaf */ { NULL, NULL, 0 },
1186 /* 0xb0 */ { NULL, NULL, 0 },
1187 /* 0xb1 */ { NULL, NULL, 0 },
1188 /* 0xb2 */ { NULL, NULL, 0 },
1189 /* 0xb3 */ { NULL, NULL, 0 },
1190 /* 0xb4 */ { NULL, NULL, 0 },
1191 /* 0xb5 */ { NULL, NULL, 0 },
1192 /* 0xb6 */ { NULL, NULL, 0 },
1193 /* 0xb7 */ { NULL, NULL, 0 },
1194 /* 0xb8 */ { NULL, NULL, 0 },
1195 /* 0xb9 */ { NULL, NULL, 0 },
1196 /* 0xba */ { NULL, NULL, 0 },
1197 /* 0xbb */ { NULL, NULL, 0 },
1198 /* 0xbc */ { NULL, NULL, 0 },
1199 /* 0xbd */ { NULL, NULL, 0 },
1200 /* 0xbe */ { NULL, NULL, 0 },
1201 /* 0xbf */ { NULL, NULL, 0 },
1202 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1203 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1204 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1205 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1206 /* 0xc4 */ { NULL, NULL, 0 },
1207 /* 0xc5 */ { NULL, NULL, 0 },
1208 /* 0xc6 */ { NULL, NULL, 0 },
1209 /* 0xc7 */ { NULL, NULL, 0 },
1210 /* 0xc8 */ { NULL, NULL, 0 },
1211 /* 0xc9 */ { NULL, NULL, 0 },
1212 /* 0xca */ { NULL, NULL, 0 },
1213 /* 0xcb */ { NULL, NULL, 0 },
1214 /* 0xcc */ { NULL, NULL, 0 },
1215 /* 0xcd */ { NULL, NULL, 0 },
1216 /* 0xce */ { NULL, NULL, 0 },
1217 /* 0xcf */ { NULL, NULL, 0 },
1218 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1219 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1220 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1221 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1222 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1223 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1224 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1225 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1226 /* 0xd8 */ { NULL, NULL, 0 },
1227 /* 0xd9 */ { NULL, NULL, 0 },
1228 /* 0xda */ { NULL, NULL, 0 },
1229 /* 0xdb */ { NULL, NULL, 0 },
1230 /* 0xdc */ { NULL, NULL, 0 },
1231 /* 0xdd */ { NULL, NULL, 0 },
1232 /* 0xde */ { NULL, NULL, 0 },
1233 /* 0xdf */ { NULL, NULL, 0 },
1234 /* 0xe0 */ { NULL, NULL, 0 },
1235 /* 0xe1 */ { NULL, NULL, 0 },
1236 /* 0xe2 */ { NULL, NULL, 0 },
1237 /* 0xe3 */ { NULL, NULL, 0 },
1238 /* 0xe4 */ { NULL, NULL, 0 },
1239 /* 0xe5 */ { NULL, NULL, 0 },
1240 /* 0xe6 */ { NULL, NULL, 0 },
1241 /* 0xe7 */ { NULL, NULL, 0 },
1242 /* 0xe8 */ { NULL, NULL, 0 },
1243 /* 0xe9 */ { NULL, NULL, 0 },
1244 /* 0xea */ { NULL, NULL, 0 },
1245 /* 0xeb */ { NULL, NULL, 0 },
1246 /* 0xec */ { NULL, NULL, 0 },
1247 /* 0xed */ { NULL, NULL, 0 },
1248 /* 0xee */ { NULL, NULL, 0 },
1249 /* 0xef */ { NULL, NULL, 0 },
1250 /* 0xf0 */ { NULL, NULL, 0 },
1251 /* 0xf1 */ { NULL, NULL, 0 },
1252 /* 0xf2 */ { NULL, NULL, 0 },
1253 /* 0xf3 */ { NULL, NULL, 0 },
1254 /* 0xf4 */ { NULL, NULL, 0 },
1255 /* 0xf5 */ { NULL, NULL, 0 },
1256 /* 0xf6 */ { NULL, NULL, 0 },
1257 /* 0xf7 */ { NULL, NULL, 0 },
1258 /* 0xf8 */ { NULL, NULL, 0 },
1259 /* 0xf9 */ { NULL, NULL, 0 },
1260 /* 0xfa */ { NULL, NULL, 0 },
1261 /* 0xfb */ { NULL, NULL, 0 },
1262 /* 0xfc */ { NULL, NULL, 0 },
1263 /* 0xfd */ { NULL, NULL, 0 },
1264 /* 0xfe */ { NULL, NULL, 0 },
1265 /* 0xff */ { NULL, NULL, 0 }
1269 /*******************************************************************
1270 allocate and initialize a reply packet
1271 ********************************************************************/
1273 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1274 const char *inbuf, char **outbuf, uint8_t num_words,
1275 uint32_t num_bytes)
1278 * Protect against integer wrap
1280 if ((num_bytes > 0xffffff)
1281 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1282 char *msg;
1283 if (asprintf(&msg, "num_bytes too large: %u",
1284 (unsigned)num_bytes) == -1) {
1285 msg = discard_const_p(char, "num_bytes too large");
1287 smb_panic(msg);
1290 *outbuf = talloc_array(mem_ctx, char,
1291 smb_size + num_words*2 + num_bytes);
1292 if (*outbuf == NULL) {
1293 return false;
1296 construct_reply_common(req, inbuf, *outbuf);
1297 srv_set_message(*outbuf, num_words, num_bytes, false);
1299 * Zero out the word area, the caller has to take care of the bcc area
1300 * himself
1302 if (num_words != 0) {
1303 memset(*outbuf + smb_vwv0, 0, num_words*2);
1306 return true;
1309 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1311 char *outbuf;
1312 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1313 num_bytes)) {
1314 smb_panic("could not allocate output buffer\n");
1316 req->outbuf = (uint8_t *)outbuf;
1320 /*******************************************************************
1321 Dump a packet to a file.
1322 ********************************************************************/
1324 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1326 int fd, i;
1327 char *fname = NULL;
1328 if (DEBUGLEVEL < 50) {
1329 return;
1332 if (len < 4) len = smb_len(data)+4;
1333 for (i=1;i<100;i++) {
1334 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1335 type ? "req" : "resp") == -1) {
1336 return;
1338 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1339 if (fd != -1 || errno != EEXIST) break;
1341 if (fd != -1) {
1342 ssize_t ret = write(fd, data, len);
1343 if (ret != len)
1344 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1345 close(fd);
1346 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1348 SAFE_FREE(fname);
1351 /****************************************************************************
1352 Prepare everything for calling the actual request function, and potentially
1353 call the request function via the "new" interface.
1355 Return False if the "legacy" function needs to be called, everything is
1356 prepared.
1358 Return True if we're done.
1360 I know this API sucks, but it is the one with the least code change I could
1361 find.
1362 ****************************************************************************/
1364 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1366 int flags;
1367 uint16 session_tag;
1368 connection_struct *conn = NULL;
1369 struct smbd_server_connection *sconn = req->sconn;
1370 char *raddr;
1372 errno = 0;
1374 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1375 * so subtract 4 from it. */
1376 if (!valid_smb_header(sconn, req->inbuf)
1377 || (size < (smb_size - 4))) {
1378 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1379 smb_len(req->inbuf)));
1380 exit_server_cleanly("Non-SMB packet");
1383 if (smb_messages[type].fn == NULL) {
1384 DEBUG(0,("Unknown message type %d!\n",type));
1385 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1386 reply_unknown_new(req, type);
1387 return NULL;
1390 flags = smb_messages[type].flags;
1392 /* In share mode security we must ignore the vuid. */
1393 session_tag = (lp_security() == SEC_SHARE)
1394 ? UID_FIELD_INVALID : req->vuid;
1395 conn = req->conn;
1397 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1398 (int)sys_getpid(), (unsigned long)conn));
1400 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1402 /* Ensure this value is replaced in the incoming packet. */
1403 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1406 * Ensure the correct username is in current_user_info. This is a
1407 * really ugly bugfix for problems with multiple session_setup_and_X's
1408 * being done and allowing %U and %G substitutions to work correctly.
1409 * There is a reason this code is done here, don't move it unless you
1410 * know what you're doing... :-).
1411 * JRA.
1414 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1415 user_struct *vuser = NULL;
1417 sconn->smb1.sessions.last_session_tag = session_tag;
1418 if(session_tag != UID_FIELD_INVALID) {
1419 vuser = get_valid_user_struct(sconn, session_tag);
1420 if (vuser) {
1421 set_current_user_info(
1422 vuser->session_info->unix_info->sanitized_username,
1423 vuser->session_info->unix_info->unix_name,
1424 vuser->session_info->info->domain_name);
1429 /* Does this call need to be run as the connected user? */
1430 if (flags & AS_USER) {
1432 /* Does this call need a valid tree connection? */
1433 if (!conn) {
1435 * Amazingly, the error code depends on the command
1436 * (from Samba4).
1438 if (type == SMBntcreateX) {
1439 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1440 } else {
1441 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1443 return NULL;
1446 if (!change_to_user(conn,session_tag)) {
1447 DEBUG(0, ("Error: Could not change to user. Removing "
1448 "deferred open, mid=%llu.\n",
1449 (unsigned long long)req->mid));
1450 reply_force_doserror(req, ERRSRV, ERRbaduid);
1451 return conn;
1454 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1456 /* Does it need write permission? */
1457 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1458 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1459 return conn;
1462 /* IPC services are limited */
1463 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1464 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1465 return conn;
1467 } else {
1468 /* This call needs to be run as root */
1469 change_to_root_user();
1472 /* load service specific parameters */
1473 if (conn) {
1474 if (req->encrypted) {
1475 conn->encrypted_tid = true;
1476 /* encrypted required from now on. */
1477 conn->encrypt_level = Required;
1478 } else if (ENCRYPTION_REQUIRED(conn)) {
1479 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1480 exit_server_cleanly("encryption required "
1481 "on connection");
1482 return conn;
1486 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1487 (flags & (AS_USER|DO_CHDIR)
1488 ?True:False))) {
1489 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1490 return conn;
1492 conn->num_smb_operations++;
1495 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1496 talloc_tos());
1497 if (raddr == NULL) {
1498 reply_nterror(req, NT_STATUS_NO_MEMORY);
1499 return conn;
1502 /* does this protocol need to be run as guest? */
1503 if ((flags & AS_GUEST)
1504 && (!change_to_guest() ||
1505 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1506 sconn->remote_hostname,
1507 raddr))) {
1508 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1509 return conn;
1512 smb_messages[type].fn(req);
1513 return req->conn;
1516 /****************************************************************************
1517 Construct a reply to the incoming packet.
1518 ****************************************************************************/
1520 static void construct_reply(struct smbd_server_connection *sconn,
1521 char *inbuf, int size, size_t unread_bytes,
1522 uint32_t seqnum, bool encrypted,
1523 struct smb_perfcount_data *deferred_pcd)
1525 connection_struct *conn;
1526 struct smb_request *req;
1528 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1529 smb_panic("could not allocate smb_request");
1532 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1533 encrypted, seqnum)) {
1534 exit_server_cleanly("Invalid SMB request");
1537 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1539 /* we popped this message off the queue - keep original perf data */
1540 if (deferred_pcd)
1541 req->pcd = *deferred_pcd;
1542 else {
1543 SMB_PERFCOUNT_START(&req->pcd);
1544 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1545 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1548 conn = switch_message(req->cmd, req, size);
1550 if (req->unread_bytes) {
1551 /* writeX failed. drain socket. */
1552 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1553 req->unread_bytes) {
1554 smb_panic("failed to drain pending bytes");
1556 req->unread_bytes = 0;
1559 if (req->done) {
1560 TALLOC_FREE(req);
1561 return;
1564 if (req->outbuf == NULL) {
1565 return;
1568 if (CVAL(req->outbuf,0) == 0) {
1569 show_msg((char *)req->outbuf);
1572 if (!srv_send_smb(req->sconn,
1573 (char *)req->outbuf,
1574 true, req->seqnum+1,
1575 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1576 &req->pcd)) {
1577 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1580 TALLOC_FREE(req);
1582 return;
1585 /****************************************************************************
1586 Process an smb from the client
1587 ****************************************************************************/
1588 static void process_smb(struct smbd_server_connection *sconn,
1589 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1590 uint32_t seqnum, bool encrypted,
1591 struct smb_perfcount_data *deferred_pcd)
1593 int msg_type = CVAL(inbuf,0);
1595 DO_PROFILE_INC(smb_count);
1597 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1598 smb_len(inbuf) ) );
1599 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1600 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1602 if (msg_type != NBSSmessage) {
1604 * NetBIOS session request, keepalive, etc.
1606 reply_special(sconn, (char *)inbuf, nread);
1607 goto done;
1610 if (sconn->using_smb2) {
1611 /* At this point we're not really using smb2,
1612 * we make the decision here.. */
1613 if (smbd_is_smb2_header(inbuf, nread)) {
1614 smbd_smb2_first_negprot(sconn, inbuf, nread);
1615 return;
1616 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1617 && CVAL(inbuf, smb_com) != 0x72) {
1618 /* This is a non-negprot SMB1 packet.
1619 Disable SMB2 from now on. */
1620 sconn->using_smb2 = false;
1624 show_msg((char *)inbuf);
1626 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1627 encrypted, deferred_pcd);
1628 sconn->trans_num++;
1630 done:
1631 sconn->num_requests++;
1633 /* The timeout_processing function isn't run nearly
1634 often enough to implement 'max log size' without
1635 overrunning the size of the file by many megabytes.
1636 This is especially true if we are running at debug
1637 level 10. Checking every 50 SMBs is a nice
1638 tradeoff of performance vs log file size overrun. */
1640 if ((sconn->num_requests % 50) == 0 &&
1641 need_to_check_log_size()) {
1642 change_to_root_user();
1643 check_log_size();
1647 /****************************************************************************
1648 Return a string containing the function name of a SMB command.
1649 ****************************************************************************/
1651 const char *smb_fn_name(int type)
1653 const char *unknown_name = "SMBunknown";
1655 if (smb_messages[type].name == NULL)
1656 return(unknown_name);
1658 return(smb_messages[type].name);
1661 /****************************************************************************
1662 Helper functions for contruct_reply.
1663 ****************************************************************************/
1665 void add_to_common_flags2(uint32 v)
1667 common_flags2 |= v;
1670 void remove_from_common_flags2(uint32 v)
1672 common_flags2 &= ~v;
1675 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1676 char *outbuf)
1678 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1679 uint16_t out_flags2 = common_flags2;
1681 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1682 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1683 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1685 srv_set_message(outbuf,0,0,false);
1687 SCVAL(outbuf, smb_com, req->cmd);
1688 SIVAL(outbuf,smb_rcls,0);
1689 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1690 SSVAL(outbuf,smb_flg2, out_flags2);
1691 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1692 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1694 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1695 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1696 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1697 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1700 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1702 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1706 * How many bytes have we already accumulated up to the current wct field
1707 * offset?
1710 size_t req_wct_ofs(struct smb_request *req)
1712 size_t buf_size;
1714 if (req->chain_outbuf == NULL) {
1715 return smb_wct - 4;
1717 buf_size = talloc_get_size(req->chain_outbuf);
1718 if ((buf_size % 4) != 0) {
1719 buf_size += (4 - (buf_size % 4));
1721 return buf_size - 4;
1725 * Hack around reply_nterror & friends not being aware of chained requests,
1726 * generating illegal (i.e. wct==0) chain replies.
1729 static void fixup_chain_error_packet(struct smb_request *req)
1731 uint8_t *outbuf = req->outbuf;
1732 req->outbuf = NULL;
1733 reply_outbuf(req, 2, 0);
1734 memcpy(req->outbuf, outbuf, smb_wct);
1735 TALLOC_FREE(outbuf);
1736 SCVAL(req->outbuf, smb_vwv0, 0xff);
1740 * @brief Find the smb_cmd offset of the last command pushed
1741 * @param[in] buf The buffer we're building up
1742 * @retval Where can we put our next andx cmd?
1744 * While chaining requests, the "next" request we're looking at needs to put
1745 * its SMB_Command before the data the previous request already built up added
1746 * to the chain. Find the offset to the place where we have to put our cmd.
1749 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1751 uint8_t cmd;
1752 size_t ofs;
1754 cmd = CVAL(buf, smb_com);
1756 SMB_ASSERT(is_andx_req(cmd));
1758 ofs = smb_vwv0;
1760 while (CVAL(buf, ofs) != 0xff) {
1762 if (!is_andx_req(CVAL(buf, ofs))) {
1763 return false;
1767 * ofs is from start of smb header, so add the 4 length
1768 * bytes. The next cmd is right after the wct field.
1770 ofs = SVAL(buf, ofs+2) + 4 + 1;
1772 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1775 *pofs = ofs;
1776 return true;
1780 * @brief Do the smb chaining at a buffer level
1781 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1782 * @param[in] smb_command The command that we want to issue
1783 * @param[in] wct How many words?
1784 * @param[in] vwv The words, already in network order
1785 * @param[in] bytes_alignment How shall we align "bytes"?
1786 * @param[in] num_bytes How many bytes?
1787 * @param[in] bytes The data the request ships
1789 * smb_splice_chain() adds the vwv and bytes to the request already present in
1790 * *poutbuf.
1793 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1794 uint8_t wct, const uint16_t *vwv,
1795 size_t bytes_alignment,
1796 uint32_t num_bytes, const uint8_t *bytes)
1798 uint8_t *outbuf;
1799 size_t old_size, new_size;
1800 size_t ofs;
1801 size_t chain_padding = 0;
1802 size_t bytes_padding = 0;
1803 bool first_request;
1805 old_size = talloc_get_size(*poutbuf);
1808 * old_size == smb_wct means we're pushing the first request in for
1809 * libsmb/
1812 first_request = (old_size == smb_wct);
1814 if (!first_request && ((old_size % 4) != 0)) {
1816 * Align the wct field of subsequent requests to a 4-byte
1817 * boundary
1819 chain_padding = 4 - (old_size % 4);
1823 * After the old request comes the new wct field (1 byte), the vwv's
1824 * and the num_bytes field. After at we might need to align the bytes
1825 * given to us to "bytes_alignment", increasing the num_bytes value.
1828 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1830 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1831 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1834 new_size += bytes_padding + num_bytes;
1836 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1837 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1838 (unsigned)new_size));
1839 return false;
1842 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1843 if (outbuf == NULL) {
1844 DEBUG(0, ("talloc failed\n"));
1845 return false;
1847 *poutbuf = outbuf;
1849 if (first_request) {
1850 SCVAL(outbuf, smb_com, smb_command);
1851 } else {
1852 size_t andx_cmd_ofs;
1854 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1855 DEBUG(1, ("invalid command chain\n"));
1856 *poutbuf = talloc_realloc(
1857 NULL, *poutbuf, uint8_t, old_size);
1858 return false;
1861 if (chain_padding != 0) {
1862 memset(outbuf + old_size, 0, chain_padding);
1863 old_size += chain_padding;
1866 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1867 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1870 ofs = old_size;
1873 * Push the chained request:
1875 * wct field
1878 SCVAL(outbuf, ofs, wct);
1879 ofs += 1;
1882 * vwv array
1885 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1886 ofs += sizeof(uint16_t) * wct;
1889 * bcc (byte count)
1892 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1893 ofs += sizeof(uint16_t);
1896 * padding
1899 if (bytes_padding != 0) {
1900 memset(outbuf + ofs, 0, bytes_padding);
1901 ofs += bytes_padding;
1905 * The bytes field
1908 memcpy(outbuf + ofs, bytes, num_bytes);
1910 return true;
1913 /****************************************************************************
1914 Construct a chained reply and add it to the already made reply
1915 ****************************************************************************/
1917 void chain_reply(struct smb_request *req)
1919 size_t smblen = smb_len(req->inbuf);
1920 size_t already_used, length_needed;
1921 uint8_t chain_cmd;
1922 uint32_t chain_offset; /* uint32_t to avoid overflow */
1924 uint8_t wct;
1925 const uint16_t *vwv;
1926 uint16_t buflen;
1927 const uint8_t *buf;
1929 if (IVAL(req->outbuf, smb_rcls) != 0) {
1930 fixup_chain_error_packet(req);
1934 * Any of the AndX requests and replies have at least a wct of
1935 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1936 * beginning of the SMB header to the next wct field.
1938 * None of the AndX requests put anything valuable in vwv[0] and [1],
1939 * so we can overwrite it here to form the chain.
1942 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1943 if (req->chain_outbuf == NULL) {
1944 req->chain_outbuf = talloc_realloc(
1945 req, req->outbuf, uint8_t,
1946 smb_len(req->outbuf) + 4);
1947 if (req->chain_outbuf == NULL) {
1948 smb_panic("talloc failed");
1951 req->outbuf = NULL;
1952 goto error;
1956 * Here we assume that this is the end of the chain. For that we need
1957 * to set "next command" to 0xff and the offset to 0. If we later find
1958 * more commands in the chain, this will be overwritten again.
1961 SCVAL(req->outbuf, smb_vwv0, 0xff);
1962 SCVAL(req->outbuf, smb_vwv0+1, 0);
1963 SSVAL(req->outbuf, smb_vwv1, 0);
1965 if (req->chain_outbuf == NULL) {
1967 * In req->chain_outbuf we collect all the replies. Start the
1968 * chain by copying in the first reply.
1970 * We do the realloc because later on we depend on
1971 * talloc_get_size to determine the length of
1972 * chain_outbuf. The reply_xxx routines might have
1973 * over-allocated (reply_pipe_read_and_X used to be such an
1974 * example).
1976 req->chain_outbuf = talloc_realloc(
1977 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1978 if (req->chain_outbuf == NULL) {
1979 smb_panic("talloc failed");
1981 req->outbuf = NULL;
1982 } else {
1984 * Update smb headers where subsequent chained commands
1985 * may have updated them.
1987 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1988 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1990 if (!smb_splice_chain(&req->chain_outbuf,
1991 CVAL(req->outbuf, smb_com),
1992 CVAL(req->outbuf, smb_wct),
1993 (uint16_t *)(req->outbuf + smb_vwv),
1994 0, smb_buflen(req->outbuf),
1995 (uint8_t *)smb_buf(req->outbuf))) {
1996 goto error;
1998 TALLOC_FREE(req->outbuf);
2002 * We use the old request's vwv field to grab the next chained command
2003 * and offset into the chained fields.
2006 chain_cmd = CVAL(req->vwv+0, 0);
2007 chain_offset = SVAL(req->vwv+1, 0);
2009 if (chain_cmd == 0xff) {
2011 * End of chain, no more requests from the client. So ship the
2012 * replies.
2014 smb_setlen((char *)(req->chain_outbuf),
2015 talloc_get_size(req->chain_outbuf) - 4);
2017 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2018 true, req->seqnum+1,
2019 IS_CONN_ENCRYPTED(req->conn)
2020 ||req->encrypted,
2021 &req->pcd)) {
2022 exit_server_cleanly("chain_reply: srv_send_smb "
2023 "failed.");
2025 TALLOC_FREE(req->chain_outbuf);
2026 req->done = true;
2027 return;
2030 /* add a new perfcounter for this element of chain */
2031 SMB_PERFCOUNT_ADD(&req->pcd);
2032 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2033 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2036 * Check if the client tries to fool us. The chain offset
2037 * needs to point beyond the current request in the chain, it
2038 * needs to strictly grow. Otherwise we might be tricked into
2039 * an endless loop always processing the same request over and
2040 * over again. We used to assume that vwv and the byte buffer
2041 * array in a chain are always attached, but OS/2 the
2042 * Write&X/Read&X chain puts the Read&X vwv array right behind
2043 * the Write&X vwv chain. The Write&X bcc array is put behind
2044 * the Read&X vwv array. So now we check whether the chain
2045 * offset points strictly behind the previous vwv
2046 * array. req->buf points right after the vwv array of the
2047 * previous request. See
2048 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2049 * information.
2052 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2053 if (chain_offset <= already_used) {
2054 goto error;
2058 * Next check: Make sure the chain offset does not point beyond the
2059 * overall smb request length.
2062 length_needed = chain_offset+1; /* wct */
2063 if (length_needed > smblen) {
2064 goto error;
2068 * Now comes the pointer magic. Goal here is to set up req->vwv and
2069 * req->buf correctly again to be able to call the subsequent
2070 * switch_message(). The chain offset (the former vwv[1]) points at
2071 * the new wct field.
2074 wct = CVAL(smb_base(req->inbuf), chain_offset);
2077 * Next consistency check: Make the new vwv array fits in the overall
2078 * smb request.
2081 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2082 if (length_needed > smblen) {
2083 goto error;
2085 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2088 * Now grab the new byte buffer....
2091 buflen = SVAL(vwv+wct, 0);
2094 * .. and check that it fits.
2097 length_needed += buflen;
2098 if (length_needed > smblen) {
2099 goto error;
2101 buf = (const uint8_t *)(vwv+wct+1);
2103 req->cmd = chain_cmd;
2104 req->wct = wct;
2105 req->vwv = discard_const_p(uint16_t, vwv);
2106 req->buflen = buflen;
2107 req->buf = buf;
2109 switch_message(chain_cmd, req, smblen);
2111 if (req->outbuf == NULL) {
2113 * This happens if the chained command has suspended itself or
2114 * if it has called srv_send_smb() itself.
2116 return;
2120 * We end up here if the chained command was not itself chained or
2121 * suspended, but for example a close() command. We now need to splice
2122 * the chained commands' outbuf into the already built up chain_outbuf
2123 * and ship the result.
2125 goto done;
2127 error:
2129 * We end up here if there's any error in the chain syntax. Report a
2130 * DOS error, just like Windows does.
2132 reply_force_doserror(req, ERRSRV, ERRerror);
2133 fixup_chain_error_packet(req);
2135 done:
2137 * This scary statement intends to set the
2138 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2139 * to the value req->outbuf carries
2141 SSVAL(req->chain_outbuf, smb_flg2,
2142 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2143 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2146 * Transfer the error codes from the subrequest to the main one
2148 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2149 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2151 if (!smb_splice_chain(&req->chain_outbuf,
2152 CVAL(req->outbuf, smb_com),
2153 CVAL(req->outbuf, smb_wct),
2154 (uint16_t *)(req->outbuf + smb_vwv),
2155 0, smb_buflen(req->outbuf),
2156 (uint8_t *)smb_buf(req->outbuf))) {
2157 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2159 TALLOC_FREE(req->outbuf);
2161 smb_setlen((char *)(req->chain_outbuf),
2162 talloc_get_size(req->chain_outbuf) - 4);
2164 show_msg((char *)(req->chain_outbuf));
2166 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2167 true, req->seqnum+1,
2168 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2169 &req->pcd)) {
2170 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2172 TALLOC_FREE(req->chain_outbuf);
2173 req->done = true;
2176 /****************************************************************************
2177 Check if services need reloading.
2178 ****************************************************************************/
2180 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2183 if (last_smb_conf_reload_time == 0) {
2184 last_smb_conf_reload_time = t;
2187 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2188 reload_services(sconn->msg_ctx, sconn->sock, True);
2189 last_smb_conf_reload_time = t;
2193 static bool fd_is_readable(int fd)
2195 int ret, revents;
2197 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2199 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2203 static void smbd_server_connection_write_handler(
2204 struct smbd_server_connection *sconn)
2206 /* TODO: make write nonblocking */
2209 static void smbd_server_connection_read_handler(
2210 struct smbd_server_connection *sconn, int fd)
2212 uint8_t *inbuf = NULL;
2213 size_t inbuf_len = 0;
2214 size_t unread_bytes = 0;
2215 bool encrypted = false;
2216 TALLOC_CTX *mem_ctx = talloc_tos();
2217 NTSTATUS status;
2218 uint32_t seqnum;
2220 bool from_client;
2222 if (lp_async_smb_echo_handler()
2223 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2225 * This is the super-ugly hack to prefer the packets
2226 * forwarded by the echo handler over the ones by the
2227 * client directly
2229 fd = sconn->smb1.echo_handler.trusted_fd;
2232 from_client = (sconn->sock == fd);
2234 if (from_client) {
2235 smbd_lock_socket(sconn);
2237 if (!fd_is_readable(fd)) {
2238 DEBUG(10,("the echo listener was faster\n"));
2239 smbd_unlock_socket(sconn);
2240 return;
2244 /* TODO: make this completely nonblocking */
2245 status = receive_smb_talloc(mem_ctx, sconn, fd,
2246 (char **)(void *)&inbuf,
2247 0, /* timeout */
2248 &unread_bytes,
2249 &encrypted,
2250 &inbuf_len, &seqnum,
2251 false /* trusted channel */);
2253 if (from_client) {
2254 smbd_unlock_socket(sconn);
2257 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2258 goto process;
2260 if (NT_STATUS_IS_ERR(status)) {
2261 exit_server_cleanly("failed to receive smb request");
2263 if (!NT_STATUS_IS_OK(status)) {
2264 return;
2267 process:
2268 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2269 seqnum, encrypted, NULL);
2272 static void smbd_server_connection_handler(struct event_context *ev,
2273 struct fd_event *fde,
2274 uint16_t flags,
2275 void *private_data)
2277 struct smbd_server_connection *conn = talloc_get_type(private_data,
2278 struct smbd_server_connection);
2280 if (flags & EVENT_FD_WRITE) {
2281 smbd_server_connection_write_handler(conn);
2282 return;
2284 if (flags & EVENT_FD_READ) {
2285 smbd_server_connection_read_handler(conn, conn->sock);
2286 return;
2290 static void smbd_server_echo_handler(struct event_context *ev,
2291 struct fd_event *fde,
2292 uint16_t flags,
2293 void *private_data)
2295 struct smbd_server_connection *conn = talloc_get_type(private_data,
2296 struct smbd_server_connection);
2298 if (flags & EVENT_FD_WRITE) {
2299 smbd_server_connection_write_handler(conn);
2300 return;
2302 if (flags & EVENT_FD_READ) {
2303 smbd_server_connection_read_handler(
2304 conn, conn->smb1.echo_handler.trusted_fd);
2305 return;
2309 #ifdef CLUSTER_SUPPORT
2310 /****************************************************************************
2311 received when we should release a specific IP
2312 ****************************************************************************/
2313 static void release_ip(const char *ip, void *priv)
2315 const char *addr = (const char *)priv;
2316 const char *p = addr;
2318 if (strncmp("::ffff:", addr, 7) == 0) {
2319 p = addr + 7;
2322 DEBUG(10, ("Got release IP message for %s, "
2323 "our address is %s\n", ip, p));
2325 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2326 /* we can't afford to do a clean exit - that involves
2327 database writes, which would potentially mean we
2328 are still running after the failover has finished -
2329 we have to get rid of this process ID straight
2330 away */
2331 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2332 ip));
2333 /* note we must exit with non-zero status so the unclean handler gets
2334 called in the parent, so that the brl database is tickled */
2335 _exit(1);
2339 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2340 struct sockaddr_storage *client)
2342 socklen_t length;
2343 length = sizeof(*server);
2344 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2345 return -1;
2347 length = sizeof(*client);
2348 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2349 return -1;
2351 return 0;
2353 #endif
2356 * Send keepalive packets to our client
2358 static bool keepalive_fn(const struct timeval *now, void *private_data)
2360 struct smbd_server_connection *sconn = talloc_get_type_abort(
2361 private_data, struct smbd_server_connection);
2362 bool ret;
2364 if (sconn->using_smb2) {
2365 /* Don't do keepalives on an SMB2 connection. */
2366 return false;
2369 smbd_lock_socket(smbd_server_conn);
2370 ret = send_keepalive(sconn->sock);
2371 smbd_unlock_socket(smbd_server_conn);
2373 if (!ret) {
2374 char addr[INET6_ADDRSTRLEN];
2376 * Try and give an error message saying what
2377 * client failed.
2379 DEBUG(0, ("send_keepalive failed for client %s. "
2380 "Error %s - exiting\n",
2381 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2382 strerror(errno)));
2383 return False;
2385 return True;
2389 * Do the recurring check if we're idle
2391 static bool deadtime_fn(const struct timeval *now, void *private_data)
2393 struct smbd_server_connection *sconn =
2394 (struct smbd_server_connection *)private_data;
2396 if ((conn_num_open(sconn) == 0)
2397 || (conn_idle_all(sconn, now->tv_sec))) {
2398 DEBUG( 2, ( "Closing idle connection\n" ) );
2399 messaging_send(sconn->msg_ctx,
2400 messaging_server_id(sconn->msg_ctx),
2401 MSG_SHUTDOWN, &data_blob_null);
2402 return False;
2405 return True;
2409 * Do the recurring log file and smb.conf reload checks.
2412 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2414 struct smbd_server_connection *sconn = talloc_get_type_abort(
2415 private_data, struct smbd_server_connection);
2417 DEBUG(5, ("housekeeping\n"));
2419 change_to_root_user();
2421 /* update printer queue caches if necessary */
2422 update_monitored_printq_cache(sconn->msg_ctx);
2424 /* check if we need to reload services */
2425 check_reload(sconn, time_mono(NULL));
2427 /* Change machine password if neccessary. */
2428 attempt_machine_password_change();
2431 * Force a log file check.
2433 force_check_log_size();
2434 check_log_size();
2435 return true;
2439 * Read an smb packet in the echo handler child, giving the parent
2440 * smbd one second to react once the socket becomes readable.
2443 struct smbd_echo_read_state {
2444 struct tevent_context *ev;
2445 struct smbd_server_connection *sconn;
2447 char *buf;
2448 size_t buflen;
2449 uint32_t seqnum;
2452 static void smbd_echo_read_readable(struct tevent_req *subreq);
2453 static void smbd_echo_read_waited(struct tevent_req *subreq);
2455 static struct tevent_req *smbd_echo_read_send(
2456 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2457 struct smbd_server_connection *sconn)
2459 struct tevent_req *req, *subreq;
2460 struct smbd_echo_read_state *state;
2462 req = tevent_req_create(mem_ctx, &state,
2463 struct smbd_echo_read_state);
2464 if (req == NULL) {
2465 return NULL;
2467 state->ev = ev;
2468 state->sconn = sconn;
2470 subreq = wait_for_read_send(state, ev, sconn->sock);
2471 if (tevent_req_nomem(subreq, req)) {
2472 return tevent_req_post(req, ev);
2474 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2475 return req;
2478 static void smbd_echo_read_readable(struct tevent_req *subreq)
2480 struct tevent_req *req = tevent_req_callback_data(
2481 subreq, struct tevent_req);
2482 struct smbd_echo_read_state *state = tevent_req_data(
2483 req, struct smbd_echo_read_state);
2484 bool ok;
2485 int err;
2487 ok = wait_for_read_recv(subreq, &err);
2488 TALLOC_FREE(subreq);
2489 if (!ok) {
2490 tevent_req_nterror(req, map_nt_error_from_unix(err));
2491 return;
2495 * Give the parent smbd one second to step in
2498 subreq = tevent_wakeup_send(
2499 state, state->ev, timeval_current_ofs(1, 0));
2500 if (tevent_req_nomem(subreq, req)) {
2501 return;
2503 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2506 static void smbd_echo_read_waited(struct tevent_req *subreq)
2508 struct tevent_req *req = tevent_req_callback_data(
2509 subreq, struct tevent_req);
2510 struct smbd_echo_read_state *state = tevent_req_data(
2511 req, struct smbd_echo_read_state);
2512 struct smbd_server_connection *sconn = state->sconn;
2513 bool ok;
2514 NTSTATUS status;
2515 size_t unread = 0;
2516 bool encrypted;
2518 ok = tevent_wakeup_recv(subreq);
2519 TALLOC_FREE(subreq);
2520 if (!ok) {
2521 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2522 return;
2525 ok = smbd_lock_socket_internal(sconn);
2526 if (!ok) {
2527 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2528 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2529 return;
2532 if (!fd_is_readable(sconn->sock)) {
2533 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2534 (int)sys_getpid()));
2536 ok = smbd_unlock_socket_internal(sconn);
2537 if (!ok) {
2538 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2539 DEBUG(1, ("%s: failed to unlock socket\n",
2540 __location__));
2541 return;
2544 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2545 if (tevent_req_nomem(subreq, req)) {
2546 return;
2548 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2549 return;
2552 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2553 0 /* timeout */,
2554 &unread,
2555 &encrypted,
2556 &state->buflen,
2557 &state->seqnum,
2558 false /* trusted_channel*/);
2560 if (tevent_req_nterror(req, status)) {
2561 tevent_req_nterror(req, status);
2562 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2563 (int)sys_getpid(), nt_errstr(status)));
2564 return;
2567 ok = smbd_unlock_socket_internal(sconn);
2568 if (!ok) {
2569 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2570 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2571 return;
2573 tevent_req_done(req);
2576 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2577 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2579 struct smbd_echo_read_state *state = tevent_req_data(
2580 req, struct smbd_echo_read_state);
2581 NTSTATUS status;
2583 if (tevent_req_is_nterror(req, &status)) {
2584 return status;
2586 *pbuf = talloc_move(mem_ctx, &state->buf);
2587 *pbuflen = state->buflen;
2588 *pseqnum = state->seqnum;
2589 return NT_STATUS_OK;
2592 struct smbd_echo_state {
2593 struct tevent_context *ev;
2594 struct iovec *pending;
2595 struct smbd_server_connection *sconn;
2596 int parent_pipe;
2598 struct tevent_fd *parent_fde;
2600 struct tevent_req *write_req;
2603 static void smbd_echo_writer_done(struct tevent_req *req);
2605 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2607 int num_pending;
2609 if (state->write_req != NULL) {
2610 return;
2613 num_pending = talloc_array_length(state->pending);
2614 if (num_pending == 0) {
2615 return;
2618 state->write_req = writev_send(state, state->ev, NULL,
2619 state->parent_pipe, false,
2620 state->pending, num_pending);
2621 if (state->write_req == NULL) {
2622 DEBUG(1, ("writev_send failed\n"));
2623 exit(1);
2626 talloc_steal(state->write_req, state->pending);
2627 state->pending = NULL;
2629 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2630 state);
2633 static void smbd_echo_writer_done(struct tevent_req *req)
2635 struct smbd_echo_state *state = tevent_req_callback_data(
2636 req, struct smbd_echo_state);
2637 ssize_t written;
2638 int err;
2640 written = writev_recv(req, &err);
2641 TALLOC_FREE(req);
2642 state->write_req = NULL;
2643 if (written == -1) {
2644 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2645 exit(1);
2647 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2648 smbd_echo_activate_writer(state);
2651 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2652 uint32_t seqnum)
2654 struct smb_request req;
2655 uint16_t num_replies;
2656 size_t out_len;
2657 char *outbuf;
2658 bool ok;
2660 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2661 DEBUG(10, ("Got netbios keepalive\n"));
2663 * Just swallow it
2665 return true;
2668 if (inbuf_len < smb_size) {
2669 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2670 return false;
2672 if (!valid_smb_header(smbd_server_conn, inbuf)) {
2673 DEBUG(10, ("Got invalid SMB header\n"));
2674 return false;
2677 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2678 seqnum)) {
2679 return false;
2681 req.inbuf = inbuf;
2683 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2684 smb_messages[req.cmd].name
2685 ? smb_messages[req.cmd].name : "unknown"));
2687 if (req.cmd != SMBecho) {
2688 return false;
2690 if (req.wct < 1) {
2691 return false;
2694 num_replies = SVAL(req.vwv+0, 0);
2695 if (num_replies != 1) {
2696 /* Not a Windows "Hey, you're still there?" request */
2697 return false;
2700 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2701 1, req.buflen)) {
2702 DEBUG(10, ("create_outbuf failed\n"));
2703 return false;
2705 req.outbuf = (uint8_t *)outbuf;
2707 SSVAL(req.outbuf, smb_vwv0, num_replies);
2709 if (req.buflen > 0) {
2710 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2713 out_len = smb_len(req.outbuf) + 4;
2715 ok = srv_send_smb(req.sconn,
2716 (char *)outbuf,
2717 true, seqnum+1,
2718 false, &req.pcd);
2719 TALLOC_FREE(outbuf);
2720 if (!ok) {
2721 exit(1);
2724 return true;
2727 static void smbd_echo_exit(struct tevent_context *ev,
2728 struct tevent_fd *fde, uint16_t flags,
2729 void *private_data)
2731 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2732 exit(0);
2735 static void smbd_echo_got_packet(struct tevent_req *req);
2737 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2738 int parent_pipe)
2740 struct smbd_echo_state *state;
2741 struct tevent_req *read_req;
2743 state = talloc_zero(sconn, struct smbd_echo_state);
2744 if (state == NULL) {
2745 DEBUG(1, ("talloc failed\n"));
2746 return;
2748 state->sconn = sconn;
2749 state->parent_pipe = parent_pipe;
2750 state->ev = s3_tevent_context_init(state);
2751 if (state->ev == NULL) {
2752 DEBUG(1, ("tevent_context_init failed\n"));
2753 TALLOC_FREE(state);
2754 return;
2756 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2757 TEVENT_FD_READ, smbd_echo_exit,
2758 state);
2759 if (state->parent_fde == NULL) {
2760 DEBUG(1, ("tevent_add_fd failed\n"));
2761 TALLOC_FREE(state);
2762 return;
2765 read_req = smbd_echo_read_send(state, state->ev, sconn);
2766 if (read_req == NULL) {
2767 DEBUG(1, ("smbd_echo_read_send failed\n"));
2768 TALLOC_FREE(state);
2769 return;
2771 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2773 while (true) {
2774 if (tevent_loop_once(state->ev) == -1) {
2775 DEBUG(1, ("tevent_loop_once failed: %s\n",
2776 strerror(errno)));
2777 break;
2780 TALLOC_FREE(state);
2783 static void smbd_echo_got_packet(struct tevent_req *req)
2785 struct smbd_echo_state *state = tevent_req_callback_data(
2786 req, struct smbd_echo_state);
2787 NTSTATUS status;
2788 char *buf = NULL;
2789 size_t buflen = 0;
2790 uint32_t seqnum = 0;
2791 bool reply;
2793 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2794 TALLOC_FREE(req);
2795 if (!NT_STATUS_IS_OK(status)) {
2796 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2797 nt_errstr(status)));
2798 exit(1);
2801 reply = smbd_echo_reply((uint8_t *)buf, buflen, seqnum);
2802 if (!reply) {
2803 size_t num_pending;
2804 struct iovec *tmp;
2805 struct iovec *iov;
2807 num_pending = talloc_array_length(state->pending);
2808 tmp = talloc_realloc(state, state->pending, struct iovec,
2809 num_pending+1);
2810 if (tmp == NULL) {
2811 DEBUG(1, ("talloc_realloc failed\n"));
2812 exit(1);
2814 state->pending = tmp;
2816 if (buflen >= smb_size) {
2818 * place the seqnum in the packet so that the main process
2819 * can reply with signing
2821 SIVAL(buf, smb_ss_field, seqnum);
2822 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2825 iov = &state->pending[num_pending];
2826 iov->iov_base = buf;
2827 iov->iov_len = buflen;
2829 DEBUG(10,("echo_handler[%d]: forward to main\n",
2830 (int)sys_getpid()));
2831 smbd_echo_activate_writer(state);
2834 req = smbd_echo_read_send(state, state->ev, state->sconn);
2835 if (req == NULL) {
2836 DEBUG(1, ("smbd_echo_read_send failed\n"));
2837 exit(1);
2839 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2844 * Handle SMBecho requests in a forked child process
2846 bool fork_echo_handler(struct smbd_server_connection *sconn)
2848 int listener_pipe[2];
2849 int res;
2850 pid_t child;
2852 res = pipe(listener_pipe);
2853 if (res == -1) {
2854 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2855 return false;
2857 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2858 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2859 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2860 goto fail;
2863 child = sys_fork();
2864 if (child == 0) {
2865 NTSTATUS status;
2867 close(listener_pipe[0]);
2868 set_blocking(listener_pipe[1], false);
2870 status = reinit_after_fork(sconn->msg_ctx,
2871 server_event_context(),
2872 procid_self(), false);
2873 if (!NT_STATUS_IS_OK(status)) {
2874 DEBUG(1, ("reinit_after_fork failed: %s\n",
2875 nt_errstr(status)));
2876 exit(1);
2878 smbd_echo_loop(sconn, listener_pipe[1]);
2879 exit(0);
2881 close(listener_pipe[1]);
2882 listener_pipe[1] = -1;
2883 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2885 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2888 * Without smb signing this is the same as the normal smbd
2889 * listener. This needs to change once signing comes in.
2891 sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
2892 sconn,
2893 sconn->smb1.echo_handler.trusted_fd,
2894 EVENT_FD_READ,
2895 smbd_server_echo_handler,
2896 sconn);
2897 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2898 DEBUG(1, ("event_add_fd failed\n"));
2899 goto fail;
2902 return true;
2904 fail:
2905 if (listener_pipe[0] != -1) {
2906 close(listener_pipe[0]);
2908 if (listener_pipe[1] != -1) {
2909 close(listener_pipe[1]);
2911 sconn->smb1.echo_handler.trusted_fd = -1;
2912 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2913 close(sconn->smb1.echo_handler.socket_lock_fd);
2915 sconn->smb1.echo_handler.trusted_fd = -1;
2916 sconn->smb1.echo_handler.socket_lock_fd = -1;
2917 return false;
2920 #if CLUSTER_SUPPORT
2922 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2923 struct sockaddr_storage *srv,
2924 struct sockaddr_storage *clnt)
2926 struct ctdbd_connection *cconn;
2927 char tmp_addr[INET6_ADDRSTRLEN];
2928 char *addr;
2930 cconn = messaging_ctdbd_connection();
2931 if (cconn == NULL) {
2932 return NT_STATUS_NO_MEMORY;
2935 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2936 addr = talloc_strdup(cconn, tmp_addr);
2937 if (addr == NULL) {
2938 return NT_STATUS_NO_MEMORY;
2940 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2943 #endif
2945 /****************************************************************************
2946 Process commands from the client
2947 ****************************************************************************/
2949 void smbd_process(struct tevent_context *ev_ctx,
2950 struct smbd_server_connection *sconn)
2952 TALLOC_CTX *frame = talloc_stackframe();
2953 struct sockaddr_storage ss;
2954 struct sockaddr *sa = NULL;
2955 socklen_t sa_socklen;
2956 struct tsocket_address *local_address = NULL;
2957 struct tsocket_address *remote_address = NULL;
2958 const char *remaddr = NULL;
2959 char *rhost;
2960 int ret;
2962 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
2964 * We're not making the decision here,
2965 * we're just allowing the client
2966 * to decide between SMB1 and SMB2
2967 * with the first negprot
2968 * packet.
2970 sconn->using_smb2 = true;
2973 /* Ensure child is set to blocking mode */
2974 set_blocking(sconn->sock,True);
2976 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2977 set_socket_options(sconn->sock, lp_socket_options());
2979 sa = (struct sockaddr *)(void *)&ss;
2980 sa_socklen = sizeof(ss);
2981 ret = getpeername(sconn->sock, sa, &sa_socklen);
2982 if (ret != 0) {
2983 int level = (errno == ENOTCONN)?2:0;
2984 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2985 exit_server_cleanly("getpeername() failed.\n");
2987 ret = tsocket_address_bsd_from_sockaddr(sconn,
2988 sa, sa_socklen,
2989 &remote_address);
2990 if (ret != 0) {
2991 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2992 __location__, strerror(errno)));
2993 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2996 sa = (struct sockaddr *)(void *)&ss;
2997 sa_socklen = sizeof(ss);
2998 ret = getsockname(sconn->sock, sa, &sa_socklen);
2999 if (ret != 0) {
3000 int level = (errno == ENOTCONN)?2:0;
3001 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3002 exit_server_cleanly("getsockname() failed.\n");
3004 ret = tsocket_address_bsd_from_sockaddr(sconn,
3005 sa, sa_socklen,
3006 &local_address);
3007 if (ret != 0) {
3008 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3009 __location__, strerror(errno)));
3010 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3013 sconn->local_address = local_address;
3014 sconn->remote_address = remote_address;
3016 if (tsocket_address_is_inet(remote_address, "ip")) {
3017 remaddr = tsocket_address_inet_addr_string(
3018 sconn->remote_address,
3019 talloc_tos());
3020 if (remaddr == NULL) {
3021 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3022 __location__, strerror(errno)));
3023 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3025 } else {
3026 remaddr = "0.0.0.0";
3029 /* this is needed so that we get decent entries
3030 in smbstatus for port 445 connects */
3031 set_remote_machine_name(remaddr, false);
3032 reload_services(sconn->msg_ctx, sconn->sock, true);
3035 * Before the first packet, check the global hosts allow/ hosts deny
3036 * parameters before doing any parsing of packets passed to us by the
3037 * client. This prevents attacks on our parsing code from hosts not in
3038 * the hosts allow list.
3041 ret = get_remote_hostname(remote_address,
3042 &rhost,
3043 talloc_tos());
3044 if (ret < 0) {
3045 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3046 __location__, strerror(errno)));
3047 exit_server_cleanly("get_remote_hostname failed.\n");
3049 if (strequal(rhost, "UNKNOWN")) {
3050 rhost = talloc_strdup(talloc_tos(), remaddr);
3052 sconn->remote_hostname = talloc_move(sconn, &rhost);
3054 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3055 sconn->remote_hostname,
3056 remaddr)) {
3058 * send a negative session response "not listening on calling
3059 * name"
3061 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3062 DEBUG( 1, ("Connection denied from %s to %s\n",
3063 tsocket_address_string(remote_address, talloc_tos()),
3064 tsocket_address_string(local_address, talloc_tos())));
3065 (void)srv_send_smb(sconn,(char *)buf, false,
3066 0, false, NULL);
3067 exit_server_cleanly("connection denied");
3070 DEBUG(10, ("Connection allowed from %s to %s\n",
3071 tsocket_address_string(remote_address, talloc_tos()),
3072 tsocket_address_string(local_address, talloc_tos())));
3074 init_modules();
3076 smb_perfcount_init();
3078 if (!init_account_policy()) {
3079 exit_server("Could not open account policy tdb.\n");
3082 if (*lp_rootdir()) {
3083 if (chroot(lp_rootdir()) != 0) {
3084 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3085 exit_server("Failed to chroot()");
3087 if (chdir("/") == -1) {
3088 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3089 exit_server("Failed to chroot()");
3091 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3094 if (!srv_init_signing(sconn)) {
3095 exit_server("Failed to init smb_signing");
3098 /* Setup oplocks */
3099 if (!init_oplocks(sconn->msg_ctx))
3100 exit_server("Failed to init oplocks");
3102 /* register our message handlers */
3103 messaging_register(sconn->msg_ctx, NULL,
3104 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3105 messaging_register(sconn->msg_ctx, NULL,
3106 MSG_SMB_CLOSE_FILE, msg_close_file);
3109 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3110 * MSGs to all child processes
3112 messaging_deregister(sconn->msg_ctx,
3113 MSG_DEBUG, NULL);
3114 messaging_register(sconn->msg_ctx, NULL,
3115 MSG_DEBUG, debug_message);
3117 if ((lp_keepalive() != 0)
3118 && !(event_add_idle(ev_ctx, NULL,
3119 timeval_set(lp_keepalive(), 0),
3120 "keepalive", keepalive_fn,
3121 sconn))) {
3122 DEBUG(0, ("Could not add keepalive event\n"));
3123 exit(1);
3126 if (!(event_add_idle(ev_ctx, NULL,
3127 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3128 "deadtime", deadtime_fn, sconn))) {
3129 DEBUG(0, ("Could not add deadtime event\n"));
3130 exit(1);
3133 if (!(event_add_idle(ev_ctx, NULL,
3134 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3135 "housekeeping", housekeeping_fn, sconn))) {
3136 DEBUG(0, ("Could not add housekeeping event\n"));
3137 exit(1);
3140 #ifdef CLUSTER_SUPPORT
3142 if (lp_clustering()) {
3144 * We need to tell ctdb about our client's TCP
3145 * connection, so that for failover ctdbd can send
3146 * tickle acks, triggering a reconnection by the
3147 * client.
3150 struct sockaddr_storage srv, clnt;
3152 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3153 NTSTATUS status;
3154 status = smbd_register_ips(sconn, &srv, &clnt);
3155 if (!NT_STATUS_IS_OK(status)) {
3156 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3157 nt_errstr(status)));
3159 } else
3161 DEBUG(0,("Unable to get tcp info for "
3162 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3163 strerror(errno)));
3167 #endif
3169 sconn->nbt.got_session = false;
3171 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3173 sconn->smb1.sessions.done_sesssetup = false;
3174 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3175 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3176 /* users from session setup */
3177 sconn->smb1.sessions.session_userlist = NULL;
3178 /* workgroup from session setup. */
3179 sconn->smb1.sessions.session_workgroup = NULL;
3180 /* this holds info on user ids that are already validated for this VC */
3181 sconn->smb1.sessions.validated_users = NULL;
3182 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3183 sconn->smb1.sessions.num_validated_vuids = 0;
3185 conn_init(sconn);
3186 if (!init_dptrs(sconn)) {
3187 exit_server("init_dptrs() failed");
3190 sconn->smb1.fde = event_add_fd(ev_ctx,
3191 sconn,
3192 sconn->sock,
3193 EVENT_FD_READ,
3194 smbd_server_connection_handler,
3195 sconn);
3196 if (!sconn->smb1.fde) {
3197 exit_server("failed to create smbd_server_connection fde");
3200 TALLOC_FREE(frame);
3202 while (True) {
3203 NTSTATUS status;
3205 frame = talloc_stackframe_pool(8192);
3207 errno = 0;
3209 status = smbd_server_connection_loop_once(ev_ctx, sconn);
3210 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3211 !NT_STATUS_IS_OK(status)) {
3212 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3213 " exiting\n", nt_errstr(status)));
3214 break;
3217 TALLOC_FREE(frame);
3220 exit_server_cleanly(NULL);
3223 bool req_is_in_chain(struct smb_request *req)
3225 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3227 * We're right now handling a subsequent request, so we must
3228 * be in a chain
3230 return true;
3233 if (!is_andx_req(req->cmd)) {
3234 return false;
3237 if (req->wct < 2) {
3239 * Okay, an illegal request, but definitely not chained :-)
3241 return false;
3244 return (CVAL(req->vwv+0, 0) != 0xFF);