2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
35 #include "lib/messages_ctdb.h"
36 #include "smbprofile.h"
37 #include "rpc_server/spoolss/srv_spoolss_nt.h"
38 #include "libsmb/libsmb.h"
39 #include "../lib/util/tevent_ntstatus.h"
40 #include "../libcli/security/dom_sid.h"
41 #include "../libcli/security/security_token.h"
42 #include "lib/id_cache.h"
43 #include "lib/util/sys_rw_data.h"
44 #include "system/threads.h"
45 #include "lib/pthreadpool/pthreadpool_tevent.h"
46 #include "util_event.h"
48 /* Internal message queue for deferred opens. */
49 struct pending_message_list {
50 struct pending_message_list *next, *prev;
51 struct timeval request_time; /* When was this first issued? */
52 struct smbd_server_connection *sconn;
53 struct smbXsrv_connection *xconn;
54 struct tevent_timer *te;
55 struct smb_perfcount_data pcd;
60 struct deferred_open_record *open_rec;
63 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
65 static struct pending_message_list *get_deferred_open_message_smb(
66 struct smbd_server_connection *sconn, uint64_t mid);
67 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
69 static void smbd_echo_init(struct smbXsrv_connection *xconn)
71 xconn->smb1.echo_handler.trusted_fd = -1;
72 xconn->smb1.echo_handler.socket_lock_fd = -1;
73 #ifdef HAVE_ROBUST_MUTEXES
74 xconn->smb1.echo_handler.socket_mutex = NULL;
78 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
80 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
84 #ifdef HAVE_ROBUST_MUTEXES
85 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
93 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
95 if (!smbd_echo_active(xconn)) {
99 xconn->smb1.echo_handler.ref_count++;
101 if (xconn->smb1.echo_handler.ref_count > 1) {
105 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
107 #ifdef HAVE_ROBUST_MUTEXES
108 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
111 while (ret == EINTR) {
112 ret = pthread_mutex_lock(
113 xconn->smb1.echo_handler.socket_mutex);
119 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
126 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
131 xconn->smb1.echo_handler.socket_lock_fd,
132 F_SETLKW, 0, 0, F_WRLCK);
133 } while (!ok && (errno == EINTR));
136 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
141 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
146 void smbd_lock_socket(struct smbXsrv_connection *xconn)
148 if (!smbd_lock_socket_internal(xconn)) {
149 exit_server_cleanly("failed to lock socket");
153 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
155 if (!smbd_echo_active(xconn)) {
159 xconn->smb1.echo_handler.ref_count--;
161 if (xconn->smb1.echo_handler.ref_count > 0) {
165 #ifdef HAVE_ROBUST_MUTEXES
166 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
168 ret = pthread_mutex_unlock(
169 xconn->smb1.echo_handler.socket_mutex);
171 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
178 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
183 xconn->smb1.echo_handler.socket_lock_fd,
184 F_SETLKW, 0, 0, F_UNLCK);
185 } while (!ok && (errno == EINTR));
188 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
193 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
198 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
200 if (!smbd_unlock_socket_internal(xconn)) {
201 exit_server_cleanly("failed to unlock socket");
205 /* Accessor function for smb_read_error for smbd functions. */
207 /****************************************************************************
209 ****************************************************************************/
211 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
212 bool do_signing, uint32_t seqnum,
214 struct smb_perfcount_data *pcd)
218 char *buf_out = buffer;
220 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
222 * we're not supposed to do any io
227 smbd_lock_socket(xconn);
230 /* Sign the outgoing packet if required. */
231 srv_calculate_sign_mac(xconn, buf_out, seqnum);
235 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
236 if (!NT_STATUS_IS_OK(status)) {
237 DEBUG(0, ("send_smb: SMB encryption failed "
238 "on outgoing packet! Error %s\n",
239 nt_errstr(status) ));
245 len = smb_len_large(buf_out) + 4;
247 ret = write_data(xconn->transport.sock, buf_out, len);
249 int saved_errno = errno;
251 * Try and give an error message saying what
254 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
255 (int)getpid(), (int)len,
256 smbXsrv_connection_dbg(xconn),
257 (int)ret, strerror(saved_errno)));
260 srv_free_enc_buffer(xconn, buf_out);
264 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
265 srv_free_enc_buffer(xconn, buf_out);
267 SMB_PERFCOUNT_END(pcd);
269 smbd_unlock_socket(xconn);
273 /*******************************************************************
274 Setup the word count and byte count for a smb message.
275 ********************************************************************/
277 int srv_set_message(char *buf,
282 if (zero && (num_words || num_bytes)) {
283 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
285 SCVAL(buf,smb_wct,num_words);
286 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
287 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
288 return (smb_size + num_words*2 + num_bytes);
291 static bool valid_smb_header(const uint8_t *inbuf)
293 if (is_encrypted_packet(inbuf)) {
297 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
298 * but it just looks weird to call strncmp for this one.
300 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
303 /* Socket functions for smbd packet processing. */
305 static bool valid_packet_size(size_t len)
308 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
309 * of header. Don't print the error if this fits.... JRA.
312 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
313 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
314 (unsigned long)len));
320 static NTSTATUS read_packet_remainder(int fd, char *buffer,
321 unsigned int timeout, ssize_t len)
329 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
330 if (!NT_STATUS_IS_OK(status)) {
331 char addr[INET6_ADDRSTRLEN];
332 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
334 get_peer_addr(fd, addr, sizeof(addr)),
340 /****************************************************************************
341 Attempt a zerocopy writeX read. We know here that len > smb_size-4
342 ****************************************************************************/
345 * Unfortunately, earlier versions of smbclient/libsmbclient
346 * don't send this "standard" writeX header. I've fixed this
347 * for 3.2 but we'll use the old method with earlier versions.
348 * Windows and CIFSFS at least use this standard size. Not
352 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
353 (2*14) + /* word count (including bcc) */ \
356 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
357 const char lenbuf[4],
358 struct smbXsrv_connection *xconn,
361 unsigned int timeout,
365 /* Size of a WRITEX call (+4 byte len). */
366 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
367 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
371 memcpy(writeX_header, lenbuf, 4);
373 status = read_fd_with_timeout(
374 sock, writeX_header + 4,
375 STANDARD_WRITE_AND_X_HEADER_SIZE,
376 STANDARD_WRITE_AND_X_HEADER_SIZE,
379 if (!NT_STATUS_IS_OK(status)) {
380 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
382 smbXsrv_connection_dbg(xconn),
388 * Ok - now try and see if this is a possible
392 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
394 * If the data offset is beyond what
395 * we've read, drain the extra bytes.
397 uint16_t doff = SVAL(writeX_header,smb_vwv11);
400 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
401 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
402 if (drain_socket(sock, drain) != drain) {
403 smb_panic("receive_smb_raw_talloc_partial_read:"
404 " failed to drain pending bytes");
407 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
410 /* Spoof down the length and null out the bcc. */
411 set_message_bcc(writeX_header, 0);
412 newlen = smb_len(writeX_header);
414 /* Copy the header we've written. */
416 *buffer = (char *)talloc_memdup(mem_ctx,
418 sizeof(writeX_header));
420 if (*buffer == NULL) {
421 DEBUG(0, ("Could not allocate inbuf of length %d\n",
422 (int)sizeof(writeX_header)));
423 return NT_STATUS_NO_MEMORY;
426 /* Work out the remaining bytes. */
427 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
428 *len_ret = newlen + 4;
432 if (!valid_packet_size(len)) {
433 return NT_STATUS_INVALID_PARAMETER;
437 * Not a valid writeX call. Just do the standard
441 *buffer = talloc_array(mem_ctx, char, len+4);
443 if (*buffer == NULL) {
444 DEBUG(0, ("Could not allocate inbuf of length %d\n",
446 return NT_STATUS_NO_MEMORY;
449 /* Copy in what we already read. */
452 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
453 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
456 status = read_packet_remainder(
458 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
461 if (!NT_STATUS_IS_OK(status)) {
462 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
472 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
473 struct smbXsrv_connection *xconn,
475 char **buffer, unsigned int timeout,
476 size_t *p_unread, size_t *plen)
480 int min_recv_size = lp_min_receive_file_size();
485 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
487 if (!NT_STATUS_IS_OK(status)) {
491 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
492 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
493 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
494 !srv_is_signing_active(xconn) &&
495 xconn->smb1.echo_handler.trusted_fde == NULL) {
497 return receive_smb_raw_talloc_partial_read(
498 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
502 if (!valid_packet_size(len)) {
503 return NT_STATUS_INVALID_PARAMETER;
507 * The +4 here can't wrap, we've checked the length above already.
510 *buffer = talloc_array(mem_ctx, char, len+4);
512 if (*buffer == NULL) {
513 DEBUG(0, ("Could not allocate inbuf of length %d\n",
515 return NT_STATUS_NO_MEMORY;
518 memcpy(*buffer, lenbuf, sizeof(lenbuf));
520 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
521 if (!NT_STATUS_IS_OK(status)) {
529 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
530 struct smbXsrv_connection *xconn,
532 char **buffer, unsigned int timeout,
533 size_t *p_unread, bool *p_encrypted,
536 bool trusted_channel)
541 *p_encrypted = false;
543 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
545 if (!NT_STATUS_IS_OK(status)) {
546 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
547 ("receive_smb_raw_talloc failed for client %s "
548 "read error = %s.\n",
549 smbXsrv_connection_dbg(xconn),
550 nt_errstr(status)) );
554 if (is_encrypted_packet((uint8_t *)*buffer)) {
555 status = srv_decrypt_buffer(xconn, *buffer);
556 if (!NT_STATUS_IS_OK(status)) {
557 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
558 "incoming packet! Error %s\n",
559 nt_errstr(status) ));
565 /* Check the incoming SMB signature. */
566 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
567 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
568 "incoming packet!\n"));
569 return NT_STATUS_INVALID_NETWORK_RESPONSE;
577 * Initialize a struct smb_request from an inbuf
580 static bool init_smb_request(struct smb_request *req,
581 struct smbd_server_connection *sconn,
582 struct smbXsrv_connection *xconn,
583 const uint8_t *inbuf,
584 size_t unread_bytes, bool encrypted,
587 struct smbXsrv_tcon *tcon;
590 size_t req_size = smb_len(inbuf) + 4;
592 /* Ensure we have at least smb_size bytes. */
593 if (req_size < smb_size) {
594 DEBUG(0,("init_smb_request: invalid request size %u\n",
595 (unsigned int)req_size ));
599 req->request_time = timeval_current();
600 now = timeval_to_nttime(&req->request_time);
602 req->cmd = CVAL(inbuf, smb_com);
603 req->flags2 = SVAL(inbuf, smb_flg2);
604 req->smbpid = SVAL(inbuf, smb_pid);
605 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
606 req->seqnum = seqnum;
607 req->vuid = SVAL(inbuf, smb_uid);
608 req->tid = SVAL(inbuf, smb_tid);
609 req->wct = CVAL(inbuf, smb_wct);
610 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
611 req->buflen = smb_buflen(inbuf);
612 req->buf = (const uint8_t *)smb_buf_const(inbuf);
613 req->unread_bytes = unread_bytes;
614 req->encrypted = encrypted;
619 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
620 if (NT_STATUS_IS_OK(status)) {
621 req->conn = tcon->compat;
624 req->chain_fsp = NULL;
626 req->priv_paths = NULL;
628 req->posix_pathnames = lp_posix_pathnames();
629 smb_init_perfcount_data(&req->pcd);
631 /* Ensure we have at least wct words and 2 bytes of bcc. */
632 if (smb_size + req->wct*2 > req_size) {
633 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
634 (unsigned int)req->wct,
635 (unsigned int)req_size));
638 /* Ensure bcc is correct. */
639 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
640 DEBUG(0,("init_smb_request: invalid bcc number %u "
641 "(wct = %u, size %u)\n",
642 (unsigned int)req->buflen,
643 (unsigned int)req->wct,
644 (unsigned int)req_size));
652 static void process_smb(struct smbXsrv_connection *xconn,
653 uint8_t *inbuf, size_t nread, size_t unread_bytes,
654 uint32_t seqnum, bool encrypted,
655 struct smb_perfcount_data *deferred_pcd);
657 static void smbd_deferred_open_timer(struct tevent_context *ev,
658 struct tevent_timer *te,
659 struct timeval _tval,
662 struct pending_message_list *msg = talloc_get_type(private_data,
663 struct pending_message_list);
664 struct smbd_server_connection *sconn = msg->sconn;
665 struct smbXsrv_connection *xconn = msg->xconn;
666 TALLOC_CTX *mem_ctx = talloc_tos();
667 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
670 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
673 exit_server("smbd_deferred_open_timer: talloc failed\n");
677 /* We leave this message on the queue so the open code can
678 know this is a retry. */
679 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
680 (unsigned long long)mid ));
682 /* Mark the message as processed so this is not
683 * re-processed in error. */
684 msg->processed = true;
686 process_smb(xconn, inbuf,
688 msg->seqnum, msg->encrypted, &msg->pcd);
690 /* If it's still there and was processed, remove it. */
691 msg = get_deferred_open_message_smb(sconn, mid);
692 if (msg && msg->processed) {
693 remove_deferred_open_message_smb(xconn, mid);
697 /****************************************************************************
698 Function to push a message onto the tail of a linked list of smb messages ready
700 ****************************************************************************/
702 static bool push_queued_message(struct smb_request *req,
703 struct timeval request_time,
704 struct timeval end_time,
705 struct deferred_open_record *open_rec)
707 int msg_len = smb_len(req->inbuf) + 4;
708 struct pending_message_list *msg;
710 msg = talloc_zero(NULL, struct pending_message_list);
713 DEBUG(0,("push_message: malloc fail (1)\n"));
716 msg->sconn = req->sconn;
717 msg->xconn = req->xconn;
719 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
720 if(msg->buf.data == NULL) {
721 DEBUG(0,("push_message: malloc fail (2)\n"));
726 msg->request_time = request_time;
727 msg->seqnum = req->seqnum;
728 msg->encrypted = req->encrypted;
729 msg->processed = false;
730 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
733 msg->open_rec = talloc_move(msg, &open_rec);
737 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
740 smbd_deferred_open_timer,
743 DEBUG(0,("push_message: event_add_timed failed\n"));
749 DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
751 DEBUG(10,("push_message: pushed message length %u on "
752 "deferred_open_queue\n", (unsigned int)msg_len));
757 /****************************************************************************
758 Function to delete a sharing violation open message by mid.
759 ****************************************************************************/
761 void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
764 struct smbd_server_connection *sconn = xconn->client->sconn;
765 struct pending_message_list *pml;
767 if (sconn->using_smb2) {
768 remove_deferred_open_message_smb2(xconn, mid);
772 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
773 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
774 DEBUG(10,("remove_deferred_open_message_smb: "
775 "deleting mid %llu len %u\n",
776 (unsigned long long)mid,
777 (unsigned int)pml->buf.length ));
778 DLIST_REMOVE(sconn->deferred_open_queue, pml);
785 /****************************************************************************
786 Move a sharing violation open retry message to the front of the list and
787 schedule it for immediate processing.
788 ****************************************************************************/
790 bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
793 struct smbd_server_connection *sconn = xconn->client->sconn;
794 struct pending_message_list *pml;
797 if (sconn->using_smb2) {
798 return schedule_deferred_open_message_smb2(xconn, mid);
801 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
802 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
804 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
807 (unsigned long long)msg_mid ));
809 if (mid == msg_mid) {
810 struct tevent_timer *te;
812 if (pml->processed) {
813 /* A processed message should not be
815 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
816 "message mid %llu was already processed\n",
817 (unsigned long long)msg_mid ));
821 DEBUG(10,("schedule_deferred_open_message_smb: "
822 "scheduling mid %llu\n",
823 (unsigned long long)mid ));
825 te = tevent_add_timer(pml->sconn->ev_ctx,
828 smbd_deferred_open_timer,
831 DEBUG(10,("schedule_deferred_open_message_smb: "
832 "event_add_timed() failed, "
833 "skipping mid %llu\n",
834 (unsigned long long)msg_mid ));
837 TALLOC_FREE(pml->te);
839 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
844 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
845 "find message mid %llu\n",
846 (unsigned long long)mid ));
851 /****************************************************************************
852 Return true if this mid is on the deferred queue and was not yet processed.
853 ****************************************************************************/
855 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
857 struct smbd_server_connection *sconn = xconn->client->sconn;
858 struct pending_message_list *pml;
860 if (sconn->using_smb2) {
861 return open_was_deferred_smb2(xconn, mid);
864 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
865 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
872 /****************************************************************************
873 Return the message queued by this mid.
874 ****************************************************************************/
876 static struct pending_message_list *get_deferred_open_message_smb(
877 struct smbd_server_connection *sconn, uint64_t mid)
879 struct pending_message_list *pml;
881 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
882 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
889 /****************************************************************************
890 Get the state data queued by this mid.
891 ****************************************************************************/
893 bool get_deferred_open_message_state(struct smb_request *smbreq,
894 struct timeval *p_request_time,
895 struct deferred_open_record **open_rec)
897 struct pending_message_list *pml;
899 if (smbreq->sconn->using_smb2) {
900 return get_deferred_open_message_state_smb2(smbreq->smb2req,
905 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
909 if (p_request_time) {
910 *p_request_time = pml->request_time;
912 if (open_rec != NULL) {
913 *open_rec = pml->open_rec;
918 /****************************************************************************
919 Function to push a deferred open smb message onto a linked list of local smb
920 messages ready for processing.
921 ****************************************************************************/
923 bool push_deferred_open_message_smb(struct smb_request *req,
924 struct timeval request_time,
925 struct timeval timeout,
927 struct deferred_open_record *open_rec)
929 struct timeval end_time;
932 return push_deferred_open_message_smb2(req->smb2req,
939 if (req->unread_bytes) {
940 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
941 "unread_bytes = %u\n",
942 (unsigned int)req->unread_bytes ));
943 smb_panic("push_deferred_open_message_smb: "
944 "logic error unread_bytes != 0" );
947 end_time = timeval_sum(&request_time, &timeout);
949 DEBUG(10,("push_deferred_open_message_smb: pushing message "
950 "len %u mid %llu timeout time [%u.%06u]\n",
951 (unsigned int) smb_len(req->inbuf)+4,
952 (unsigned long long)req->mid,
953 (unsigned int)end_time.tv_sec,
954 (unsigned int)end_time.tv_usec));
956 return push_queued_message(req, request_time, end_time, open_rec);
959 static void smbd_sig_term_handler(struct tevent_context *ev,
960 struct tevent_signal *se,
966 exit_server_cleanly("termination signal");
969 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
971 struct tevent_signal *se;
973 se = tevent_add_signal(sconn->ev_ctx,
976 smbd_sig_term_handler,
979 exit_server("failed to setup SIGTERM handler");
983 static void smbd_sig_hup_handler(struct tevent_context *ev,
984 struct tevent_signal *se,
990 struct smbd_server_connection *sconn =
991 talloc_get_type_abort(private_data,
992 struct smbd_server_connection);
994 change_to_root_user();
995 DEBUG(1,("Reloading services after SIGHUP\n"));
996 reload_services(sconn, conn_snum_used, false);
999 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1001 struct tevent_signal *se;
1003 se = tevent_add_signal(sconn->ev_ctx,
1006 smbd_sig_hup_handler,
1009 exit_server("failed to setup SIGHUP handler");
1013 static void smbd_conf_updated(struct messaging_context *msg,
1016 struct server_id server_id,
1019 struct smbd_server_connection *sconn =
1020 talloc_get_type_abort(private_data,
1021 struct smbd_server_connection);
1023 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1024 "updated. Reloading.\n"));
1025 change_to_root_user();
1026 reload_services(sconn, conn_snum_used, false);
1030 * Only allow 5 outstanding trans requests. We're allocating memory, so
1034 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1037 for (; list != NULL; list = list->next) {
1039 if (list->mid == mid) {
1040 return NT_STATUS_INVALID_PARAMETER;
1046 return NT_STATUS_INSUFFICIENT_RESOURCES;
1049 return NT_STATUS_OK;
1053 These flags determine some of the permissions required to do an operation
1055 Note that I don't set NEED_WRITE on some write operations because they
1056 are used by some brain-dead clients when printing, and I don't want to
1057 force write permissions on print services.
1059 #define AS_USER (1<<0)
1060 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1061 #define TIME_INIT (1<<2)
1062 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1063 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1064 #define DO_CHDIR (1<<6)
1067 define a list of possible SMB messages and their corresponding
1068 functions. Any message that has a NULL function is unimplemented -
1069 please feel free to contribute implementations!
1071 static const struct smb_message_struct {
1073 void (*fn)(struct smb_request *req);
1075 } smb_messages[256] = {
1077 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1078 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1079 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1080 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1081 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1082 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1083 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1084 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1085 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1086 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1087 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1088 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1089 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1090 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1091 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1092 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1093 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1094 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1095 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1096 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1097 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1098 /* 0x15 */ { NULL, NULL, 0 },
1099 /* 0x16 */ { NULL, NULL, 0 },
1100 /* 0x17 */ { NULL, NULL, 0 },
1101 /* 0x18 */ { NULL, NULL, 0 },
1102 /* 0x19 */ { NULL, NULL, 0 },
1103 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1104 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1105 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1106 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1107 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1108 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1109 /* 0x20 */ { "SMBwritec", NULL,0},
1110 /* 0x21 */ { NULL, NULL, 0 },
1111 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1112 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1113 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1114 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1115 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1116 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1117 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1118 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1119 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1120 /* 0x2b */ { "SMBecho",reply_echo,0},
1121 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1122 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1123 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1124 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1125 /* 0x30 */ { NULL, NULL, 0 },
1126 /* 0x31 */ { NULL, NULL, 0 },
1127 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1128 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1129 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1130 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1131 /* 0x36 */ { NULL, NULL, 0 },
1132 /* 0x37 */ { NULL, NULL, 0 },
1133 /* 0x38 */ { NULL, NULL, 0 },
1134 /* 0x39 */ { NULL, NULL, 0 },
1135 /* 0x3a */ { NULL, NULL, 0 },
1136 /* 0x3b */ { NULL, NULL, 0 },
1137 /* 0x3c */ { NULL, NULL, 0 },
1138 /* 0x3d */ { NULL, NULL, 0 },
1139 /* 0x3e */ { NULL, NULL, 0 },
1140 /* 0x3f */ { NULL, NULL, 0 },
1141 /* 0x40 */ { NULL, NULL, 0 },
1142 /* 0x41 */ { NULL, NULL, 0 },
1143 /* 0x42 */ { NULL, NULL, 0 },
1144 /* 0x43 */ { NULL, NULL, 0 },
1145 /* 0x44 */ { NULL, NULL, 0 },
1146 /* 0x45 */ { NULL, NULL, 0 },
1147 /* 0x46 */ { NULL, NULL, 0 },
1148 /* 0x47 */ { NULL, NULL, 0 },
1149 /* 0x48 */ { NULL, NULL, 0 },
1150 /* 0x49 */ { NULL, NULL, 0 },
1151 /* 0x4a */ { NULL, NULL, 0 },
1152 /* 0x4b */ { NULL, NULL, 0 },
1153 /* 0x4c */ { NULL, NULL, 0 },
1154 /* 0x4d */ { NULL, NULL, 0 },
1155 /* 0x4e */ { NULL, NULL, 0 },
1156 /* 0x4f */ { NULL, NULL, 0 },
1157 /* 0x50 */ { NULL, NULL, 0 },
1158 /* 0x51 */ { NULL, NULL, 0 },
1159 /* 0x52 */ { NULL, NULL, 0 },
1160 /* 0x53 */ { NULL, NULL, 0 },
1161 /* 0x54 */ { NULL, NULL, 0 },
1162 /* 0x55 */ { NULL, NULL, 0 },
1163 /* 0x56 */ { NULL, NULL, 0 },
1164 /* 0x57 */ { NULL, NULL, 0 },
1165 /* 0x58 */ { NULL, NULL, 0 },
1166 /* 0x59 */ { NULL, NULL, 0 },
1167 /* 0x5a */ { NULL, NULL, 0 },
1168 /* 0x5b */ { NULL, NULL, 0 },
1169 /* 0x5c */ { NULL, NULL, 0 },
1170 /* 0x5d */ { NULL, NULL, 0 },
1171 /* 0x5e */ { NULL, NULL, 0 },
1172 /* 0x5f */ { NULL, NULL, 0 },
1173 /* 0x60 */ { NULL, NULL, 0 },
1174 /* 0x61 */ { NULL, NULL, 0 },
1175 /* 0x62 */ { NULL, NULL, 0 },
1176 /* 0x63 */ { NULL, NULL, 0 },
1177 /* 0x64 */ { NULL, NULL, 0 },
1178 /* 0x65 */ { NULL, NULL, 0 },
1179 /* 0x66 */ { NULL, NULL, 0 },
1180 /* 0x67 */ { NULL, NULL, 0 },
1181 /* 0x68 */ { NULL, NULL, 0 },
1182 /* 0x69 */ { NULL, NULL, 0 },
1183 /* 0x6a */ { NULL, NULL, 0 },
1184 /* 0x6b */ { NULL, NULL, 0 },
1185 /* 0x6c */ { NULL, NULL, 0 },
1186 /* 0x6d */ { NULL, NULL, 0 },
1187 /* 0x6e */ { NULL, NULL, 0 },
1188 /* 0x6f */ { NULL, NULL, 0 },
1189 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1190 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1191 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1192 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1193 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1194 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1195 /* 0x76 */ { NULL, NULL, 0 },
1196 /* 0x77 */ { NULL, NULL, 0 },
1197 /* 0x78 */ { NULL, NULL, 0 },
1198 /* 0x79 */ { NULL, NULL, 0 },
1199 /* 0x7a */ { NULL, NULL, 0 },
1200 /* 0x7b */ { NULL, NULL, 0 },
1201 /* 0x7c */ { NULL, NULL, 0 },
1202 /* 0x7d */ { NULL, NULL, 0 },
1203 /* 0x7e */ { NULL, NULL, 0 },
1204 /* 0x7f */ { NULL, NULL, 0 },
1205 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1206 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1207 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1208 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1209 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1210 /* 0x85 */ { NULL, NULL, 0 },
1211 /* 0x86 */ { NULL, NULL, 0 },
1212 /* 0x87 */ { NULL, NULL, 0 },
1213 /* 0x88 */ { NULL, NULL, 0 },
1214 /* 0x89 */ { NULL, NULL, 0 },
1215 /* 0x8a */ { NULL, NULL, 0 },
1216 /* 0x8b */ { NULL, NULL, 0 },
1217 /* 0x8c */ { NULL, NULL, 0 },
1218 /* 0x8d */ { NULL, NULL, 0 },
1219 /* 0x8e */ { NULL, NULL, 0 },
1220 /* 0x8f */ { NULL, NULL, 0 },
1221 /* 0x90 */ { NULL, NULL, 0 },
1222 /* 0x91 */ { NULL, NULL, 0 },
1223 /* 0x92 */ { NULL, NULL, 0 },
1224 /* 0x93 */ { NULL, NULL, 0 },
1225 /* 0x94 */ { NULL, NULL, 0 },
1226 /* 0x95 */ { NULL, NULL, 0 },
1227 /* 0x96 */ { NULL, NULL, 0 },
1228 /* 0x97 */ { NULL, NULL, 0 },
1229 /* 0x98 */ { NULL, NULL, 0 },
1230 /* 0x99 */ { NULL, NULL, 0 },
1231 /* 0x9a */ { NULL, NULL, 0 },
1232 /* 0x9b */ { NULL, NULL, 0 },
1233 /* 0x9c */ { NULL, NULL, 0 },
1234 /* 0x9d */ { NULL, NULL, 0 },
1235 /* 0x9e */ { NULL, NULL, 0 },
1236 /* 0x9f */ { NULL, NULL, 0 },
1237 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1238 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1239 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1240 /* 0xa3 */ { NULL, NULL, 0 },
1241 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1242 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1243 /* 0xa6 */ { NULL, NULL, 0 },
1244 /* 0xa7 */ { NULL, NULL, 0 },
1245 /* 0xa8 */ { NULL, NULL, 0 },
1246 /* 0xa9 */ { NULL, NULL, 0 },
1247 /* 0xaa */ { NULL, NULL, 0 },
1248 /* 0xab */ { NULL, NULL, 0 },
1249 /* 0xac */ { NULL, NULL, 0 },
1250 /* 0xad */ { NULL, NULL, 0 },
1251 /* 0xae */ { NULL, NULL, 0 },
1252 /* 0xaf */ { NULL, NULL, 0 },
1253 /* 0xb0 */ { NULL, NULL, 0 },
1254 /* 0xb1 */ { NULL, NULL, 0 },
1255 /* 0xb2 */ { NULL, NULL, 0 },
1256 /* 0xb3 */ { NULL, NULL, 0 },
1257 /* 0xb4 */ { NULL, NULL, 0 },
1258 /* 0xb5 */ { NULL, NULL, 0 },
1259 /* 0xb6 */ { NULL, NULL, 0 },
1260 /* 0xb7 */ { NULL, NULL, 0 },
1261 /* 0xb8 */ { NULL, NULL, 0 },
1262 /* 0xb9 */ { NULL, NULL, 0 },
1263 /* 0xba */ { NULL, NULL, 0 },
1264 /* 0xbb */ { NULL, NULL, 0 },
1265 /* 0xbc */ { NULL, NULL, 0 },
1266 /* 0xbd */ { NULL, NULL, 0 },
1267 /* 0xbe */ { NULL, NULL, 0 },
1268 /* 0xbf */ { NULL, NULL, 0 },
1269 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1270 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1271 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1272 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1273 /* 0xc4 */ { NULL, NULL, 0 },
1274 /* 0xc5 */ { NULL, NULL, 0 },
1275 /* 0xc6 */ { NULL, NULL, 0 },
1276 /* 0xc7 */ { NULL, NULL, 0 },
1277 /* 0xc8 */ { NULL, NULL, 0 },
1278 /* 0xc9 */ { NULL, NULL, 0 },
1279 /* 0xca */ { NULL, NULL, 0 },
1280 /* 0xcb */ { NULL, NULL, 0 },
1281 /* 0xcc */ { NULL, NULL, 0 },
1282 /* 0xcd */ { NULL, NULL, 0 },
1283 /* 0xce */ { NULL, NULL, 0 },
1284 /* 0xcf */ { NULL, NULL, 0 },
1285 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1286 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1287 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1288 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1289 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1290 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1291 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1292 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1293 /* 0xd8 */ { NULL, NULL, 0 },
1294 /* 0xd9 */ { NULL, NULL, 0 },
1295 /* 0xda */ { NULL, NULL, 0 },
1296 /* 0xdb */ { NULL, NULL, 0 },
1297 /* 0xdc */ { NULL, NULL, 0 },
1298 /* 0xdd */ { NULL, NULL, 0 },
1299 /* 0xde */ { NULL, NULL, 0 },
1300 /* 0xdf */ { NULL, NULL, 0 },
1301 /* 0xe0 */ { NULL, NULL, 0 },
1302 /* 0xe1 */ { NULL, NULL, 0 },
1303 /* 0xe2 */ { NULL, NULL, 0 },
1304 /* 0xe3 */ { NULL, NULL, 0 },
1305 /* 0xe4 */ { NULL, NULL, 0 },
1306 /* 0xe5 */ { NULL, NULL, 0 },
1307 /* 0xe6 */ { NULL, NULL, 0 },
1308 /* 0xe7 */ { NULL, NULL, 0 },
1309 /* 0xe8 */ { NULL, NULL, 0 },
1310 /* 0xe9 */ { NULL, NULL, 0 },
1311 /* 0xea */ { NULL, NULL, 0 },
1312 /* 0xeb */ { NULL, NULL, 0 },
1313 /* 0xec */ { NULL, NULL, 0 },
1314 /* 0xed */ { NULL, NULL, 0 },
1315 /* 0xee */ { NULL, NULL, 0 },
1316 /* 0xef */ { NULL, NULL, 0 },
1317 /* 0xf0 */ { NULL, NULL, 0 },
1318 /* 0xf1 */ { NULL, NULL, 0 },
1319 /* 0xf2 */ { NULL, NULL, 0 },
1320 /* 0xf3 */ { NULL, NULL, 0 },
1321 /* 0xf4 */ { NULL, NULL, 0 },
1322 /* 0xf5 */ { NULL, NULL, 0 },
1323 /* 0xf6 */ { NULL, NULL, 0 },
1324 /* 0xf7 */ { NULL, NULL, 0 },
1325 /* 0xf8 */ { NULL, NULL, 0 },
1326 /* 0xf9 */ { NULL, NULL, 0 },
1327 /* 0xfa */ { NULL, NULL, 0 },
1328 /* 0xfb */ { NULL, NULL, 0 },
1329 /* 0xfc */ { NULL, NULL, 0 },
1330 /* 0xfd */ { NULL, NULL, 0 },
1331 /* 0xfe */ { NULL, NULL, 0 },
1332 /* 0xff */ { NULL, NULL, 0 }
1336 /*******************************************************************
1337 allocate and initialize a reply packet
1338 ********************************************************************/
1340 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1341 const uint8_t *inbuf, char **outbuf,
1342 uint8_t num_words, uint32_t num_bytes)
1344 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1347 * Protect against integer wrap.
1348 * The SMB layer reply can be up to 0xFFFFFF bytes.
1350 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1352 if (asprintf(&msg, "num_bytes too large: %u",
1353 (unsigned)num_bytes) == -1) {
1354 msg = discard_const_p(char, "num_bytes too large");
1360 * Here we include the NBT header for now.
1362 *outbuf = talloc_array(mem_ctx, char,
1363 NBT_HDR_SIZE + smb_len);
1364 if (*outbuf == NULL) {
1368 construct_reply_common(req->cmd, inbuf, *outbuf);
1369 srv_set_message(*outbuf, num_words, num_bytes, false);
1371 * Zero out the word area, the caller has to take care of the bcc area
1374 if (num_words != 0) {
1375 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1381 void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1384 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1386 smb_panic("could not allocate output buffer\n");
1388 req->outbuf = (uint8_t *)outbuf;
1392 /*******************************************************************
1393 Dump a packet to a file.
1394 ********************************************************************/
1396 static void smb_dump(const char *name, int type, const char *data)
1401 if (DEBUGLEVEL < 50) {
1405 len = smb_len_tcp(data)+4;
1406 for (i=1;i<100;i++) {
1407 fname = talloc_asprintf(talloc_tos(),
1411 type ? "req" : "resp");
1412 if (fname == NULL) {
1415 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1416 if (fd != -1 || errno != EEXIST) break;
1420 ssize_t ret = write(fd, data, len);
1422 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1424 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1429 static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
1430 struct smb_request *req,
1432 bool *update_session_globalp,
1433 bool *update_tcon_globalp)
1435 connection_struct *conn = req->conn;
1436 struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
1437 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
1438 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1439 bool update_session = false;
1440 bool update_tcon = false;
1442 if (req->encrypted) {
1443 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
1446 if (srv_is_signing_active(req->xconn)) {
1447 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
1448 } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
1450 * echo can be unsigned. Sesssion setup except final
1451 * session setup response too
1453 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1456 update_session |= smbXsrv_set_crypto_flag(
1457 &session->global->encryption_flags, encrypt_flag);
1458 update_session |= smbXsrv_set_crypto_flag(
1459 &session->global->signing_flags, sign_flag);
1462 update_tcon |= smbXsrv_set_crypto_flag(
1463 &tcon->global->encryption_flags, encrypt_flag);
1464 update_tcon |= smbXsrv_set_crypto_flag(
1465 &tcon->global->signing_flags, sign_flag);
1468 if (update_session) {
1469 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1472 *update_session_globalp = update_session;
1473 *update_tcon_globalp = update_tcon;
1477 /****************************************************************************
1478 Prepare everything for calling the actual request function, and potentially
1479 call the request function via the "new" interface.
1481 Return False if the "legacy" function needs to be called, everything is
1484 Return True if we're done.
1486 I know this API sucks, but it is the one with the least code change I could
1488 ****************************************************************************/
1490 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1493 uint64_t session_tag;
1494 connection_struct *conn = NULL;
1495 struct smbXsrv_connection *xconn = req->xconn;
1496 NTTIME now = timeval_to_nttime(&req->request_time);
1497 struct smbXsrv_session *session = NULL;
1502 if (!xconn->smb1.negprot.done) {
1505 * Without a negprot the request must
1506 * either be a negprot, or one of the
1507 * evil old SMB mailslot messaging types.
1515 exit_server_cleanly("The first request "
1516 "should be a negprot");
1520 if (smb_messages[type].fn == NULL) {
1521 DEBUG(0,("Unknown message type %d!\n",type));
1522 smb_dump("Unknown", 1, (const char *)req->inbuf);
1523 reply_unknown_new(req, type);
1527 flags = smb_messages[type].flags;
1529 /* In share mode security we must ignore the vuid. */
1530 session_tag = req->vuid;
1533 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1534 (int)getpid(), (unsigned long)conn));
1536 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1538 /* Ensure this value is replaced in the incoming packet. */
1539 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1542 * Ensure the correct username is in current_user_info. This is a
1543 * really ugly bugfix for problems with multiple session_setup_and_X's
1544 * being done and allowing %U and %G substitutions to work correctly.
1545 * There is a reason this code is done here, don't move it unless you
1546 * know what you're doing... :-).
1551 * lookup an existing session
1553 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1554 * here, the main check is still in change_to_user()
1556 status = smb1srv_session_lookup(xconn,
1560 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1563 status = NT_STATUS_OK;
1566 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1567 (unsigned long long)session_tag,
1568 (unsigned long long)req->mid));
1569 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1574 if (session_tag != xconn->client->last_session_id) {
1575 struct user_struct *vuser = NULL;
1577 xconn->client->last_session_id = session_tag;
1579 vuser = session->compat;
1582 set_current_user_info(
1583 vuser->session_info->unix_info->sanitized_username,
1584 vuser->session_info->unix_info->unix_name,
1585 vuser->session_info->info->domain_name);
1589 /* Does this call need to be run as the connected user? */
1590 if (flags & AS_USER) {
1592 /* Does this call need a valid tree connection? */
1595 * Amazingly, the error code depends on the command
1598 if (type == SMBntcreateX) {
1599 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1601 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1606 if (!change_to_user(conn,session_tag)) {
1607 DEBUG(0, ("Error: Could not change to user. Removing "
1608 "deferred open, mid=%llu.\n",
1609 (unsigned long long)req->mid));
1610 reply_force_doserror(req, ERRSRV, ERRbaduid);
1614 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1616 /* Does it need write permission? */
1617 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1618 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1622 /* IPC services are limited */
1623 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1624 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1628 /* This call needs to be run as root */
1629 change_to_root_user();
1632 /* load service specific parameters */
1634 if (req->encrypted) {
1635 conn->encrypted_tid = true;
1636 /* encrypted required from now on. */
1637 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1638 } else if (ENCRYPTION_REQUIRED(conn)) {
1639 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1640 DEBUG(1,("service[%s] requires encryption"
1641 "%s ACCESS_DENIED. mid=%llu\n",
1642 lp_servicename(talloc_tos(), SNUM(conn)),
1644 (unsigned long long)req->mid));
1645 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1650 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1651 (flags & (AS_USER|DO_CHDIR)
1653 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1656 conn->num_smb_operations++;
1660 * Does this protocol need to be run as guest? (Only archane
1661 * messenger service requests have this...)
1663 if (flags & AS_GUEST) {
1667 if (!change_to_guest()) {
1668 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1672 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1674 if (raddr == NULL) {
1675 reply_nterror(req, NT_STATUS_NO_MEMORY);
1680 * Haven't we checked this in smbd_process already???
1683 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1684 xconn->remote_hostname, raddr);
1688 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1694 * Update encryption and signing state tracking flags that are
1695 * used by smbstatus to display signing and encryption status.
1697 if (session != NULL) {
1698 bool update_session_global = false;
1699 bool update_tcon_global = false;
1701 smb1srv_update_crypto_flags(session, req, type,
1702 &update_session_global,
1703 &update_tcon_global);
1705 if (update_session_global) {
1706 status = smbXsrv_session_update(session);
1707 if (!NT_STATUS_IS_OK(status)) {
1708 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1713 if (update_tcon_global) {
1714 status = smbXsrv_tcon_update(req->conn->tcon);
1715 if (!NT_STATUS_IS_OK(status)) {
1716 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1722 smb_messages[type].fn(req);
1726 /****************************************************************************
1727 Construct a reply to the incoming packet.
1728 ****************************************************************************/
1730 static void construct_reply(struct smbXsrv_connection *xconn,
1731 char *inbuf, int size, size_t unread_bytes,
1732 uint32_t seqnum, bool encrypted,
1733 struct smb_perfcount_data *deferred_pcd)
1735 struct smbd_server_connection *sconn = xconn->client->sconn;
1736 struct smb_request *req;
1738 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1739 smb_panic("could not allocate smb_request");
1742 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1743 encrypted, seqnum)) {
1744 exit_server_cleanly("Invalid SMB request");
1747 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1749 /* we popped this message off the queue - keep original perf data */
1751 req->pcd = *deferred_pcd;
1753 SMB_PERFCOUNT_START(&req->pcd);
1754 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1755 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1758 req->conn = switch_message(req->cmd, req);
1760 if (req->outbuf == NULL) {
1762 * Request has suspended itself, will come
1767 if (CVAL(req->outbuf,0) == 0) {
1768 show_msg((char *)req->outbuf);
1770 smb_request_done(req);
1773 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1774 char *inbuf, int size, uint32_t seqnum,
1776 struct smb_perfcount_data *deferred_pcd)
1778 struct smb_request **reqs = NULL;
1779 struct smb_request *req;
1783 ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
1784 seqnum, &reqs, &num_reqs);
1786 char errbuf[smb_size];
1787 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1788 __LINE__, __FILE__);
1789 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1791 exit_server_cleanly("construct_reply_chain: "
1792 "srv_send_smb failed.");
1798 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1800 req->conn = switch_message(req->cmd, req);
1802 if (req->outbuf == NULL) {
1804 * Request has suspended itself, will come
1809 smb_request_done(req);
1813 * To be called from an async SMB handler that is potentially chained
1814 * when it is finished for shipping.
1817 void smb_request_done(struct smb_request *req)
1819 struct smb_request **reqs = NULL;
1820 struct smb_request *first_req;
1821 size_t i, num_reqs, next_index;
1824 if (req->chain == NULL) {
1830 num_reqs = talloc_array_length(reqs);
1832 for (i=0; i<num_reqs; i++) {
1833 if (reqs[i] == req) {
1837 if (i == num_reqs) {
1839 * Invalid chain, should not happen
1841 status = NT_STATUS_INTERNAL_ERROR;
1846 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1847 struct smb_request *next = reqs[next_index];
1848 struct smbXsrv_tcon *tcon;
1849 NTTIME now = timeval_to_nttime(&req->request_time);
1851 next->vuid = SVAL(req->outbuf, smb_uid);
1852 next->tid = SVAL(req->outbuf, smb_tid);
1853 status = smb1srv_tcon_lookup(req->xconn, next->tid,
1856 if (NT_STATUS_IS_OK(status)) {
1857 next->conn = tcon->compat;
1861 next->chain_fsp = req->chain_fsp;
1862 next->inbuf = req->inbuf;
1865 req->conn = switch_message(req->cmd, req);
1867 if (req->outbuf == NULL) {
1869 * Request has suspended itself, will come
1877 first_req = reqs[0];
1879 for (i=1; i<next_index; i++) {
1882 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1884 status = NT_STATUS_INTERNAL_ERROR;
1889 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1890 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1893 * This scary statement intends to set the
1894 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1895 * to the value last_req->outbuf carries
1897 SSVAL(first_req->outbuf, smb_flg2,
1898 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1899 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1902 * Transfer the error codes from the subrequest to the main one
1904 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1905 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1908 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1911 if (!srv_send_smb(first_req->xconn,
1912 (char *)first_req->outbuf,
1913 true, first_req->seqnum+1,
1914 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1916 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1919 TALLOC_FREE(req); /* non-chained case */
1920 TALLOC_FREE(reqs); /* chained case */
1925 char errbuf[smb_size];
1926 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1927 if (!srv_send_smb(req->xconn, errbuf, true,
1928 req->seqnum+1, req->encrypted,
1930 exit_server_cleanly("construct_reply_chain: "
1931 "srv_send_smb failed.");
1934 TALLOC_FREE(req); /* non-chained case */
1935 TALLOC_FREE(reqs); /* chained case */
1938 /****************************************************************************
1939 Process an smb from the client
1940 ****************************************************************************/
1941 static void process_smb(struct smbXsrv_connection *xconn,
1942 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1943 uint32_t seqnum, bool encrypted,
1944 struct smb_perfcount_data *deferred_pcd)
1946 struct smbd_server_connection *sconn = xconn->client->sconn;
1947 int msg_type = CVAL(inbuf,0);
1949 DO_PROFILE_INC(request);
1951 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1953 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1954 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1956 if (msg_type != NBSSmessage) {
1958 * NetBIOS session request, keepalive, etc.
1960 reply_special(xconn, (char *)inbuf, nread);
1964 if (sconn->using_smb2) {
1965 /* At this point we're not really using smb2,
1966 * we make the decision here.. */
1967 if (smbd_is_smb2_header(inbuf, nread)) {
1968 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1969 size_t pdulen = nread - NBT_HDR_SIZE;
1970 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1973 if (nread >= smb_size && valid_smb_header(inbuf)
1974 && CVAL(inbuf, smb_com) != 0x72) {
1975 /* This is a non-negprot SMB1 packet.
1976 Disable SMB2 from now on. */
1977 sconn->using_smb2 = false;
1981 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1982 * so subtract 4 from it. */
1983 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1984 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1987 /* special magic for immediate exit */
1989 (IVAL(inbuf, 4) == 0x74697865) &&
1990 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1991 uint8_t exitcode = CVAL(inbuf, 8);
1992 DEBUG(1, ("Exiting immediately with code %d\n",
1997 exit_server_cleanly("Non-SMB packet");
2000 show_msg((char *)inbuf);
2002 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
2003 construct_reply_chain(xconn, (char *)inbuf, nread,
2004 seqnum, encrypted, deferred_pcd);
2006 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
2007 seqnum, encrypted, deferred_pcd);
2013 sconn->num_requests++;
2015 /* The timeout_processing function isn't run nearly
2016 often enough to implement 'max log size' without
2017 overrunning the size of the file by many megabytes.
2018 This is especially true if we are running at debug
2019 level 10. Checking every 50 SMBs is a nice
2020 tradeoff of performance vs log file size overrun. */
2022 if ((sconn->num_requests % 50) == 0 &&
2023 need_to_check_log_size()) {
2024 change_to_root_user();
2029 /****************************************************************************
2030 Return a string containing the function name of a SMB command.
2031 ****************************************************************************/
2033 const char *smb_fn_name(int type)
2035 const char *unknown_name = "SMBunknown";
2037 if (smb_messages[type].name == NULL)
2038 return(unknown_name);
2040 return(smb_messages[type].name);
2043 /****************************************************************************
2044 Helper functions for contruct_reply.
2045 ****************************************************************************/
2047 void add_to_common_flags2(uint32_t v)
2052 void remove_from_common_flags2(uint32_t v)
2054 common_flags2 &= ~v;
2057 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
2060 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
2061 uint16_t out_flags2 = common_flags2;
2063 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
2064 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
2065 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
2067 srv_set_message(outbuf,0,0,false);
2069 SCVAL(outbuf, smb_com, cmd);
2070 SIVAL(outbuf,smb_rcls,0);
2071 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
2072 SSVAL(outbuf,smb_flg2, out_flags2);
2073 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
2074 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2076 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2077 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2078 SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
2079 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2080 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2083 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2085 construct_reply_common(req->cmd, req->inbuf, outbuf);
2089 * @brief Find the smb_cmd offset of the last command pushed
2090 * @param[in] buf The buffer we're building up
2091 * @retval Where can we put our next andx cmd?
2093 * While chaining requests, the "next" request we're looking at needs to put
2094 * its SMB_Command before the data the previous request already built up added
2095 * to the chain. Find the offset to the place where we have to put our cmd.
2098 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2103 cmd = CVAL(buf, smb_com);
2105 if (!is_andx_req(cmd)) {
2111 while (CVAL(buf, ofs) != 0xff) {
2113 if (!is_andx_req(CVAL(buf, ofs))) {
2118 * ofs is from start of smb header, so add the 4 length
2119 * bytes. The next cmd is right after the wct field.
2121 ofs = SVAL(buf, ofs+2) + 4 + 1;
2123 if (ofs+4 >= talloc_get_size(buf)) {
2133 * @brief Do the smb chaining at a buffer level
2134 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2135 * @param[in] andx_buf Buffer to be appended
2138 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2140 uint8_t smb_command = CVAL(andx_buf, smb_com);
2141 uint8_t wct = CVAL(andx_buf, smb_wct);
2142 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2143 uint32_t num_bytes = smb_buflen(andx_buf);
2144 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2147 size_t old_size, new_size;
2149 size_t chain_padding = 0;
2150 size_t andx_cmd_ofs;
2153 old_size = talloc_get_size(*poutbuf);
2155 if ((old_size % 4) != 0) {
2157 * Align the wct field of subsequent requests to a 4-byte
2160 chain_padding = 4 - (old_size % 4);
2164 * After the old request comes the new wct field (1 byte), the vwv's
2165 * and the num_bytes field.
2168 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2169 new_size += num_bytes;
2171 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2172 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2173 (unsigned)new_size));
2177 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2178 if (outbuf == NULL) {
2179 DEBUG(0, ("talloc failed\n"));
2184 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2185 DEBUG(1, ("invalid command chain\n"));
2186 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2190 if (chain_padding != 0) {
2191 memset(outbuf + old_size, 0, chain_padding);
2192 old_size += chain_padding;
2195 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2196 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2201 * Push the chained request:
2206 SCVAL(outbuf, ofs, wct);
2213 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2218 * Read&X has an offset into its data buffer at
2219 * vwv[6]. reply_read_andx has no idea anymore that it's
2220 * running from within a chain, so we have to fix up the
2223 * Although it looks disgusting at this place, I want to keep
2224 * it here. The alternative would be to push knowledge about
2225 * the andx chain down into read&x again.
2228 if (smb_command == SMBreadX) {
2229 uint8_t *bytes_addr;
2233 * Invalid read&x response
2238 bytes_addr = outbuf + ofs /* vwv start */
2239 + sizeof(uint16_t) * wct /* vwv array */
2240 + sizeof(uint16_t) /* bcc */
2241 + 1; /* padding byte */
2243 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2244 bytes_addr - outbuf - 4);
2247 ofs += sizeof(uint16_t) * wct;
2253 SSVAL(outbuf, ofs, num_bytes);
2254 ofs += sizeof(uint16_t);
2260 memcpy(outbuf + ofs, bytes, num_bytes);
2265 bool smb1_is_chain(const uint8_t *buf)
2267 uint8_t cmd, wct, andx_cmd;
2269 cmd = CVAL(buf, smb_com);
2270 if (!is_andx_req(cmd)) {
2273 wct = CVAL(buf, smb_wct);
2277 andx_cmd = CVAL(buf, smb_vwv);
2278 return (andx_cmd != 0xFF);
2281 bool smb1_walk_chain(const uint8_t *buf,
2282 bool (*fn)(uint8_t cmd,
2283 uint8_t wct, const uint16_t *vwv,
2284 uint16_t num_bytes, const uint8_t *bytes,
2285 void *private_data),
2288 size_t smblen = smb_len(buf);
2289 const char *smb_buf = smb_base(buf);
2290 uint8_t cmd, chain_cmd;
2292 const uint16_t *vwv;
2294 const uint8_t *bytes;
2296 cmd = CVAL(buf, smb_com);
2297 wct = CVAL(buf, smb_wct);
2298 vwv = (const uint16_t *)(buf + smb_vwv);
2299 num_bytes = smb_buflen(buf);
2300 bytes = (const uint8_t *)smb_buf_const(buf);
2302 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2306 if (!is_andx_req(cmd)) {
2313 chain_cmd = CVAL(vwv, 0);
2315 while (chain_cmd != 0xff) {
2316 uint32_t chain_offset; /* uint32_t to avoid overflow */
2317 size_t length_needed;
2318 ptrdiff_t vwv_offset;
2320 chain_offset = SVAL(vwv+1, 0);
2323 * Check if the client tries to fool us. The chain
2324 * offset needs to point beyond the current request in
2325 * the chain, it needs to strictly grow. Otherwise we
2326 * might be tricked into an endless loop always
2327 * processing the same request over and over again. We
2328 * used to assume that vwv and the byte buffer array
2329 * in a chain are always attached, but OS/2 the
2330 * Write&X/Read&X chain puts the Read&X vwv array
2331 * right behind the Write&X vwv chain. The Write&X bcc
2332 * array is put behind the Read&X vwv array. So now we
2333 * check whether the chain offset points strictly
2334 * behind the previous vwv array. req->buf points
2335 * right after the vwv array of the previous
2337 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2341 vwv_offset = ((const char *)vwv - smb_buf);
2342 if (chain_offset <= vwv_offset) {
2347 * Next check: Make sure the chain offset does not
2348 * point beyond the overall smb request length.
2351 length_needed = chain_offset+1; /* wct */
2352 if (length_needed > smblen) {
2357 * Now comes the pointer magic. Goal here is to set up
2358 * vwv and buf correctly again. The chain offset (the
2359 * former vwv[1]) points at the new wct field.
2362 wct = CVAL(smb_buf, chain_offset);
2364 if (is_andx_req(chain_cmd) && (wct < 2)) {
2369 * Next consistency check: Make the new vwv array fits
2370 * in the overall smb request.
2373 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2374 if (length_needed > smblen) {
2377 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2380 * Now grab the new byte buffer....
2383 num_bytes = SVAL(vwv+wct, 0);
2386 * .. and check that it fits.
2389 length_needed += num_bytes;
2390 if (length_needed > smblen) {
2393 bytes = (const uint8_t *)(vwv+wct+1);
2395 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2399 if (!is_andx_req(chain_cmd)) {
2402 chain_cmd = CVAL(vwv, 0);
2407 static bool smb1_chain_length_cb(uint8_t cmd,
2408 uint8_t wct, const uint16_t *vwv,
2409 uint16_t num_bytes, const uint8_t *bytes,
2412 unsigned *count = (unsigned *)private_data;
2417 unsigned smb1_chain_length(const uint8_t *buf)
2421 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2427 struct smb1_parse_chain_state {
2428 TALLOC_CTX *mem_ctx;
2430 struct smbd_server_connection *sconn;
2431 struct smbXsrv_connection *xconn;
2435 struct smb_request **reqs;
2439 static bool smb1_parse_chain_cb(uint8_t cmd,
2440 uint8_t wct, const uint16_t *vwv,
2441 uint16_t num_bytes, const uint8_t *bytes,
2444 struct smb1_parse_chain_state *state =
2445 (struct smb1_parse_chain_state *)private_data;
2446 struct smb_request **reqs;
2447 struct smb_request *req;
2450 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2451 struct smb_request *, state->num_reqs+1);
2457 req = talloc(reqs, struct smb_request);
2462 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2463 state->encrypted, state->seqnum);
2470 req->buflen = num_bytes;
2473 reqs[state->num_reqs] = req;
2474 state->num_reqs += 1;
2478 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2479 struct smbXsrv_connection *xconn,
2480 bool encrypted, uint32_t seqnum,
2481 struct smb_request ***reqs, unsigned *num_reqs)
2483 struct smbd_server_connection *sconn = NULL;
2484 struct smb1_parse_chain_state state;
2487 if (xconn != NULL) {
2488 sconn = xconn->client->sconn;
2491 state.mem_ctx = mem_ctx;
2493 state.sconn = sconn;
2494 state.xconn = xconn;
2495 state.encrypted = encrypted;
2496 state.seqnum = seqnum;
2500 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2501 TALLOC_FREE(state.reqs);
2504 for (i=0; i<state.num_reqs; i++) {
2505 state.reqs[i]->chain = state.reqs;
2508 *num_reqs = state.num_reqs;
2512 /****************************************************************************
2513 Check if services need reloading.
2514 ****************************************************************************/
2516 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2519 if (last_smb_conf_reload_time == 0) {
2520 last_smb_conf_reload_time = t;
2523 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2524 reload_services(sconn, conn_snum_used, true);
2525 last_smb_conf_reload_time = t;
2529 static bool fd_is_readable(int fd)
2533 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2535 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2539 static void smbd_server_connection_write_handler(
2540 struct smbXsrv_connection *xconn)
2542 /* TODO: make write nonblocking */
2545 static void smbd_server_connection_read_handler(
2546 struct smbXsrv_connection *xconn, int fd)
2548 uint8_t *inbuf = NULL;
2549 size_t inbuf_len = 0;
2550 size_t unread_bytes = 0;
2551 bool encrypted = false;
2552 TALLOC_CTX *mem_ctx = talloc_tos();
2556 bool async_echo = lp_async_smb_echo_handler();
2557 bool from_client = false;
2560 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2562 * This is the super-ugly hack to prefer the packets
2563 * forwarded by the echo handler over the ones by the
2566 fd = xconn->smb1.echo_handler.trusted_fd;
2570 from_client = (xconn->transport.sock == fd);
2572 if (async_echo && from_client) {
2573 smbd_lock_socket(xconn);
2575 if (!fd_is_readable(fd)) {
2576 DEBUG(10,("the echo listener was faster\n"));
2577 smbd_unlock_socket(xconn);
2582 /* TODO: make this completely nonblocking */
2583 status = receive_smb_talloc(mem_ctx, xconn, fd,
2584 (char **)(void *)&inbuf,
2588 &inbuf_len, &seqnum,
2589 !from_client /* trusted channel */);
2591 if (async_echo && from_client) {
2592 smbd_unlock_socket(xconn);
2595 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2598 if (NT_STATUS_IS_ERR(status)) {
2599 exit_server_cleanly("failed to receive smb request");
2601 if (!NT_STATUS_IS_OK(status)) {
2606 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2607 seqnum, encrypted, NULL);
2610 static void smbd_server_connection_handler(struct tevent_context *ev,
2611 struct tevent_fd *fde,
2615 struct smbXsrv_connection *xconn =
2616 talloc_get_type_abort(private_data,
2617 struct smbXsrv_connection);
2619 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2621 * we're not supposed to do any io
2623 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2624 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2628 if (flags & TEVENT_FD_WRITE) {
2629 smbd_server_connection_write_handler(xconn);
2632 if (flags & TEVENT_FD_READ) {
2633 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2638 static void smbd_server_echo_handler(struct tevent_context *ev,
2639 struct tevent_fd *fde,
2643 struct smbXsrv_connection *xconn =
2644 talloc_get_type_abort(private_data,
2645 struct smbXsrv_connection);
2647 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2649 * we're not supposed to do any io
2651 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2652 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2656 if (flags & TEVENT_FD_WRITE) {
2657 smbd_server_connection_write_handler(xconn);
2660 if (flags & TEVENT_FD_READ) {
2661 smbd_server_connection_read_handler(
2662 xconn, xconn->smb1.echo_handler.trusted_fd);
2667 struct smbd_release_ip_state {
2668 struct smbXsrv_connection *xconn;
2669 struct tevent_immediate *im;
2670 char addr[INET6_ADDRSTRLEN];
2673 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2674 struct tevent_immediate *im,
2677 struct smbd_release_ip_state *state =
2678 talloc_get_type_abort(private_data,
2679 struct smbd_release_ip_state);
2680 struct smbXsrv_connection *xconn = state->xconn;
2682 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2684 * smbd_server_connection_terminate() already triggered ?
2689 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2692 /****************************************************************************
2693 received when we should release a specific IP
2694 ****************************************************************************/
2695 static int release_ip(struct tevent_context *ev,
2696 uint32_t src_vnn, uint32_t dst_vnn,
2698 const uint8_t *msg, size_t msglen,
2701 struct smbd_release_ip_state *state =
2702 talloc_get_type_abort(private_data,
2703 struct smbd_release_ip_state);
2704 struct smbXsrv_connection *xconn = state->xconn;
2706 const char *addr = state->addr;
2707 const char *p = addr;
2712 if (msg[msglen-1] != '\0') {
2716 ip = (const char *)msg;
2718 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2719 /* avoid recursion */
2723 if (strncmp("::ffff:", addr, 7) == 0) {
2727 DEBUG(10, ("Got release IP message for %s, "
2728 "our address is %s\n", ip, p));
2730 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2731 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2734 * With SMB2 we should do a clean disconnect,
2735 * the previous_session_id in the session setup
2736 * will cleanup the old session, tcons and opens.
2738 * A clean disconnect is needed in order to support
2741 * Note: typically this is never triggered
2742 * as we got a TCP RST (triggered by ctdb event scripts)
2743 * before we get CTDB_SRVID_RELEASE_IP.
2745 * We used to call _exit(1) here, but as this was mostly never
2746 * triggered and has implication on our process model,
2747 * we can just use smbd_server_connection_terminate()
2750 * We don't call smbd_server_connection_terminate() directly
2751 * as we might be called from within ctdbd_migrate(),
2752 * we need to defer our action to the next event loop
2754 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2755 smbd_release_ip_immediate, state);
2758 * Make sure we don't get any io on the connection.
2760 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2761 return EADDRNOTAVAIL;
2767 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2768 struct sockaddr_storage *srv,
2769 struct sockaddr_storage *clnt)
2771 struct smbd_release_ip_state *state;
2772 struct ctdbd_connection *cconn;
2775 cconn = messaging_ctdb_connection();
2776 if (cconn == NULL) {
2777 return NT_STATUS_NO_MEMORY;
2780 state = talloc_zero(xconn, struct smbd_release_ip_state);
2781 if (state == NULL) {
2782 return NT_STATUS_NO_MEMORY;
2784 state->xconn = xconn;
2785 state->im = tevent_create_immediate(state);
2786 if (state->im == NULL) {
2787 return NT_STATUS_NO_MEMORY;
2789 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2790 return NT_STATUS_NO_MEMORY;
2793 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2795 return map_nt_error_from_unix(ret);
2797 return NT_STATUS_OK;
2800 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2801 void *private_data, uint32_t msg_type,
2802 struct server_id server_id, DATA_BLOB *data)
2804 struct smbd_server_connection *sconn = talloc_get_type_abort(
2805 private_data, struct smbd_server_connection);
2806 const char *ip = (char *) data->data;
2809 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2811 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2813 if (client_ip == NULL) {
2817 if (strequal(ip, client_ip)) {
2818 DBG_WARNING("Got kill client message for %s - "
2819 "exiting immediately\n", ip);
2820 exit_server_cleanly("Forced disconnect for client");
2823 TALLOC_FREE(client_ip);
2827 * Send keepalive packets to our client
2829 static bool keepalive_fn(const struct timeval *now, void *private_data)
2831 struct smbd_server_connection *sconn = talloc_get_type_abort(
2832 private_data, struct smbd_server_connection);
2833 struct smbXsrv_connection *xconn = NULL;
2836 if (sconn->using_smb2) {
2837 /* Don't do keepalives on an SMB2 connection. */
2842 * With SMB1 we only have 1 connection
2844 xconn = sconn->client->connections;
2845 smbd_lock_socket(xconn);
2846 ret = send_keepalive(xconn->transport.sock);
2847 smbd_unlock_socket(xconn);
2850 int saved_errno = errno;
2852 * Try and give an error message saying what
2855 DEBUG(0, ("send_keepalive failed for client %s. "
2856 "Error %s - exiting\n",
2857 smbXsrv_connection_dbg(xconn),
2858 strerror(saved_errno)));
2859 errno = saved_errno;
2866 * Do the recurring check if we're idle
2868 static bool deadtime_fn(const struct timeval *now, void *private_data)
2870 struct smbd_server_connection *sconn =
2871 (struct smbd_server_connection *)private_data;
2873 if ((conn_num_open(sconn) == 0)
2874 || (conn_idle_all(sconn, now->tv_sec))) {
2875 DEBUG( 2, ( "Closing idle connection\n" ) );
2876 messaging_send(sconn->msg_ctx,
2877 messaging_server_id(sconn->msg_ctx),
2878 MSG_SHUTDOWN, &data_blob_null);
2886 * Do the recurring log file and smb.conf reload checks.
2889 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2891 struct smbd_server_connection *sconn = talloc_get_type_abort(
2892 private_data, struct smbd_server_connection);
2894 DEBUG(5, ("housekeeping\n"));
2896 change_to_root_user();
2898 /* update printer queue caches if necessary */
2899 update_monitored_printq_cache(sconn->msg_ctx);
2901 /* check if we need to reload services */
2902 check_reload(sconn, time_mono(NULL));
2905 * Force a log file check.
2907 force_check_log_size();
2913 * Read an smb packet in the echo handler child, giving the parent
2914 * smbd one second to react once the socket becomes readable.
2917 struct smbd_echo_read_state {
2918 struct tevent_context *ev;
2919 struct smbXsrv_connection *xconn;
2926 static void smbd_echo_read_readable(struct tevent_req *subreq);
2927 static void smbd_echo_read_waited(struct tevent_req *subreq);
2929 static struct tevent_req *smbd_echo_read_send(
2930 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2931 struct smbXsrv_connection *xconn)
2933 struct tevent_req *req, *subreq;
2934 struct smbd_echo_read_state *state;
2936 req = tevent_req_create(mem_ctx, &state,
2937 struct smbd_echo_read_state);
2942 state->xconn = xconn;
2944 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2945 if (tevent_req_nomem(subreq, req)) {
2946 return tevent_req_post(req, ev);
2948 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2952 static void smbd_echo_read_readable(struct tevent_req *subreq)
2954 struct tevent_req *req = tevent_req_callback_data(
2955 subreq, struct tevent_req);
2956 struct smbd_echo_read_state *state = tevent_req_data(
2957 req, struct smbd_echo_read_state);
2961 ok = wait_for_read_recv(subreq, &err);
2962 TALLOC_FREE(subreq);
2964 tevent_req_nterror(req, map_nt_error_from_unix(err));
2969 * Give the parent smbd one second to step in
2972 subreq = tevent_wakeup_send(
2973 state, state->ev, timeval_current_ofs(1, 0));
2974 if (tevent_req_nomem(subreq, req)) {
2977 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2980 static void smbd_echo_read_waited(struct tevent_req *subreq)
2982 struct tevent_req *req = tevent_req_callback_data(
2983 subreq, struct tevent_req);
2984 struct smbd_echo_read_state *state = tevent_req_data(
2985 req, struct smbd_echo_read_state);
2986 struct smbXsrv_connection *xconn = state->xconn;
2992 ok = tevent_wakeup_recv(subreq);
2993 TALLOC_FREE(subreq);
2995 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2999 ok = smbd_lock_socket_internal(xconn);
3001 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3002 DEBUG(0, ("%s: failed to lock socket\n", __location__));
3006 if (!fd_is_readable(xconn->transport.sock)) {
3007 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3010 ok = smbd_unlock_socket_internal(xconn);
3012 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3013 DEBUG(1, ("%s: failed to unlock socket\n",
3018 subreq = wait_for_read_send(state, state->ev,
3019 xconn->transport.sock, false);
3020 if (tevent_req_nomem(subreq, req)) {
3023 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
3027 status = receive_smb_talloc(state, xconn,
3028 xconn->transport.sock,
3035 false /* trusted_channel*/);
3037 if (tevent_req_nterror(req, status)) {
3038 tevent_req_nterror(req, status);
3039 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3040 (int)getpid(), nt_errstr(status)));
3044 ok = smbd_unlock_socket_internal(xconn);
3046 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3047 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
3050 tevent_req_done(req);
3053 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3054 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
3056 struct smbd_echo_read_state *state = tevent_req_data(
3057 req, struct smbd_echo_read_state);
3060 if (tevent_req_is_nterror(req, &status)) {
3063 *pbuf = talloc_move(mem_ctx, &state->buf);
3064 *pbuflen = state->buflen;
3065 *pseqnum = state->seqnum;
3066 return NT_STATUS_OK;
3069 struct smbd_echo_state {
3070 struct tevent_context *ev;
3071 struct iovec *pending;
3072 struct smbd_server_connection *sconn;
3073 struct smbXsrv_connection *xconn;
3076 struct tevent_fd *parent_fde;
3078 struct tevent_req *write_req;
3081 static void smbd_echo_writer_done(struct tevent_req *req);
3083 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3087 if (state->write_req != NULL) {
3091 num_pending = talloc_array_length(state->pending);
3092 if (num_pending == 0) {
3096 state->write_req = writev_send(state, state->ev, NULL,
3097 state->parent_pipe, false,
3098 state->pending, num_pending);
3099 if (state->write_req == NULL) {
3100 DEBUG(1, ("writev_send failed\n"));
3104 talloc_steal(state->write_req, state->pending);
3105 state->pending = NULL;
3107 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3111 static void smbd_echo_writer_done(struct tevent_req *req)
3113 struct smbd_echo_state *state = tevent_req_callback_data(
3114 req, struct smbd_echo_state);
3118 written = writev_recv(req, &err);
3120 state->write_req = NULL;
3121 if (written == -1) {
3122 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3125 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3126 smbd_echo_activate_writer(state);
3129 static bool smbd_echo_reply(struct smbd_echo_state *state,
3130 uint8_t *inbuf, size_t inbuf_len,
3133 struct smb_request req;
3134 uint16_t num_replies;
3138 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3139 DEBUG(10, ("Got netbios keepalive\n"));
3146 if (inbuf_len < smb_size) {
3147 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3150 if (!valid_smb_header(inbuf)) {
3151 DEBUG(10, ("Got invalid SMB header\n"));
3155 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3161 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3162 smb_messages[req.cmd].name
3163 ? smb_messages[req.cmd].name : "unknown"));
3165 if (req.cmd != SMBecho) {
3172 num_replies = SVAL(req.vwv+0, 0);
3173 if (num_replies != 1) {
3174 /* Not a Windows "Hey, you're still there?" request */
3178 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3180 DEBUG(10, ("create_outbuf failed\n"));
3183 req.outbuf = (uint8_t *)outbuf;
3185 SSVAL(req.outbuf, smb_vwv0, num_replies);
3187 if (req.buflen > 0) {
3188 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3191 ok = srv_send_smb(req.xconn,
3195 TALLOC_FREE(outbuf);
3203 static void smbd_echo_exit(struct tevent_context *ev,
3204 struct tevent_fd *fde, uint16_t flags,
3207 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3211 static void smbd_echo_got_packet(struct tevent_req *req);
3213 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3216 struct smbd_echo_state *state;
3217 struct tevent_req *read_req;
3219 state = talloc_zero(xconn, struct smbd_echo_state);
3220 if (state == NULL) {
3221 DEBUG(1, ("talloc failed\n"));
3224 state->xconn = xconn;
3225 state->parent_pipe = parent_pipe;
3226 state->ev = samba_tevent_context_init(state);
3227 if (state->ev == NULL) {
3228 DEBUG(1, ("samba_tevent_context_init failed\n"));
3232 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3233 TEVENT_FD_READ, smbd_echo_exit,
3235 if (state->parent_fde == NULL) {
3236 DEBUG(1, ("tevent_add_fd failed\n"));
3241 read_req = smbd_echo_read_send(state, state->ev, xconn);
3242 if (read_req == NULL) {
3243 DEBUG(1, ("smbd_echo_read_send failed\n"));
3247 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3250 if (tevent_loop_once(state->ev) == -1) {
3251 DEBUG(1, ("tevent_loop_once failed: %s\n",
3259 static void smbd_echo_got_packet(struct tevent_req *req)
3261 struct smbd_echo_state *state = tevent_req_callback_data(
3262 req, struct smbd_echo_state);
3266 uint32_t seqnum = 0;
3269 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3271 if (!NT_STATUS_IS_OK(status)) {
3272 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3273 nt_errstr(status)));
3277 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3283 num_pending = talloc_array_length(state->pending);
3284 tmp = talloc_realloc(state, state->pending, struct iovec,
3287 DEBUG(1, ("talloc_realloc failed\n"));
3290 state->pending = tmp;
3292 if (buflen >= smb_size) {
3294 * place the seqnum in the packet so that the main process
3295 * can reply with signing
3297 SIVAL(buf, smb_ss_field, seqnum);
3298 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3301 iov = &state->pending[num_pending];
3302 iov->iov_base = talloc_move(state->pending, &buf);
3303 iov->iov_len = buflen;
3305 DEBUG(10,("echo_handler[%d]: forward to main\n",
3307 smbd_echo_activate_writer(state);
3310 req = smbd_echo_read_send(state, state->ev, state->xconn);
3312 DEBUG(1, ("smbd_echo_read_send failed\n"));
3315 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3320 * Handle SMBecho requests in a forked child process
3322 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3324 int listener_pipe[2];
3327 bool use_mutex = false;
3329 res = pipe(listener_pipe);
3331 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3335 #ifdef HAVE_ROBUST_MUTEXES
3336 use_mutex = tdb_runtime_check_for_robust_mutexes();
3339 pthread_mutexattr_t a;
3341 xconn->smb1.echo_handler.socket_mutex =
3342 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3343 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3344 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3349 res = pthread_mutexattr_init(&a);
3351 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3355 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3357 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3359 pthread_mutexattr_destroy(&a);
3362 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3364 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3366 pthread_mutexattr_destroy(&a);
3369 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3371 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3372 "%s\n", strerror(res)));
3373 pthread_mutexattr_destroy(&a);
3376 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3378 pthread_mutexattr_destroy(&a);
3380 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3388 xconn->smb1.echo_handler.socket_lock_fd =
3389 create_unlink_tmp(lp_lock_directory());
3390 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3391 DEBUG(1, ("Could not create lock fd: %s\n",
3401 close(listener_pipe[0]);
3402 set_blocking(listener_pipe[1], false);
3404 status = smbd_reinit_after_fork(xconn->msg_ctx, xconn->ev_ctx,
3406 if (!NT_STATUS_IS_OK(status)) {
3407 DEBUG(1, ("reinit_after_fork failed: %s\n",
3408 nt_errstr(status)));
3411 initialize_password_db(true, xconn->ev_ctx);
3412 smbd_echo_loop(xconn, listener_pipe[1]);
3415 close(listener_pipe[1]);
3416 listener_pipe[1] = -1;
3417 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3419 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3422 * Without smb signing this is the same as the normal smbd
3423 * listener. This needs to change once signing comes in.
3425 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3427 xconn->smb1.echo_handler.trusted_fd,
3429 smbd_server_echo_handler,
3431 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3432 DEBUG(1, ("event_add_fd failed\n"));
3439 if (listener_pipe[0] != -1) {
3440 close(listener_pipe[0]);
3442 if (listener_pipe[1] != -1) {
3443 close(listener_pipe[1]);
3445 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3446 close(xconn->smb1.echo_handler.socket_lock_fd);
3448 #ifdef HAVE_ROBUST_MUTEXES
3449 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3450 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3451 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3454 smbd_echo_init(xconn);
3459 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3462 if (user->session_info &&
3463 (user->session_info->unix_token->uid == uid)) {
3471 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3474 if (user->session_info != NULL) {
3476 struct security_unix_token *utok;
3478 utok = user->session_info->unix_token;
3479 if (utok->gid == gid) {
3482 for(i=0; i<utok->ngroups; i++) {
3483 if (utok->groups[i] == gid) {
3493 static bool sid_in_use(const struct user_struct *user,
3494 const struct dom_sid *psid)
3497 struct security_token *tok;
3499 if (user->session_info == NULL) {
3502 tok = user->session_info->security_token;
3505 * Not sure session_info->security_token can
3506 * ever be NULL. This check might be not
3511 if (security_token_has_sid(tok, psid)) {
3519 static bool id_in_use(const struct user_struct *user,
3520 const struct id_cache_ref *id)
3524 return uid_in_use(user, id->id.uid);
3526 return gid_in_use(user, id->id.gid);
3528 return sid_in_use(user, &id->id.sid);
3535 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3538 struct server_id server_id,
3541 const char *msg = (data && data->data)
3542 ? (const char *)data->data : "<NULL>";
3543 struct id_cache_ref id;
3544 struct smbd_server_connection *sconn =
3545 talloc_get_type_abort(private_data,
3546 struct smbd_server_connection);
3548 if (!id_cache_ref_parse(msg, &id)) {
3549 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3553 if (id_in_use(sconn->users, &id)) {
3554 exit_server_cleanly(msg);
3556 id_cache_delete_from_cache(&id);
3559 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3560 enum protocol_types protocol)
3564 conn->protocol = protocol;
3566 if (conn->client->session_table != NULL) {
3567 return NT_STATUS_OK;
3570 if (protocol >= PROTOCOL_SMB2_02) {
3571 status = smb2srv_session_table_init(conn);
3572 if (!NT_STATUS_IS_OK(status)) {
3573 conn->protocol = PROTOCOL_NONE;
3577 status = smb2srv_open_table_init(conn);
3578 if (!NT_STATUS_IS_OK(status)) {
3579 conn->protocol = PROTOCOL_NONE;
3583 status = smb1srv_session_table_init(conn);
3584 if (!NT_STATUS_IS_OK(status)) {
3585 conn->protocol = PROTOCOL_NONE;
3589 status = smb1srv_tcon_table_init(conn);
3590 if (!NT_STATUS_IS_OK(status)) {
3591 conn->protocol = PROTOCOL_NONE;
3595 status = smb1srv_open_table_init(conn);
3596 if (!NT_STATUS_IS_OK(status)) {
3597 conn->protocol = PROTOCOL_NONE;
3602 set_Protocol(protocol);
3603 return NT_STATUS_OK;
3606 struct smbd_tevent_trace_state {
3607 struct tevent_context *ev;
3609 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3612 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3615 struct smbd_tevent_trace_state *state =
3616 (struct smbd_tevent_trace_state *)private_data;
3619 case TEVENT_TRACE_BEFORE_WAIT:
3620 if (!smbprofile_dump_pending()) {
3622 * If there's no dump pending
3623 * we don't want to schedule a new 1 sec timer.
3625 * Instead we want to sleep as long as nothing happens.
3627 smbprofile_dump_setup(NULL);
3629 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3631 case TEVENT_TRACE_AFTER_WAIT:
3632 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3633 if (!smbprofile_dump_pending()) {
3635 * We need to flush our state after sleeping
3636 * (hopefully a long time).
3640 * future profiling events should trigger timers
3641 * on our main event context.
3643 smbprofile_dump_setup(state->ev);
3646 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3647 TALLOC_FREE(state->frame);
3648 state->frame = talloc_stackframe_pool(8192);
3650 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3651 TALLOC_FREE(state->frame);
3659 * Create a debug string for the connection
3661 * This is allocated to talloc_tos() or a string constant
3662 * in certain corner cases. The returned string should
3663 * hence not be free'd directly but only via the talloc stack.
3665 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3670 * TODO: this can be improved later
3671 * maybe including the client guid or more
3673 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3675 return "<tsocket_address_string() failed>";
3681 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3682 struct smbXsrv_connection **_xconn)
3684 TALLOC_CTX *frame = talloc_stackframe();
3685 struct smbXsrv_connection *xconn;
3686 struct sockaddr_storage ss_srv;
3687 void *sp_srv = (void *)&ss_srv;
3688 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3689 struct sockaddr_storage ss_clnt;
3690 void *sp_clnt = (void *)&ss_clnt;
3691 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3692 socklen_t sa_socklen;
3693 struct tsocket_address *local_address = NULL;
3694 struct tsocket_address *remote_address = NULL;
3695 const char *remaddr = NULL;
3697 const char *rhost = NULL;
3703 DO_PROFILE_INC(connect);
3705 xconn = talloc_zero(client, struct smbXsrv_connection);
3706 if (xconn == NULL) {
3707 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3709 return NT_STATUS_NO_MEMORY;
3711 talloc_steal(frame, xconn);
3713 xconn->ev_ctx = client->ev_ctx;
3714 xconn->msg_ctx = client->msg_ctx;
3715 xconn->transport.sock = sock_fd;
3716 smbd_echo_init(xconn);
3717 xconn->protocol = PROTOCOL_NONE;
3719 /* Ensure child is set to blocking mode */
3720 set_blocking(sock_fd,True);
3722 set_socket_options(sock_fd, "SO_KEEPALIVE");
3723 set_socket_options(sock_fd, lp_socket_options());
3725 sa_socklen = sizeof(ss_clnt);
3726 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3728 int saved_errno = errno;
3729 int level = (errno == ENOTCONN)?2:0;
3730 DEBUG(level,("getpeername() failed - %s\n",
3731 strerror(saved_errno)));
3733 return map_nt_error_from_unix_common(saved_errno);
3735 ret = tsocket_address_bsd_from_sockaddr(xconn,
3736 sa_clnt, sa_socklen,
3739 int saved_errno = errno;
3740 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3741 __location__, strerror(saved_errno)));
3743 return map_nt_error_from_unix_common(saved_errno);
3746 sa_socklen = sizeof(ss_srv);
3747 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3749 int saved_errno = errno;
3750 int level = (errno == ENOTCONN)?2:0;
3751 DEBUG(level,("getsockname() failed - %s\n",
3752 strerror(saved_errno)));
3754 return map_nt_error_from_unix_common(saved_errno);
3756 ret = tsocket_address_bsd_from_sockaddr(xconn,
3760 int saved_errno = errno;
3761 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3762 __location__, strerror(saved_errno)));
3764 return map_nt_error_from_unix_common(saved_errno);
3767 if (tsocket_address_is_inet(remote_address, "ip")) {
3768 remaddr = tsocket_address_inet_addr_string(remote_address,
3770 if (remaddr == NULL) {
3771 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3772 __location__, strerror(errno)));
3774 return NT_STATUS_NO_MEMORY;
3777 remaddr = "0.0.0.0";
3781 * Before the first packet, check the global hosts allow/ hosts deny
3782 * parameters before doing any parsing of packets passed to us by the
3783 * client. This prevents attacks on our parsing code from hosts not in
3784 * the hosts allow list.
3787 ret = get_remote_hostname(remote_address,
3790 int saved_errno = errno;
3791 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3792 __location__, strerror(saved_errno)));
3794 return map_nt_error_from_unix_common(saved_errno);
3797 if (strequal(rhost, "UNKNOWN")) {
3801 xconn->local_address = local_address;
3802 xconn->remote_address = remote_address;
3803 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3804 if (xconn->remote_hostname == NULL) {
3805 return NT_STATUS_NO_MEMORY;
3808 if (!srv_init_signing(xconn)) {
3809 DEBUG(0, ("Failed to init smb_signing\n"));
3811 return NT_STATUS_INTERNAL_ERROR;
3814 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3815 xconn->remote_hostname,
3817 DEBUG( 1, ("Connection denied from %s to %s\n",
3818 tsocket_address_string(remote_address, talloc_tos()),
3819 tsocket_address_string(local_address, talloc_tos())));
3822 * We return a valid xconn
3823 * so that the caller can return an error message
3826 client->connections = xconn;
3827 xconn->client = client;
3828 talloc_steal(client, xconn);
3832 return NT_STATUS_NETWORK_ACCESS_DENIED;
3835 DEBUG(10, ("Connection allowed from %s to %s\n",
3836 tsocket_address_string(remote_address, talloc_tos()),
3837 tsocket_address_string(local_address, talloc_tos())));
3839 if (lp_clustering()) {
3841 * We need to tell ctdb about our client's TCP
3842 * connection, so that for failover ctdbd can send
3843 * tickle acks, triggering a reconnection by the
3848 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3849 if (!NT_STATUS_IS_OK(status)) {
3850 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3851 nt_errstr(status)));
3855 tmp = lp_max_xmit();
3856 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3857 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3859 xconn->smb1.negprot.max_recv = tmp;
3861 xconn->smb1.sessions.done_sesssetup = false;
3862 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3864 xconn->transport.fde = tevent_add_fd(client->ev_ctx,
3868 smbd_server_connection_handler,
3870 if (!xconn->transport.fde) {
3872 return NT_STATUS_NO_MEMORY;
3875 /* for now we only have one connection */
3876 DLIST_ADD_END(client->connections, xconn);
3877 xconn->client = client;
3878 talloc_steal(client, xconn);
3882 return NT_STATUS_OK;
3885 /****************************************************************************
3886 Process commands from the client
3887 ****************************************************************************/
3889 void smbd_process(struct tevent_context *ev_ctx,
3890 struct messaging_context *msg_ctx,
3894 struct smbd_tevent_trace_state trace_state = {
3896 .frame = talloc_stackframe(),
3898 struct smbXsrv_client *client = NULL;
3899 struct smbd_server_connection *sconn = NULL;
3900 struct smbXsrv_connection *xconn = NULL;
3901 const char *locaddr = NULL;
3902 const char *remaddr = NULL;
3905 struct timeval tv = timeval_current();
3906 NTTIME now = timeval_to_nttime(&tv);
3907 char *chroot_dir = NULL;
3910 status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
3911 if (!NT_STATUS_IS_OK(status)) {
3912 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
3913 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3917 * TODO: remove this...:-)
3919 global_smbXsrv_client = client;
3921 sconn = talloc_zero(client, struct smbd_server_connection);
3922 if (sconn == NULL) {
3923 exit_server("failed to create smbd_server_connection");
3926 client->sconn = sconn;
3927 sconn->client = client;
3929 sconn->ev_ctx = ev_ctx;
3930 sconn->msg_ctx = msg_ctx;
3932 ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
3935 exit_server("pthreadpool_tevent_init() failed.");
3938 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3940 * We're not making the decision here,
3941 * we're just allowing the client
3942 * to decide between SMB1 and SMB2
3943 * with the first negprot
3946 sconn->using_smb2 = true;
3950 smbd_setup_sig_term_handler(sconn);
3951 smbd_setup_sig_hup_handler(sconn);
3954 status = smbd_add_connection(client, sock_fd, &xconn);
3955 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3957 * send a negative session response "not listening on calling
3960 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3961 (void)srv_send_smb(xconn,(char *)buf, false,
3963 exit_server_cleanly("connection denied");
3964 } else if (!NT_STATUS_IS_OK(status)) {
3965 exit_server_cleanly(nt_errstr(status));
3968 sconn->local_address =
3969 tsocket_address_copy(xconn->local_address, sconn);
3970 if (sconn->local_address == NULL) {
3971 exit_server_cleanly("tsocket_address_copy() failed");
3973 sconn->remote_address =
3974 tsocket_address_copy(xconn->remote_address, sconn);
3975 if (sconn->remote_address == NULL) {
3976 exit_server_cleanly("tsocket_address_copy() failed");
3978 sconn->remote_hostname =
3979 talloc_strdup(sconn, xconn->remote_hostname);
3980 if (sconn->remote_hostname == NULL) {
3981 exit_server_cleanly("tsocket_strdup() failed");
3984 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3985 locaddr = tsocket_address_inet_addr_string(
3986 sconn->local_address,
3988 if (locaddr == NULL) {
3989 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3990 __location__, strerror(errno)));
3991 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3994 locaddr = "0.0.0.0";
3997 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
3998 remaddr = tsocket_address_inet_addr_string(
3999 sconn->remote_address,
4001 if (remaddr == NULL) {
4002 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4003 __location__, strerror(errno)));
4004 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4007 remaddr = "0.0.0.0";
4010 /* this is needed so that we get decent entries
4011 in smbstatus for port 445 connects */
4012 set_remote_machine_name(remaddr, false);
4013 reload_services(sconn, conn_snum_used, true);
4014 sub_set_socket_ids(remaddr,
4015 sconn->remote_hostname,
4018 if (lp_preload_modules()) {
4019 smb_load_all_modules_absoute_path(lp_preload_modules());
4022 smb_perfcount_init();
4024 if (!init_account_policy()) {
4025 exit_server("Could not open account policy tdb.\n");
4028 chroot_dir = lp_root_directory(talloc_tos());
4029 if (chroot_dir[0] != '\0') {
4030 rc = chdir(chroot_dir);
4032 DBG_ERR("Failed to chdir to %s\n", chroot_dir);
4033 exit_server("Failed to chdir()");
4036 rc = chroot(chroot_dir);
4038 DBG_ERR("Failed to change root to %s\n", chroot_dir);
4039 exit_server("Failed to chroot()");
4041 DBG_WARNING("Changed root to %s\n", chroot_dir);
4043 TALLOC_FREE(chroot_dir);
4046 if (!file_init(sconn)) {
4047 exit_server("file_init() failed");
4051 if (!init_oplocks(sconn))
4052 exit_server("Failed to init oplocks");
4054 /* register our message handlers */
4055 messaging_register(sconn->msg_ctx, sconn,
4056 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4057 messaging_register(sconn->msg_ctx, sconn,
4058 MSG_SMB_CLOSE_FILE, msg_close_file);
4059 messaging_register(sconn->msg_ctx, sconn,
4060 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
4062 id_cache_register_msgs(sconn->msg_ctx);
4063 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
4064 messaging_register(sconn->msg_ctx, sconn,
4065 ID_CACHE_KILL, smbd_id_cache_kill);
4067 messaging_deregister(sconn->msg_ctx,
4068 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
4069 messaging_register(sconn->msg_ctx, sconn,
4070 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
4072 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
4074 messaging_register(sconn->msg_ctx, sconn,
4075 MSG_SMB_KILL_CLIENT_IP,
4076 msg_kill_client_ip);
4078 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
4081 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4082 * MSGs to all child processes
4084 messaging_deregister(sconn->msg_ctx,
4086 messaging_register(sconn->msg_ctx, NULL,
4087 MSG_DEBUG, debug_message);
4089 if ((lp_keepalive() != 0)
4090 && !(event_add_idle(ev_ctx, NULL,
4091 timeval_set(lp_keepalive(), 0),
4092 "keepalive", keepalive_fn,
4094 DEBUG(0, ("Could not add keepalive event\n"));
4098 if (!(event_add_idle(ev_ctx, NULL,
4099 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4100 "deadtime", deadtime_fn, sconn))) {
4101 DEBUG(0, ("Could not add deadtime event\n"));
4105 if (!(event_add_idle(ev_ctx, NULL,
4106 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4107 "housekeeping", housekeeping_fn, sconn))) {
4108 DEBUG(0, ("Could not add housekeeping event\n"));
4112 smbprofile_dump_setup(ev_ctx);
4114 if (!init_dptrs(sconn)) {
4115 exit_server("init_dptrs() failed");
4118 TALLOC_FREE(trace_state.frame);
4120 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4123 ret = tevent_loop_wait(ev_ctx);
4125 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4126 " exiting\n", ret, strerror(errno)));
4129 TALLOC_FREE(trace_state.frame);
4131 exit_server_cleanly(NULL);
4134 bool req_is_in_chain(const struct smb_request *req)
4136 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4138 * We're right now handling a subsequent request, so we must
4144 if (!is_andx_req(req->cmd)) {
4150 * Okay, an illegal request, but definitely not chained :-)
4155 return (CVAL(req->vwv+0, 0) != 0xFF);