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"
47 #include "libcli/smb/smbXcli_base.h"
48 #include "lib/util/time_basic.h"
50 /* Internal message queue for deferred opens. */
51 struct pending_message_list {
52 struct pending_message_list *next, *prev;
53 struct timeval request_time; /* When was this first issued? */
54 struct smbd_server_connection *sconn;
55 struct smbXsrv_connection *xconn;
56 struct tevent_timer *te;
57 struct smb_perfcount_data pcd;
62 struct deferred_open_record *open_rec;
65 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
67 static struct pending_message_list *get_deferred_open_message_smb(
68 struct smbd_server_connection *sconn, uint64_t mid);
69 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
71 static void smbd_echo_init(struct smbXsrv_connection *xconn)
73 xconn->smb1.echo_handler.trusted_fd = -1;
74 xconn->smb1.echo_handler.socket_lock_fd = -1;
75 #ifdef HAVE_ROBUST_MUTEXES
76 xconn->smb1.echo_handler.socket_mutex = NULL;
80 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
82 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
86 #ifdef HAVE_ROBUST_MUTEXES
87 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
95 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
97 if (!smbd_echo_active(xconn)) {
101 xconn->smb1.echo_handler.ref_count++;
103 if (xconn->smb1.echo_handler.ref_count > 1) {
107 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
109 #ifdef HAVE_ROBUST_MUTEXES
110 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
113 while (ret == EINTR) {
114 ret = pthread_mutex_lock(
115 xconn->smb1.echo_handler.socket_mutex);
121 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
128 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
133 xconn->smb1.echo_handler.socket_lock_fd,
134 F_SETLKW, 0, 0, F_WRLCK);
135 } while (!ok && (errno == EINTR));
138 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
143 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
148 void smbd_lock_socket(struct smbXsrv_connection *xconn)
150 if (!smbd_lock_socket_internal(xconn)) {
151 exit_server_cleanly("failed to lock socket");
155 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
157 if (!smbd_echo_active(xconn)) {
161 xconn->smb1.echo_handler.ref_count--;
163 if (xconn->smb1.echo_handler.ref_count > 0) {
167 #ifdef HAVE_ROBUST_MUTEXES
168 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
170 ret = pthread_mutex_unlock(
171 xconn->smb1.echo_handler.socket_mutex);
173 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
180 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
185 xconn->smb1.echo_handler.socket_lock_fd,
186 F_SETLKW, 0, 0, F_UNLCK);
187 } while (!ok && (errno == EINTR));
190 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
195 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
200 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
202 if (!smbd_unlock_socket_internal(xconn)) {
203 exit_server_cleanly("failed to unlock socket");
207 /* Accessor function for smb_read_error for smbd functions. */
209 /****************************************************************************
211 ****************************************************************************/
213 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
214 bool do_signing, uint32_t seqnum,
216 struct smb_perfcount_data *pcd)
220 char *buf_out = buffer;
222 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
224 * we're not supposed to do any io
229 smbd_lock_socket(xconn);
234 /* Sign the outgoing packet if required. */
235 status = srv_calculate_sign_mac(xconn, buf_out, seqnum);
236 if (!NT_STATUS_IS_OK(status)) {
237 DBG_ERR("Failed to calculate signing mac: %s\n",
244 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
245 if (!NT_STATUS_IS_OK(status)) {
246 DEBUG(0, ("send_smb: SMB encryption failed "
247 "on outgoing packet! Error %s\n",
248 nt_errstr(status) ));
254 len = smb_len_large(buf_out) + 4;
256 ret = write_data(xconn->transport.sock, buf_out, len);
258 int saved_errno = errno;
260 * Try and give an error message saying what
263 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
264 (int)getpid(), (int)len,
265 smbXsrv_connection_dbg(xconn),
266 (int)ret, strerror(saved_errno)));
269 srv_free_enc_buffer(xconn, buf_out);
273 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
274 srv_free_enc_buffer(xconn, buf_out);
276 SMB_PERFCOUNT_END(pcd);
278 smbd_unlock_socket(xconn);
282 /*******************************************************************
283 Setup the word count and byte count for a smb message.
284 ********************************************************************/
286 size_t srv_set_message(char *buf,
291 if (zero && (num_words || num_bytes)) {
292 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
294 SCVAL(buf,smb_wct,num_words);
295 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
296 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
297 return (smb_size + num_words*2 + num_bytes);
300 static bool valid_smb_header(const uint8_t *inbuf)
302 if (is_encrypted_packet(inbuf)) {
306 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
307 * but it just looks weird to call strncmp for this one.
309 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
312 /* Socket functions for smbd packet processing. */
314 static bool valid_packet_size(size_t len)
317 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
318 * of header. Don't print the error if this fits.... JRA.
321 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
322 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
323 (unsigned long)len));
329 static NTSTATUS read_packet_remainder(int fd, char *buffer,
330 unsigned int timeout, ssize_t len)
338 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
339 if (!NT_STATUS_IS_OK(status)) {
340 char addr[INET6_ADDRSTRLEN];
341 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
343 get_peer_addr(fd, addr, sizeof(addr)),
349 /****************************************************************************
350 Attempt a zerocopy writeX read. We know here that len > smb_size-4
351 ****************************************************************************/
354 * Unfortunately, earlier versions of smbclient/libsmbclient
355 * don't send this "standard" writeX header. I've fixed this
356 * for 3.2 but we'll use the old method with earlier versions.
357 * Windows and CIFSFS at least use this standard size. Not
361 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
362 (2*14) + /* word count (including bcc) */ \
365 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
366 const char lenbuf[4],
367 struct smbXsrv_connection *xconn,
370 unsigned int timeout,
374 /* Size of a WRITEX call (+4 byte len). */
375 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
376 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
380 memcpy(writeX_header, lenbuf, 4);
382 status = read_fd_with_timeout(
383 sock, writeX_header + 4,
384 STANDARD_WRITE_AND_X_HEADER_SIZE,
385 STANDARD_WRITE_AND_X_HEADER_SIZE,
388 if (!NT_STATUS_IS_OK(status)) {
389 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
391 smbXsrv_connection_dbg(xconn),
397 * Ok - now try and see if this is a possible
401 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
403 * If the data offset is beyond what
404 * we've read, drain the extra bytes.
406 uint16_t doff = SVAL(writeX_header,smb_vwv11);
409 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
410 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
411 if (drain_socket(sock, drain) != drain) {
412 smb_panic("receive_smb_raw_talloc_partial_read:"
413 " failed to drain pending bytes");
416 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
419 /* Spoof down the length and null out the bcc. */
420 set_message_bcc(writeX_header, 0);
421 newlen = smb_len(writeX_header);
423 /* Copy the header we've written. */
425 *buffer = (char *)talloc_memdup(mem_ctx,
427 sizeof(writeX_header));
429 if (*buffer == NULL) {
430 DEBUG(0, ("Could not allocate inbuf of length %d\n",
431 (int)sizeof(writeX_header)));
432 return NT_STATUS_NO_MEMORY;
435 /* Work out the remaining bytes. */
436 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
437 *len_ret = newlen + 4;
441 if (!valid_packet_size(len)) {
442 return NT_STATUS_INVALID_PARAMETER;
446 * Not a valid writeX call. Just do the standard
450 *buffer = talloc_array(mem_ctx, char, len+4);
452 if (*buffer == NULL) {
453 DEBUG(0, ("Could not allocate inbuf of length %d\n",
455 return NT_STATUS_NO_MEMORY;
458 /* Copy in what we already read. */
461 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
462 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
465 status = read_packet_remainder(
467 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
470 if (!NT_STATUS_IS_OK(status)) {
471 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
481 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
482 struct smbXsrv_connection *xconn,
484 char **buffer, unsigned int timeout,
485 size_t *p_unread, size_t *plen)
489 int min_recv_size = lp_min_receive_file_size();
494 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
496 if (!NT_STATUS_IS_OK(status)) {
500 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
501 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
502 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
503 !srv_is_signing_active(xconn) &&
504 xconn->smb1.echo_handler.trusted_fde == NULL) {
506 return receive_smb_raw_talloc_partial_read(
507 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
511 if (!valid_packet_size(len)) {
512 return NT_STATUS_INVALID_PARAMETER;
516 * The +4 here can't wrap, we've checked the length above already.
519 *buffer = talloc_array(mem_ctx, char, len+4);
521 if (*buffer == NULL) {
522 DEBUG(0, ("Could not allocate inbuf of length %d\n",
524 return NT_STATUS_NO_MEMORY;
527 memcpy(*buffer, lenbuf, sizeof(lenbuf));
529 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
530 if (!NT_STATUS_IS_OK(status)) {
538 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
539 struct smbXsrv_connection *xconn,
541 char **buffer, unsigned int timeout,
542 size_t *p_unread, bool *p_encrypted,
545 bool trusted_channel)
550 *p_encrypted = false;
552 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
554 if (!NT_STATUS_IS_OK(status)) {
555 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
556 ("receive_smb_raw_talloc failed for client %s "
557 "read error = %s.\n",
558 smbXsrv_connection_dbg(xconn),
559 nt_errstr(status)) );
563 if (is_encrypted_packet((uint8_t *)*buffer)) {
564 status = srv_decrypt_buffer(xconn, *buffer);
565 if (!NT_STATUS_IS_OK(status)) {
566 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
567 "incoming packet! Error %s\n",
568 nt_errstr(status) ));
574 /* Check the incoming SMB signature. */
575 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
576 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
577 "incoming packet!\n"));
578 return NT_STATUS_INVALID_NETWORK_RESPONSE;
586 * Initialize a struct smb_request from an inbuf
589 static bool init_smb_request(struct smb_request *req,
590 struct smbd_server_connection *sconn,
591 struct smbXsrv_connection *xconn,
592 const uint8_t *inbuf,
593 size_t unread_bytes, bool encrypted,
596 struct smbXsrv_tcon *tcon;
599 size_t req_size = smb_len(inbuf) + 4;
601 /* Ensure we have at least smb_size bytes. */
602 if (req_size < smb_size) {
603 DEBUG(0,("init_smb_request: invalid request size %u\n",
604 (unsigned int)req_size ));
608 req->request_time = timeval_current();
609 now = timeval_to_nttime(&req->request_time);
611 req->cmd = CVAL(inbuf, smb_com);
612 req->flags2 = SVAL(inbuf, smb_flg2);
613 req->smbpid = SVAL(inbuf, smb_pid);
614 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
615 req->seqnum = seqnum;
616 req->vuid = SVAL(inbuf, smb_uid);
617 req->tid = SVAL(inbuf, smb_tid);
618 req->wct = CVAL(inbuf, smb_wct);
619 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
620 req->buflen = smb_buflen(inbuf);
621 req->buf = (const uint8_t *)smb_buf_const(inbuf);
622 req->unread_bytes = unread_bytes;
623 req->encrypted = encrypted;
628 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
629 if (NT_STATUS_IS_OK(status)) {
630 req->conn = tcon->compat;
633 req->chain_fsp = NULL;
635 req->priv_paths = NULL;
637 req->posix_pathnames = lp_posix_pathnames();
638 smb_init_perfcount_data(&req->pcd);
640 /* Ensure we have at least wct words and 2 bytes of bcc. */
641 if (smb_size + req->wct*2 > req_size) {
642 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
643 (unsigned int)req->wct,
644 (unsigned int)req_size));
647 /* Ensure bcc is correct. */
648 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
649 DEBUG(0,("init_smb_request: invalid bcc number %u "
650 "(wct = %u, size %u)\n",
651 (unsigned int)req->buflen,
652 (unsigned int)req->wct,
653 (unsigned int)req_size));
661 static void process_smb(struct smbXsrv_connection *xconn,
662 uint8_t *inbuf, size_t nread, size_t unread_bytes,
663 uint32_t seqnum, bool encrypted,
664 struct smb_perfcount_data *deferred_pcd);
666 static void smbd_deferred_open_timer(struct tevent_context *ev,
667 struct tevent_timer *te,
668 struct timeval _tval,
671 struct pending_message_list *msg = talloc_get_type(private_data,
672 struct pending_message_list);
673 struct smbd_server_connection *sconn = msg->sconn;
674 struct smbXsrv_connection *xconn = msg->xconn;
675 TALLOC_CTX *mem_ctx = talloc_tos();
676 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
679 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
682 exit_server("smbd_deferred_open_timer: talloc failed\n");
686 /* We leave this message on the queue so the open code can
687 know this is a retry. */
688 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
689 (unsigned long long)mid ));
691 /* Mark the message as processed so this is not
692 * re-processed in error. */
693 msg->processed = true;
695 process_smb(xconn, inbuf,
697 msg->seqnum, msg->encrypted, &msg->pcd);
699 /* If it's still there and was processed, remove it. */
700 msg = get_deferred_open_message_smb(sconn, mid);
701 if (msg && msg->processed) {
702 remove_deferred_open_message_smb(xconn, mid);
706 /****************************************************************************
707 Function to push a message onto the tail of a linked list of smb messages ready
709 ****************************************************************************/
711 static bool push_queued_message(struct smb_request *req,
712 struct timeval request_time,
713 struct timeval end_time,
714 struct deferred_open_record *open_rec)
716 int msg_len = smb_len(req->inbuf) + 4;
717 struct pending_message_list *msg;
719 msg = talloc_zero(NULL, struct pending_message_list);
722 DEBUG(0,("push_message: malloc fail (1)\n"));
725 msg->sconn = req->sconn;
726 msg->xconn = req->xconn;
728 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
729 if(msg->buf.data == NULL) {
730 DEBUG(0,("push_message: malloc fail (2)\n"));
735 msg->request_time = request_time;
736 msg->seqnum = req->seqnum;
737 msg->encrypted = req->encrypted;
738 msg->processed = false;
739 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
742 msg->open_rec = talloc_move(msg, &open_rec);
746 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
749 smbd_deferred_open_timer,
752 DEBUG(0,("push_message: event_add_timed failed\n"));
758 DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
760 DEBUG(10,("push_message: pushed message length %u on "
761 "deferred_open_queue\n", (unsigned int)msg_len));
766 /****************************************************************************
767 Function to delete a sharing violation open message by mid.
768 ****************************************************************************/
770 void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
773 struct smbd_server_connection *sconn = xconn->client->sconn;
774 struct pending_message_list *pml;
776 if (sconn->using_smb2) {
777 remove_deferred_open_message_smb2(xconn, mid);
781 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
782 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
783 DEBUG(10,("remove_deferred_open_message_smb: "
784 "deleting mid %llu len %u\n",
785 (unsigned long long)mid,
786 (unsigned int)pml->buf.length ));
787 DLIST_REMOVE(sconn->deferred_open_queue, pml);
794 /****************************************************************************
795 Move a sharing violation open retry message to the front of the list and
796 schedule it for immediate processing.
797 ****************************************************************************/
799 bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
802 struct smbd_server_connection *sconn = xconn->client->sconn;
803 struct pending_message_list *pml;
806 if (sconn->using_smb2) {
807 return schedule_deferred_open_message_smb2(xconn, mid);
810 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
811 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
813 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
816 (unsigned long long)msg_mid ));
818 if (mid == msg_mid) {
819 struct tevent_timer *te;
821 if (pml->processed) {
822 /* A processed message should not be
824 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
825 "message mid %llu was already processed\n",
826 (unsigned long long)msg_mid ));
830 DEBUG(10,("schedule_deferred_open_message_smb: "
831 "scheduling mid %llu\n",
832 (unsigned long long)mid ));
835 * smbd_deferred_open_timer() calls
836 * process_smb() to redispatch the request
837 * including the required impersonation.
839 * So we can just use the raw tevent_context.
841 te = tevent_add_timer(xconn->client->raw_ev_ctx,
844 smbd_deferred_open_timer,
847 DEBUG(10,("schedule_deferred_open_message_smb: "
848 "event_add_timed() failed, "
849 "skipping mid %llu\n",
850 (unsigned long long)msg_mid ));
853 TALLOC_FREE(pml->te);
855 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
860 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
861 "find message mid %llu\n",
862 (unsigned long long)mid ));
867 /****************************************************************************
868 Return true if this mid is on the deferred queue and was not yet processed.
869 ****************************************************************************/
871 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
873 struct smbd_server_connection *sconn = xconn->client->sconn;
874 struct pending_message_list *pml;
876 if (sconn->using_smb2) {
877 return open_was_deferred_smb2(xconn, mid);
880 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
881 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
888 /****************************************************************************
889 Return the message queued by this mid.
890 ****************************************************************************/
892 static struct pending_message_list *get_deferred_open_message_smb(
893 struct smbd_server_connection *sconn, uint64_t mid)
895 struct pending_message_list *pml;
897 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
898 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
905 /****************************************************************************
906 Get the state data queued by this mid.
907 ****************************************************************************/
909 bool get_deferred_open_message_state(struct smb_request *smbreq,
910 struct timeval *p_request_time,
911 struct deferred_open_record **open_rec)
913 struct pending_message_list *pml;
915 if (smbreq->sconn->using_smb2) {
916 return get_deferred_open_message_state_smb2(smbreq->smb2req,
921 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
925 if (p_request_time) {
926 *p_request_time = pml->request_time;
928 if (open_rec != NULL) {
929 *open_rec = pml->open_rec;
934 /****************************************************************************
935 Function to push a deferred open smb message onto a linked list of local smb
936 messages ready for processing.
937 ****************************************************************************/
939 bool push_deferred_open_message_smb(struct smb_request *req,
940 struct timeval timeout,
942 struct deferred_open_record *open_rec)
944 struct timeval_buf tvbuf;
945 struct timeval end_time;
948 return push_deferred_open_message_smb2(req->smb2req,
955 if (req->unread_bytes) {
956 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
957 "unread_bytes = %u\n",
958 (unsigned int)req->unread_bytes ));
959 smb_panic("push_deferred_open_message_smb: "
960 "logic error unread_bytes != 0" );
963 end_time = timeval_sum(&req->request_time, &timeout);
965 DBG_DEBUG("pushing message len %u mid %"PRIu64" timeout time [%s]\n",
966 (unsigned int) smb_len(req->inbuf)+4,
968 timeval_str_buf(&end_time, false, true, &tvbuf));
970 return push_queued_message(req, req->request_time, end_time, open_rec);
973 static void smbd_sig_term_handler(struct tevent_context *ev,
974 struct tevent_signal *se,
980 exit_server_cleanly("termination signal");
983 static void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
985 struct tevent_signal *se;
987 se = tevent_add_signal(sconn->ev_ctx,
990 smbd_sig_term_handler,
993 exit_server("failed to setup SIGTERM handler");
997 static void smbd_sig_hup_handler(struct tevent_context *ev,
998 struct tevent_signal *se,
1004 struct smbd_server_connection *sconn =
1005 talloc_get_type_abort(private_data,
1006 struct smbd_server_connection);
1008 change_to_root_user();
1009 DEBUG(1,("Reloading services after SIGHUP\n"));
1010 reload_services(sconn, conn_snum_used, false);
1013 static void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1015 struct tevent_signal *se;
1017 se = tevent_add_signal(sconn->ev_ctx,
1020 smbd_sig_hup_handler,
1023 exit_server("failed to setup SIGHUP handler");
1027 static void smbd_conf_updated(struct messaging_context *msg,
1030 struct server_id server_id,
1033 struct smbd_server_connection *sconn =
1034 talloc_get_type_abort(private_data,
1035 struct smbd_server_connection);
1037 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1038 "updated. Reloading.\n"));
1039 change_to_root_user();
1040 reload_services(sconn, conn_snum_used, false);
1044 * Only allow 5 outstanding trans requests. We're allocating memory, so
1048 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1051 for (; list != NULL; list = list->next) {
1053 if (list->mid == mid) {
1054 return NT_STATUS_INVALID_PARAMETER;
1060 return NT_STATUS_INSUFFICIENT_RESOURCES;
1063 return NT_STATUS_OK;
1067 These flags determine some of the permissions required to do an operation
1069 Note that I don't set NEED_WRITE on some write operations because they
1070 are used by some brain-dead clients when printing, and I don't want to
1071 force write permissions on print services.
1073 #define AS_USER (1<<0)
1074 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1075 #define TIME_INIT (1<<2)
1076 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1077 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1078 #define DO_CHDIR (1<<6)
1081 define a list of possible SMB messages and their corresponding
1082 functions. Any message that has a NULL function is unimplemented -
1083 please feel free to contribute implementations!
1085 static const struct smb_message_struct {
1087 void (*fn)(struct smb_request *req);
1089 } smb_messages[256] = {
1091 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1092 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1093 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1094 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1095 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1096 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1097 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1098 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1099 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1100 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1101 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1102 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1103 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1104 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1105 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1106 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1107 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1108 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1109 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1110 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1111 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1112 /* 0x15 */ { NULL, NULL, 0 },
1113 /* 0x16 */ { NULL, NULL, 0 },
1114 /* 0x17 */ { NULL, NULL, 0 },
1115 /* 0x18 */ { NULL, NULL, 0 },
1116 /* 0x19 */ { NULL, NULL, 0 },
1117 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1118 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1119 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1120 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1121 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1122 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1123 /* 0x20 */ { "SMBwritec", NULL,0},
1124 /* 0x21 */ { NULL, NULL, 0 },
1125 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1126 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1127 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1128 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1129 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1130 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1131 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1132 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1133 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1134 /* 0x2b */ { "SMBecho",reply_echo,0},
1135 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1136 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1137 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1138 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1139 /* 0x30 */ { NULL, NULL, 0 },
1140 /* 0x31 */ { NULL, NULL, 0 },
1141 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1142 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1143 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1144 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1145 /* 0x36 */ { NULL, NULL, 0 },
1146 /* 0x37 */ { NULL, NULL, 0 },
1147 /* 0x38 */ { NULL, NULL, 0 },
1148 /* 0x39 */ { NULL, NULL, 0 },
1149 /* 0x3a */ { NULL, NULL, 0 },
1150 /* 0x3b */ { NULL, NULL, 0 },
1151 /* 0x3c */ { NULL, NULL, 0 },
1152 /* 0x3d */ { NULL, NULL, 0 },
1153 /* 0x3e */ { NULL, NULL, 0 },
1154 /* 0x3f */ { NULL, NULL, 0 },
1155 /* 0x40 */ { NULL, NULL, 0 },
1156 /* 0x41 */ { NULL, NULL, 0 },
1157 /* 0x42 */ { NULL, NULL, 0 },
1158 /* 0x43 */ { NULL, NULL, 0 },
1159 /* 0x44 */ { NULL, NULL, 0 },
1160 /* 0x45 */ { NULL, NULL, 0 },
1161 /* 0x46 */ { NULL, NULL, 0 },
1162 /* 0x47 */ { NULL, NULL, 0 },
1163 /* 0x48 */ { NULL, NULL, 0 },
1164 /* 0x49 */ { NULL, NULL, 0 },
1165 /* 0x4a */ { NULL, NULL, 0 },
1166 /* 0x4b */ { NULL, NULL, 0 },
1167 /* 0x4c */ { NULL, NULL, 0 },
1168 /* 0x4d */ { NULL, NULL, 0 },
1169 /* 0x4e */ { NULL, NULL, 0 },
1170 /* 0x4f */ { NULL, NULL, 0 },
1171 /* 0x50 */ { NULL, NULL, 0 },
1172 /* 0x51 */ { NULL, NULL, 0 },
1173 /* 0x52 */ { NULL, NULL, 0 },
1174 /* 0x53 */ { NULL, NULL, 0 },
1175 /* 0x54 */ { NULL, NULL, 0 },
1176 /* 0x55 */ { NULL, NULL, 0 },
1177 /* 0x56 */ { NULL, NULL, 0 },
1178 /* 0x57 */ { NULL, NULL, 0 },
1179 /* 0x58 */ { NULL, NULL, 0 },
1180 /* 0x59 */ { NULL, NULL, 0 },
1181 /* 0x5a */ { NULL, NULL, 0 },
1182 /* 0x5b */ { NULL, NULL, 0 },
1183 /* 0x5c */ { NULL, NULL, 0 },
1184 /* 0x5d */ { NULL, NULL, 0 },
1185 /* 0x5e */ { NULL, NULL, 0 },
1186 /* 0x5f */ { NULL, NULL, 0 },
1187 /* 0x60 */ { NULL, NULL, 0 },
1188 /* 0x61 */ { NULL, NULL, 0 },
1189 /* 0x62 */ { NULL, NULL, 0 },
1190 /* 0x63 */ { NULL, NULL, 0 },
1191 /* 0x64 */ { NULL, NULL, 0 },
1192 /* 0x65 */ { NULL, NULL, 0 },
1193 /* 0x66 */ { NULL, NULL, 0 },
1194 /* 0x67 */ { NULL, NULL, 0 },
1195 /* 0x68 */ { NULL, NULL, 0 },
1196 /* 0x69 */ { NULL, NULL, 0 },
1197 /* 0x6a */ { NULL, NULL, 0 },
1198 /* 0x6b */ { NULL, NULL, 0 },
1199 /* 0x6c */ { NULL, NULL, 0 },
1200 /* 0x6d */ { NULL, NULL, 0 },
1201 /* 0x6e */ { NULL, NULL, 0 },
1202 /* 0x6f */ { NULL, NULL, 0 },
1203 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1204 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1205 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1206 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1207 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1208 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1209 /* 0x76 */ { NULL, NULL, 0 },
1210 /* 0x77 */ { NULL, NULL, 0 },
1211 /* 0x78 */ { NULL, NULL, 0 },
1212 /* 0x79 */ { NULL, NULL, 0 },
1213 /* 0x7a */ { NULL, NULL, 0 },
1214 /* 0x7b */ { NULL, NULL, 0 },
1215 /* 0x7c */ { NULL, NULL, 0 },
1216 /* 0x7d */ { NULL, NULL, 0 },
1217 /* 0x7e */ { NULL, NULL, 0 },
1218 /* 0x7f */ { NULL, NULL, 0 },
1219 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1220 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1221 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1222 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1223 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1224 /* 0x85 */ { NULL, NULL, 0 },
1225 /* 0x86 */ { NULL, NULL, 0 },
1226 /* 0x87 */ { NULL, NULL, 0 },
1227 /* 0x88 */ { NULL, NULL, 0 },
1228 /* 0x89 */ { NULL, NULL, 0 },
1229 /* 0x8a */ { NULL, NULL, 0 },
1230 /* 0x8b */ { NULL, NULL, 0 },
1231 /* 0x8c */ { NULL, NULL, 0 },
1232 /* 0x8d */ { NULL, NULL, 0 },
1233 /* 0x8e */ { NULL, NULL, 0 },
1234 /* 0x8f */ { NULL, NULL, 0 },
1235 /* 0x90 */ { NULL, NULL, 0 },
1236 /* 0x91 */ { NULL, NULL, 0 },
1237 /* 0x92 */ { NULL, NULL, 0 },
1238 /* 0x93 */ { NULL, NULL, 0 },
1239 /* 0x94 */ { NULL, NULL, 0 },
1240 /* 0x95 */ { NULL, NULL, 0 },
1241 /* 0x96 */ { NULL, NULL, 0 },
1242 /* 0x97 */ { NULL, NULL, 0 },
1243 /* 0x98 */ { NULL, NULL, 0 },
1244 /* 0x99 */ { NULL, NULL, 0 },
1245 /* 0x9a */ { NULL, NULL, 0 },
1246 /* 0x9b */ { NULL, NULL, 0 },
1247 /* 0x9c */ { NULL, NULL, 0 },
1248 /* 0x9d */ { NULL, NULL, 0 },
1249 /* 0x9e */ { NULL, NULL, 0 },
1250 /* 0x9f */ { NULL, NULL, 0 },
1251 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1252 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1253 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1254 /* 0xa3 */ { NULL, NULL, 0 },
1255 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1256 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1257 /* 0xa6 */ { NULL, NULL, 0 },
1258 /* 0xa7 */ { NULL, NULL, 0 },
1259 /* 0xa8 */ { NULL, NULL, 0 },
1260 /* 0xa9 */ { NULL, NULL, 0 },
1261 /* 0xaa */ { NULL, NULL, 0 },
1262 /* 0xab */ { NULL, NULL, 0 },
1263 /* 0xac */ { NULL, NULL, 0 },
1264 /* 0xad */ { NULL, NULL, 0 },
1265 /* 0xae */ { NULL, NULL, 0 },
1266 /* 0xaf */ { NULL, NULL, 0 },
1267 /* 0xb0 */ { NULL, NULL, 0 },
1268 /* 0xb1 */ { NULL, NULL, 0 },
1269 /* 0xb2 */ { NULL, NULL, 0 },
1270 /* 0xb3 */ { NULL, NULL, 0 },
1271 /* 0xb4 */ { NULL, NULL, 0 },
1272 /* 0xb5 */ { NULL, NULL, 0 },
1273 /* 0xb6 */ { NULL, NULL, 0 },
1274 /* 0xb7 */ { NULL, NULL, 0 },
1275 /* 0xb8 */ { NULL, NULL, 0 },
1276 /* 0xb9 */ { NULL, NULL, 0 },
1277 /* 0xba */ { NULL, NULL, 0 },
1278 /* 0xbb */ { NULL, NULL, 0 },
1279 /* 0xbc */ { NULL, NULL, 0 },
1280 /* 0xbd */ { NULL, NULL, 0 },
1281 /* 0xbe */ { NULL, NULL, 0 },
1282 /* 0xbf */ { NULL, NULL, 0 },
1283 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1284 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1285 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1286 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1287 /* 0xc4 */ { NULL, NULL, 0 },
1288 /* 0xc5 */ { NULL, NULL, 0 },
1289 /* 0xc6 */ { NULL, NULL, 0 },
1290 /* 0xc7 */ { NULL, NULL, 0 },
1291 /* 0xc8 */ { NULL, NULL, 0 },
1292 /* 0xc9 */ { NULL, NULL, 0 },
1293 /* 0xca */ { NULL, NULL, 0 },
1294 /* 0xcb */ { NULL, NULL, 0 },
1295 /* 0xcc */ { NULL, NULL, 0 },
1296 /* 0xcd */ { NULL, NULL, 0 },
1297 /* 0xce */ { NULL, NULL, 0 },
1298 /* 0xcf */ { NULL, NULL, 0 },
1299 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1300 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1301 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1302 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1303 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1304 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1305 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1306 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1307 /* 0xd8 */ { NULL, NULL, 0 },
1308 /* 0xd9 */ { NULL, NULL, 0 },
1309 /* 0xda */ { NULL, NULL, 0 },
1310 /* 0xdb */ { NULL, NULL, 0 },
1311 /* 0xdc */ { NULL, NULL, 0 },
1312 /* 0xdd */ { NULL, NULL, 0 },
1313 /* 0xde */ { NULL, NULL, 0 },
1314 /* 0xdf */ { NULL, NULL, 0 },
1315 /* 0xe0 */ { NULL, NULL, 0 },
1316 /* 0xe1 */ { NULL, NULL, 0 },
1317 /* 0xe2 */ { NULL, NULL, 0 },
1318 /* 0xe3 */ { NULL, NULL, 0 },
1319 /* 0xe4 */ { NULL, NULL, 0 },
1320 /* 0xe5 */ { NULL, NULL, 0 },
1321 /* 0xe6 */ { NULL, NULL, 0 },
1322 /* 0xe7 */ { NULL, NULL, 0 },
1323 /* 0xe8 */ { NULL, NULL, 0 },
1324 /* 0xe9 */ { NULL, NULL, 0 },
1325 /* 0xea */ { NULL, NULL, 0 },
1326 /* 0xeb */ { NULL, NULL, 0 },
1327 /* 0xec */ { NULL, NULL, 0 },
1328 /* 0xed */ { NULL, NULL, 0 },
1329 /* 0xee */ { NULL, NULL, 0 },
1330 /* 0xef */ { NULL, NULL, 0 },
1331 /* 0xf0 */ { NULL, NULL, 0 },
1332 /* 0xf1 */ { NULL, NULL, 0 },
1333 /* 0xf2 */ { NULL, NULL, 0 },
1334 /* 0xf3 */ { NULL, NULL, 0 },
1335 /* 0xf4 */ { NULL, NULL, 0 },
1336 /* 0xf5 */ { NULL, NULL, 0 },
1337 /* 0xf6 */ { NULL, NULL, 0 },
1338 /* 0xf7 */ { NULL, NULL, 0 },
1339 /* 0xf8 */ { NULL, NULL, 0 },
1340 /* 0xf9 */ { NULL, NULL, 0 },
1341 /* 0xfa */ { NULL, NULL, 0 },
1342 /* 0xfb */ { NULL, NULL, 0 },
1343 /* 0xfc */ { NULL, NULL, 0 },
1344 /* 0xfd */ { NULL, NULL, 0 },
1345 /* 0xfe */ { NULL, NULL, 0 },
1346 /* 0xff */ { NULL, NULL, 0 }
1350 /*******************************************************************
1351 allocate and initialize a reply packet
1352 ********************************************************************/
1354 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1355 const uint8_t *inbuf, char **outbuf,
1356 uint8_t num_words, uint32_t num_bytes)
1358 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1361 * Protect against integer wrap.
1362 * The SMB layer reply can be up to 0xFFFFFF bytes.
1364 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1366 if (asprintf(&msg, "num_bytes too large: %u",
1367 (unsigned)num_bytes) == -1) {
1368 msg = discard_const_p(char, "num_bytes too large");
1374 * Here we include the NBT header for now.
1376 *outbuf = talloc_array(mem_ctx, char,
1377 NBT_HDR_SIZE + smb_len);
1378 if (*outbuf == NULL) {
1382 construct_reply_common(req->cmd, inbuf, *outbuf);
1383 srv_set_message(*outbuf, num_words, num_bytes, false);
1385 * Zero out the word area, the caller has to take care of the bcc area
1388 if (num_words != 0) {
1389 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1395 void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1398 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1400 smb_panic("could not allocate output buffer\n");
1402 req->outbuf = (uint8_t *)outbuf;
1406 /*******************************************************************
1407 Dump a packet to a file.
1408 ********************************************************************/
1410 static void smb_dump(const char *name, int type, const char *data)
1415 if (DEBUGLEVEL < 50) {
1419 len = smb_len_tcp(data)+4;
1420 for (i=1;i<100;i++) {
1421 fname = talloc_asprintf(talloc_tos(),
1425 type ? "req" : "resp");
1426 if (fname == NULL) {
1429 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1430 if (fd != -1 || errno != EEXIST) break;
1434 ssize_t ret = write(fd, data, len);
1436 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1438 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1443 static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
1444 struct smb_request *req,
1446 bool *update_session_globalp,
1447 bool *update_tcon_globalp)
1449 connection_struct *conn = req->conn;
1450 struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
1451 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
1452 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1453 bool update_session = false;
1454 bool update_tcon = false;
1456 if (req->encrypted) {
1457 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
1460 if (srv_is_signing_active(req->xconn)) {
1461 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
1462 } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
1464 * echo can be unsigned. Sesssion setup except final
1465 * session setup response too
1467 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1470 update_session |= smbXsrv_set_crypto_flag(
1471 &session->global->encryption_flags, encrypt_flag);
1472 update_session |= smbXsrv_set_crypto_flag(
1473 &session->global->signing_flags, sign_flag);
1476 update_tcon |= smbXsrv_set_crypto_flag(
1477 &tcon->global->encryption_flags, encrypt_flag);
1478 update_tcon |= smbXsrv_set_crypto_flag(
1479 &tcon->global->signing_flags, sign_flag);
1482 if (update_session) {
1483 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1486 *update_session_globalp = update_session;
1487 *update_tcon_globalp = update_tcon;
1491 /****************************************************************************
1492 Prepare everything for calling the actual request function, and potentially
1493 call the request function via the "new" interface.
1495 Return False if the "legacy" function needs to be called, everything is
1498 Return True if we're done.
1500 I know this API sucks, but it is the one with the least code change I could
1502 ****************************************************************************/
1504 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1506 const struct loadparm_substitution *lp_sub =
1507 loadparm_s3_global_substitution();
1509 uint64_t session_tag;
1510 connection_struct *conn = NULL;
1511 struct smbXsrv_connection *xconn = req->xconn;
1512 NTTIME now = timeval_to_nttime(&req->request_time);
1513 struct smbXsrv_session *session = NULL;
1518 if (!xconn->smb1.negprot.done) {
1521 * Without a negprot the request must
1522 * either be a negprot, or one of the
1523 * evil old SMB mailslot messaging types.
1531 exit_server_cleanly("The first request "
1532 "should be a negprot");
1536 if (smb_messages[type].fn == NULL) {
1537 DEBUG(0,("Unknown message type %d!\n",type));
1538 smb_dump("Unknown", 1, (const char *)req->inbuf);
1539 reply_unknown_new(req, type);
1543 flags = smb_messages[type].flags;
1545 /* In share mode security we must ignore the vuid. */
1546 session_tag = req->vuid;
1549 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1550 (int)getpid(), (unsigned long)conn));
1552 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1554 /* Ensure this value is replaced in the incoming packet. */
1555 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1558 * Ensure the correct username is in current_user_info. This is a
1559 * really ugly bugfix for problems with multiple session_setup_and_X's
1560 * being done and allowing %U and %G substitutions to work correctly.
1561 * There is a reason this code is done here, don't move it unless you
1562 * know what you're doing... :-).
1567 * lookup an existing session
1569 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1570 * here, the main check is still in change_to_user()
1572 status = smb1srv_session_lookup(xconn,
1576 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1579 status = NT_STATUS_OK;
1582 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1583 (unsigned long long)session_tag,
1584 (unsigned long long)req->mid));
1585 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1590 if (session != NULL &&
1591 session->global->auth_session_info != NULL &&
1595 * change_to_user() implies set_current_user_info()
1596 * and chdir_connect_service().
1598 * So we only call set_current_user_info if
1599 * we don't have AS_USER specified.
1601 set_current_user_info(
1602 session->global->auth_session_info->unix_info->sanitized_username,
1603 session->global->auth_session_info->unix_info->unix_name,
1604 session->global->auth_session_info->info->domain_name);
1607 /* Does this call need to be run as the connected user? */
1608 if (flags & AS_USER) {
1610 /* Does this call need a valid tree connection? */
1613 * Amazingly, the error code depends on the command
1616 if (type == SMBntcreateX) {
1617 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1619 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1624 set_current_case_sensitive(conn, SVAL(req->inbuf,smb_flg));
1627 * change_to_user() implies set_current_user_info()
1628 * and chdir_connect_service().
1630 if (!change_to_user_and_service(conn,session_tag)) {
1631 DEBUG(0, ("Error: Could not change to user. Removing "
1632 "deferred open, mid=%llu.\n",
1633 (unsigned long long)req->mid));
1634 reply_force_doserror(req, ERRSRV, ERRbaduid);
1638 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1640 /* Does it need write permission? */
1641 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1642 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1646 /* IPC services are limited */
1647 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1648 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1651 } else if (flags & AS_GUEST) {
1653 * Does this protocol need to be run as guest? (Only archane
1654 * messenger service requests have this...)
1656 if (!change_to_guest()) {
1657 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1661 /* This call needs to be run as root */
1662 change_to_root_user();
1665 /* load service specific parameters */
1667 if (req->encrypted) {
1668 conn->encrypted_tid = true;
1669 /* encrypted required from now on. */
1670 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1671 } else if (ENCRYPTION_REQUIRED(conn)) {
1672 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1673 DEBUG(1,("service[%s] requires encryption"
1674 "%s ACCESS_DENIED. mid=%llu\n",
1675 lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
1677 (unsigned long long)req->mid));
1678 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1683 if (flags & DO_CHDIR) {
1686 ok = chdir_current_service(conn);
1688 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1692 conn->num_smb_operations++;
1696 * Update encryption and signing state tracking flags that are
1697 * used by smbstatus to display signing and encryption status.
1699 if (session != NULL) {
1700 bool update_session_global = false;
1701 bool update_tcon_global = false;
1703 req->session = session;
1705 smb1srv_update_crypto_flags(session, req, type,
1706 &update_session_global,
1707 &update_tcon_global);
1709 if (update_session_global) {
1710 status = smbXsrv_session_update(session);
1711 if (!NT_STATUS_IS_OK(status)) {
1712 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1717 if (update_tcon_global) {
1718 status = smbXsrv_tcon_update(req->conn->tcon);
1719 if (!NT_STATUS_IS_OK(status)) {
1720 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1726 smb_messages[type].fn(req);
1730 /****************************************************************************
1731 Construct a reply to the incoming packet.
1732 ****************************************************************************/
1734 static void construct_reply(struct smbXsrv_connection *xconn,
1735 char *inbuf, int size, size_t unread_bytes,
1736 uint32_t seqnum, bool encrypted,
1737 struct smb_perfcount_data *deferred_pcd)
1739 struct smbd_server_connection *sconn = xconn->client->sconn;
1740 struct smb_request *req;
1742 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1743 smb_panic("could not allocate smb_request");
1746 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1747 encrypted, seqnum)) {
1748 exit_server_cleanly("Invalid SMB request");
1751 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1753 /* we popped this message off the queue - keep original perf data */
1755 req->pcd = *deferred_pcd;
1757 SMB_PERFCOUNT_START(&req->pcd);
1758 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1759 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1762 req->conn = switch_message(req->cmd, req);
1764 if (req->outbuf == NULL) {
1766 * Request has suspended itself, will come
1771 if (CVAL(req->outbuf,0) == 0) {
1772 show_msg((char *)req->outbuf);
1774 smb_request_done(req);
1777 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1778 char *inbuf, int size, uint32_t seqnum,
1780 struct smb_perfcount_data *deferred_pcd)
1782 struct smb_request **reqs = NULL;
1783 struct smb_request *req;
1787 ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
1788 seqnum, &reqs, &num_reqs);
1790 char errbuf[smb_size];
1791 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1792 __LINE__, __FILE__);
1793 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1795 exit_server_cleanly("construct_reply_chain: "
1796 "srv_send_smb failed.");
1802 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1804 req->conn = switch_message(req->cmd, req);
1806 if (req->outbuf == NULL) {
1808 * Request has suspended itself, will come
1813 smb_request_done(req);
1817 * To be called from an async SMB handler that is potentially chained
1818 * when it is finished for shipping.
1821 void smb_request_done(struct smb_request *req)
1823 struct smb_request **reqs = NULL;
1824 struct smb_request *first_req;
1825 size_t i, num_reqs, next_index;
1828 if (req->chain == NULL) {
1834 num_reqs = talloc_array_length(reqs);
1836 for (i=0; i<num_reqs; i++) {
1837 if (reqs[i] == req) {
1841 if (i == num_reqs) {
1843 * Invalid chain, should not happen
1845 status = NT_STATUS_INTERNAL_ERROR;
1850 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1851 struct smb_request *next = reqs[next_index];
1852 struct smbXsrv_tcon *tcon;
1853 NTTIME now = timeval_to_nttime(&req->request_time);
1855 next->vuid = SVAL(req->outbuf, smb_uid);
1856 next->tid = SVAL(req->outbuf, smb_tid);
1857 status = smb1srv_tcon_lookup(req->xconn, next->tid,
1860 if (NT_STATUS_IS_OK(status)) {
1861 next->conn = tcon->compat;
1865 next->chain_fsp = req->chain_fsp;
1866 next->inbuf = req->inbuf;
1869 req->conn = switch_message(req->cmd, req);
1871 if (req->outbuf == NULL) {
1873 * Request has suspended itself, will come
1881 first_req = reqs[0];
1883 for (i=1; i<next_index; i++) {
1886 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1888 status = NT_STATUS_INTERNAL_ERROR;
1893 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1894 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1897 * This scary statement intends to set the
1898 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1899 * to the value last_req->outbuf carries
1901 SSVAL(first_req->outbuf, smb_flg2,
1902 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1903 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1906 * Transfer the error codes from the subrequest to the main one
1908 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1909 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1912 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1915 if (!srv_send_smb(first_req->xconn,
1916 (char *)first_req->outbuf,
1917 true, first_req->seqnum+1,
1918 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1920 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1923 TALLOC_FREE(req); /* non-chained case */
1924 TALLOC_FREE(reqs); /* chained case */
1929 char errbuf[smb_size];
1930 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1931 if (!srv_send_smb(req->xconn, errbuf, true,
1932 req->seqnum+1, req->encrypted,
1934 exit_server_cleanly("construct_reply_chain: "
1935 "srv_send_smb failed.");
1938 TALLOC_FREE(req); /* non-chained case */
1939 TALLOC_FREE(reqs); /* chained case */
1942 /****************************************************************************
1943 Process an smb from the client
1944 ****************************************************************************/
1945 static void process_smb(struct smbXsrv_connection *xconn,
1946 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1947 uint32_t seqnum, bool encrypted,
1948 struct smb_perfcount_data *deferred_pcd)
1950 struct smbd_server_connection *sconn = xconn->client->sconn;
1951 int msg_type = CVAL(inbuf,0);
1953 DO_PROFILE_INC(request);
1955 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1957 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1958 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1960 if (msg_type != NBSSmessage) {
1962 * NetBIOS session request, keepalive, etc.
1964 reply_special(xconn, (char *)inbuf, nread);
1968 if (sconn->using_smb2) {
1969 /* At this point we're not really using smb2,
1970 * we make the decision here.. */
1971 if (smbd_is_smb2_header(inbuf, nread)) {
1972 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1973 size_t pdulen = nread - NBT_HDR_SIZE;
1974 NTSTATUS status = smbd_smb2_process_negprot(
1979 if (!NT_STATUS_IS_OK(status)) {
1980 exit_server_cleanly("SMB2 negprot fail");
1984 if (nread >= smb_size && valid_smb_header(inbuf)
1985 && CVAL(inbuf, smb_com) != 0x72) {
1986 /* This is a non-negprot SMB1 packet.
1987 Disable SMB2 from now on. */
1988 sconn->using_smb2 = false;
1992 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1993 * so subtract 4 from it. */
1994 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1995 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1998 /* special magic for immediate exit */
2000 (IVAL(inbuf, 4) == SMB_SUICIDE_PACKET) &&
2001 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
2002 uint8_t exitcode = CVAL(inbuf, 8);
2003 DBG_WARNING("SUICIDE: Exiting immediately with code %d\n",
2008 exit_server_cleanly("Non-SMB packet");
2011 show_msg((char *)inbuf);
2013 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
2014 construct_reply_chain(xconn, (char *)inbuf, nread,
2015 seqnum, encrypted, deferred_pcd);
2017 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
2018 seqnum, encrypted, deferred_pcd);
2024 sconn->num_requests++;
2026 /* The timeout_processing function isn't run nearly
2027 often enough to implement 'max log size' without
2028 overrunning the size of the file by many megabytes.
2029 This is especially true if we are running at debug
2030 level 10. Checking every 50 SMBs is a nice
2031 tradeoff of performance vs log file size overrun. */
2033 if ((sconn->num_requests % 50) == 0 &&
2034 need_to_check_log_size()) {
2035 change_to_root_user();
2040 /****************************************************************************
2041 Return a string containing the function name of a SMB command.
2042 ****************************************************************************/
2044 const char *smb_fn_name(int type)
2046 const char *unknown_name = "SMBunknown";
2048 if (smb_messages[type].name == NULL)
2049 return(unknown_name);
2051 return(smb_messages[type].name);
2054 /****************************************************************************
2055 Helper functions for contruct_reply.
2056 ****************************************************************************/
2058 void add_to_common_flags2(uint32_t v)
2063 void remove_from_common_flags2(uint32_t v)
2065 common_flags2 &= ~v;
2068 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
2071 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
2072 uint16_t out_flags2 = common_flags2;
2074 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
2075 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
2076 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
2078 srv_set_message(outbuf,0,0,false);
2080 SCVAL(outbuf, smb_com, cmd);
2081 SIVAL(outbuf,smb_rcls,0);
2082 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
2083 SSVAL(outbuf,smb_flg2, out_flags2);
2084 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
2085 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2087 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2088 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2089 SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
2090 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2091 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2094 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2096 construct_reply_common(req->cmd, req->inbuf, outbuf);
2100 * @brief Find the smb_cmd offset of the last command pushed
2101 * @param[in] buf The buffer we're building up
2102 * @retval Where can we put our next andx cmd?
2104 * While chaining requests, the "next" request we're looking at needs to put
2105 * its SMB_Command before the data the previous request already built up added
2106 * to the chain. Find the offset to the place where we have to put our cmd.
2109 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2114 cmd = CVAL(buf, smb_com);
2116 if (!smb1cli_is_andx_req(cmd)) {
2122 while (CVAL(buf, ofs) != 0xff) {
2124 if (!smb1cli_is_andx_req(CVAL(buf, ofs))) {
2129 * ofs is from start of smb header, so add the 4 length
2130 * bytes. The next cmd is right after the wct field.
2132 ofs = SVAL(buf, ofs+2) + 4 + 1;
2134 if (ofs+4 >= talloc_get_size(buf)) {
2144 * @brief Do the smb chaining at a buffer level
2145 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2146 * @param[in] andx_buf Buffer to be appended
2149 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2151 uint8_t smb_command = CVAL(andx_buf, smb_com);
2152 uint8_t wct = CVAL(andx_buf, smb_wct);
2153 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2154 uint32_t num_bytes = smb_buflen(andx_buf);
2155 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2158 size_t old_size, new_size;
2160 size_t chain_padding = 0;
2161 size_t andx_cmd_ofs;
2164 old_size = talloc_get_size(*poutbuf);
2166 if ((old_size % 4) != 0) {
2168 * Align the wct field of subsequent requests to a 4-byte
2171 chain_padding = 4 - (old_size % 4);
2175 * After the old request comes the new wct field (1 byte), the vwv's
2176 * and the num_bytes field.
2179 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2180 new_size += num_bytes;
2182 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2183 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2184 (unsigned)new_size));
2188 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2189 if (outbuf == NULL) {
2190 DEBUG(0, ("talloc failed\n"));
2195 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2196 DEBUG(1, ("invalid command chain\n"));
2197 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2201 if (chain_padding != 0) {
2202 memset(outbuf + old_size, 0, chain_padding);
2203 old_size += chain_padding;
2206 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2207 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2212 * Push the chained request:
2217 SCVAL(outbuf, ofs, wct);
2224 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2229 * Read&X has an offset into its data buffer at
2230 * vwv[6]. reply_read_andx has no idea anymore that it's
2231 * running from within a chain, so we have to fix up the
2234 * Although it looks disgusting at this place, I want to keep
2235 * it here. The alternative would be to push knowledge about
2236 * the andx chain down into read&x again.
2239 if (smb_command == SMBreadX) {
2240 uint8_t *bytes_addr;
2244 * Invalid read&x response
2249 bytes_addr = outbuf + ofs /* vwv start */
2250 + sizeof(uint16_t) * wct /* vwv array */
2251 + sizeof(uint16_t) /* bcc */
2252 + 1; /* padding byte */
2254 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2255 bytes_addr - outbuf - 4);
2258 ofs += sizeof(uint16_t) * wct;
2264 SSVAL(outbuf, ofs, num_bytes);
2265 ofs += sizeof(uint16_t);
2271 memcpy(outbuf + ofs, bytes, num_bytes);
2276 bool smb1_is_chain(const uint8_t *buf)
2278 uint8_t cmd, wct, andx_cmd;
2280 cmd = CVAL(buf, smb_com);
2281 if (!smb1cli_is_andx_req(cmd)) {
2284 wct = CVAL(buf, smb_wct);
2288 andx_cmd = CVAL(buf, smb_vwv);
2289 return (andx_cmd != 0xFF);
2292 bool smb1_walk_chain(const uint8_t *buf,
2293 bool (*fn)(uint8_t cmd,
2294 uint8_t wct, const uint16_t *vwv,
2295 uint16_t num_bytes, const uint8_t *bytes,
2296 void *private_data),
2299 size_t smblen = smb_len(buf);
2300 const char *smb_buf = smb_base(buf);
2301 uint8_t cmd, chain_cmd;
2303 const uint16_t *vwv;
2305 const uint8_t *bytes;
2307 cmd = CVAL(buf, smb_com);
2308 wct = CVAL(buf, smb_wct);
2309 vwv = (const uint16_t *)(buf + smb_vwv);
2310 num_bytes = smb_buflen(buf);
2311 bytes = (const uint8_t *)smb_buf_const(buf);
2313 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2317 if (!smb1cli_is_andx_req(cmd)) {
2324 chain_cmd = CVAL(vwv, 0);
2326 while (chain_cmd != 0xff) {
2327 uint32_t chain_offset; /* uint32_t to avoid overflow */
2328 size_t length_needed;
2329 ptrdiff_t vwv_offset;
2331 chain_offset = SVAL(vwv+1, 0);
2334 * Check if the client tries to fool us. The chain
2335 * offset needs to point beyond the current request in
2336 * the chain, it needs to strictly grow. Otherwise we
2337 * might be tricked into an endless loop always
2338 * processing the same request over and over again. We
2339 * used to assume that vwv and the byte buffer array
2340 * in a chain are always attached, but OS/2 the
2341 * Write&X/Read&X chain puts the Read&X vwv array
2342 * right behind the Write&X vwv chain. The Write&X bcc
2343 * array is put behind the Read&X vwv array. So now we
2344 * check whether the chain offset points strictly
2345 * behind the previous vwv array. req->buf points
2346 * right after the vwv array of the previous
2348 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2352 vwv_offset = ((const char *)vwv - smb_buf);
2353 if (chain_offset <= vwv_offset) {
2358 * Next check: Make sure the chain offset does not
2359 * point beyond the overall smb request length.
2362 length_needed = chain_offset+1; /* wct */
2363 if (length_needed > smblen) {
2368 * Now comes the pointer magic. Goal here is to set up
2369 * vwv and buf correctly again. The chain offset (the
2370 * former vwv[1]) points at the new wct field.
2373 wct = CVAL(smb_buf, chain_offset);
2375 if (smb1cli_is_andx_req(chain_cmd) && (wct < 2)) {
2380 * Next consistency check: Make the new vwv array fits
2381 * in the overall smb request.
2384 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2385 if (length_needed > smblen) {
2388 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2391 * Now grab the new byte buffer....
2394 num_bytes = SVAL(vwv+wct, 0);
2397 * .. and check that it fits.
2400 length_needed += num_bytes;
2401 if (length_needed > smblen) {
2404 bytes = (const uint8_t *)(vwv+wct+1);
2406 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2410 if (!smb1cli_is_andx_req(chain_cmd)) {
2413 chain_cmd = CVAL(vwv, 0);
2418 static bool smb1_chain_length_cb(uint8_t cmd,
2419 uint8_t wct, const uint16_t *vwv,
2420 uint16_t num_bytes, const uint8_t *bytes,
2423 unsigned *count = (unsigned *)private_data;
2428 unsigned smb1_chain_length(const uint8_t *buf)
2432 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2438 struct smb1_parse_chain_state {
2439 TALLOC_CTX *mem_ctx;
2441 struct smbd_server_connection *sconn;
2442 struct smbXsrv_connection *xconn;
2446 struct smb_request **reqs;
2450 static bool smb1_parse_chain_cb(uint8_t cmd,
2451 uint8_t wct, const uint16_t *vwv,
2452 uint16_t num_bytes, const uint8_t *bytes,
2455 struct smb1_parse_chain_state *state =
2456 (struct smb1_parse_chain_state *)private_data;
2457 struct smb_request **reqs;
2458 struct smb_request *req;
2461 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2462 struct smb_request *, state->num_reqs+1);
2468 req = talloc(reqs, struct smb_request);
2473 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2474 state->encrypted, state->seqnum);
2481 req->buflen = num_bytes;
2484 reqs[state->num_reqs] = req;
2485 state->num_reqs += 1;
2489 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2490 struct smbXsrv_connection *xconn,
2491 bool encrypted, uint32_t seqnum,
2492 struct smb_request ***reqs, unsigned *num_reqs)
2494 struct smbd_server_connection *sconn = NULL;
2495 struct smb1_parse_chain_state state;
2498 if (xconn != NULL) {
2499 sconn = xconn->client->sconn;
2502 state.mem_ctx = mem_ctx;
2504 state.sconn = sconn;
2505 state.xconn = xconn;
2506 state.encrypted = encrypted;
2507 state.seqnum = seqnum;
2511 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2512 TALLOC_FREE(state.reqs);
2515 for (i=0; i<state.num_reqs; i++) {
2516 state.reqs[i]->chain = state.reqs;
2519 *num_reqs = state.num_reqs;
2523 /****************************************************************************
2524 Check if services need reloading.
2525 ****************************************************************************/
2527 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2530 if (last_smb_conf_reload_time == 0) {
2531 last_smb_conf_reload_time = t;
2534 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2535 reload_services(sconn, conn_snum_used, true);
2536 last_smb_conf_reload_time = t;
2540 static bool fd_is_readable(int fd)
2544 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2546 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2550 static void smbd_server_connection_write_handler(
2551 struct smbXsrv_connection *xconn)
2553 /* TODO: make write nonblocking */
2556 static void smbd_server_connection_read_handler(
2557 struct smbXsrv_connection *xconn, int fd)
2559 uint8_t *inbuf = NULL;
2560 size_t inbuf_len = 0;
2561 size_t unread_bytes = 0;
2562 bool encrypted = false;
2563 TALLOC_CTX *mem_ctx = talloc_tos();
2567 bool async_echo = lp_async_smb_echo_handler();
2568 bool from_client = false;
2571 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2573 * This is the super-ugly hack to prefer the packets
2574 * forwarded by the echo handler over the ones by the
2577 fd = xconn->smb1.echo_handler.trusted_fd;
2581 from_client = (xconn->transport.sock == fd);
2583 if (async_echo && from_client) {
2584 smbd_lock_socket(xconn);
2586 if (!fd_is_readable(fd)) {
2587 DEBUG(10,("the echo listener was faster\n"));
2588 smbd_unlock_socket(xconn);
2593 /* TODO: make this completely nonblocking */
2594 status = receive_smb_talloc(mem_ctx, xconn, fd,
2595 (char **)(void *)&inbuf,
2599 &inbuf_len, &seqnum,
2600 !from_client /* trusted channel */);
2602 if (async_echo && from_client) {
2603 smbd_unlock_socket(xconn);
2606 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2609 if (NT_STATUS_IS_ERR(status)) {
2610 exit_server_cleanly("failed to receive smb request");
2612 if (!NT_STATUS_IS_OK(status)) {
2617 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2618 seqnum, encrypted, NULL);
2621 static void smbd_server_connection_handler(struct tevent_context *ev,
2622 struct tevent_fd *fde,
2626 struct smbXsrv_connection *xconn =
2627 talloc_get_type_abort(private_data,
2628 struct smbXsrv_connection);
2630 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2632 * we're not supposed to do any io
2634 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2635 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2639 if (flags & TEVENT_FD_WRITE) {
2640 smbd_server_connection_write_handler(xconn);
2643 if (flags & TEVENT_FD_READ) {
2644 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2649 static void smbd_server_echo_handler(struct tevent_context *ev,
2650 struct tevent_fd *fde,
2654 struct smbXsrv_connection *xconn =
2655 talloc_get_type_abort(private_data,
2656 struct smbXsrv_connection);
2658 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2660 * we're not supposed to do any io
2662 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2663 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2667 if (flags & TEVENT_FD_WRITE) {
2668 smbd_server_connection_write_handler(xconn);
2671 if (flags & TEVENT_FD_READ) {
2672 smbd_server_connection_read_handler(
2673 xconn, xconn->smb1.echo_handler.trusted_fd);
2678 struct smbd_release_ip_state {
2679 struct smbXsrv_connection *xconn;
2680 struct tevent_immediate *im;
2681 char addr[INET6_ADDRSTRLEN];
2684 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2685 struct tevent_immediate *im,
2688 struct smbd_release_ip_state *state =
2689 talloc_get_type_abort(private_data,
2690 struct smbd_release_ip_state);
2691 struct smbXsrv_connection *xconn = state->xconn;
2693 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2695 * smbd_server_connection_terminate() already triggered ?
2700 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2703 /****************************************************************************
2704 received when we should release a specific IP
2705 ****************************************************************************/
2706 static int release_ip(struct tevent_context *ev,
2707 uint32_t src_vnn, uint32_t dst_vnn,
2709 const uint8_t *msg, size_t msglen,
2712 struct smbd_release_ip_state *state =
2713 talloc_get_type_abort(private_data,
2714 struct smbd_release_ip_state);
2715 struct smbXsrv_connection *xconn = state->xconn;
2717 const char *addr = state->addr;
2718 const char *p = addr;
2723 if (msg[msglen-1] != '\0') {
2727 ip = (const char *)msg;
2729 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2730 /* avoid recursion */
2734 if (strncmp("::ffff:", addr, 7) == 0) {
2738 DEBUG(10, ("Got release IP message for %s, "
2739 "our address is %s\n", ip, p));
2741 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2742 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2745 * With SMB2 we should do a clean disconnect,
2746 * the previous_session_id in the session setup
2747 * will cleanup the old session, tcons and opens.
2749 * A clean disconnect is needed in order to support
2752 * Note: typically this is never triggered
2753 * as we got a TCP RST (triggered by ctdb event scripts)
2754 * before we get CTDB_SRVID_RELEASE_IP.
2756 * We used to call _exit(1) here, but as this was mostly never
2757 * triggered and has implication on our process model,
2758 * we can just use smbd_server_connection_terminate()
2761 * We don't call smbd_server_connection_terminate() directly
2762 * as we might be called from within ctdbd_migrate(),
2763 * we need to defer our action to the next event loop
2765 tevent_schedule_immediate(state->im,
2766 xconn->client->raw_ev_ctx,
2767 smbd_release_ip_immediate,
2771 * Make sure we don't get any io on the connection.
2773 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2774 return EADDRNOTAVAIL;
2780 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2781 struct sockaddr_storage *srv,
2782 struct sockaddr_storage *clnt)
2784 struct smbd_release_ip_state *state;
2785 struct ctdbd_connection *cconn;
2788 cconn = messaging_ctdb_connection();
2789 if (cconn == NULL) {
2790 return NT_STATUS_NO_MEMORY;
2793 state = talloc_zero(xconn, struct smbd_release_ip_state);
2794 if (state == NULL) {
2795 return NT_STATUS_NO_MEMORY;
2797 state->xconn = xconn;
2798 state->im = tevent_create_immediate(state);
2799 if (state->im == NULL) {
2800 return NT_STATUS_NO_MEMORY;
2802 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2803 return NT_STATUS_NO_MEMORY;
2806 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2808 return map_nt_error_from_unix(ret);
2810 return NT_STATUS_OK;
2813 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2814 void *private_data, uint32_t msg_type,
2815 struct server_id server_id, DATA_BLOB *data)
2817 struct smbd_server_connection *sconn = talloc_get_type_abort(
2818 private_data, struct smbd_server_connection);
2819 const char *ip = (char *) data->data;
2822 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2824 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2826 if (client_ip == NULL) {
2830 if (strequal(ip, client_ip)) {
2831 DBG_WARNING("Got kill client message for %s - "
2832 "exiting immediately\n", ip);
2833 exit_server_cleanly("Forced disconnect for client");
2836 TALLOC_FREE(client_ip);
2840 * Send keepalive packets to our client
2842 static bool keepalive_fn(const struct timeval *now, void *private_data)
2844 struct smbd_server_connection *sconn = talloc_get_type_abort(
2845 private_data, struct smbd_server_connection);
2846 struct smbXsrv_connection *xconn = NULL;
2849 if (sconn->using_smb2) {
2850 /* Don't do keepalives on an SMB2 connection. */
2855 * With SMB1 we only have 1 connection
2857 xconn = sconn->client->connections;
2858 smbd_lock_socket(xconn);
2859 ret = send_keepalive(xconn->transport.sock);
2860 smbd_unlock_socket(xconn);
2863 int saved_errno = errno;
2865 * Try and give an error message saying what
2868 DEBUG(0, ("send_keepalive failed for client %s. "
2869 "Error %s - exiting\n",
2870 smbXsrv_connection_dbg(xconn),
2871 strerror(saved_errno)));
2872 errno = saved_errno;
2879 * Do the recurring check if we're idle
2881 static bool deadtime_fn(const struct timeval *now, void *private_data)
2883 struct smbd_server_connection *sconn =
2884 (struct smbd_server_connection *)private_data;
2886 if ((conn_num_open(sconn) == 0)
2887 || (conn_idle_all(sconn, now->tv_sec))) {
2888 DEBUG( 2, ( "Closing idle connection\n" ) );
2889 messaging_send(sconn->msg_ctx,
2890 messaging_server_id(sconn->msg_ctx),
2891 MSG_SHUTDOWN, &data_blob_null);
2899 * Do the recurring log file and smb.conf reload checks.
2902 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2904 struct smbd_server_connection *sconn = talloc_get_type_abort(
2905 private_data, struct smbd_server_connection);
2907 DEBUG(5, ("housekeeping\n"));
2909 change_to_root_user();
2911 /* update printer queue caches if necessary */
2912 update_monitored_printq_cache(sconn->msg_ctx);
2914 /* check if we need to reload services */
2915 check_reload(sconn, time_mono(NULL));
2918 * Force a log file check.
2920 force_check_log_size();
2926 * Read an smb packet in the echo handler child, giving the parent
2927 * smbd one second to react once the socket becomes readable.
2930 struct smbd_echo_read_state {
2931 struct tevent_context *ev;
2932 struct smbXsrv_connection *xconn;
2939 static void smbd_echo_read_readable(struct tevent_req *subreq);
2940 static void smbd_echo_read_waited(struct tevent_req *subreq);
2942 static struct tevent_req *smbd_echo_read_send(
2943 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2944 struct smbXsrv_connection *xconn)
2946 struct tevent_req *req, *subreq;
2947 struct smbd_echo_read_state *state;
2949 req = tevent_req_create(mem_ctx, &state,
2950 struct smbd_echo_read_state);
2955 state->xconn = xconn;
2957 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2958 if (tevent_req_nomem(subreq, req)) {
2959 return tevent_req_post(req, ev);
2961 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2965 static void smbd_echo_read_readable(struct tevent_req *subreq)
2967 struct tevent_req *req = tevent_req_callback_data(
2968 subreq, struct tevent_req);
2969 struct smbd_echo_read_state *state = tevent_req_data(
2970 req, struct smbd_echo_read_state);
2974 ok = wait_for_read_recv(subreq, &err);
2975 TALLOC_FREE(subreq);
2977 tevent_req_nterror(req, map_nt_error_from_unix(err));
2982 * Give the parent smbd one second to step in
2985 subreq = tevent_wakeup_send(
2986 state, state->ev, timeval_current_ofs(1, 0));
2987 if (tevent_req_nomem(subreq, req)) {
2990 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2993 static void smbd_echo_read_waited(struct tevent_req *subreq)
2995 struct tevent_req *req = tevent_req_callback_data(
2996 subreq, struct tevent_req);
2997 struct smbd_echo_read_state *state = tevent_req_data(
2998 req, struct smbd_echo_read_state);
2999 struct smbXsrv_connection *xconn = state->xconn;
3005 ok = tevent_wakeup_recv(subreq);
3006 TALLOC_FREE(subreq);
3008 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
3012 ok = smbd_lock_socket_internal(xconn);
3014 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3015 DEBUG(0, ("%s: failed to lock socket\n", __location__));
3019 if (!fd_is_readable(xconn->transport.sock)) {
3020 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3023 ok = smbd_unlock_socket_internal(xconn);
3025 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3026 DEBUG(1, ("%s: failed to unlock socket\n",
3031 subreq = wait_for_read_send(state, state->ev,
3032 xconn->transport.sock, false);
3033 if (tevent_req_nomem(subreq, req)) {
3036 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
3040 status = receive_smb_talloc(state, xconn,
3041 xconn->transport.sock,
3048 false /* trusted_channel*/);
3050 if (tevent_req_nterror(req, status)) {
3051 tevent_req_nterror(req, status);
3052 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3053 (int)getpid(), nt_errstr(status)));
3057 ok = smbd_unlock_socket_internal(xconn);
3059 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3060 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
3063 tevent_req_done(req);
3066 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3067 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
3069 struct smbd_echo_read_state *state = tevent_req_data(
3070 req, struct smbd_echo_read_state);
3073 if (tevent_req_is_nterror(req, &status)) {
3076 *pbuf = talloc_move(mem_ctx, &state->buf);
3077 *pbuflen = state->buflen;
3078 *pseqnum = state->seqnum;
3079 return NT_STATUS_OK;
3082 struct smbd_echo_state {
3083 struct tevent_context *ev;
3084 struct iovec *pending;
3085 struct smbd_server_connection *sconn;
3086 struct smbXsrv_connection *xconn;
3089 struct tevent_fd *parent_fde;
3091 struct tevent_req *write_req;
3094 static void smbd_echo_writer_done(struct tevent_req *req);
3096 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3100 if (state->write_req != NULL) {
3104 num_pending = talloc_array_length(state->pending);
3105 if (num_pending == 0) {
3109 state->write_req = writev_send(state, state->ev, NULL,
3110 state->parent_pipe, false,
3111 state->pending, num_pending);
3112 if (state->write_req == NULL) {
3113 DEBUG(1, ("writev_send failed\n"));
3117 talloc_steal(state->write_req, state->pending);
3118 state->pending = NULL;
3120 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3124 static void smbd_echo_writer_done(struct tevent_req *req)
3126 struct smbd_echo_state *state = tevent_req_callback_data(
3127 req, struct smbd_echo_state);
3131 written = writev_recv(req, &err);
3133 state->write_req = NULL;
3134 if (written == -1) {
3135 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3138 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3139 smbd_echo_activate_writer(state);
3142 static bool smbd_echo_reply(struct smbd_echo_state *state,
3143 uint8_t *inbuf, size_t inbuf_len,
3146 struct smb_request req;
3147 uint16_t num_replies;
3151 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3152 DEBUG(10, ("Got netbios keepalive\n"));
3159 if (inbuf_len < smb_size) {
3160 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3163 if (!valid_smb_header(inbuf)) {
3164 DEBUG(10, ("Got invalid SMB header\n"));
3168 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3174 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3175 smb_messages[req.cmd].name
3176 ? smb_messages[req.cmd].name : "unknown"));
3178 if (req.cmd != SMBecho) {
3185 num_replies = SVAL(req.vwv+0, 0);
3186 if (num_replies != 1) {
3187 /* Not a Windows "Hey, you're still there?" request */
3191 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3193 DEBUG(10, ("create_outbuf failed\n"));
3196 req.outbuf = (uint8_t *)outbuf;
3198 SSVAL(req.outbuf, smb_vwv0, num_replies);
3200 if (req.buflen > 0) {
3201 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3204 ok = srv_send_smb(req.xconn,
3208 TALLOC_FREE(outbuf);
3216 static void smbd_echo_exit(struct tevent_context *ev,
3217 struct tevent_fd *fde, uint16_t flags,
3220 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3224 static void smbd_echo_got_packet(struct tevent_req *req);
3226 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3229 struct smbd_echo_state *state;
3230 struct tevent_req *read_req;
3232 state = talloc_zero(xconn, struct smbd_echo_state);
3233 if (state == NULL) {
3234 DEBUG(1, ("talloc failed\n"));
3237 state->xconn = xconn;
3238 state->parent_pipe = parent_pipe;
3239 state->ev = samba_tevent_context_init(state);
3240 if (state->ev == NULL) {
3241 DEBUG(1, ("samba_tevent_context_init failed\n"));
3245 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3246 TEVENT_FD_READ, smbd_echo_exit,
3248 if (state->parent_fde == NULL) {
3249 DEBUG(1, ("tevent_add_fd failed\n"));
3254 read_req = smbd_echo_read_send(state, state->ev, xconn);
3255 if (read_req == NULL) {
3256 DEBUG(1, ("smbd_echo_read_send failed\n"));
3260 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3263 if (tevent_loop_once(state->ev) == -1) {
3264 DEBUG(1, ("tevent_loop_once failed: %s\n",
3272 static void smbd_echo_got_packet(struct tevent_req *req)
3274 struct smbd_echo_state *state = tevent_req_callback_data(
3275 req, struct smbd_echo_state);
3279 uint32_t seqnum = 0;
3282 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3284 if (!NT_STATUS_IS_OK(status)) {
3285 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3286 nt_errstr(status)));
3290 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3296 num_pending = talloc_array_length(state->pending);
3297 tmp = talloc_realloc(state, state->pending, struct iovec,
3300 DEBUG(1, ("talloc_realloc failed\n"));
3303 state->pending = tmp;
3305 if (buflen >= smb_size) {
3307 * place the seqnum in the packet so that the main process
3308 * can reply with signing
3310 SIVAL(buf, smb_ss_field, seqnum);
3311 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3314 iov = &state->pending[num_pending];
3315 iov->iov_base = talloc_move(state->pending, &buf);
3316 iov->iov_len = buflen;
3318 DEBUG(10,("echo_handler[%d]: forward to main\n",
3320 smbd_echo_activate_writer(state);
3323 req = smbd_echo_read_send(state, state->ev, state->xconn);
3325 DEBUG(1, ("smbd_echo_read_send failed\n"));
3328 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3333 * Handle SMBecho requests in a forked child process
3335 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3337 int listener_pipe[2];
3340 bool use_mutex = false;
3342 res = pipe(listener_pipe);
3344 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3348 #ifdef HAVE_ROBUST_MUTEXES
3349 use_mutex = tdb_runtime_check_for_robust_mutexes();
3352 pthread_mutexattr_t a;
3354 xconn->smb1.echo_handler.socket_mutex =
3355 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3356 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3357 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3362 res = pthread_mutexattr_init(&a);
3364 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3368 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3370 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3372 pthread_mutexattr_destroy(&a);
3375 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3377 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3379 pthread_mutexattr_destroy(&a);
3382 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3384 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3385 "%s\n", strerror(res)));
3386 pthread_mutexattr_destroy(&a);
3389 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3391 pthread_mutexattr_destroy(&a);
3393 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3401 xconn->smb1.echo_handler.socket_lock_fd =
3402 create_unlink_tmp(lp_lock_directory());
3403 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3404 DEBUG(1, ("Could not create lock fd: %s\n",
3414 close(listener_pipe[0]);
3415 set_blocking(listener_pipe[1], false);
3417 status = smbd_reinit_after_fork(xconn->client->msg_ctx,
3418 xconn->client->raw_ev_ctx,
3421 if (!NT_STATUS_IS_OK(status)) {
3422 DEBUG(1, ("reinit_after_fork failed: %s\n",
3423 nt_errstr(status)));
3426 initialize_password_db(true, xconn->client->raw_ev_ctx);
3427 smbd_echo_loop(xconn, listener_pipe[1]);
3430 close(listener_pipe[1]);
3431 listener_pipe[1] = -1;
3432 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3434 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3437 * Without smb signing this is the same as the normal smbd
3438 * listener. This needs to change once signing comes in.
3440 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(
3441 xconn->client->raw_ev_ctx,
3443 xconn->smb1.echo_handler.trusted_fd,
3445 smbd_server_echo_handler,
3447 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3448 DEBUG(1, ("event_add_fd failed\n"));
3455 if (listener_pipe[0] != -1) {
3456 close(listener_pipe[0]);
3458 if (listener_pipe[1] != -1) {
3459 close(listener_pipe[1]);
3461 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3462 close(xconn->smb1.echo_handler.socket_lock_fd);
3464 #ifdef HAVE_ROBUST_MUTEXES
3465 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3466 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3467 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3470 smbd_echo_init(xconn);
3475 static bool uid_in_use(struct auth_session_info *session_info,
3478 if (session_info->unix_token->uid == uid) {
3484 static bool gid_in_use(struct auth_session_info *session_info,
3488 struct security_unix_token *utok = NULL;
3490 utok = session_info->unix_token;
3491 if (utok->gid == gid) {
3495 for(i = 0; i < utok->ngroups; i++) {
3496 if (utok->groups[i] == gid) {
3503 static bool sid_in_use(struct auth_session_info *session_info,
3504 const struct dom_sid *psid)
3506 struct security_token *tok = NULL;
3508 tok = 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)) {
3523 struct id_in_use_state {
3524 const struct id_cache_ref *id;
3528 static int id_in_use_cb(struct smbXsrv_session *session,
3531 struct id_in_use_state *state = (struct id_in_use_state *)
3533 struct auth_session_info *session_info =
3534 session->global->auth_session_info;
3536 switch(state->id->type) {
3538 state->match = uid_in_use(session_info, state->id->id.uid);
3541 state->match = gid_in_use(session_info, state->id->id.gid);
3544 state->match = sid_in_use(session_info, &state->id->id.sid);
3547 state->match = false;
3556 static bool id_in_use(struct smbd_server_connection *sconn,
3557 const struct id_cache_ref *id)
3559 struct id_in_use_state state;
3562 state = (struct id_in_use_state) {
3567 status = smbXsrv_session_local_traverse(sconn->client,
3570 if (!NT_STATUS_IS_OK(status)) {
3577 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3580 struct server_id server_id,
3583 const char *msg = (data && data->data)
3584 ? (const char *)data->data : "<NULL>";
3585 struct id_cache_ref id;
3586 struct smbd_server_connection *sconn =
3587 talloc_get_type_abort(private_data,
3588 struct smbd_server_connection);
3590 if (!id_cache_ref_parse(msg, &id)) {
3591 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3595 if (id_in_use(sconn, &id)) {
3596 exit_server_cleanly(msg);
3598 id_cache_delete_from_cache(&id);
3601 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3602 enum protocol_types protocol)
3606 conn->protocol = protocol;
3608 if (conn->client->session_table != NULL) {
3609 return NT_STATUS_OK;
3612 if (protocol >= PROTOCOL_SMB2_02) {
3613 status = smb2srv_session_table_init(conn);
3614 if (!NT_STATUS_IS_OK(status)) {
3615 conn->protocol = PROTOCOL_NONE;
3619 status = smb2srv_open_table_init(conn);
3620 if (!NT_STATUS_IS_OK(status)) {
3621 conn->protocol = PROTOCOL_NONE;
3625 status = smb1srv_session_table_init(conn);
3626 if (!NT_STATUS_IS_OK(status)) {
3627 conn->protocol = PROTOCOL_NONE;
3631 status = smb1srv_tcon_table_init(conn);
3632 if (!NT_STATUS_IS_OK(status)) {
3633 conn->protocol = PROTOCOL_NONE;
3637 status = smb1srv_open_table_init(conn);
3638 if (!NT_STATUS_IS_OK(status)) {
3639 conn->protocol = PROTOCOL_NONE;
3644 set_Protocol(protocol);
3645 return NT_STATUS_OK;
3648 struct smbd_tevent_trace_state {
3649 struct tevent_context *ev;
3651 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3654 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3657 struct smbd_tevent_trace_state *state =
3658 (struct smbd_tevent_trace_state *)private_data;
3661 case TEVENT_TRACE_BEFORE_WAIT:
3662 if (!smbprofile_dump_pending()) {
3664 * If there's no dump pending
3665 * we don't want to schedule a new 1 sec timer.
3667 * Instead we want to sleep as long as nothing happens.
3669 smbprofile_dump_setup(NULL);
3671 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3673 case TEVENT_TRACE_AFTER_WAIT:
3674 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3675 if (!smbprofile_dump_pending()) {
3677 * We need to flush our state after sleeping
3678 * (hopefully a long time).
3682 * future profiling events should trigger timers
3683 * on our main event context.
3685 smbprofile_dump_setup(state->ev);
3688 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3689 TALLOC_FREE(state->frame);
3690 state->frame = talloc_stackframe_pool(8192);
3692 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3693 TALLOC_FREE(state->frame);
3701 * Create a debug string for the connection
3703 * This is allocated to talloc_tos() or a string constant
3704 * in certain corner cases. The returned string should
3705 * hence not be free'd directly but only via the talloc stack.
3707 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3712 * TODO: this can be improved later
3713 * maybe including the client guid or more
3715 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3717 return "<tsocket_address_string() failed>";
3723 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3724 struct smbXsrv_connection **_xconn)
3726 TALLOC_CTX *frame = talloc_stackframe();
3727 struct smbXsrv_connection *xconn;
3728 struct sockaddr_storage ss_srv;
3729 void *sp_srv = (void *)&ss_srv;
3730 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3731 struct sockaddr_storage ss_clnt;
3732 void *sp_clnt = (void *)&ss_clnt;
3733 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3734 socklen_t sa_socklen;
3735 struct tsocket_address *local_address = NULL;
3736 struct tsocket_address *remote_address = NULL;
3737 const char *remaddr = NULL;
3739 const char *rhost = NULL;
3745 DO_PROFILE_INC(connect);
3747 xconn = talloc_zero(client, struct smbXsrv_connection);
3748 if (xconn == NULL) {
3749 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3751 return NT_STATUS_NO_MEMORY;
3753 talloc_steal(frame, xconn);
3755 xconn->transport.sock = sock_fd;
3756 smbd_echo_init(xconn);
3757 xconn->protocol = PROTOCOL_NONE;
3759 /* Ensure child is set to blocking mode */
3760 set_blocking(sock_fd,True);
3762 set_socket_options(sock_fd, "SO_KEEPALIVE");
3763 set_socket_options(sock_fd, lp_socket_options());
3765 sa_socklen = sizeof(ss_clnt);
3766 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3768 int saved_errno = errno;
3769 int level = (errno == ENOTCONN)?2:0;
3770 DEBUG(level,("getpeername() failed - %s\n",
3771 strerror(saved_errno)));
3773 return map_nt_error_from_unix_common(saved_errno);
3775 ret = tsocket_address_bsd_from_sockaddr(xconn,
3776 sa_clnt, sa_socklen,
3779 int saved_errno = errno;
3780 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3781 __location__, strerror(saved_errno)));
3783 return map_nt_error_from_unix_common(saved_errno);
3786 sa_socklen = sizeof(ss_srv);
3787 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3789 int saved_errno = errno;
3790 int level = (errno == ENOTCONN)?2:0;
3791 DEBUG(level,("getsockname() failed - %s\n",
3792 strerror(saved_errno)));
3794 return map_nt_error_from_unix_common(saved_errno);
3796 ret = tsocket_address_bsd_from_sockaddr(xconn,
3800 int saved_errno = errno;
3801 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3802 __location__, strerror(saved_errno)));
3804 return map_nt_error_from_unix_common(saved_errno);
3807 if (tsocket_address_is_inet(remote_address, "ip")) {
3808 remaddr = tsocket_address_inet_addr_string(remote_address,
3810 if (remaddr == NULL) {
3811 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3812 __location__, strerror(errno)));
3814 return NT_STATUS_NO_MEMORY;
3817 remaddr = "0.0.0.0";
3821 * Before the first packet, check the global hosts allow/ hosts deny
3822 * parameters before doing any parsing of packets passed to us by the
3823 * client. This prevents attacks on our parsing code from hosts not in
3824 * the hosts allow list.
3827 ret = get_remote_hostname(remote_address,
3830 int saved_errno = errno;
3831 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3832 __location__, strerror(saved_errno)));
3834 return map_nt_error_from_unix_common(saved_errno);
3837 if (strequal(rhost, "UNKNOWN")) {
3841 xconn->local_address = local_address;
3842 xconn->remote_address = remote_address;
3843 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3844 if (xconn->remote_hostname == NULL) {
3845 return NT_STATUS_NO_MEMORY;
3848 if (!srv_init_signing(xconn)) {
3849 DEBUG(0, ("Failed to init smb_signing\n"));
3851 return NT_STATUS_INTERNAL_ERROR;
3854 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3855 xconn->remote_hostname,
3857 DEBUG( 1, ("Connection denied from %s to %s\n",
3858 tsocket_address_string(remote_address, talloc_tos()),
3859 tsocket_address_string(local_address, talloc_tos())));
3862 * We return a valid xconn
3863 * so that the caller can return an error message
3866 client->connections = xconn;
3867 xconn->client = client;
3868 talloc_steal(client, xconn);
3872 return NT_STATUS_NETWORK_ACCESS_DENIED;
3875 DEBUG(10, ("Connection allowed from %s to %s\n",
3876 tsocket_address_string(remote_address, talloc_tos()),
3877 tsocket_address_string(local_address, talloc_tos())));
3879 if (lp_clustering()) {
3881 * We need to tell ctdb about our client's TCP
3882 * connection, so that for failover ctdbd can send
3883 * tickle acks, triggering a reconnection by the
3888 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3889 if (!NT_STATUS_IS_OK(status)) {
3890 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3891 nt_errstr(status)));
3895 tmp = lp_max_xmit();
3896 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3897 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3899 xconn->smb1.negprot.max_recv = tmp;
3901 xconn->smb1.sessions.done_sesssetup = false;
3902 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3904 xconn->transport.fde = tevent_add_fd(client->raw_ev_ctx,
3908 smbd_server_connection_handler,
3910 if (!xconn->transport.fde) {
3912 return NT_STATUS_NO_MEMORY;
3915 /* for now we only have one connection */
3916 DLIST_ADD_END(client->connections, xconn);
3917 xconn->client = client;
3918 talloc_steal(client, xconn);
3922 return NT_STATUS_OK;
3925 /****************************************************************************
3926 Process commands from the client
3927 ****************************************************************************/
3929 void smbd_process(struct tevent_context *ev_ctx,
3930 struct messaging_context *msg_ctx,
3934 struct smbd_tevent_trace_state trace_state = {
3936 .frame = talloc_stackframe(),
3938 const struct loadparm_substitution *lp_sub =
3939 loadparm_s3_global_substitution();
3940 struct smbXsrv_client *client = NULL;
3941 struct smbd_server_connection *sconn = NULL;
3942 struct smbXsrv_connection *xconn = NULL;
3943 const char *locaddr = NULL;
3944 const char *remaddr = NULL;
3947 struct timeval tv = timeval_current();
3948 NTTIME now = timeval_to_nttime(&tv);
3949 char *chroot_dir = NULL;
3952 status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
3953 if (!NT_STATUS_IS_OK(status)) {
3954 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
3955 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3959 * TODO: remove this...:-)
3961 global_smbXsrv_client = client;
3963 sconn = talloc_zero(client, struct smbd_server_connection);
3964 if (sconn == NULL) {
3965 exit_server("failed to create smbd_server_connection");
3968 client->sconn = sconn;
3969 sconn->client = client;
3971 sconn->ev_ctx = ev_ctx;
3972 sconn->msg_ctx = msg_ctx;
3974 ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
3977 exit_server("pthreadpool_tevent_init() failed.");
3980 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3982 * We're not making the decision here,
3983 * we're just allowing the client
3984 * to decide between SMB1 and SMB2
3985 * with the first negprot
3988 sconn->using_smb2 = true;
3992 smbd_setup_sig_term_handler(sconn);
3993 smbd_setup_sig_hup_handler(sconn);
3996 status = smbd_add_connection(client, sock_fd, &xconn);
3997 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3999 * send a negative session response "not listening on calling
4002 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
4003 (void)srv_send_smb(xconn,(char *)buf, false,
4005 exit_server_cleanly("connection denied");
4006 } else if (!NT_STATUS_IS_OK(status)) {
4007 exit_server_cleanly(nt_errstr(status));
4010 sconn->local_address =
4011 tsocket_address_copy(xconn->local_address, sconn);
4012 if (sconn->local_address == NULL) {
4013 exit_server_cleanly("tsocket_address_copy() failed");
4015 sconn->remote_address =
4016 tsocket_address_copy(xconn->remote_address, sconn);
4017 if (sconn->remote_address == NULL) {
4018 exit_server_cleanly("tsocket_address_copy() failed");
4020 sconn->remote_hostname =
4021 talloc_strdup(sconn, xconn->remote_hostname);
4022 if (sconn->remote_hostname == NULL) {
4023 exit_server_cleanly("tsocket_strdup() failed");
4026 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
4027 locaddr = tsocket_address_inet_addr_string(
4028 sconn->local_address,
4030 if (locaddr == NULL) {
4031 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4032 __location__, strerror(errno)));
4033 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4036 locaddr = "0.0.0.0";
4039 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
4040 remaddr = tsocket_address_inet_addr_string(
4041 sconn->remote_address,
4043 if (remaddr == NULL) {
4044 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4045 __location__, strerror(errno)));
4046 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4049 remaddr = "0.0.0.0";
4052 /* this is needed so that we get decent entries
4053 in smbstatus for port 445 connects */
4054 set_remote_machine_name(remaddr, false);
4055 reload_services(sconn, conn_snum_used, true);
4056 sub_set_socket_ids(remaddr,
4057 sconn->remote_hostname,
4060 if (lp_preload_modules()) {
4061 smb_load_all_modules_absoute_path(lp_preload_modules());
4064 smb_perfcount_init();
4066 if (!init_account_policy()) {
4067 exit_server("Could not open account policy tdb.\n");
4070 chroot_dir = lp_root_directory(talloc_tos(), lp_sub);
4071 if (chroot_dir[0] != '\0') {
4072 rc = chdir(chroot_dir);
4074 DBG_ERR("Failed to chdir to %s\n", chroot_dir);
4075 exit_server("Failed to chdir()");
4078 rc = chroot(chroot_dir);
4080 DBG_ERR("Failed to change root to %s\n", chroot_dir);
4081 exit_server("Failed to chroot()");
4083 DBG_WARNING("Changed root to %s\n", chroot_dir);
4085 TALLOC_FREE(chroot_dir);
4088 if (!file_init(sconn)) {
4089 exit_server("file_init() failed");
4093 if (!init_oplocks(sconn))
4094 exit_server("Failed to init oplocks");
4096 /* register our message handlers */
4097 messaging_register(sconn->msg_ctx, sconn,
4098 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4102 MSG_SMB_FORCE_TDIS_DENIED,
4103 msg_force_tdis_denied);
4104 messaging_register(sconn->msg_ctx, sconn,
4105 MSG_SMB_CLOSE_FILE, msg_close_file);
4106 messaging_register(sconn->msg_ctx, sconn,
4107 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
4109 id_cache_register_msgs(sconn->msg_ctx);
4110 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
4111 messaging_register(sconn->msg_ctx, sconn,
4112 ID_CACHE_KILL, smbd_id_cache_kill);
4114 messaging_deregister(sconn->msg_ctx,
4115 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
4116 messaging_register(sconn->msg_ctx, sconn,
4117 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
4119 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
4121 messaging_register(sconn->msg_ctx, sconn,
4122 MSG_SMB_KILL_CLIENT_IP,
4123 msg_kill_client_ip);
4125 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
4128 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4129 * MSGs to all child processes
4131 messaging_deregister(sconn->msg_ctx,
4133 messaging_register(sconn->msg_ctx, NULL,
4134 MSG_DEBUG, debug_message);
4136 if ((lp_keepalive() != 0)
4137 && !(event_add_idle(ev_ctx, NULL,
4138 timeval_set(lp_keepalive(), 0),
4139 "keepalive", keepalive_fn,
4141 DEBUG(0, ("Could not add keepalive event\n"));
4145 if (!(event_add_idle(ev_ctx, NULL,
4146 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4147 "deadtime", deadtime_fn, sconn))) {
4148 DEBUG(0, ("Could not add deadtime event\n"));
4152 if (!(event_add_idle(ev_ctx, NULL,
4153 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4154 "housekeeping", housekeeping_fn, sconn))) {
4155 DEBUG(0, ("Could not add housekeeping event\n"));
4159 smbprofile_dump_setup(ev_ctx);
4161 if (!init_dptrs(sconn)) {
4162 exit_server("init_dptrs() failed");
4165 TALLOC_FREE(trace_state.frame);
4167 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4170 ret = tevent_loop_wait(ev_ctx);
4172 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4173 " exiting\n", ret, strerror(errno)));
4176 TALLOC_FREE(trace_state.frame);
4178 exit_server_cleanly(NULL);
4181 bool req_is_in_chain(const struct smb_request *req)
4183 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4185 * We're right now handling a subsequent request, so we must
4191 if (!smb1cli_is_andx_req(req->cmd)) {
4197 * Okay, an illegal request, but definitely not chained :-)
4202 return (CVAL(req->vwv+0, 0) != 0xFF);