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/>.
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"
35 #include "lib/messages_ctdb.h"
36 #include "smbprofile.h"
37 #include "rpc_server/spoolss/srv_spoolss_nt.h"
38 #include "libsmb/libsmb.h"
39 #include "../lib/util/tevent_ntstatus.h"
40 #include "../libcli/security/dom_sid.h"
41 #include "../libcli/security/security_token.h"
42 #include "lib/id_cache.h"
43 #include "lib/util/sys_rw_data.h"
44 #include "system/threads.h"
45 #include "lib/pthreadpool/pthreadpool_tevent.h"
46 #include "util_event.h"
48 /* Internal message queue for deferred opens. */
49 struct pending_message_list {
50 struct pending_message_list *next, *prev;
51 struct timeval request_time; /* When was this first issued? */
52 struct smbd_server_connection *sconn;
53 struct smbXsrv_connection *xconn;
54 struct tevent_timer *te;
55 struct smb_perfcount_data pcd;
60 struct deferred_open_record *open_rec;
63 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
65 static struct pending_message_list *get_deferred_open_message_smb(
66 struct smbd_server_connection *sconn, uint64_t mid);
67 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
69 static void smbd_echo_init(struct smbXsrv_connection *xconn)
71 xconn->smb1.echo_handler.trusted_fd = -1;
72 xconn->smb1.echo_handler.socket_lock_fd = -1;
73 #ifdef HAVE_ROBUST_MUTEXES
74 xconn->smb1.echo_handler.socket_mutex = NULL;
78 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
80 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
84 #ifdef HAVE_ROBUST_MUTEXES
85 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
93 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
95 if (!smbd_echo_active(xconn)) {
99 xconn->smb1.echo_handler.ref_count++;
101 if (xconn->smb1.echo_handler.ref_count > 1) {
105 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
107 #ifdef HAVE_ROBUST_MUTEXES
108 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
111 while (ret == EINTR) {
112 ret = pthread_mutex_lock(
113 xconn->smb1.echo_handler.socket_mutex);
119 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
126 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
131 xconn->smb1.echo_handler.socket_lock_fd,
132 F_SETLKW, 0, 0, F_WRLCK);
133 } while (!ok && (errno == EINTR));
136 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
141 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
146 void smbd_lock_socket(struct smbXsrv_connection *xconn)
148 if (!smbd_lock_socket_internal(xconn)) {
149 exit_server_cleanly("failed to lock socket");
153 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
155 if (!smbd_echo_active(xconn)) {
159 xconn->smb1.echo_handler.ref_count--;
161 if (xconn->smb1.echo_handler.ref_count > 0) {
165 #ifdef HAVE_ROBUST_MUTEXES
166 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
168 ret = pthread_mutex_unlock(
169 xconn->smb1.echo_handler.socket_mutex);
171 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
178 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
183 xconn->smb1.echo_handler.socket_lock_fd,
184 F_SETLKW, 0, 0, F_UNLCK);
185 } while (!ok && (errno == EINTR));
188 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
193 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
198 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
200 if (!smbd_unlock_socket_internal(xconn)) {
201 exit_server_cleanly("failed to unlock socket");
205 /* Accessor function for smb_read_error for smbd functions. */
207 /****************************************************************************
209 ****************************************************************************/
211 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
212 bool do_signing, uint32_t seqnum,
214 struct smb_perfcount_data *pcd)
218 char *buf_out = buffer;
220 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
222 * we're not supposed to do any io
227 smbd_lock_socket(xconn);
230 /* Sign the outgoing packet if required. */
231 srv_calculate_sign_mac(xconn, buf_out, seqnum);
235 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
236 if (!NT_STATUS_IS_OK(status)) {
237 DEBUG(0, ("send_smb: SMB encryption failed "
238 "on outgoing packet! Error %s\n",
239 nt_errstr(status) ));
245 len = smb_len_large(buf_out) + 4;
247 ret = write_data(xconn->transport.sock, buf_out, len);
249 int saved_errno = errno;
251 * Try and give an error message saying what
254 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
255 (int)getpid(), (int)len,
256 smbXsrv_connection_dbg(xconn),
257 (int)ret, strerror(saved_errno)));
260 srv_free_enc_buffer(xconn, buf_out);
264 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
265 srv_free_enc_buffer(xconn, buf_out);
267 SMB_PERFCOUNT_END(pcd);
269 smbd_unlock_socket(xconn);
273 /*******************************************************************
274 Setup the word count and byte count for a smb message.
275 ********************************************************************/
277 size_t srv_set_message(char *buf,
282 if (zero && (num_words || num_bytes)) {
283 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
285 SCVAL(buf,smb_wct,num_words);
286 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
287 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
288 return (smb_size + num_words*2 + num_bytes);
291 static bool valid_smb_header(const uint8_t *inbuf)
293 if (is_encrypted_packet(inbuf)) {
297 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
298 * but it just looks weird to call strncmp for this one.
300 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
303 /* Socket functions for smbd packet processing. */
305 static bool valid_packet_size(size_t len)
308 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
309 * of header. Don't print the error if this fits.... JRA.
312 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
313 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
314 (unsigned long)len));
320 static NTSTATUS read_packet_remainder(int fd, char *buffer,
321 unsigned int timeout, ssize_t len)
329 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
330 if (!NT_STATUS_IS_OK(status)) {
331 char addr[INET6_ADDRSTRLEN];
332 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
334 get_peer_addr(fd, addr, sizeof(addr)),
340 /****************************************************************************
341 Attempt a zerocopy writeX read. We know here that len > smb_size-4
342 ****************************************************************************/
345 * Unfortunately, earlier versions of smbclient/libsmbclient
346 * don't send this "standard" writeX header. I've fixed this
347 * for 3.2 but we'll use the old method with earlier versions.
348 * Windows and CIFSFS at least use this standard size. Not
352 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
353 (2*14) + /* word count (including bcc) */ \
356 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
357 const char lenbuf[4],
358 struct smbXsrv_connection *xconn,
361 unsigned int timeout,
365 /* Size of a WRITEX call (+4 byte len). */
366 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
367 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
371 memcpy(writeX_header, lenbuf, 4);
373 status = read_fd_with_timeout(
374 sock, writeX_header + 4,
375 STANDARD_WRITE_AND_X_HEADER_SIZE,
376 STANDARD_WRITE_AND_X_HEADER_SIZE,
379 if (!NT_STATUS_IS_OK(status)) {
380 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
382 smbXsrv_connection_dbg(xconn),
388 * Ok - now try and see if this is a possible
392 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
394 * If the data offset is beyond what
395 * we've read, drain the extra bytes.
397 uint16_t doff = SVAL(writeX_header,smb_vwv11);
400 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
401 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
402 if (drain_socket(sock, drain) != drain) {
403 smb_panic("receive_smb_raw_talloc_partial_read:"
404 " failed to drain pending bytes");
407 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
410 /* Spoof down the length and null out the bcc. */
411 set_message_bcc(writeX_header, 0);
412 newlen = smb_len(writeX_header);
414 /* Copy the header we've written. */
416 *buffer = (char *)talloc_memdup(mem_ctx,
418 sizeof(writeX_header));
420 if (*buffer == NULL) {
421 DEBUG(0, ("Could not allocate inbuf of length %d\n",
422 (int)sizeof(writeX_header)));
423 return NT_STATUS_NO_MEMORY;
426 /* Work out the remaining bytes. */
427 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
428 *len_ret = newlen + 4;
432 if (!valid_packet_size(len)) {
433 return NT_STATUS_INVALID_PARAMETER;
437 * Not a valid writeX call. Just do the standard
441 *buffer = talloc_array(mem_ctx, char, len+4);
443 if (*buffer == NULL) {
444 DEBUG(0, ("Could not allocate inbuf of length %d\n",
446 return NT_STATUS_NO_MEMORY;
449 /* Copy in what we already read. */
452 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
453 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
456 status = read_packet_remainder(
458 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
461 if (!NT_STATUS_IS_OK(status)) {
462 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
472 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
473 struct smbXsrv_connection *xconn,
475 char **buffer, unsigned int timeout,
476 size_t *p_unread, size_t *plen)
480 int min_recv_size = lp_min_receive_file_size();
485 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
487 if (!NT_STATUS_IS_OK(status)) {
491 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
492 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
493 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
494 !srv_is_signing_active(xconn) &&
495 xconn->smb1.echo_handler.trusted_fde == NULL) {
497 return receive_smb_raw_talloc_partial_read(
498 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
502 if (!valid_packet_size(len)) {
503 return NT_STATUS_INVALID_PARAMETER;
507 * The +4 here can't wrap, we've checked the length above already.
510 *buffer = talloc_array(mem_ctx, char, len+4);
512 if (*buffer == NULL) {
513 DEBUG(0, ("Could not allocate inbuf of length %d\n",
515 return NT_STATUS_NO_MEMORY;
518 memcpy(*buffer, lenbuf, sizeof(lenbuf));
520 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
521 if (!NT_STATUS_IS_OK(status)) {
529 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
530 struct smbXsrv_connection *xconn,
532 char **buffer, unsigned int timeout,
533 size_t *p_unread, bool *p_encrypted,
536 bool trusted_channel)
541 *p_encrypted = false;
543 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
545 if (!NT_STATUS_IS_OK(status)) {
546 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
547 ("receive_smb_raw_talloc failed for client %s "
548 "read error = %s.\n",
549 smbXsrv_connection_dbg(xconn),
550 nt_errstr(status)) );
554 if (is_encrypted_packet((uint8_t *)*buffer)) {
555 status = srv_decrypt_buffer(xconn, *buffer);
556 if (!NT_STATUS_IS_OK(status)) {
557 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
558 "incoming packet! Error %s\n",
559 nt_errstr(status) ));
565 /* Check the incoming SMB signature. */
566 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
567 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
568 "incoming packet!\n"));
569 return NT_STATUS_INVALID_NETWORK_RESPONSE;
577 * Initialize a struct smb_request from an inbuf
580 static bool init_smb_request(struct smb_request *req,
581 struct smbd_server_connection *sconn,
582 struct smbXsrv_connection *xconn,
583 const uint8_t *inbuf,
584 size_t unread_bytes, bool encrypted,
587 struct smbXsrv_tcon *tcon;
590 size_t req_size = smb_len(inbuf) + 4;
592 /* Ensure we have at least smb_size bytes. */
593 if (req_size < smb_size) {
594 DEBUG(0,("init_smb_request: invalid request size %u\n",
595 (unsigned int)req_size ));
599 req->request_time = timeval_current();
600 now = timeval_to_nttime(&req->request_time);
602 req->cmd = CVAL(inbuf, smb_com);
603 req->flags2 = SVAL(inbuf, smb_flg2);
604 req->smbpid = SVAL(inbuf, smb_pid);
605 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
606 req->seqnum = seqnum;
607 req->vuid = SVAL(inbuf, smb_uid);
608 req->tid = SVAL(inbuf, smb_tid);
609 req->wct = CVAL(inbuf, smb_wct);
610 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
611 req->buflen = smb_buflen(inbuf);
612 req->buf = (const uint8_t *)smb_buf_const(inbuf);
613 req->unread_bytes = unread_bytes;
614 req->encrypted = encrypted;
619 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
620 if (NT_STATUS_IS_OK(status)) {
621 req->conn = tcon->compat;
624 req->chain_fsp = NULL;
626 req->priv_paths = NULL;
628 req->posix_pathnames = lp_posix_pathnames();
629 smb_init_perfcount_data(&req->pcd);
631 /* Ensure we have at least wct words and 2 bytes of bcc. */
632 if (smb_size + req->wct*2 > req_size) {
633 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
634 (unsigned int)req->wct,
635 (unsigned int)req_size));
638 /* Ensure bcc is correct. */
639 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
640 DEBUG(0,("init_smb_request: invalid bcc number %u "
641 "(wct = %u, size %u)\n",
642 (unsigned int)req->buflen,
643 (unsigned int)req->wct,
644 (unsigned int)req_size));
652 static void process_smb(struct smbXsrv_connection *xconn,
653 uint8_t *inbuf, size_t nread, size_t unread_bytes,
654 uint32_t seqnum, bool encrypted,
655 struct smb_perfcount_data *deferred_pcd);
657 static void smbd_deferred_open_timer(struct tevent_context *ev,
658 struct tevent_timer *te,
659 struct timeval _tval,
662 struct pending_message_list *msg = talloc_get_type(private_data,
663 struct pending_message_list);
664 struct smbd_server_connection *sconn = msg->sconn;
665 struct smbXsrv_connection *xconn = msg->xconn;
666 TALLOC_CTX *mem_ctx = talloc_tos();
667 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
670 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
673 exit_server("smbd_deferred_open_timer: talloc failed\n");
677 /* We leave this message on the queue so the open code can
678 know this is a retry. */
679 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
680 (unsigned long long)mid ));
682 /* Mark the message as processed so this is not
683 * re-processed in error. */
684 msg->processed = true;
686 process_smb(xconn, inbuf,
688 msg->seqnum, msg->encrypted, &msg->pcd);
690 /* If it's still there and was processed, remove it. */
691 msg = get_deferred_open_message_smb(sconn, mid);
692 if (msg && msg->processed) {
693 remove_deferred_open_message_smb(xconn, mid);
697 /****************************************************************************
698 Function to push a message onto the tail of a linked list of smb messages ready
700 ****************************************************************************/
702 static bool push_queued_message(struct smb_request *req,
703 struct timeval request_time,
704 struct timeval end_time,
705 struct deferred_open_record *open_rec)
707 int msg_len = smb_len(req->inbuf) + 4;
708 struct pending_message_list *msg;
710 msg = talloc_zero(NULL, struct pending_message_list);
713 DEBUG(0,("push_message: malloc fail (1)\n"));
716 msg->sconn = req->sconn;
717 msg->xconn = req->xconn;
719 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
720 if(msg->buf.data == NULL) {
721 DEBUG(0,("push_message: malloc fail (2)\n"));
726 msg->request_time = request_time;
727 msg->seqnum = req->seqnum;
728 msg->encrypted = req->encrypted;
729 msg->processed = false;
730 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
733 msg->open_rec = talloc_move(msg, &open_rec);
737 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
740 smbd_deferred_open_timer,
743 DEBUG(0,("push_message: event_add_timed failed\n"));
749 DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
751 DEBUG(10,("push_message: pushed message length %u on "
752 "deferred_open_queue\n", (unsigned int)msg_len));
757 /****************************************************************************
758 Function to delete a sharing violation open message by mid.
759 ****************************************************************************/
761 void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
764 struct smbd_server_connection *sconn = xconn->client->sconn;
765 struct pending_message_list *pml;
767 if (sconn->using_smb2) {
768 remove_deferred_open_message_smb2(xconn, mid);
772 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
773 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
774 DEBUG(10,("remove_deferred_open_message_smb: "
775 "deleting mid %llu len %u\n",
776 (unsigned long long)mid,
777 (unsigned int)pml->buf.length ));
778 DLIST_REMOVE(sconn->deferred_open_queue, pml);
785 /****************************************************************************
786 Move a sharing violation open retry message to the front of the list and
787 schedule it for immediate processing.
788 ****************************************************************************/
790 bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
793 struct smbd_server_connection *sconn = xconn->client->sconn;
794 struct pending_message_list *pml;
797 if (sconn->using_smb2) {
798 return schedule_deferred_open_message_smb2(xconn, mid);
801 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
802 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
804 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
807 (unsigned long long)msg_mid ));
809 if (mid == msg_mid) {
810 struct tevent_timer *te;
812 if (pml->processed) {
813 /* A processed message should not be
815 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
816 "message mid %llu was already processed\n",
817 (unsigned long long)msg_mid ));
821 DEBUG(10,("schedule_deferred_open_message_smb: "
822 "scheduling mid %llu\n",
823 (unsigned long long)mid ));
826 * smbd_deferred_open_timer() calls
827 * process_smb() to redispatch the request
828 * including the required impersonation.
830 * So we can just use the raw tevent_context.
832 te = tevent_add_timer(xconn->client->raw_ev_ctx,
835 smbd_deferred_open_timer,
838 DEBUG(10,("schedule_deferred_open_message_smb: "
839 "event_add_timed() failed, "
840 "skipping mid %llu\n",
841 (unsigned long long)msg_mid ));
844 TALLOC_FREE(pml->te);
846 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
851 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
852 "find message mid %llu\n",
853 (unsigned long long)mid ));
858 /****************************************************************************
859 Return true if this mid is on the deferred queue and was not yet processed.
860 ****************************************************************************/
862 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
864 struct smbd_server_connection *sconn = xconn->client->sconn;
865 struct pending_message_list *pml;
867 if (sconn->using_smb2) {
868 return open_was_deferred_smb2(xconn, mid);
871 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
872 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
879 /****************************************************************************
880 Return the message queued by this mid.
881 ****************************************************************************/
883 static struct pending_message_list *get_deferred_open_message_smb(
884 struct smbd_server_connection *sconn, uint64_t mid)
886 struct pending_message_list *pml;
888 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
889 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
896 /****************************************************************************
897 Get the state data queued by this mid.
898 ****************************************************************************/
900 bool get_deferred_open_message_state(struct smb_request *smbreq,
901 struct timeval *p_request_time,
902 struct deferred_open_record **open_rec)
904 struct pending_message_list *pml;
906 if (smbreq->sconn->using_smb2) {
907 return get_deferred_open_message_state_smb2(smbreq->smb2req,
912 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
916 if (p_request_time) {
917 *p_request_time = pml->request_time;
919 if (open_rec != NULL) {
920 *open_rec = pml->open_rec;
925 /****************************************************************************
926 Function to push a deferred open smb message onto a linked list of local smb
927 messages ready for processing.
928 ****************************************************************************/
930 bool push_deferred_open_message_smb(struct smb_request *req,
931 struct timeval request_time,
932 struct timeval timeout,
934 struct deferred_open_record *open_rec)
936 struct timeval end_time;
939 return push_deferred_open_message_smb2(req->smb2req,
946 if (req->unread_bytes) {
947 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
948 "unread_bytes = %u\n",
949 (unsigned int)req->unread_bytes ));
950 smb_panic("push_deferred_open_message_smb: "
951 "logic error unread_bytes != 0" );
954 end_time = timeval_sum(&request_time, &timeout);
956 DEBUG(10,("push_deferred_open_message_smb: pushing message "
957 "len %u mid %llu timeout time [%u.%06u]\n",
958 (unsigned int) smb_len(req->inbuf)+4,
959 (unsigned long long)req->mid,
960 (unsigned int)end_time.tv_sec,
961 (unsigned int)end_time.tv_usec));
963 return push_queued_message(req, request_time, end_time, open_rec);
966 static void smbd_sig_term_handler(struct tevent_context *ev,
967 struct tevent_signal *se,
973 exit_server_cleanly("termination signal");
976 static void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
978 struct tevent_signal *se;
980 se = tevent_add_signal(sconn->root_ev_ctx,
983 smbd_sig_term_handler,
986 exit_server("failed to setup SIGTERM handler");
990 static void smbd_sig_hup_handler(struct tevent_context *ev,
991 struct tevent_signal *se,
997 struct smbd_server_connection *sconn =
998 talloc_get_type_abort(private_data,
999 struct smbd_server_connection);
1001 DEBUG(1,("Reloading services after SIGHUP\n"));
1002 reload_services(sconn, conn_snum_used, false);
1005 static void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1007 struct tevent_signal *se;
1009 se = tevent_add_signal(sconn->root_ev_ctx,
1012 smbd_sig_hup_handler,
1015 exit_server("failed to setup SIGHUP handler");
1019 static void smbd_conf_updated(struct messaging_context *msg,
1022 struct server_id server_id,
1025 struct smbd_server_connection *sconn =
1026 talloc_get_type_abort(private_data,
1027 struct smbd_server_connection);
1029 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1030 "updated. Reloading.\n"));
1031 change_to_root_user();
1032 reload_services(sconn, conn_snum_used, false);
1036 * Only allow 5 outstanding trans requests. We're allocating memory, so
1040 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1043 for (; list != NULL; list = list->next) {
1045 if (list->mid == mid) {
1046 return NT_STATUS_INVALID_PARAMETER;
1052 return NT_STATUS_INSUFFICIENT_RESOURCES;
1055 return NT_STATUS_OK;
1059 These flags determine some of the permissions required to do an operation
1061 Note that I don't set NEED_WRITE on some write operations because they
1062 are used by some brain-dead clients when printing, and I don't want to
1063 force write permissions on print services.
1065 #define AS_USER (1<<0)
1066 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1067 #define TIME_INIT (1<<2)
1068 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1069 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1070 #define DO_CHDIR (1<<6)
1073 define a list of possible SMB messages and their corresponding
1074 functions. Any message that has a NULL function is unimplemented -
1075 please feel free to contribute implementations!
1077 static const struct smb_message_struct {
1079 void (*fn)(struct smb_request *req);
1081 } smb_messages[256] = {
1083 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1084 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1085 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1086 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1087 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1088 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1089 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1090 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1091 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1092 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1093 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1094 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1095 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1096 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1097 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1098 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1099 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1100 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1101 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1102 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1103 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1104 /* 0x15 */ { NULL, NULL, 0 },
1105 /* 0x16 */ { NULL, NULL, 0 },
1106 /* 0x17 */ { NULL, NULL, 0 },
1107 /* 0x18 */ { NULL, NULL, 0 },
1108 /* 0x19 */ { NULL, NULL, 0 },
1109 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1110 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1111 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1112 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1113 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1114 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1115 /* 0x20 */ { "SMBwritec", NULL,0},
1116 /* 0x21 */ { NULL, NULL, 0 },
1117 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1118 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1119 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1120 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1121 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1122 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1123 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1124 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1125 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1126 /* 0x2b */ { "SMBecho",reply_echo,0},
1127 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1128 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1129 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1130 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1131 /* 0x30 */ { NULL, NULL, 0 },
1132 /* 0x31 */ { NULL, NULL, 0 },
1133 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1134 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1135 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1136 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1137 /* 0x36 */ { NULL, NULL, 0 },
1138 /* 0x37 */ { NULL, NULL, 0 },
1139 /* 0x38 */ { NULL, NULL, 0 },
1140 /* 0x39 */ { NULL, NULL, 0 },
1141 /* 0x3a */ { NULL, NULL, 0 },
1142 /* 0x3b */ { NULL, NULL, 0 },
1143 /* 0x3c */ { NULL, NULL, 0 },
1144 /* 0x3d */ { NULL, NULL, 0 },
1145 /* 0x3e */ { NULL, NULL, 0 },
1146 /* 0x3f */ { NULL, NULL, 0 },
1147 /* 0x40 */ { NULL, NULL, 0 },
1148 /* 0x41 */ { NULL, NULL, 0 },
1149 /* 0x42 */ { NULL, NULL, 0 },
1150 /* 0x43 */ { NULL, NULL, 0 },
1151 /* 0x44 */ { NULL, NULL, 0 },
1152 /* 0x45 */ { NULL, NULL, 0 },
1153 /* 0x46 */ { NULL, NULL, 0 },
1154 /* 0x47 */ { NULL, NULL, 0 },
1155 /* 0x48 */ { NULL, NULL, 0 },
1156 /* 0x49 */ { NULL, NULL, 0 },
1157 /* 0x4a */ { NULL, NULL, 0 },
1158 /* 0x4b */ { NULL, NULL, 0 },
1159 /* 0x4c */ { NULL, NULL, 0 },
1160 /* 0x4d */ { NULL, NULL, 0 },
1161 /* 0x4e */ { NULL, NULL, 0 },
1162 /* 0x4f */ { NULL, NULL, 0 },
1163 /* 0x50 */ { NULL, NULL, 0 },
1164 /* 0x51 */ { NULL, NULL, 0 },
1165 /* 0x52 */ { NULL, NULL, 0 },
1166 /* 0x53 */ { NULL, NULL, 0 },
1167 /* 0x54 */ { NULL, NULL, 0 },
1168 /* 0x55 */ { NULL, NULL, 0 },
1169 /* 0x56 */ { NULL, NULL, 0 },
1170 /* 0x57 */ { NULL, NULL, 0 },
1171 /* 0x58 */ { NULL, NULL, 0 },
1172 /* 0x59 */ { NULL, NULL, 0 },
1173 /* 0x5a */ { NULL, NULL, 0 },
1174 /* 0x5b */ { NULL, NULL, 0 },
1175 /* 0x5c */ { NULL, NULL, 0 },
1176 /* 0x5d */ { NULL, NULL, 0 },
1177 /* 0x5e */ { NULL, NULL, 0 },
1178 /* 0x5f */ { NULL, NULL, 0 },
1179 /* 0x60 */ { NULL, NULL, 0 },
1180 /* 0x61 */ { NULL, NULL, 0 },
1181 /* 0x62 */ { NULL, NULL, 0 },
1182 /* 0x63 */ { NULL, NULL, 0 },
1183 /* 0x64 */ { NULL, NULL, 0 },
1184 /* 0x65 */ { NULL, NULL, 0 },
1185 /* 0x66 */ { NULL, NULL, 0 },
1186 /* 0x67 */ { NULL, NULL, 0 },
1187 /* 0x68 */ { NULL, NULL, 0 },
1188 /* 0x69 */ { NULL, NULL, 0 },
1189 /* 0x6a */ { NULL, NULL, 0 },
1190 /* 0x6b */ { NULL, NULL, 0 },
1191 /* 0x6c */ { NULL, NULL, 0 },
1192 /* 0x6d */ { NULL, NULL, 0 },
1193 /* 0x6e */ { NULL, NULL, 0 },
1194 /* 0x6f */ { NULL, NULL, 0 },
1195 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1196 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1197 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1198 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1199 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1200 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1201 /* 0x76 */ { NULL, NULL, 0 },
1202 /* 0x77 */ { NULL, NULL, 0 },
1203 /* 0x78 */ { NULL, NULL, 0 },
1204 /* 0x79 */ { NULL, NULL, 0 },
1205 /* 0x7a */ { NULL, NULL, 0 },
1206 /* 0x7b */ { NULL, NULL, 0 },
1207 /* 0x7c */ { NULL, NULL, 0 },
1208 /* 0x7d */ { NULL, NULL, 0 },
1209 /* 0x7e */ { NULL, NULL, 0 },
1210 /* 0x7f */ { NULL, NULL, 0 },
1211 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1212 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1213 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1214 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1215 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1216 /* 0x85 */ { NULL, NULL, 0 },
1217 /* 0x86 */ { NULL, NULL, 0 },
1218 /* 0x87 */ { NULL, NULL, 0 },
1219 /* 0x88 */ { NULL, NULL, 0 },
1220 /* 0x89 */ { NULL, NULL, 0 },
1221 /* 0x8a */ { NULL, NULL, 0 },
1222 /* 0x8b */ { NULL, NULL, 0 },
1223 /* 0x8c */ { NULL, NULL, 0 },
1224 /* 0x8d */ { NULL, NULL, 0 },
1225 /* 0x8e */ { NULL, NULL, 0 },
1226 /* 0x8f */ { NULL, NULL, 0 },
1227 /* 0x90 */ { NULL, NULL, 0 },
1228 /* 0x91 */ { NULL, NULL, 0 },
1229 /* 0x92 */ { NULL, NULL, 0 },
1230 /* 0x93 */ { NULL, NULL, 0 },
1231 /* 0x94 */ { NULL, NULL, 0 },
1232 /* 0x95 */ { NULL, NULL, 0 },
1233 /* 0x96 */ { NULL, NULL, 0 },
1234 /* 0x97 */ { NULL, NULL, 0 },
1235 /* 0x98 */ { NULL, NULL, 0 },
1236 /* 0x99 */ { NULL, NULL, 0 },
1237 /* 0x9a */ { NULL, NULL, 0 },
1238 /* 0x9b */ { NULL, NULL, 0 },
1239 /* 0x9c */ { NULL, NULL, 0 },
1240 /* 0x9d */ { NULL, NULL, 0 },
1241 /* 0x9e */ { NULL, NULL, 0 },
1242 /* 0x9f */ { NULL, NULL, 0 },
1243 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1244 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1245 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1246 /* 0xa3 */ { NULL, NULL, 0 },
1247 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1248 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1249 /* 0xa6 */ { NULL, NULL, 0 },
1250 /* 0xa7 */ { NULL, NULL, 0 },
1251 /* 0xa8 */ { NULL, NULL, 0 },
1252 /* 0xa9 */ { NULL, NULL, 0 },
1253 /* 0xaa */ { NULL, NULL, 0 },
1254 /* 0xab */ { NULL, NULL, 0 },
1255 /* 0xac */ { NULL, NULL, 0 },
1256 /* 0xad */ { NULL, NULL, 0 },
1257 /* 0xae */ { NULL, NULL, 0 },
1258 /* 0xaf */ { NULL, NULL, 0 },
1259 /* 0xb0 */ { NULL, NULL, 0 },
1260 /* 0xb1 */ { NULL, NULL, 0 },
1261 /* 0xb2 */ { NULL, NULL, 0 },
1262 /* 0xb3 */ { NULL, NULL, 0 },
1263 /* 0xb4 */ { NULL, NULL, 0 },
1264 /* 0xb5 */ { NULL, NULL, 0 },
1265 /* 0xb6 */ { NULL, NULL, 0 },
1266 /* 0xb7 */ { NULL, NULL, 0 },
1267 /* 0xb8 */ { NULL, NULL, 0 },
1268 /* 0xb9 */ { NULL, NULL, 0 },
1269 /* 0xba */ { NULL, NULL, 0 },
1270 /* 0xbb */ { NULL, NULL, 0 },
1271 /* 0xbc */ { NULL, NULL, 0 },
1272 /* 0xbd */ { NULL, NULL, 0 },
1273 /* 0xbe */ { NULL, NULL, 0 },
1274 /* 0xbf */ { NULL, NULL, 0 },
1275 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1276 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1277 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1278 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1279 /* 0xc4 */ { NULL, NULL, 0 },
1280 /* 0xc5 */ { NULL, NULL, 0 },
1281 /* 0xc6 */ { NULL, NULL, 0 },
1282 /* 0xc7 */ { NULL, NULL, 0 },
1283 /* 0xc8 */ { NULL, NULL, 0 },
1284 /* 0xc9 */ { NULL, NULL, 0 },
1285 /* 0xca */ { NULL, NULL, 0 },
1286 /* 0xcb */ { NULL, NULL, 0 },
1287 /* 0xcc */ { NULL, NULL, 0 },
1288 /* 0xcd */ { NULL, NULL, 0 },
1289 /* 0xce */ { NULL, NULL, 0 },
1290 /* 0xcf */ { NULL, NULL, 0 },
1291 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1292 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1293 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1294 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1295 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1296 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1297 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1298 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1299 /* 0xd8 */ { NULL, NULL, 0 },
1300 /* 0xd9 */ { NULL, NULL, 0 },
1301 /* 0xda */ { NULL, NULL, 0 },
1302 /* 0xdb */ { NULL, NULL, 0 },
1303 /* 0xdc */ { NULL, NULL, 0 },
1304 /* 0xdd */ { NULL, NULL, 0 },
1305 /* 0xde */ { NULL, NULL, 0 },
1306 /* 0xdf */ { NULL, NULL, 0 },
1307 /* 0xe0 */ { NULL, NULL, 0 },
1308 /* 0xe1 */ { NULL, NULL, 0 },
1309 /* 0xe2 */ { NULL, NULL, 0 },
1310 /* 0xe3 */ { NULL, NULL, 0 },
1311 /* 0xe4 */ { NULL, NULL, 0 },
1312 /* 0xe5 */ { NULL, NULL, 0 },
1313 /* 0xe6 */ { NULL, NULL, 0 },
1314 /* 0xe7 */ { NULL, NULL, 0 },
1315 /* 0xe8 */ { NULL, NULL, 0 },
1316 /* 0xe9 */ { NULL, NULL, 0 },
1317 /* 0xea */ { NULL, NULL, 0 },
1318 /* 0xeb */ { NULL, NULL, 0 },
1319 /* 0xec */ { NULL, NULL, 0 },
1320 /* 0xed */ { NULL, NULL, 0 },
1321 /* 0xee */ { NULL, NULL, 0 },
1322 /* 0xef */ { NULL, NULL, 0 },
1323 /* 0xf0 */ { NULL, NULL, 0 },
1324 /* 0xf1 */ { NULL, NULL, 0 },
1325 /* 0xf2 */ { NULL, NULL, 0 },
1326 /* 0xf3 */ { NULL, NULL, 0 },
1327 /* 0xf4 */ { NULL, NULL, 0 },
1328 /* 0xf5 */ { NULL, NULL, 0 },
1329 /* 0xf6 */ { NULL, NULL, 0 },
1330 /* 0xf7 */ { NULL, NULL, 0 },
1331 /* 0xf8 */ { NULL, NULL, 0 },
1332 /* 0xf9 */ { NULL, NULL, 0 },
1333 /* 0xfa */ { NULL, NULL, 0 },
1334 /* 0xfb */ { NULL, NULL, 0 },
1335 /* 0xfc */ { NULL, NULL, 0 },
1336 /* 0xfd */ { NULL, NULL, 0 },
1337 /* 0xfe */ { NULL, NULL, 0 },
1338 /* 0xff */ { NULL, NULL, 0 }
1342 /*******************************************************************
1343 allocate and initialize a reply packet
1344 ********************************************************************/
1346 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1347 const uint8_t *inbuf, char **outbuf,
1348 uint8_t num_words, uint32_t num_bytes)
1350 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1353 * Protect against integer wrap.
1354 * The SMB layer reply can be up to 0xFFFFFF bytes.
1356 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1358 if (asprintf(&msg, "num_bytes too large: %u",
1359 (unsigned)num_bytes) == -1) {
1360 msg = discard_const_p(char, "num_bytes too large");
1366 * Here we include the NBT header for now.
1368 *outbuf = talloc_array(mem_ctx, char,
1369 NBT_HDR_SIZE + smb_len);
1370 if (*outbuf == NULL) {
1374 construct_reply_common(req->cmd, inbuf, *outbuf);
1375 srv_set_message(*outbuf, num_words, num_bytes, false);
1377 * Zero out the word area, the caller has to take care of the bcc area
1380 if (num_words != 0) {
1381 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1387 void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1390 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1392 smb_panic("could not allocate output buffer\n");
1394 req->outbuf = (uint8_t *)outbuf;
1398 /*******************************************************************
1399 Dump a packet to a file.
1400 ********************************************************************/
1402 static void smb_dump(const char *name, int type, const char *data)
1407 if (DEBUGLEVEL < 50) {
1411 len = smb_len_tcp(data)+4;
1412 for (i=1;i<100;i++) {
1413 fname = talloc_asprintf(talloc_tos(),
1417 type ? "req" : "resp");
1418 if (fname == NULL) {
1421 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1422 if (fd != -1 || errno != EEXIST) break;
1426 ssize_t ret = write(fd, data, len);
1428 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1430 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1435 static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
1436 struct smb_request *req,
1438 bool *update_session_globalp,
1439 bool *update_tcon_globalp)
1441 connection_struct *conn = req->conn;
1442 struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
1443 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
1444 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1445 bool update_session = false;
1446 bool update_tcon = false;
1448 if (req->encrypted) {
1449 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
1452 if (srv_is_signing_active(req->xconn)) {
1453 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
1454 } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
1456 * echo can be unsigned. Sesssion setup except final
1457 * session setup response too
1459 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1462 update_session |= smbXsrv_set_crypto_flag(
1463 &session->global->encryption_flags, encrypt_flag);
1464 update_session |= smbXsrv_set_crypto_flag(
1465 &session->global->signing_flags, sign_flag);
1468 update_tcon |= smbXsrv_set_crypto_flag(
1469 &tcon->global->encryption_flags, encrypt_flag);
1470 update_tcon |= smbXsrv_set_crypto_flag(
1471 &tcon->global->signing_flags, sign_flag);
1474 if (update_session) {
1475 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1478 *update_session_globalp = update_session;
1479 *update_tcon_globalp = update_tcon;
1483 /****************************************************************************
1484 Prepare everything for calling the actual request function, and potentially
1485 call the request function via the "new" interface.
1487 Return False if the "legacy" function needs to be called, everything is
1490 Return True if we're done.
1492 I know this API sucks, but it is the one with the least code change I could
1494 ****************************************************************************/
1496 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1499 uint64_t session_tag;
1500 connection_struct *conn = NULL;
1501 struct smbXsrv_connection *xconn = req->xconn;
1502 NTTIME now = timeval_to_nttime(&req->request_time);
1503 struct smbXsrv_session *session = NULL;
1510 if (!xconn->smb1.negprot.done) {
1513 * Without a negprot the request must
1514 * either be a negprot, or one of the
1515 * evil old SMB mailslot messaging types.
1523 exit_server_cleanly("The first request "
1524 "should be a negprot");
1528 if (smb_messages[type].fn == NULL) {
1529 DEBUG(0,("Unknown message type %d!\n",type));
1530 smb_dump("Unknown", 1, (const char *)req->inbuf);
1531 reply_unknown_new(req, type);
1535 flags = smb_messages[type].flags;
1537 /* In share mode security we must ignore the vuid. */
1538 session_tag = req->vuid;
1541 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1542 (int)getpid(), (unsigned long)conn));
1544 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1546 /* Ensure this value is replaced in the incoming packet. */
1547 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1550 * Ensure the correct username is in current_user_info. This is a
1551 * really ugly bugfix for problems with multiple session_setup_and_X's
1552 * being done and allowing %U and %G substitutions to work correctly.
1553 * There is a reason this code is done here, don't move it unless you
1554 * know what you're doing... :-).
1559 * lookup an existing session
1561 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1562 * here, the main check is still in change_to_user()
1564 status = smb1srv_session_lookup(xconn,
1568 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1571 status = NT_STATUS_OK;
1574 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1575 (unsigned long long)session_tag,
1576 (unsigned long long)req->mid));
1577 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1582 if (session != NULL && !(flags & AS_USER)) {
1583 struct user_struct *vuser = session->compat;
1586 * change_to_user() implies set_current_user_info()
1587 * and chdir_connect_service().
1589 * So we only call set_current_user_info if
1590 * we don't have AS_USER specified.
1593 set_current_user_info(
1594 vuser->session_info->unix_info->sanitized_username,
1595 vuser->session_info->unix_info->unix_name,
1596 vuser->session_info->info->domain_name);
1600 /* Does this call need to be run as the connected user? */
1601 if (flags & AS_USER) {
1603 /* Does this call need a valid tree connection? */
1606 * Amazingly, the error code depends on the command
1609 if (type == SMBntcreateX) {
1610 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1612 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1617 set_current_case_sensitive(conn, SVAL(req->inbuf,smb_flg));
1620 * change_to_user() implies set_current_user_info()
1621 * and chdir_connect_service().
1623 if (!change_to_user(conn,session_tag)) {
1624 DEBUG(0, ("Error: Could not change to user. Removing "
1625 "deferred open, mid=%llu.\n",
1626 (unsigned long long)req->mid));
1627 reply_force_doserror(req, ERRSRV, ERRbaduid);
1631 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1633 /* Does it need write permission? */
1634 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1635 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1639 /* IPC services are limited */
1640 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1641 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1645 req->ev_ctx = conn->user_ev_ctx;
1646 } else if (flags & AS_GUEST) {
1648 * Does this protocol need to be run as guest? (Only archane
1649 * messenger service requests have this...)
1651 if (!change_to_guest()) {
1652 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1656 req->ev_ctx = req->sconn->guest_ev_ctx;
1658 /* This call needs to be run as root */
1659 change_to_root_user();
1661 req->ev_ctx = req->sconn->root_ev_ctx;
1664 /* load service specific parameters */
1666 if (req->encrypted) {
1667 conn->encrypted_tid = true;
1668 /* encrypted required from now on. */
1669 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1670 } else if (ENCRYPTION_REQUIRED(conn)) {
1671 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1672 DEBUG(1,("service[%s] requires encryption"
1673 "%s ACCESS_DENIED. mid=%llu\n",
1674 lp_servicename(talloc_tos(), SNUM(conn)),
1676 (unsigned long long)req->mid));
1677 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1682 if (flags & DO_CHDIR) {
1685 ok = chdir_current_service(conn);
1687 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1691 conn->num_smb_operations++;
1695 * Update encryption and signing state tracking flags that are
1696 * used by smbstatus to display signing and encryption status.
1698 if (session != NULL) {
1699 bool update_session_global = false;
1700 bool update_tcon_global = false;
1702 smb1srv_update_crypto_flags(session, req, type,
1703 &update_session_global,
1704 &update_tcon_global);
1706 if (update_session_global) {
1707 status = smbXsrv_session_update(session);
1708 if (!NT_STATUS_IS_OK(status)) {
1709 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1714 if (update_tcon_global) {
1715 status = smbXsrv_tcon_update(req->conn->tcon);
1716 if (!NT_STATUS_IS_OK(status)) {
1717 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1723 smb_messages[type].fn(req);
1727 /****************************************************************************
1728 Construct a reply to the incoming packet.
1729 ****************************************************************************/
1731 static void construct_reply(struct smbXsrv_connection *xconn,
1732 char *inbuf, int size, size_t unread_bytes,
1733 uint32_t seqnum, bool encrypted,
1734 struct smb_perfcount_data *deferred_pcd)
1736 struct smbd_server_connection *sconn = xconn->client->sconn;
1737 struct smb_request *req;
1739 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1740 smb_panic("could not allocate smb_request");
1743 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1744 encrypted, seqnum)) {
1745 exit_server_cleanly("Invalid SMB request");
1748 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1750 /* we popped this message off the queue - keep original perf data */
1752 req->pcd = *deferred_pcd;
1754 SMB_PERFCOUNT_START(&req->pcd);
1755 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1756 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1759 req->conn = switch_message(req->cmd, req);
1761 if (req->outbuf == NULL) {
1763 * Request has suspended itself, will come
1768 if (CVAL(req->outbuf,0) == 0) {
1769 show_msg((char *)req->outbuf);
1771 smb_request_done(req);
1774 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1775 char *inbuf, int size, uint32_t seqnum,
1777 struct smb_perfcount_data *deferred_pcd)
1779 struct smb_request **reqs = NULL;
1780 struct smb_request *req;
1784 ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
1785 seqnum, &reqs, &num_reqs);
1787 char errbuf[smb_size];
1788 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1789 __LINE__, __FILE__);
1790 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1792 exit_server_cleanly("construct_reply_chain: "
1793 "srv_send_smb failed.");
1799 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1801 req->conn = switch_message(req->cmd, req);
1803 if (req->outbuf == NULL) {
1805 * Request has suspended itself, will come
1810 smb_request_done(req);
1814 * To be called from an async SMB handler that is potentially chained
1815 * when it is finished for shipping.
1818 void smb_request_done(struct smb_request *req)
1820 struct smb_request **reqs = NULL;
1821 struct smb_request *first_req;
1822 size_t i, num_reqs, next_index;
1825 if (req->chain == NULL) {
1831 num_reqs = talloc_array_length(reqs);
1833 for (i=0; i<num_reqs; i++) {
1834 if (reqs[i] == req) {
1838 if (i == num_reqs) {
1840 * Invalid chain, should not happen
1842 status = NT_STATUS_INTERNAL_ERROR;
1847 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1848 struct smb_request *next = reqs[next_index];
1849 struct smbXsrv_tcon *tcon;
1850 NTTIME now = timeval_to_nttime(&req->request_time);
1852 next->vuid = SVAL(req->outbuf, smb_uid);
1853 next->tid = SVAL(req->outbuf, smb_tid);
1854 status = smb1srv_tcon_lookup(req->xconn, next->tid,
1857 if (NT_STATUS_IS_OK(status)) {
1858 next->conn = tcon->compat;
1862 next->chain_fsp = req->chain_fsp;
1863 next->inbuf = req->inbuf;
1866 req->conn = switch_message(req->cmd, req);
1868 if (req->outbuf == NULL) {
1870 * Request has suspended itself, will come
1878 first_req = reqs[0];
1880 for (i=1; i<next_index; i++) {
1883 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1885 status = NT_STATUS_INTERNAL_ERROR;
1890 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1891 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1894 * This scary statement intends to set the
1895 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1896 * to the value last_req->outbuf carries
1898 SSVAL(first_req->outbuf, smb_flg2,
1899 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1900 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1903 * Transfer the error codes from the subrequest to the main one
1905 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1906 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1909 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1912 if (!srv_send_smb(first_req->xconn,
1913 (char *)first_req->outbuf,
1914 true, first_req->seqnum+1,
1915 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1917 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1920 TALLOC_FREE(req); /* non-chained case */
1921 TALLOC_FREE(reqs); /* chained case */
1926 char errbuf[smb_size];
1927 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1928 if (!srv_send_smb(req->xconn, errbuf, true,
1929 req->seqnum+1, req->encrypted,
1931 exit_server_cleanly("construct_reply_chain: "
1932 "srv_send_smb failed.");
1935 TALLOC_FREE(req); /* non-chained case */
1936 TALLOC_FREE(reqs); /* chained case */
1939 /****************************************************************************
1940 Process an smb from the client
1941 ****************************************************************************/
1942 static void process_smb(struct smbXsrv_connection *xconn,
1943 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1944 uint32_t seqnum, bool encrypted,
1945 struct smb_perfcount_data *deferred_pcd)
1947 struct smbd_server_connection *sconn = xconn->client->sconn;
1948 int msg_type = CVAL(inbuf,0);
1950 DO_PROFILE_INC(request);
1952 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1954 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1955 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1957 if (msg_type != NBSSmessage) {
1959 * NetBIOS session request, keepalive, etc.
1961 reply_special(xconn, (char *)inbuf, nread);
1965 if (sconn->using_smb2) {
1966 /* At this point we're not really using smb2,
1967 * we make the decision here.. */
1968 if (smbd_is_smb2_header(inbuf, nread)) {
1969 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1970 size_t pdulen = nread - NBT_HDR_SIZE;
1971 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1974 if (nread >= smb_size && valid_smb_header(inbuf)
1975 && CVAL(inbuf, smb_com) != 0x72) {
1976 /* This is a non-negprot SMB1 packet.
1977 Disable SMB2 from now on. */
1978 sconn->using_smb2 = false;
1982 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1983 * so subtract 4 from it. */
1984 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1985 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1988 /* special magic for immediate exit */
1990 (IVAL(inbuf, 4) == 0x74697865) &&
1991 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1992 uint8_t exitcode = CVAL(inbuf, 8);
1993 DEBUG(1, ("Exiting immediately with code %d\n",
1998 exit_server_cleanly("Non-SMB packet");
2001 show_msg((char *)inbuf);
2003 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
2004 construct_reply_chain(xconn, (char *)inbuf, nread,
2005 seqnum, encrypted, deferred_pcd);
2007 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
2008 seqnum, encrypted, deferred_pcd);
2014 sconn->num_requests++;
2016 /* The timeout_processing function isn't run nearly
2017 often enough to implement 'max log size' without
2018 overrunning the size of the file by many megabytes.
2019 This is especially true if we are running at debug
2020 level 10. Checking every 50 SMBs is a nice
2021 tradeoff of performance vs log file size overrun. */
2023 if ((sconn->num_requests % 50) == 0 &&
2024 need_to_check_log_size()) {
2025 change_to_root_user();
2030 /****************************************************************************
2031 Return a string containing the function name of a SMB command.
2032 ****************************************************************************/
2034 const char *smb_fn_name(int type)
2036 const char *unknown_name = "SMBunknown";
2038 if (smb_messages[type].name == NULL)
2039 return(unknown_name);
2041 return(smb_messages[type].name);
2044 /****************************************************************************
2045 Helper functions for contruct_reply.
2046 ****************************************************************************/
2048 void add_to_common_flags2(uint32_t v)
2053 void remove_from_common_flags2(uint32_t v)
2055 common_flags2 &= ~v;
2058 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
2061 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
2062 uint16_t out_flags2 = common_flags2;
2064 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
2065 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
2066 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
2068 srv_set_message(outbuf,0,0,false);
2070 SCVAL(outbuf, smb_com, cmd);
2071 SIVAL(outbuf,smb_rcls,0);
2072 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
2073 SSVAL(outbuf,smb_flg2, out_flags2);
2074 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
2075 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2077 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2078 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2079 SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
2080 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2081 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2084 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2086 construct_reply_common(req->cmd, req->inbuf, outbuf);
2090 * @brief Find the smb_cmd offset of the last command pushed
2091 * @param[in] buf The buffer we're building up
2092 * @retval Where can we put our next andx cmd?
2094 * While chaining requests, the "next" request we're looking at needs to put
2095 * its SMB_Command before the data the previous request already built up added
2096 * to the chain. Find the offset to the place where we have to put our cmd.
2099 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2104 cmd = CVAL(buf, smb_com);
2106 if (!is_andx_req(cmd)) {
2112 while (CVAL(buf, ofs) != 0xff) {
2114 if (!is_andx_req(CVAL(buf, ofs))) {
2119 * ofs is from start of smb header, so add the 4 length
2120 * bytes. The next cmd is right after the wct field.
2122 ofs = SVAL(buf, ofs+2) + 4 + 1;
2124 if (ofs+4 >= talloc_get_size(buf)) {
2134 * @brief Do the smb chaining at a buffer level
2135 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2136 * @param[in] andx_buf Buffer to be appended
2139 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2141 uint8_t smb_command = CVAL(andx_buf, smb_com);
2142 uint8_t wct = CVAL(andx_buf, smb_wct);
2143 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2144 uint32_t num_bytes = smb_buflen(andx_buf);
2145 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2148 size_t old_size, new_size;
2150 size_t chain_padding = 0;
2151 size_t andx_cmd_ofs;
2154 old_size = talloc_get_size(*poutbuf);
2156 if ((old_size % 4) != 0) {
2158 * Align the wct field of subsequent requests to a 4-byte
2161 chain_padding = 4 - (old_size % 4);
2165 * After the old request comes the new wct field (1 byte), the vwv's
2166 * and the num_bytes field.
2169 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2170 new_size += num_bytes;
2172 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2173 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2174 (unsigned)new_size));
2178 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2179 if (outbuf == NULL) {
2180 DEBUG(0, ("talloc failed\n"));
2185 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2186 DEBUG(1, ("invalid command chain\n"));
2187 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2191 if (chain_padding != 0) {
2192 memset(outbuf + old_size, 0, chain_padding);
2193 old_size += chain_padding;
2196 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2197 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2202 * Push the chained request:
2207 SCVAL(outbuf, ofs, wct);
2214 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2219 * Read&X has an offset into its data buffer at
2220 * vwv[6]. reply_read_andx has no idea anymore that it's
2221 * running from within a chain, so we have to fix up the
2224 * Although it looks disgusting at this place, I want to keep
2225 * it here. The alternative would be to push knowledge about
2226 * the andx chain down into read&x again.
2229 if (smb_command == SMBreadX) {
2230 uint8_t *bytes_addr;
2234 * Invalid read&x response
2239 bytes_addr = outbuf + ofs /* vwv start */
2240 + sizeof(uint16_t) * wct /* vwv array */
2241 + sizeof(uint16_t) /* bcc */
2242 + 1; /* padding byte */
2244 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2245 bytes_addr - outbuf - 4);
2248 ofs += sizeof(uint16_t) * wct;
2254 SSVAL(outbuf, ofs, num_bytes);
2255 ofs += sizeof(uint16_t);
2261 memcpy(outbuf + ofs, bytes, num_bytes);
2266 bool smb1_is_chain(const uint8_t *buf)
2268 uint8_t cmd, wct, andx_cmd;
2270 cmd = CVAL(buf, smb_com);
2271 if (!is_andx_req(cmd)) {
2274 wct = CVAL(buf, smb_wct);
2278 andx_cmd = CVAL(buf, smb_vwv);
2279 return (andx_cmd != 0xFF);
2282 bool smb1_walk_chain(const uint8_t *buf,
2283 bool (*fn)(uint8_t cmd,
2284 uint8_t wct, const uint16_t *vwv,
2285 uint16_t num_bytes, const uint8_t *bytes,
2286 void *private_data),
2289 size_t smblen = smb_len(buf);
2290 const char *smb_buf = smb_base(buf);
2291 uint8_t cmd, chain_cmd;
2293 const uint16_t *vwv;
2295 const uint8_t *bytes;
2297 cmd = CVAL(buf, smb_com);
2298 wct = CVAL(buf, smb_wct);
2299 vwv = (const uint16_t *)(buf + smb_vwv);
2300 num_bytes = smb_buflen(buf);
2301 bytes = (const uint8_t *)smb_buf_const(buf);
2303 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2307 if (!is_andx_req(cmd)) {
2314 chain_cmd = CVAL(vwv, 0);
2316 while (chain_cmd != 0xff) {
2317 uint32_t chain_offset; /* uint32_t to avoid overflow */
2318 size_t length_needed;
2319 ptrdiff_t vwv_offset;
2321 chain_offset = SVAL(vwv+1, 0);
2324 * Check if the client tries to fool us. The chain
2325 * offset needs to point beyond the current request in
2326 * the chain, it needs to strictly grow. Otherwise we
2327 * might be tricked into an endless loop always
2328 * processing the same request over and over again. We
2329 * used to assume that vwv and the byte buffer array
2330 * in a chain are always attached, but OS/2 the
2331 * Write&X/Read&X chain puts the Read&X vwv array
2332 * right behind the Write&X vwv chain. The Write&X bcc
2333 * array is put behind the Read&X vwv array. So now we
2334 * check whether the chain offset points strictly
2335 * behind the previous vwv array. req->buf points
2336 * right after the vwv array of the previous
2338 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2342 vwv_offset = ((const char *)vwv - smb_buf);
2343 if (chain_offset <= vwv_offset) {
2348 * Next check: Make sure the chain offset does not
2349 * point beyond the overall smb request length.
2352 length_needed = chain_offset+1; /* wct */
2353 if (length_needed > smblen) {
2358 * Now comes the pointer magic. Goal here is to set up
2359 * vwv and buf correctly again. The chain offset (the
2360 * former vwv[1]) points at the new wct field.
2363 wct = CVAL(smb_buf, chain_offset);
2365 if (is_andx_req(chain_cmd) && (wct < 2)) {
2370 * Next consistency check: Make the new vwv array fits
2371 * in the overall smb request.
2374 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2375 if (length_needed > smblen) {
2378 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2381 * Now grab the new byte buffer....
2384 num_bytes = SVAL(vwv+wct, 0);
2387 * .. and check that it fits.
2390 length_needed += num_bytes;
2391 if (length_needed > smblen) {
2394 bytes = (const uint8_t *)(vwv+wct+1);
2396 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2400 if (!is_andx_req(chain_cmd)) {
2403 chain_cmd = CVAL(vwv, 0);
2408 static bool smb1_chain_length_cb(uint8_t cmd,
2409 uint8_t wct, const uint16_t *vwv,
2410 uint16_t num_bytes, const uint8_t *bytes,
2413 unsigned *count = (unsigned *)private_data;
2418 unsigned smb1_chain_length(const uint8_t *buf)
2422 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2428 struct smb1_parse_chain_state {
2429 TALLOC_CTX *mem_ctx;
2431 struct smbd_server_connection *sconn;
2432 struct smbXsrv_connection *xconn;
2436 struct smb_request **reqs;
2440 static bool smb1_parse_chain_cb(uint8_t cmd,
2441 uint8_t wct, const uint16_t *vwv,
2442 uint16_t num_bytes, const uint8_t *bytes,
2445 struct smb1_parse_chain_state *state =
2446 (struct smb1_parse_chain_state *)private_data;
2447 struct smb_request **reqs;
2448 struct smb_request *req;
2451 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2452 struct smb_request *, state->num_reqs+1);
2458 req = talloc(reqs, struct smb_request);
2463 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2464 state->encrypted, state->seqnum);
2471 req->buflen = num_bytes;
2474 reqs[state->num_reqs] = req;
2475 state->num_reqs += 1;
2479 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2480 struct smbXsrv_connection *xconn,
2481 bool encrypted, uint32_t seqnum,
2482 struct smb_request ***reqs, unsigned *num_reqs)
2484 struct smbd_server_connection *sconn = NULL;
2485 struct smb1_parse_chain_state state;
2488 if (xconn != NULL) {
2489 sconn = xconn->client->sconn;
2492 state.mem_ctx = mem_ctx;
2494 state.sconn = sconn;
2495 state.xconn = xconn;
2496 state.encrypted = encrypted;
2497 state.seqnum = seqnum;
2501 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2502 TALLOC_FREE(state.reqs);
2505 for (i=0; i<state.num_reqs; i++) {
2506 state.reqs[i]->chain = state.reqs;
2509 *num_reqs = state.num_reqs;
2513 /****************************************************************************
2514 Check if services need reloading.
2515 ****************************************************************************/
2517 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2520 if (last_smb_conf_reload_time == 0) {
2521 last_smb_conf_reload_time = t;
2524 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2525 reload_services(sconn, conn_snum_used, true);
2526 last_smb_conf_reload_time = t;
2530 static bool fd_is_readable(int fd)
2534 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2536 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2540 static void smbd_server_connection_write_handler(
2541 struct smbXsrv_connection *xconn)
2543 /* TODO: make write nonblocking */
2546 static void smbd_server_connection_read_handler(
2547 struct smbXsrv_connection *xconn, int fd)
2549 uint8_t *inbuf = NULL;
2550 size_t inbuf_len = 0;
2551 size_t unread_bytes = 0;
2552 bool encrypted = false;
2553 TALLOC_CTX *mem_ctx = talloc_tos();
2557 bool async_echo = lp_async_smb_echo_handler();
2558 bool from_client = false;
2561 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2563 * This is the super-ugly hack to prefer the packets
2564 * forwarded by the echo handler over the ones by the
2567 fd = xconn->smb1.echo_handler.trusted_fd;
2571 from_client = (xconn->transport.sock == fd);
2573 if (async_echo && from_client) {
2574 smbd_lock_socket(xconn);
2576 if (!fd_is_readable(fd)) {
2577 DEBUG(10,("the echo listener was faster\n"));
2578 smbd_unlock_socket(xconn);
2583 /* TODO: make this completely nonblocking */
2584 status = receive_smb_talloc(mem_ctx, xconn, fd,
2585 (char **)(void *)&inbuf,
2589 &inbuf_len, &seqnum,
2590 !from_client /* trusted channel */);
2592 if (async_echo && from_client) {
2593 smbd_unlock_socket(xconn);
2596 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2599 if (NT_STATUS_IS_ERR(status)) {
2600 exit_server_cleanly("failed to receive smb request");
2602 if (!NT_STATUS_IS_OK(status)) {
2607 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2608 seqnum, encrypted, NULL);
2611 static void smbd_server_connection_handler(struct tevent_context *ev,
2612 struct tevent_fd *fde,
2616 struct smbXsrv_connection *xconn =
2617 talloc_get_type_abort(private_data,
2618 struct smbXsrv_connection);
2620 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2622 * we're not supposed to do any io
2624 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2625 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2629 if (flags & TEVENT_FD_WRITE) {
2630 smbd_server_connection_write_handler(xconn);
2633 if (flags & TEVENT_FD_READ) {
2634 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2639 static void smbd_server_echo_handler(struct tevent_context *ev,
2640 struct tevent_fd *fde,
2644 struct smbXsrv_connection *xconn =
2645 talloc_get_type_abort(private_data,
2646 struct smbXsrv_connection);
2648 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2650 * we're not supposed to do any io
2652 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2653 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2657 if (flags & TEVENT_FD_WRITE) {
2658 smbd_server_connection_write_handler(xconn);
2661 if (flags & TEVENT_FD_READ) {
2662 smbd_server_connection_read_handler(
2663 xconn, xconn->smb1.echo_handler.trusted_fd);
2668 struct smbd_release_ip_state {
2669 struct smbXsrv_connection *xconn;
2670 struct tevent_immediate *im;
2671 char addr[INET6_ADDRSTRLEN];
2674 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2675 struct tevent_immediate *im,
2678 struct smbd_release_ip_state *state =
2679 talloc_get_type_abort(private_data,
2680 struct smbd_release_ip_state);
2681 struct smbXsrv_connection *xconn = state->xconn;
2683 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2685 * smbd_server_connection_terminate() already triggered ?
2690 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2693 /****************************************************************************
2694 received when we should release a specific IP
2695 ****************************************************************************/
2696 static int release_ip(struct tevent_context *ev,
2697 uint32_t src_vnn, uint32_t dst_vnn,
2699 const uint8_t *msg, size_t msglen,
2702 struct smbd_release_ip_state *state =
2703 talloc_get_type_abort(private_data,
2704 struct smbd_release_ip_state);
2705 struct smbXsrv_connection *xconn = state->xconn;
2707 const char *addr = state->addr;
2708 const char *p = addr;
2713 if (msg[msglen-1] != '\0') {
2717 ip = (const char *)msg;
2719 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2720 /* avoid recursion */
2724 if (strncmp("::ffff:", addr, 7) == 0) {
2728 DEBUG(10, ("Got release IP message for %s, "
2729 "our address is %s\n", ip, p));
2731 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2732 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2735 * With SMB2 we should do a clean disconnect,
2736 * the previous_session_id in the session setup
2737 * will cleanup the old session, tcons and opens.
2739 * A clean disconnect is needed in order to support
2742 * Note: typically this is never triggered
2743 * as we got a TCP RST (triggered by ctdb event scripts)
2744 * before we get CTDB_SRVID_RELEASE_IP.
2746 * We used to call _exit(1) here, but as this was mostly never
2747 * triggered and has implication on our process model,
2748 * we can just use smbd_server_connection_terminate()
2751 * We don't call smbd_server_connection_terminate() directly
2752 * as we might be called from within ctdbd_migrate(),
2753 * we need to defer our action to the next event loop
2755 tevent_schedule_immediate(state->im,
2756 xconn->client->raw_ev_ctx,
2757 smbd_release_ip_immediate,
2761 * Make sure we don't get any io on the connection.
2763 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2764 return EADDRNOTAVAIL;
2770 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2771 struct sockaddr_storage *srv,
2772 struct sockaddr_storage *clnt)
2774 struct smbd_release_ip_state *state;
2775 struct ctdbd_connection *cconn;
2778 cconn = messaging_ctdb_connection();
2779 if (cconn == NULL) {
2780 return NT_STATUS_NO_MEMORY;
2783 state = talloc_zero(xconn, struct smbd_release_ip_state);
2784 if (state == NULL) {
2785 return NT_STATUS_NO_MEMORY;
2787 state->xconn = xconn;
2788 state->im = tevent_create_immediate(state);
2789 if (state->im == NULL) {
2790 return NT_STATUS_NO_MEMORY;
2792 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2793 return NT_STATUS_NO_MEMORY;
2796 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2798 return map_nt_error_from_unix(ret);
2800 return NT_STATUS_OK;
2803 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2804 void *private_data, uint32_t msg_type,
2805 struct server_id server_id, DATA_BLOB *data)
2807 struct smbd_server_connection *sconn = talloc_get_type_abort(
2808 private_data, struct smbd_server_connection);
2809 const char *ip = (char *) data->data;
2812 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2814 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2816 if (client_ip == NULL) {
2820 if (strequal(ip, client_ip)) {
2821 DBG_WARNING("Got kill client message for %s - "
2822 "exiting immediately\n", ip);
2823 exit_server_cleanly("Forced disconnect for client");
2826 TALLOC_FREE(client_ip);
2830 * Send keepalive packets to our client
2832 static bool keepalive_fn(const struct timeval *now, void *private_data)
2834 struct smbd_server_connection *sconn = talloc_get_type_abort(
2835 private_data, struct smbd_server_connection);
2836 struct smbXsrv_connection *xconn = NULL;
2839 if (sconn->using_smb2) {
2840 /* Don't do keepalives on an SMB2 connection. */
2845 * With SMB1 we only have 1 connection
2847 xconn = sconn->client->connections;
2848 smbd_lock_socket(xconn);
2849 ret = send_keepalive(xconn->transport.sock);
2850 smbd_unlock_socket(xconn);
2853 int saved_errno = errno;
2855 * Try and give an error message saying what
2858 DEBUG(0, ("send_keepalive failed for client %s. "
2859 "Error %s - exiting\n",
2860 smbXsrv_connection_dbg(xconn),
2861 strerror(saved_errno)));
2862 errno = saved_errno;
2869 * Do the recurring check if we're idle
2871 static bool deadtime_fn(const struct timeval *now, void *private_data)
2873 struct smbd_server_connection *sconn =
2874 (struct smbd_server_connection *)private_data;
2876 if ((conn_num_open(sconn) == 0)
2877 || (conn_idle_all(sconn, now->tv_sec))) {
2878 DEBUG( 2, ( "Closing idle connection\n" ) );
2879 messaging_send(sconn->msg_ctx,
2880 messaging_server_id(sconn->msg_ctx),
2881 MSG_SHUTDOWN, &data_blob_null);
2889 * Do the recurring log file and smb.conf reload checks.
2892 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2894 struct smbd_server_connection *sconn = talloc_get_type_abort(
2895 private_data, struct smbd_server_connection);
2897 DEBUG(5, ("housekeeping\n"));
2899 change_to_root_user();
2901 /* update printer queue caches if necessary */
2902 update_monitored_printq_cache(sconn->msg_ctx);
2904 /* check if we need to reload services */
2905 check_reload(sconn, time_mono(NULL));
2908 * Force a log file check.
2910 force_check_log_size();
2916 * Read an smb packet in the echo handler child, giving the parent
2917 * smbd one second to react once the socket becomes readable.
2920 struct smbd_echo_read_state {
2921 struct tevent_context *ev;
2922 struct smbXsrv_connection *xconn;
2929 static void smbd_echo_read_readable(struct tevent_req *subreq);
2930 static void smbd_echo_read_waited(struct tevent_req *subreq);
2932 static struct tevent_req *smbd_echo_read_send(
2933 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2934 struct smbXsrv_connection *xconn)
2936 struct tevent_req *req, *subreq;
2937 struct smbd_echo_read_state *state;
2939 req = tevent_req_create(mem_ctx, &state,
2940 struct smbd_echo_read_state);
2945 state->xconn = xconn;
2947 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2948 if (tevent_req_nomem(subreq, req)) {
2949 return tevent_req_post(req, ev);
2951 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2955 static void smbd_echo_read_readable(struct tevent_req *subreq)
2957 struct tevent_req *req = tevent_req_callback_data(
2958 subreq, struct tevent_req);
2959 struct smbd_echo_read_state *state = tevent_req_data(
2960 req, struct smbd_echo_read_state);
2964 ok = wait_for_read_recv(subreq, &err);
2965 TALLOC_FREE(subreq);
2967 tevent_req_nterror(req, map_nt_error_from_unix(err));
2972 * Give the parent smbd one second to step in
2975 subreq = tevent_wakeup_send(
2976 state, state->ev, timeval_current_ofs(1, 0));
2977 if (tevent_req_nomem(subreq, req)) {
2980 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2983 static void smbd_echo_read_waited(struct tevent_req *subreq)
2985 struct tevent_req *req = tevent_req_callback_data(
2986 subreq, struct tevent_req);
2987 struct smbd_echo_read_state *state = tevent_req_data(
2988 req, struct smbd_echo_read_state);
2989 struct smbXsrv_connection *xconn = state->xconn;
2995 ok = tevent_wakeup_recv(subreq);
2996 TALLOC_FREE(subreq);
2998 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
3002 ok = smbd_lock_socket_internal(xconn);
3004 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3005 DEBUG(0, ("%s: failed to lock socket\n", __location__));
3009 if (!fd_is_readable(xconn->transport.sock)) {
3010 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3013 ok = smbd_unlock_socket_internal(xconn);
3015 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3016 DEBUG(1, ("%s: failed to unlock socket\n",
3021 subreq = wait_for_read_send(state, state->ev,
3022 xconn->transport.sock, false);
3023 if (tevent_req_nomem(subreq, req)) {
3026 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
3030 status = receive_smb_talloc(state, xconn,
3031 xconn->transport.sock,
3038 false /* trusted_channel*/);
3040 if (tevent_req_nterror(req, status)) {
3041 tevent_req_nterror(req, status);
3042 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3043 (int)getpid(), nt_errstr(status)));
3047 ok = smbd_unlock_socket_internal(xconn);
3049 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3050 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
3053 tevent_req_done(req);
3056 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3057 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
3059 struct smbd_echo_read_state *state = tevent_req_data(
3060 req, struct smbd_echo_read_state);
3063 if (tevent_req_is_nterror(req, &status)) {
3066 *pbuf = talloc_move(mem_ctx, &state->buf);
3067 *pbuflen = state->buflen;
3068 *pseqnum = state->seqnum;
3069 return NT_STATUS_OK;
3072 struct smbd_echo_state {
3073 struct tevent_context *ev;
3074 struct iovec *pending;
3075 struct smbd_server_connection *sconn;
3076 struct smbXsrv_connection *xconn;
3079 struct tevent_fd *parent_fde;
3081 struct tevent_req *write_req;
3084 static void smbd_echo_writer_done(struct tevent_req *req);
3086 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3090 if (state->write_req != NULL) {
3094 num_pending = talloc_array_length(state->pending);
3095 if (num_pending == 0) {
3099 state->write_req = writev_send(state, state->ev, NULL,
3100 state->parent_pipe, false,
3101 state->pending, num_pending);
3102 if (state->write_req == NULL) {
3103 DEBUG(1, ("writev_send failed\n"));
3107 talloc_steal(state->write_req, state->pending);
3108 state->pending = NULL;
3110 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3114 static void smbd_echo_writer_done(struct tevent_req *req)
3116 struct smbd_echo_state *state = tevent_req_callback_data(
3117 req, struct smbd_echo_state);
3121 written = writev_recv(req, &err);
3123 state->write_req = NULL;
3124 if (written == -1) {
3125 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3128 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3129 smbd_echo_activate_writer(state);
3132 static bool smbd_echo_reply(struct smbd_echo_state *state,
3133 uint8_t *inbuf, size_t inbuf_len,
3136 struct smb_request req;
3137 uint16_t num_replies;
3141 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3142 DEBUG(10, ("Got netbios keepalive\n"));
3149 if (inbuf_len < smb_size) {
3150 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3153 if (!valid_smb_header(inbuf)) {
3154 DEBUG(10, ("Got invalid SMB header\n"));
3158 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3164 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3165 smb_messages[req.cmd].name
3166 ? smb_messages[req.cmd].name : "unknown"));
3168 if (req.cmd != SMBecho) {
3175 num_replies = SVAL(req.vwv+0, 0);
3176 if (num_replies != 1) {
3177 /* Not a Windows "Hey, you're still there?" request */
3181 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3183 DEBUG(10, ("create_outbuf failed\n"));
3186 req.outbuf = (uint8_t *)outbuf;
3188 SSVAL(req.outbuf, smb_vwv0, num_replies);
3190 if (req.buflen > 0) {
3191 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3194 ok = srv_send_smb(req.xconn,
3198 TALLOC_FREE(outbuf);
3206 static void smbd_echo_exit(struct tevent_context *ev,
3207 struct tevent_fd *fde, uint16_t flags,
3210 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3214 static void smbd_echo_got_packet(struct tevent_req *req);
3216 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3219 struct smbd_echo_state *state;
3220 struct tevent_req *read_req;
3222 state = talloc_zero(xconn, struct smbd_echo_state);
3223 if (state == NULL) {
3224 DEBUG(1, ("talloc failed\n"));
3227 state->xconn = xconn;
3228 state->parent_pipe = parent_pipe;
3229 state->ev = samba_tevent_context_init(state);
3230 if (state->ev == NULL) {
3231 DEBUG(1, ("samba_tevent_context_init failed\n"));
3235 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3236 TEVENT_FD_READ, smbd_echo_exit,
3238 if (state->parent_fde == NULL) {
3239 DEBUG(1, ("tevent_add_fd failed\n"));
3244 read_req = smbd_echo_read_send(state, state->ev, xconn);
3245 if (read_req == NULL) {
3246 DEBUG(1, ("smbd_echo_read_send failed\n"));
3250 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3253 if (tevent_loop_once(state->ev) == -1) {
3254 DEBUG(1, ("tevent_loop_once failed: %s\n",
3262 static void smbd_echo_got_packet(struct tevent_req *req)
3264 struct smbd_echo_state *state = tevent_req_callback_data(
3265 req, struct smbd_echo_state);
3269 uint32_t seqnum = 0;
3272 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3274 if (!NT_STATUS_IS_OK(status)) {
3275 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3276 nt_errstr(status)));
3280 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3286 num_pending = talloc_array_length(state->pending);
3287 tmp = talloc_realloc(state, state->pending, struct iovec,
3290 DEBUG(1, ("talloc_realloc failed\n"));
3293 state->pending = tmp;
3295 if (buflen >= smb_size) {
3297 * place the seqnum in the packet so that the main process
3298 * can reply with signing
3300 SIVAL(buf, smb_ss_field, seqnum);
3301 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3304 iov = &state->pending[num_pending];
3305 iov->iov_base = talloc_move(state->pending, &buf);
3306 iov->iov_len = buflen;
3308 DEBUG(10,("echo_handler[%d]: forward to main\n",
3310 smbd_echo_activate_writer(state);
3313 req = smbd_echo_read_send(state, state->ev, state->xconn);
3315 DEBUG(1, ("smbd_echo_read_send failed\n"));
3318 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3323 * Handle SMBecho requests in a forked child process
3325 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3327 int listener_pipe[2];
3330 bool use_mutex = false;
3332 res = pipe(listener_pipe);
3334 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3338 #ifdef HAVE_ROBUST_MUTEXES
3339 use_mutex = tdb_runtime_check_for_robust_mutexes();
3342 pthread_mutexattr_t a;
3344 xconn->smb1.echo_handler.socket_mutex =
3345 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3346 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3347 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3352 res = pthread_mutexattr_init(&a);
3354 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3358 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3360 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3362 pthread_mutexattr_destroy(&a);
3365 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3367 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3369 pthread_mutexattr_destroy(&a);
3372 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3374 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3375 "%s\n", strerror(res)));
3376 pthread_mutexattr_destroy(&a);
3379 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3381 pthread_mutexattr_destroy(&a);
3383 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3391 xconn->smb1.echo_handler.socket_lock_fd =
3392 create_unlink_tmp(lp_lock_directory());
3393 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3394 DEBUG(1, ("Could not create lock fd: %s\n",
3404 close(listener_pipe[0]);
3405 set_blocking(listener_pipe[1], false);
3407 status = smbd_reinit_after_fork(xconn->client->msg_ctx,
3408 xconn->client->raw_ev_ctx,
3411 if (!NT_STATUS_IS_OK(status)) {
3412 DEBUG(1, ("reinit_after_fork failed: %s\n",
3413 nt_errstr(status)));
3416 initialize_password_db(true, xconn->client->raw_ev_ctx);
3417 smbd_echo_loop(xconn, listener_pipe[1]);
3420 close(listener_pipe[1]);
3421 listener_pipe[1] = -1;
3422 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3424 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3427 * Without smb signing this is the same as the normal smbd
3428 * listener. This needs to change once signing comes in.
3430 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(
3431 xconn->client->raw_ev_ctx,
3433 xconn->smb1.echo_handler.trusted_fd,
3435 smbd_server_echo_handler,
3437 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3438 DEBUG(1, ("event_add_fd failed\n"));
3445 if (listener_pipe[0] != -1) {
3446 close(listener_pipe[0]);
3448 if (listener_pipe[1] != -1) {
3449 close(listener_pipe[1]);
3451 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3452 close(xconn->smb1.echo_handler.socket_lock_fd);
3454 #ifdef HAVE_ROBUST_MUTEXES
3455 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3456 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3457 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3460 smbd_echo_init(xconn);
3465 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3468 if (user->session_info &&
3469 (user->session_info->unix_token->uid == uid)) {
3477 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3480 if (user->session_info != NULL) {
3482 struct security_unix_token *utok;
3484 utok = user->session_info->unix_token;
3485 if (utok->gid == gid) {
3488 for(i=0; i<utok->ngroups; i++) {
3489 if (utok->groups[i] == gid) {
3499 static bool sid_in_use(const struct user_struct *user,
3500 const struct dom_sid *psid)
3503 struct security_token *tok;
3505 if (user->session_info == NULL) {
3508 tok = user->session_info->security_token;
3511 * Not sure session_info->security_token can
3512 * ever be NULL. This check might be not
3517 if (security_token_has_sid(tok, psid)) {
3525 static bool id_in_use(const struct user_struct *user,
3526 const struct id_cache_ref *id)
3530 return uid_in_use(user, id->id.uid);
3532 return gid_in_use(user, id->id.gid);
3534 return sid_in_use(user, &id->id.sid);
3541 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3544 struct server_id server_id,
3547 const char *msg = (data && data->data)
3548 ? (const char *)data->data : "<NULL>";
3549 struct id_cache_ref id;
3550 struct smbd_server_connection *sconn =
3551 talloc_get_type_abort(private_data,
3552 struct smbd_server_connection);
3554 if (!id_cache_ref_parse(msg, &id)) {
3555 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3559 if (id_in_use(sconn->users, &id)) {
3560 exit_server_cleanly(msg);
3562 id_cache_delete_from_cache(&id);
3565 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3566 enum protocol_types protocol)
3570 conn->protocol = protocol;
3572 if (conn->client->session_table != NULL) {
3573 return NT_STATUS_OK;
3576 if (protocol >= PROTOCOL_SMB2_02) {
3577 status = smb2srv_session_table_init(conn);
3578 if (!NT_STATUS_IS_OK(status)) {
3579 conn->protocol = PROTOCOL_NONE;
3583 status = smb2srv_open_table_init(conn);
3584 if (!NT_STATUS_IS_OK(status)) {
3585 conn->protocol = PROTOCOL_NONE;
3589 status = smb1srv_session_table_init(conn);
3590 if (!NT_STATUS_IS_OK(status)) {
3591 conn->protocol = PROTOCOL_NONE;
3595 status = smb1srv_tcon_table_init(conn);
3596 if (!NT_STATUS_IS_OK(status)) {
3597 conn->protocol = PROTOCOL_NONE;
3601 status = smb1srv_open_table_init(conn);
3602 if (!NT_STATUS_IS_OK(status)) {
3603 conn->protocol = PROTOCOL_NONE;
3608 set_Protocol(protocol);
3609 return NT_STATUS_OK;
3612 struct smbd_tevent_trace_state {
3613 struct tevent_context *ev;
3615 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3618 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3621 struct smbd_tevent_trace_state *state =
3622 (struct smbd_tevent_trace_state *)private_data;
3625 case TEVENT_TRACE_BEFORE_WAIT:
3626 if (!smbprofile_dump_pending()) {
3628 * If there's no dump pending
3629 * we don't want to schedule a new 1 sec timer.
3631 * Instead we want to sleep as long as nothing happens.
3633 smbprofile_dump_setup(NULL);
3635 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3637 case TEVENT_TRACE_AFTER_WAIT:
3638 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3639 if (!smbprofile_dump_pending()) {
3641 * We need to flush our state after sleeping
3642 * (hopefully a long time).
3646 * future profiling events should trigger timers
3647 * on our main event context.
3649 smbprofile_dump_setup(state->ev);
3652 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3653 TALLOC_FREE(state->frame);
3654 state->frame = talloc_stackframe_pool(8192);
3656 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3657 TALLOC_FREE(state->frame);
3665 * Create a debug string for the connection
3667 * This is allocated to talloc_tos() or a string constant
3668 * in certain corner cases. The returned string should
3669 * hence not be free'd directly but only via the talloc stack.
3671 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3676 * TODO: this can be improved later
3677 * maybe including the client guid or more
3679 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3681 return "<tsocket_address_string() failed>";
3687 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3688 struct smbXsrv_connection **_xconn)
3690 TALLOC_CTX *frame = talloc_stackframe();
3691 struct smbXsrv_connection *xconn;
3692 struct sockaddr_storage ss_srv;
3693 void *sp_srv = (void *)&ss_srv;
3694 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3695 struct sockaddr_storage ss_clnt;
3696 void *sp_clnt = (void *)&ss_clnt;
3697 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3698 socklen_t sa_socklen;
3699 struct tsocket_address *local_address = NULL;
3700 struct tsocket_address *remote_address = NULL;
3701 const char *remaddr = NULL;
3703 const char *rhost = NULL;
3709 DO_PROFILE_INC(connect);
3711 xconn = talloc_zero(client, struct smbXsrv_connection);
3712 if (xconn == NULL) {
3713 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3715 return NT_STATUS_NO_MEMORY;
3717 talloc_steal(frame, xconn);
3719 xconn->transport.sock = sock_fd;
3720 smbd_echo_init(xconn);
3721 xconn->protocol = PROTOCOL_NONE;
3723 /* Ensure child is set to blocking mode */
3724 set_blocking(sock_fd,True);
3726 set_socket_options(sock_fd, "SO_KEEPALIVE");
3727 set_socket_options(sock_fd, lp_socket_options());
3729 sa_socklen = sizeof(ss_clnt);
3730 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3732 int saved_errno = errno;
3733 int level = (errno == ENOTCONN)?2:0;
3734 DEBUG(level,("getpeername() failed - %s\n",
3735 strerror(saved_errno)));
3737 return map_nt_error_from_unix_common(saved_errno);
3739 ret = tsocket_address_bsd_from_sockaddr(xconn,
3740 sa_clnt, sa_socklen,
3743 int saved_errno = errno;
3744 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3745 __location__, strerror(saved_errno)));
3747 return map_nt_error_from_unix_common(saved_errno);
3750 sa_socklen = sizeof(ss_srv);
3751 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3753 int saved_errno = errno;
3754 int level = (errno == ENOTCONN)?2:0;
3755 DEBUG(level,("getsockname() failed - %s\n",
3756 strerror(saved_errno)));
3758 return map_nt_error_from_unix_common(saved_errno);
3760 ret = tsocket_address_bsd_from_sockaddr(xconn,
3764 int saved_errno = errno;
3765 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3766 __location__, strerror(saved_errno)));
3768 return map_nt_error_from_unix_common(saved_errno);
3771 if (tsocket_address_is_inet(remote_address, "ip")) {
3772 remaddr = tsocket_address_inet_addr_string(remote_address,
3774 if (remaddr == NULL) {
3775 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3776 __location__, strerror(errno)));
3778 return NT_STATUS_NO_MEMORY;
3781 remaddr = "0.0.0.0";
3785 * Before the first packet, check the global hosts allow/ hosts deny
3786 * parameters before doing any parsing of packets passed to us by the
3787 * client. This prevents attacks on our parsing code from hosts not in
3788 * the hosts allow list.
3791 ret = get_remote_hostname(remote_address,
3794 int saved_errno = errno;
3795 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3796 __location__, strerror(saved_errno)));
3798 return map_nt_error_from_unix_common(saved_errno);
3801 if (strequal(rhost, "UNKNOWN")) {
3805 xconn->local_address = local_address;
3806 xconn->remote_address = remote_address;
3807 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3808 if (xconn->remote_hostname == NULL) {
3809 return NT_STATUS_NO_MEMORY;
3812 if (!srv_init_signing(xconn)) {
3813 DEBUG(0, ("Failed to init smb_signing\n"));
3815 return NT_STATUS_INTERNAL_ERROR;
3818 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3819 xconn->remote_hostname,
3821 DEBUG( 1, ("Connection denied from %s to %s\n",
3822 tsocket_address_string(remote_address, talloc_tos()),
3823 tsocket_address_string(local_address, talloc_tos())));
3826 * We return a valid xconn
3827 * so that the caller can return an error message
3830 client->connections = xconn;
3831 xconn->client = client;
3832 talloc_steal(client, xconn);
3836 return NT_STATUS_NETWORK_ACCESS_DENIED;
3839 DEBUG(10, ("Connection allowed from %s to %s\n",
3840 tsocket_address_string(remote_address, talloc_tos()),
3841 tsocket_address_string(local_address, talloc_tos())));
3843 if (lp_clustering()) {
3845 * We need to tell ctdb about our client's TCP
3846 * connection, so that for failover ctdbd can send
3847 * tickle acks, triggering a reconnection by the
3852 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3853 if (!NT_STATUS_IS_OK(status)) {
3854 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3855 nt_errstr(status)));
3859 tmp = lp_max_xmit();
3860 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3861 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3863 xconn->smb1.negprot.max_recv = tmp;
3865 xconn->smb1.sessions.done_sesssetup = false;
3866 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3868 xconn->transport.fde = tevent_add_fd(client->raw_ev_ctx,
3872 smbd_server_connection_handler,
3874 if (!xconn->transport.fde) {
3876 return NT_STATUS_NO_MEMORY;
3879 /* for now we only have one connection */
3880 DLIST_ADD_END(client->connections, xconn);
3881 xconn->client = client;
3882 talloc_steal(client, xconn);
3886 return NT_STATUS_OK;
3889 /****************************************************************************
3890 Process commands from the client
3891 ****************************************************************************/
3893 void smbd_process(struct tevent_context *ev_ctx,
3894 struct messaging_context *msg_ctx,
3898 struct smbd_tevent_trace_state trace_state = {
3900 .frame = talloc_stackframe(),
3902 struct tevent_context *root_ev_ctx = NULL;
3903 struct tevent_context *guest_ev_ctx = NULL;
3904 struct smbXsrv_client *client = NULL;
3905 struct smbd_server_connection *sconn = NULL;
3906 struct smbXsrv_connection *xconn = NULL;
3907 const char *locaddr = NULL;
3908 const char *remaddr = NULL;
3912 struct timeval tv = timeval_current();
3913 NTTIME now = timeval_to_nttime(&tv);
3914 char *chroot_dir = NULL;
3917 root_ev_ctx = smbd_impersonate_root_create(ev_ctx);
3918 if (root_ev_ctx == NULL) {
3919 DEBUG(0,("smbd_impersonate_root_create() failed\n"));
3920 exit_server_cleanly("smbd_impersonate_root_create().\n");
3923 guest_ev_ctx = smbd_impersonate_guest_create(ev_ctx);
3924 if (guest_ev_ctx == NULL) {
3925 DEBUG(0,("smbd_impersonate_guest_create() failed\n"));
3926 exit_server_cleanly("smbd_impersonate_guest_create().\n");
3929 status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
3930 if (!NT_STATUS_IS_OK(status)) {
3931 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
3932 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3936 * TODO: remove this...:-)
3938 global_smbXsrv_client = client;
3940 sconn = talloc_zero(client, struct smbd_server_connection);
3941 if (sconn == NULL) {
3942 exit_server("failed to create smbd_server_connection");
3945 client->sconn = sconn;
3946 sconn->client = client;
3948 sconn->raw_ev_ctx = ev_ctx;
3949 sconn->root_ev_ctx = root_ev_ctx;
3950 sconn->guest_ev_ctx = guest_ev_ctx;
3951 sconn->msg_ctx = msg_ctx;
3953 ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
3954 &sconn->raw_thread_pool);
3956 exit_server("pthreadpool_tevent_init(raw) failed.");
3959 max_threads = pthreadpool_tevent_max_threads(sconn->raw_thread_pool);
3960 if (max_threads == 0) {
3962 * We only have a sync pool, no need to create a 2nd one.
3964 sconn->sync_thread_pool = sconn->raw_thread_pool;
3966 ret = pthreadpool_tevent_init(sconn, 0, &sconn->sync_thread_pool);
3968 exit_server("pthreadpool_tevent_init(sync) failed.");
3972 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3974 * We're not making the decision here,
3975 * we're just allowing the client
3976 * to decide between SMB1 and SMB2
3977 * with the first negprot
3980 sconn->using_smb2 = true;
3984 smbd_setup_sig_term_handler(sconn);
3985 smbd_setup_sig_hup_handler(sconn);
3988 status = smbd_add_connection(client, sock_fd, &xconn);
3989 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3991 * send a negative session response "not listening on calling
3994 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3995 (void)srv_send_smb(xconn,(char *)buf, false,
3997 exit_server_cleanly("connection denied");
3998 } else if (!NT_STATUS_IS_OK(status)) {
3999 exit_server_cleanly(nt_errstr(status));
4002 sconn->local_address =
4003 tsocket_address_copy(xconn->local_address, sconn);
4004 if (sconn->local_address == NULL) {
4005 exit_server_cleanly("tsocket_address_copy() failed");
4007 sconn->remote_address =
4008 tsocket_address_copy(xconn->remote_address, sconn);
4009 if (sconn->remote_address == NULL) {
4010 exit_server_cleanly("tsocket_address_copy() failed");
4012 sconn->remote_hostname =
4013 talloc_strdup(sconn, xconn->remote_hostname);
4014 if (sconn->remote_hostname == NULL) {
4015 exit_server_cleanly("tsocket_strdup() failed");
4018 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
4019 locaddr = tsocket_address_inet_addr_string(
4020 sconn->local_address,
4022 if (locaddr == NULL) {
4023 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4024 __location__, strerror(errno)));
4025 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4028 locaddr = "0.0.0.0";
4031 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
4032 remaddr = tsocket_address_inet_addr_string(
4033 sconn->remote_address,
4035 if (remaddr == NULL) {
4036 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4037 __location__, strerror(errno)));
4038 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4041 remaddr = "0.0.0.0";
4044 /* this is needed so that we get decent entries
4045 in smbstatus for port 445 connects */
4046 set_remote_machine_name(remaddr, false);
4047 reload_services(sconn, conn_snum_used, true);
4048 sub_set_socket_ids(remaddr,
4049 sconn->remote_hostname,
4052 if (lp_preload_modules()) {
4053 smb_load_all_modules_absoute_path(lp_preload_modules());
4056 smb_perfcount_init();
4058 if (!init_account_policy()) {
4059 exit_server("Could not open account policy tdb.\n");
4062 chroot_dir = lp_root_directory(talloc_tos());
4063 if (chroot_dir[0] != '\0') {
4064 rc = chdir(chroot_dir);
4066 DBG_ERR("Failed to chdir to %s\n", chroot_dir);
4067 exit_server("Failed to chdir()");
4070 rc = chroot(chroot_dir);
4072 DBG_ERR("Failed to change root to %s\n", chroot_dir);
4073 exit_server("Failed to chroot()");
4075 DBG_WARNING("Changed root to %s\n", chroot_dir);
4077 TALLOC_FREE(chroot_dir);
4080 if (!file_init(sconn)) {
4081 exit_server("file_init() failed");
4085 if (!init_oplocks(sconn))
4086 exit_server("Failed to init oplocks");
4088 /* register our message handlers */
4089 messaging_register(sconn->msg_ctx, sconn,
4090 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4091 messaging_register(sconn->msg_ctx, sconn,
4092 MSG_SMB_CLOSE_FILE, msg_close_file);
4093 messaging_register(sconn->msg_ctx, sconn,
4094 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
4096 id_cache_register_msgs(sconn->msg_ctx);
4097 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
4098 messaging_register(sconn->msg_ctx, sconn,
4099 ID_CACHE_KILL, smbd_id_cache_kill);
4101 messaging_deregister(sconn->msg_ctx,
4102 MSG_SMB_CONF_UPDATED, sconn->raw_ev_ctx);
4103 messaging_register(sconn->msg_ctx, sconn,
4104 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
4106 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
4108 messaging_register(sconn->msg_ctx, sconn,
4109 MSG_SMB_KILL_CLIENT_IP,
4110 msg_kill_client_ip);
4112 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
4115 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4116 * MSGs to all child processes
4118 messaging_deregister(sconn->msg_ctx,
4120 messaging_register(sconn->msg_ctx, NULL,
4121 MSG_DEBUG, debug_message);
4123 if ((lp_keepalive() != 0)
4124 && !(event_add_idle(ev_ctx, NULL,
4125 timeval_set(lp_keepalive(), 0),
4126 "keepalive", keepalive_fn,
4128 DEBUG(0, ("Could not add keepalive event\n"));
4132 if (!(event_add_idle(ev_ctx, NULL,
4133 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4134 "deadtime", deadtime_fn, sconn))) {
4135 DEBUG(0, ("Could not add deadtime event\n"));
4139 if (!(event_add_idle(ev_ctx, NULL,
4140 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4141 "housekeeping", housekeeping_fn, sconn))) {
4142 DEBUG(0, ("Could not add housekeeping event\n"));
4146 smbprofile_dump_setup(ev_ctx);
4148 if (!init_dptrs(sconn)) {
4149 exit_server("init_dptrs() failed");
4152 TALLOC_FREE(trace_state.frame);
4154 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4157 ret = tevent_loop_wait(ev_ctx);
4159 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4160 " exiting\n", ret, strerror(errno)));
4163 TALLOC_FREE(trace_state.frame);
4165 exit_server_cleanly(NULL);
4168 bool req_is_in_chain(const struct smb_request *req)
4170 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4172 * We're right now handling a subsequent request, so we must
4178 if (!is_andx_req(req->cmd)) {
4184 * Okay, an illegal request, but definitely not chained :-)
4189 return (CVAL(req->vwv+0, 0) != 0xFF);