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"
46 /* Internal message queue for deferred opens. */
47 struct pending_message_list {
48 struct pending_message_list *next, *prev;
49 struct timeval request_time; /* When was this first issued? */
50 struct smbd_server_connection *sconn;
51 struct smbXsrv_connection *xconn;
52 struct tevent_timer *te;
53 struct smb_perfcount_data pcd;
58 struct deferred_open_record *open_rec;
61 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
63 static struct pending_message_list *get_deferred_open_message_smb(
64 struct smbd_server_connection *sconn, uint64_t mid);
65 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
67 static void smbd_echo_init(struct smbXsrv_connection *xconn)
69 xconn->smb1.echo_handler.trusted_fd = -1;
70 xconn->smb1.echo_handler.socket_lock_fd = -1;
71 #ifdef HAVE_ROBUST_MUTEXES
72 xconn->smb1.echo_handler.socket_mutex = NULL;
76 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
78 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
82 #ifdef HAVE_ROBUST_MUTEXES
83 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
91 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
93 if (!smbd_echo_active(xconn)) {
97 xconn->smb1.echo_handler.ref_count++;
99 if (xconn->smb1.echo_handler.ref_count > 1) {
103 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
105 #ifdef HAVE_ROBUST_MUTEXES
106 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
109 while (ret == EINTR) {
110 ret = pthread_mutex_lock(
111 xconn->smb1.echo_handler.socket_mutex);
117 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
124 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
129 xconn->smb1.echo_handler.socket_lock_fd,
130 F_SETLKW, 0, 0, F_WRLCK);
131 } while (!ok && (errno == EINTR));
134 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
139 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
144 void smbd_lock_socket(struct smbXsrv_connection *xconn)
146 if (!smbd_lock_socket_internal(xconn)) {
147 exit_server_cleanly("failed to lock socket");
151 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
153 if (!smbd_echo_active(xconn)) {
157 xconn->smb1.echo_handler.ref_count--;
159 if (xconn->smb1.echo_handler.ref_count > 0) {
163 #ifdef HAVE_ROBUST_MUTEXES
164 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
167 while (ret == EINTR) {
168 ret = pthread_mutex_unlock(
169 xconn->smb1.echo_handler.socket_mutex);
175 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
182 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
187 xconn->smb1.echo_handler.socket_lock_fd,
188 F_SETLKW, 0, 0, F_UNLCK);
189 } while (!ok && (errno == EINTR));
192 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
197 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
202 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
204 if (!smbd_unlock_socket_internal(xconn)) {
205 exit_server_cleanly("failed to unlock socket");
209 /* Accessor function for smb_read_error for smbd functions. */
211 /****************************************************************************
213 ****************************************************************************/
215 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
216 bool do_signing, uint32_t seqnum,
218 struct smb_perfcount_data *pcd)
222 char *buf_out = buffer;
224 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
226 * we're not supposed to do any io
231 smbd_lock_socket(xconn);
234 /* Sign the outgoing packet if required. */
235 srv_calculate_sign_mac(xconn, buf_out, seqnum);
239 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
240 if (!NT_STATUS_IS_OK(status)) {
241 DEBUG(0, ("send_smb: SMB encryption failed "
242 "on outgoing packet! Error %s\n",
243 nt_errstr(status) ));
249 len = smb_len_large(buf_out) + 4;
251 ret = write_data(xconn->transport.sock, buf_out, len);
253 int saved_errno = errno;
255 * Try and give an error message saying what
258 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
259 (int)getpid(), (int)len,
260 smbXsrv_connection_dbg(xconn),
261 (int)ret, strerror(saved_errno)));
264 srv_free_enc_buffer(xconn, buf_out);
268 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
269 srv_free_enc_buffer(xconn, buf_out);
271 SMB_PERFCOUNT_END(pcd);
273 smbd_unlock_socket(xconn);
277 /*******************************************************************
278 Setup the word count and byte count for a smb message.
279 ********************************************************************/
281 int srv_set_message(char *buf,
286 if (zero && (num_words || num_bytes)) {
287 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
289 SCVAL(buf,smb_wct,num_words);
290 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
291 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
292 return (smb_size + num_words*2 + num_bytes);
295 static bool valid_smb_header(const uint8_t *inbuf)
297 if (is_encrypted_packet(inbuf)) {
301 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
302 * but it just looks weird to call strncmp for this one.
304 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
307 /* Socket functions for smbd packet processing. */
309 static bool valid_packet_size(size_t len)
312 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
313 * of header. Don't print the error if this fits.... JRA.
316 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
317 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
318 (unsigned long)len));
324 static NTSTATUS read_packet_remainder(int fd, char *buffer,
325 unsigned int timeout, ssize_t len)
333 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
334 if (!NT_STATUS_IS_OK(status)) {
335 char addr[INET6_ADDRSTRLEN];
336 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
338 get_peer_addr(fd, addr, sizeof(addr)),
344 /****************************************************************************
345 Attempt a zerocopy writeX read. We know here that len > smb_size-4
346 ****************************************************************************/
349 * Unfortunately, earlier versions of smbclient/libsmbclient
350 * don't send this "standard" writeX header. I've fixed this
351 * for 3.2 but we'll use the old method with earlier versions.
352 * Windows and CIFSFS at least use this standard size. Not
356 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
357 (2*14) + /* word count (including bcc) */ \
360 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
361 const char lenbuf[4],
362 struct smbXsrv_connection *xconn,
365 unsigned int timeout,
369 /* Size of a WRITEX call (+4 byte len). */
370 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
371 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
375 memcpy(writeX_header, lenbuf, 4);
377 status = read_fd_with_timeout(
378 sock, writeX_header + 4,
379 STANDARD_WRITE_AND_X_HEADER_SIZE,
380 STANDARD_WRITE_AND_X_HEADER_SIZE,
383 if (!NT_STATUS_IS_OK(status)) {
384 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
386 smbXsrv_connection_dbg(xconn),
392 * Ok - now try and see if this is a possible
396 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
398 * If the data offset is beyond what
399 * we've read, drain the extra bytes.
401 uint16_t doff = SVAL(writeX_header,smb_vwv11);
404 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
405 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
406 if (drain_socket(sock, drain) != drain) {
407 smb_panic("receive_smb_raw_talloc_partial_read:"
408 " failed to drain pending bytes");
411 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
414 /* Spoof down the length and null out the bcc. */
415 set_message_bcc(writeX_header, 0);
416 newlen = smb_len(writeX_header);
418 /* Copy the header we've written. */
420 *buffer = (char *)talloc_memdup(mem_ctx,
422 sizeof(writeX_header));
424 if (*buffer == NULL) {
425 DEBUG(0, ("Could not allocate inbuf of length %d\n",
426 (int)sizeof(writeX_header)));
427 return NT_STATUS_NO_MEMORY;
430 /* Work out the remaining bytes. */
431 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
432 *len_ret = newlen + 4;
436 if (!valid_packet_size(len)) {
437 return NT_STATUS_INVALID_PARAMETER;
441 * Not a valid writeX call. Just do the standard
445 *buffer = talloc_array(mem_ctx, char, len+4);
447 if (*buffer == NULL) {
448 DEBUG(0, ("Could not allocate inbuf of length %d\n",
450 return NT_STATUS_NO_MEMORY;
453 /* Copy in what we already read. */
456 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
457 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
460 status = read_packet_remainder(
462 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
465 if (!NT_STATUS_IS_OK(status)) {
466 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
476 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
477 struct smbXsrv_connection *xconn,
479 char **buffer, unsigned int timeout,
480 size_t *p_unread, size_t *plen)
484 int min_recv_size = lp_min_receive_file_size();
489 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
491 if (!NT_STATUS_IS_OK(status)) {
495 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
496 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
497 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
498 !srv_is_signing_active(xconn) &&
499 xconn->smb1.echo_handler.trusted_fde == NULL) {
501 return receive_smb_raw_talloc_partial_read(
502 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
506 if (!valid_packet_size(len)) {
507 return NT_STATUS_INVALID_PARAMETER;
511 * The +4 here can't wrap, we've checked the length above already.
514 *buffer = talloc_array(mem_ctx, char, len+4);
516 if (*buffer == NULL) {
517 DEBUG(0, ("Could not allocate inbuf of length %d\n",
519 return NT_STATUS_NO_MEMORY;
522 memcpy(*buffer, lenbuf, sizeof(lenbuf));
524 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
525 if (!NT_STATUS_IS_OK(status)) {
533 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
534 struct smbXsrv_connection *xconn,
536 char **buffer, unsigned int timeout,
537 size_t *p_unread, bool *p_encrypted,
540 bool trusted_channel)
545 *p_encrypted = false;
547 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
549 if (!NT_STATUS_IS_OK(status)) {
550 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
551 ("receive_smb_raw_talloc failed for client %s "
552 "read error = %s.\n",
553 smbXsrv_connection_dbg(xconn),
554 nt_errstr(status)) );
558 if (is_encrypted_packet((uint8_t *)*buffer)) {
559 status = srv_decrypt_buffer(xconn, *buffer);
560 if (!NT_STATUS_IS_OK(status)) {
561 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
562 "incoming packet! Error %s\n",
563 nt_errstr(status) ));
569 /* Check the incoming SMB signature. */
570 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
571 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
572 "incoming packet!\n"));
573 return NT_STATUS_INVALID_NETWORK_RESPONSE;
581 * Initialize a struct smb_request from an inbuf
584 static bool init_smb_request(struct smb_request *req,
585 struct smbd_server_connection *sconn,
586 struct smbXsrv_connection *xconn,
587 const uint8_t *inbuf,
588 size_t unread_bytes, bool encrypted,
591 struct smbXsrv_tcon *tcon;
594 size_t req_size = smb_len(inbuf) + 4;
596 /* Ensure we have at least smb_size bytes. */
597 if (req_size < smb_size) {
598 DEBUG(0,("init_smb_request: invalid request size %u\n",
599 (unsigned int)req_size ));
603 req->request_time = timeval_current();
604 now = timeval_to_nttime(&req->request_time);
606 req->cmd = CVAL(inbuf, smb_com);
607 req->flags2 = SVAL(inbuf, smb_flg2);
608 req->smbpid = SVAL(inbuf, smb_pid);
609 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
610 req->seqnum = seqnum;
611 req->vuid = SVAL(inbuf, smb_uid);
612 req->tid = SVAL(inbuf, smb_tid);
613 req->wct = CVAL(inbuf, smb_wct);
614 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
615 req->buflen = smb_buflen(inbuf);
616 req->buf = (const uint8_t *)smb_buf_const(inbuf);
617 req->unread_bytes = unread_bytes;
618 req->encrypted = encrypted;
623 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
624 if (NT_STATUS_IS_OK(status)) {
625 req->conn = tcon->compat;
628 req->chain_fsp = NULL;
630 req->priv_paths = NULL;
632 req->posix_pathnames = lp_posix_pathnames();
633 smb_init_perfcount_data(&req->pcd);
635 /* Ensure we have at least wct words and 2 bytes of bcc. */
636 if (smb_size + req->wct*2 > req_size) {
637 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
638 (unsigned int)req->wct,
639 (unsigned int)req_size));
642 /* Ensure bcc is correct. */
643 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
644 DEBUG(0,("init_smb_request: invalid bcc number %u "
645 "(wct = %u, size %u)\n",
646 (unsigned int)req->buflen,
647 (unsigned int)req->wct,
648 (unsigned int)req_size));
656 static void process_smb(struct smbXsrv_connection *xconn,
657 uint8_t *inbuf, size_t nread, size_t unread_bytes,
658 uint32_t seqnum, bool encrypted,
659 struct smb_perfcount_data *deferred_pcd);
661 static void smbd_deferred_open_timer(struct tevent_context *ev,
662 struct tevent_timer *te,
663 struct timeval _tval,
666 struct pending_message_list *msg = talloc_get_type(private_data,
667 struct pending_message_list);
668 struct smbd_server_connection *sconn = msg->sconn;
669 struct smbXsrv_connection *xconn = msg->xconn;
670 TALLOC_CTX *mem_ctx = talloc_tos();
671 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
674 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
677 exit_server("smbd_deferred_open_timer: talloc failed\n");
681 /* We leave this message on the queue so the open code can
682 know this is a retry. */
683 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
684 (unsigned long long)mid ));
686 /* Mark the message as processed so this is not
687 * re-processed in error. */
688 msg->processed = true;
690 process_smb(xconn, inbuf,
692 msg->seqnum, msg->encrypted, &msg->pcd);
694 /* If it's still there and was processed, remove it. */
695 msg = get_deferred_open_message_smb(sconn, mid);
696 if (msg && msg->processed) {
697 remove_deferred_open_message_smb(xconn, mid);
701 /****************************************************************************
702 Function to push a message onto the tail of a linked list of smb messages ready
704 ****************************************************************************/
706 static bool push_queued_message(struct smb_request *req,
707 struct timeval request_time,
708 struct timeval end_time,
709 struct deferred_open_record *open_rec)
711 int msg_len = smb_len(req->inbuf) + 4;
712 struct pending_message_list *msg;
714 msg = talloc_zero(NULL, struct pending_message_list);
717 DEBUG(0,("push_message: malloc fail (1)\n"));
720 msg->sconn = req->sconn;
721 msg->xconn = req->xconn;
723 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
724 if(msg->buf.data == NULL) {
725 DEBUG(0,("push_message: malloc fail (2)\n"));
730 msg->request_time = request_time;
731 msg->seqnum = req->seqnum;
732 msg->encrypted = req->encrypted;
733 msg->processed = false;
734 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
737 msg->open_rec = talloc_move(msg, &open_rec);
741 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
744 smbd_deferred_open_timer,
747 DEBUG(0,("push_message: event_add_timed failed\n"));
753 DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
755 DEBUG(10,("push_message: pushed message length %u on "
756 "deferred_open_queue\n", (unsigned int)msg_len));
761 /****************************************************************************
762 Function to delete a sharing violation open message by mid.
763 ****************************************************************************/
765 void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
768 struct smbd_server_connection *sconn = xconn->client->sconn;
769 struct pending_message_list *pml;
771 if (sconn->using_smb2) {
772 remove_deferred_open_message_smb2(xconn, mid);
776 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
777 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
778 DEBUG(10,("remove_deferred_open_message_smb: "
779 "deleting mid %llu len %u\n",
780 (unsigned long long)mid,
781 (unsigned int)pml->buf.length ));
782 DLIST_REMOVE(sconn->deferred_open_queue, pml);
789 /****************************************************************************
790 Move a sharing violation open retry message to the front of the list and
791 schedule it for immediate processing.
792 ****************************************************************************/
794 bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
797 struct smbd_server_connection *sconn = xconn->client->sconn;
798 struct pending_message_list *pml;
801 if (sconn->using_smb2) {
802 return schedule_deferred_open_message_smb2(xconn, mid);
805 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
806 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
808 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
811 (unsigned long long)msg_mid ));
813 if (mid == msg_mid) {
814 struct tevent_timer *te;
816 if (pml->processed) {
817 /* A processed message should not be
819 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
820 "message mid %llu was already processed\n",
821 (unsigned long long)msg_mid ));
825 DEBUG(10,("schedule_deferred_open_message_smb: "
826 "scheduling mid %llu\n",
827 (unsigned long long)mid ));
829 te = tevent_add_timer(pml->sconn->ev_ctx,
832 smbd_deferred_open_timer,
835 DEBUG(10,("schedule_deferred_open_message_smb: "
836 "event_add_timed() failed, "
837 "skipping mid %llu\n",
838 (unsigned long long)msg_mid ));
841 TALLOC_FREE(pml->te);
843 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
848 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
849 "find message mid %llu\n",
850 (unsigned long long)mid ));
855 /****************************************************************************
856 Return true if this mid is on the deferred queue and was not yet processed.
857 ****************************************************************************/
859 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
861 struct smbd_server_connection *sconn = xconn->client->sconn;
862 struct pending_message_list *pml;
864 if (sconn->using_smb2) {
865 return open_was_deferred_smb2(xconn, mid);
868 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
869 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
876 /****************************************************************************
877 Return the message queued by this mid.
878 ****************************************************************************/
880 static struct pending_message_list *get_deferred_open_message_smb(
881 struct smbd_server_connection *sconn, uint64_t mid)
883 struct pending_message_list *pml;
885 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
886 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
893 /****************************************************************************
894 Get the state data queued by this mid.
895 ****************************************************************************/
897 bool get_deferred_open_message_state(struct smb_request *smbreq,
898 struct timeval *p_request_time,
899 struct deferred_open_record **open_rec)
901 struct pending_message_list *pml;
903 if (smbreq->sconn->using_smb2) {
904 return get_deferred_open_message_state_smb2(smbreq->smb2req,
909 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
913 if (p_request_time) {
914 *p_request_time = pml->request_time;
916 if (open_rec != NULL) {
917 *open_rec = pml->open_rec;
922 /****************************************************************************
923 Function to push a deferred open smb message onto a linked list of local smb
924 messages ready for processing.
925 ****************************************************************************/
927 bool push_deferred_open_message_smb(struct smb_request *req,
928 struct timeval request_time,
929 struct timeval timeout,
931 struct deferred_open_record *open_rec)
933 struct timeval end_time;
936 return push_deferred_open_message_smb2(req->smb2req,
943 if (req->unread_bytes) {
944 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
945 "unread_bytes = %u\n",
946 (unsigned int)req->unread_bytes ));
947 smb_panic("push_deferred_open_message_smb: "
948 "logic error unread_bytes != 0" );
951 end_time = timeval_sum(&request_time, &timeout);
953 DEBUG(10,("push_deferred_open_message_smb: pushing message "
954 "len %u mid %llu timeout time [%u.%06u]\n",
955 (unsigned int) smb_len(req->inbuf)+4,
956 (unsigned long long)req->mid,
957 (unsigned int)end_time.tv_sec,
958 (unsigned int)end_time.tv_usec));
960 return push_queued_message(req, request_time, end_time, open_rec);
963 static void smbd_sig_term_handler(struct tevent_context *ev,
964 struct tevent_signal *se,
970 exit_server_cleanly("termination signal");
973 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
975 struct tevent_signal *se;
977 se = tevent_add_signal(sconn->ev_ctx,
980 smbd_sig_term_handler,
983 exit_server("failed to setup SIGTERM handler");
987 static void smbd_sig_hup_handler(struct tevent_context *ev,
988 struct tevent_signal *se,
994 struct smbd_server_connection *sconn =
995 talloc_get_type_abort(private_data,
996 struct smbd_server_connection);
998 change_to_root_user();
999 DEBUG(1,("Reloading services after SIGHUP\n"));
1000 reload_services(sconn, conn_snum_used, false);
1003 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1005 struct tevent_signal *se;
1007 se = tevent_add_signal(sconn->ev_ctx,
1010 smbd_sig_hup_handler,
1013 exit_server("failed to setup SIGHUP handler");
1017 static void smbd_conf_updated(struct messaging_context *msg,
1020 struct server_id server_id,
1023 struct smbd_server_connection *sconn =
1024 talloc_get_type_abort(private_data,
1025 struct smbd_server_connection);
1027 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1028 "updated. Reloading.\n"));
1029 change_to_root_user();
1030 reload_services(sconn, conn_snum_used, false);
1034 * Only allow 5 outstanding trans requests. We're allocating memory, so
1038 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1041 for (; list != NULL; list = list->next) {
1043 if (list->mid == mid) {
1044 return NT_STATUS_INVALID_PARAMETER;
1050 return NT_STATUS_INSUFFICIENT_RESOURCES;
1053 return NT_STATUS_OK;
1057 These flags determine some of the permissions required to do an operation
1059 Note that I don't set NEED_WRITE on some write operations because they
1060 are used by some brain-dead clients when printing, and I don't want to
1061 force write permissions on print services.
1063 #define AS_USER (1<<0)
1064 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1065 #define TIME_INIT (1<<2)
1066 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1067 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1068 #define DO_CHDIR (1<<6)
1071 define a list of possible SMB messages and their corresponding
1072 functions. Any message that has a NULL function is unimplemented -
1073 please feel free to contribute implementations!
1075 static const struct smb_message_struct {
1077 void (*fn)(struct smb_request *req);
1079 } smb_messages[256] = {
1081 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1082 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1083 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1084 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1085 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1086 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1087 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1088 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1089 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1090 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1091 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1092 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1093 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1094 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1095 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1096 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1097 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1098 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1099 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1100 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1101 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1102 /* 0x15 */ { NULL, NULL, 0 },
1103 /* 0x16 */ { NULL, NULL, 0 },
1104 /* 0x17 */ { NULL, NULL, 0 },
1105 /* 0x18 */ { NULL, NULL, 0 },
1106 /* 0x19 */ { NULL, NULL, 0 },
1107 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1108 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1109 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1110 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1111 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1112 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1113 /* 0x20 */ { "SMBwritec", NULL,0},
1114 /* 0x21 */ { NULL, NULL, 0 },
1115 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1116 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1117 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1118 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1119 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1120 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1121 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1122 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1123 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1124 /* 0x2b */ { "SMBecho",reply_echo,0},
1125 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1126 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1127 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1128 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1129 /* 0x30 */ { NULL, NULL, 0 },
1130 /* 0x31 */ { NULL, NULL, 0 },
1131 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1132 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1133 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1134 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1135 /* 0x36 */ { NULL, NULL, 0 },
1136 /* 0x37 */ { NULL, NULL, 0 },
1137 /* 0x38 */ { NULL, NULL, 0 },
1138 /* 0x39 */ { NULL, NULL, 0 },
1139 /* 0x3a */ { NULL, NULL, 0 },
1140 /* 0x3b */ { NULL, NULL, 0 },
1141 /* 0x3c */ { NULL, NULL, 0 },
1142 /* 0x3d */ { NULL, NULL, 0 },
1143 /* 0x3e */ { NULL, NULL, 0 },
1144 /* 0x3f */ { NULL, NULL, 0 },
1145 /* 0x40 */ { NULL, NULL, 0 },
1146 /* 0x41 */ { NULL, NULL, 0 },
1147 /* 0x42 */ { NULL, NULL, 0 },
1148 /* 0x43 */ { NULL, NULL, 0 },
1149 /* 0x44 */ { NULL, NULL, 0 },
1150 /* 0x45 */ { NULL, NULL, 0 },
1151 /* 0x46 */ { NULL, NULL, 0 },
1152 /* 0x47 */ { NULL, NULL, 0 },
1153 /* 0x48 */ { NULL, NULL, 0 },
1154 /* 0x49 */ { NULL, NULL, 0 },
1155 /* 0x4a */ { NULL, NULL, 0 },
1156 /* 0x4b */ { NULL, NULL, 0 },
1157 /* 0x4c */ { NULL, NULL, 0 },
1158 /* 0x4d */ { NULL, NULL, 0 },
1159 /* 0x4e */ { NULL, NULL, 0 },
1160 /* 0x4f */ { NULL, NULL, 0 },
1161 /* 0x50 */ { NULL, NULL, 0 },
1162 /* 0x51 */ { NULL, NULL, 0 },
1163 /* 0x52 */ { NULL, NULL, 0 },
1164 /* 0x53 */ { NULL, NULL, 0 },
1165 /* 0x54 */ { NULL, NULL, 0 },
1166 /* 0x55 */ { NULL, NULL, 0 },
1167 /* 0x56 */ { NULL, NULL, 0 },
1168 /* 0x57 */ { NULL, NULL, 0 },
1169 /* 0x58 */ { NULL, NULL, 0 },
1170 /* 0x59 */ { NULL, NULL, 0 },
1171 /* 0x5a */ { NULL, NULL, 0 },
1172 /* 0x5b */ { NULL, NULL, 0 },
1173 /* 0x5c */ { NULL, NULL, 0 },
1174 /* 0x5d */ { NULL, NULL, 0 },
1175 /* 0x5e */ { NULL, NULL, 0 },
1176 /* 0x5f */ { NULL, NULL, 0 },
1177 /* 0x60 */ { NULL, NULL, 0 },
1178 /* 0x61 */ { NULL, NULL, 0 },
1179 /* 0x62 */ { NULL, NULL, 0 },
1180 /* 0x63 */ { NULL, NULL, 0 },
1181 /* 0x64 */ { NULL, NULL, 0 },
1182 /* 0x65 */ { NULL, NULL, 0 },
1183 /* 0x66 */ { NULL, NULL, 0 },
1184 /* 0x67 */ { NULL, NULL, 0 },
1185 /* 0x68 */ { NULL, NULL, 0 },
1186 /* 0x69 */ { NULL, NULL, 0 },
1187 /* 0x6a */ { NULL, NULL, 0 },
1188 /* 0x6b */ { NULL, NULL, 0 },
1189 /* 0x6c */ { NULL, NULL, 0 },
1190 /* 0x6d */ { NULL, NULL, 0 },
1191 /* 0x6e */ { NULL, NULL, 0 },
1192 /* 0x6f */ { NULL, NULL, 0 },
1193 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1194 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1195 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1196 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1197 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1198 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1199 /* 0x76 */ { NULL, NULL, 0 },
1200 /* 0x77 */ { NULL, NULL, 0 },
1201 /* 0x78 */ { NULL, NULL, 0 },
1202 /* 0x79 */ { NULL, NULL, 0 },
1203 /* 0x7a */ { NULL, NULL, 0 },
1204 /* 0x7b */ { NULL, NULL, 0 },
1205 /* 0x7c */ { NULL, NULL, 0 },
1206 /* 0x7d */ { NULL, NULL, 0 },
1207 /* 0x7e */ { NULL, NULL, 0 },
1208 /* 0x7f */ { NULL, NULL, 0 },
1209 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1210 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1211 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1212 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1213 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1214 /* 0x85 */ { NULL, NULL, 0 },
1215 /* 0x86 */ { NULL, NULL, 0 },
1216 /* 0x87 */ { NULL, NULL, 0 },
1217 /* 0x88 */ { NULL, NULL, 0 },
1218 /* 0x89 */ { NULL, NULL, 0 },
1219 /* 0x8a */ { NULL, NULL, 0 },
1220 /* 0x8b */ { NULL, NULL, 0 },
1221 /* 0x8c */ { NULL, NULL, 0 },
1222 /* 0x8d */ { NULL, NULL, 0 },
1223 /* 0x8e */ { NULL, NULL, 0 },
1224 /* 0x8f */ { NULL, NULL, 0 },
1225 /* 0x90 */ { NULL, NULL, 0 },
1226 /* 0x91 */ { NULL, NULL, 0 },
1227 /* 0x92 */ { NULL, NULL, 0 },
1228 /* 0x93 */ { NULL, NULL, 0 },
1229 /* 0x94 */ { NULL, NULL, 0 },
1230 /* 0x95 */ { NULL, NULL, 0 },
1231 /* 0x96 */ { NULL, NULL, 0 },
1232 /* 0x97 */ { NULL, NULL, 0 },
1233 /* 0x98 */ { NULL, NULL, 0 },
1234 /* 0x99 */ { NULL, NULL, 0 },
1235 /* 0x9a */ { NULL, NULL, 0 },
1236 /* 0x9b */ { NULL, NULL, 0 },
1237 /* 0x9c */ { NULL, NULL, 0 },
1238 /* 0x9d */ { NULL, NULL, 0 },
1239 /* 0x9e */ { NULL, NULL, 0 },
1240 /* 0x9f */ { NULL, NULL, 0 },
1241 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1242 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1243 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1244 /* 0xa3 */ { NULL, NULL, 0 },
1245 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1246 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1247 /* 0xa6 */ { NULL, NULL, 0 },
1248 /* 0xa7 */ { NULL, NULL, 0 },
1249 /* 0xa8 */ { NULL, NULL, 0 },
1250 /* 0xa9 */ { NULL, NULL, 0 },
1251 /* 0xaa */ { NULL, NULL, 0 },
1252 /* 0xab */ { NULL, NULL, 0 },
1253 /* 0xac */ { NULL, NULL, 0 },
1254 /* 0xad */ { NULL, NULL, 0 },
1255 /* 0xae */ { NULL, NULL, 0 },
1256 /* 0xaf */ { NULL, NULL, 0 },
1257 /* 0xb0 */ { NULL, NULL, 0 },
1258 /* 0xb1 */ { NULL, NULL, 0 },
1259 /* 0xb2 */ { NULL, NULL, 0 },
1260 /* 0xb3 */ { NULL, NULL, 0 },
1261 /* 0xb4 */ { NULL, NULL, 0 },
1262 /* 0xb5 */ { NULL, NULL, 0 },
1263 /* 0xb6 */ { NULL, NULL, 0 },
1264 /* 0xb7 */ { NULL, NULL, 0 },
1265 /* 0xb8 */ { NULL, NULL, 0 },
1266 /* 0xb9 */ { NULL, NULL, 0 },
1267 /* 0xba */ { NULL, NULL, 0 },
1268 /* 0xbb */ { NULL, NULL, 0 },
1269 /* 0xbc */ { NULL, NULL, 0 },
1270 /* 0xbd */ { NULL, NULL, 0 },
1271 /* 0xbe */ { NULL, NULL, 0 },
1272 /* 0xbf */ { NULL, NULL, 0 },
1273 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1274 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1275 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1276 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1277 /* 0xc4 */ { NULL, NULL, 0 },
1278 /* 0xc5 */ { NULL, NULL, 0 },
1279 /* 0xc6 */ { NULL, NULL, 0 },
1280 /* 0xc7 */ { NULL, NULL, 0 },
1281 /* 0xc8 */ { NULL, NULL, 0 },
1282 /* 0xc9 */ { NULL, NULL, 0 },
1283 /* 0xca */ { NULL, NULL, 0 },
1284 /* 0xcb */ { NULL, NULL, 0 },
1285 /* 0xcc */ { NULL, NULL, 0 },
1286 /* 0xcd */ { NULL, NULL, 0 },
1287 /* 0xce */ { NULL, NULL, 0 },
1288 /* 0xcf */ { NULL, NULL, 0 },
1289 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1290 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1291 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1292 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1293 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1294 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1295 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1296 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1297 /* 0xd8 */ { NULL, NULL, 0 },
1298 /* 0xd9 */ { NULL, NULL, 0 },
1299 /* 0xda */ { NULL, NULL, 0 },
1300 /* 0xdb */ { NULL, NULL, 0 },
1301 /* 0xdc */ { NULL, NULL, 0 },
1302 /* 0xdd */ { NULL, NULL, 0 },
1303 /* 0xde */ { NULL, NULL, 0 },
1304 /* 0xdf */ { NULL, NULL, 0 },
1305 /* 0xe0 */ { NULL, NULL, 0 },
1306 /* 0xe1 */ { NULL, NULL, 0 },
1307 /* 0xe2 */ { NULL, NULL, 0 },
1308 /* 0xe3 */ { NULL, NULL, 0 },
1309 /* 0xe4 */ { NULL, NULL, 0 },
1310 /* 0xe5 */ { NULL, NULL, 0 },
1311 /* 0xe6 */ { NULL, NULL, 0 },
1312 /* 0xe7 */ { NULL, NULL, 0 },
1313 /* 0xe8 */ { NULL, NULL, 0 },
1314 /* 0xe9 */ { NULL, NULL, 0 },
1315 /* 0xea */ { NULL, NULL, 0 },
1316 /* 0xeb */ { NULL, NULL, 0 },
1317 /* 0xec */ { NULL, NULL, 0 },
1318 /* 0xed */ { NULL, NULL, 0 },
1319 /* 0xee */ { NULL, NULL, 0 },
1320 /* 0xef */ { NULL, NULL, 0 },
1321 /* 0xf0 */ { NULL, NULL, 0 },
1322 /* 0xf1 */ { NULL, NULL, 0 },
1323 /* 0xf2 */ { NULL, NULL, 0 },
1324 /* 0xf3 */ { NULL, NULL, 0 },
1325 /* 0xf4 */ { NULL, NULL, 0 },
1326 /* 0xf5 */ { NULL, NULL, 0 },
1327 /* 0xf6 */ { NULL, NULL, 0 },
1328 /* 0xf7 */ { NULL, NULL, 0 },
1329 /* 0xf8 */ { NULL, NULL, 0 },
1330 /* 0xf9 */ { NULL, NULL, 0 },
1331 /* 0xfa */ { NULL, NULL, 0 },
1332 /* 0xfb */ { NULL, NULL, 0 },
1333 /* 0xfc */ { NULL, NULL, 0 },
1334 /* 0xfd */ { NULL, NULL, 0 },
1335 /* 0xfe */ { NULL, NULL, 0 },
1336 /* 0xff */ { NULL, NULL, 0 }
1340 /*******************************************************************
1341 allocate and initialize a reply packet
1342 ********************************************************************/
1344 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1345 const uint8_t *inbuf, char **outbuf,
1346 uint8_t num_words, uint32_t num_bytes)
1348 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1351 * Protect against integer wrap.
1352 * The SMB layer reply can be up to 0xFFFFFF bytes.
1354 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1356 if (asprintf(&msg, "num_bytes too large: %u",
1357 (unsigned)num_bytes) == -1) {
1358 msg = discard_const_p(char, "num_bytes too large");
1364 * Here we include the NBT header for now.
1366 *outbuf = talloc_array(mem_ctx, char,
1367 NBT_HDR_SIZE + smb_len);
1368 if (*outbuf == NULL) {
1372 construct_reply_common(req->cmd, inbuf, *outbuf);
1373 srv_set_message(*outbuf, num_words, num_bytes, false);
1375 * Zero out the word area, the caller has to take care of the bcc area
1378 if (num_words != 0) {
1379 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1385 void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1388 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1390 smb_panic("could not allocate output buffer\n");
1392 req->outbuf = (uint8_t *)outbuf;
1396 /*******************************************************************
1397 Dump a packet to a file.
1398 ********************************************************************/
1400 static void smb_dump(const char *name, int type, const char *data)
1405 if (DEBUGLEVEL < 50) {
1409 len = smb_len_tcp(data)+4;
1410 for (i=1;i<100;i++) {
1411 fname = talloc_asprintf(talloc_tos(),
1415 type ? "req" : "resp");
1416 if (fname == NULL) {
1419 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1420 if (fd != -1 || errno != EEXIST) break;
1424 ssize_t ret = write(fd, data, len);
1426 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1428 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1433 static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
1434 struct smb_request *req,
1436 bool *update_session_globalp,
1437 bool *update_tcon_globalp)
1439 connection_struct *conn = req->conn;
1440 struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
1441 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
1442 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1443 bool update_session = false;
1444 bool update_tcon = false;
1446 if (req->encrypted) {
1447 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
1450 if (srv_is_signing_active(req->xconn)) {
1451 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
1452 } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
1454 * echo can be unsigned. Sesssion setup except final
1455 * session setup response too
1457 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1460 update_session |= smbXsrv_set_crypto_flag(
1461 &session->global->encryption_flags, encrypt_flag);
1462 update_session |= smbXsrv_set_crypto_flag(
1463 &session->global->signing_flags, sign_flag);
1466 update_tcon |= smbXsrv_set_crypto_flag(
1467 &tcon->global->encryption_flags, encrypt_flag);
1468 update_tcon |= smbXsrv_set_crypto_flag(
1469 &tcon->global->signing_flags, sign_flag);
1472 if (update_session) {
1473 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1476 *update_session_globalp = update_session;
1477 *update_tcon_globalp = update_tcon;
1481 /****************************************************************************
1482 Prepare everything for calling the actual request function, and potentially
1483 call the request function via the "new" interface.
1485 Return False if the "legacy" function needs to be called, everything is
1488 Return True if we're done.
1490 I know this API sucks, but it is the one with the least code change I could
1492 ****************************************************************************/
1494 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1497 uint64_t session_tag;
1498 connection_struct *conn = NULL;
1499 struct smbXsrv_connection *xconn = req->xconn;
1500 NTTIME now = timeval_to_nttime(&req->request_time);
1501 struct smbXsrv_session *session = NULL;
1506 if (!xconn->smb1.negprot.done) {
1509 * Without a negprot the request must
1510 * either be a negprot, or one of the
1511 * evil old SMB mailslot messaging types.
1519 exit_server_cleanly("The first request "
1520 "should be a negprot");
1524 if (smb_messages[type].fn == NULL) {
1525 DEBUG(0,("Unknown message type %d!\n",type));
1526 smb_dump("Unknown", 1, (const char *)req->inbuf);
1527 reply_unknown_new(req, type);
1531 flags = smb_messages[type].flags;
1533 /* In share mode security we must ignore the vuid. */
1534 session_tag = req->vuid;
1537 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1538 (int)getpid(), (unsigned long)conn));
1540 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1542 /* Ensure this value is replaced in the incoming packet. */
1543 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1546 * Ensure the correct username is in current_user_info. This is a
1547 * really ugly bugfix for problems with multiple session_setup_and_X's
1548 * being done and allowing %U and %G substitutions to work correctly.
1549 * There is a reason this code is done here, don't move it unless you
1550 * know what you're doing... :-).
1555 * lookup an existing session
1557 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1558 * here, the main check is still in change_to_user()
1560 status = smb1srv_session_lookup(xconn,
1564 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1567 status = NT_STATUS_OK;
1570 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1571 (unsigned long long)session_tag,
1572 (unsigned long long)req->mid));
1573 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1578 if (session_tag != xconn->client->last_session_id) {
1579 struct user_struct *vuser = NULL;
1581 xconn->client->last_session_id = session_tag;
1583 vuser = session->compat;
1586 set_current_user_info(
1587 vuser->session_info->unix_info->sanitized_username,
1588 vuser->session_info->unix_info->unix_name,
1589 vuser->session_info->info->domain_name);
1593 /* Does this call need to be run as the connected user? */
1594 if (flags & AS_USER) {
1596 /* Does this call need a valid tree connection? */
1599 * Amazingly, the error code depends on the command
1602 if (type == SMBntcreateX) {
1603 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1605 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1610 if (!change_to_user(conn,session_tag)) {
1611 DEBUG(0, ("Error: Could not change to user. Removing "
1612 "deferred open, mid=%llu.\n",
1613 (unsigned long long)req->mid));
1614 reply_force_doserror(req, ERRSRV, ERRbaduid);
1618 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1620 /* Does it need write permission? */
1621 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1622 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1626 /* IPC services are limited */
1627 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1628 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1632 /* This call needs to be run as root */
1633 change_to_root_user();
1636 /* load service specific parameters */
1638 if (req->encrypted) {
1639 conn->encrypted_tid = true;
1640 /* encrypted required from now on. */
1641 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1642 } else if (ENCRYPTION_REQUIRED(conn)) {
1643 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1644 DEBUG(1,("service[%s] requires encryption"
1645 "%s ACCESS_DENIED. mid=%llu\n",
1646 lp_servicename(talloc_tos(), SNUM(conn)),
1648 (unsigned long long)req->mid));
1649 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1654 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1655 (flags & (AS_USER|DO_CHDIR)
1657 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1660 conn->num_smb_operations++;
1664 * Does this protocol need to be run as guest? (Only archane
1665 * messenger service requests have this...)
1667 if (flags & AS_GUEST) {
1671 if (!change_to_guest()) {
1672 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1676 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1678 if (raddr == NULL) {
1679 reply_nterror(req, NT_STATUS_NO_MEMORY);
1684 * Haven't we checked this in smbd_process already???
1687 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1688 xconn->remote_hostname, raddr);
1692 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1698 * Update encryption and signing state tracking flags that are
1699 * used by smbstatus to display signing and encryption status.
1701 if (session != NULL) {
1702 bool update_session_global = false;
1703 bool update_tcon_global = false;
1705 smb1srv_update_crypto_flags(session, req, type,
1706 &update_session_global,
1707 &update_tcon_global);
1709 if (update_session_global) {
1710 status = smbXsrv_session_update(session);
1711 if (!NT_STATUS_IS_OK(status)) {
1712 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1717 if (update_tcon_global) {
1718 status = smbXsrv_tcon_update(req->conn->tcon);
1719 if (!NT_STATUS_IS_OK(status)) {
1720 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1726 smb_messages[type].fn(req);
1730 /****************************************************************************
1731 Construct a reply to the incoming packet.
1732 ****************************************************************************/
1734 static void construct_reply(struct smbXsrv_connection *xconn,
1735 char *inbuf, int size, size_t unread_bytes,
1736 uint32_t seqnum, bool encrypted,
1737 struct smb_perfcount_data *deferred_pcd)
1739 struct smbd_server_connection *sconn = xconn->client->sconn;
1740 struct smb_request *req;
1742 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1743 smb_panic("could not allocate smb_request");
1746 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1747 encrypted, seqnum)) {
1748 exit_server_cleanly("Invalid SMB request");
1751 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1753 /* we popped this message off the queue - keep original perf data */
1755 req->pcd = *deferred_pcd;
1757 SMB_PERFCOUNT_START(&req->pcd);
1758 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1759 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1762 req->conn = switch_message(req->cmd, req);
1764 if (req->outbuf == NULL) {
1766 * Request has suspended itself, will come
1771 if (CVAL(req->outbuf,0) == 0) {
1772 show_msg((char *)req->outbuf);
1774 smb_request_done(req);
1777 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1778 char *inbuf, int size, uint32_t seqnum,
1780 struct smb_perfcount_data *deferred_pcd)
1782 struct smb_request **reqs = NULL;
1783 struct smb_request *req;
1787 ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
1788 seqnum, &reqs, &num_reqs);
1790 char errbuf[smb_size];
1791 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1792 __LINE__, __FILE__);
1793 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1795 exit_server_cleanly("construct_reply_chain: "
1796 "srv_send_smb failed.");
1802 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1804 req->conn = switch_message(req->cmd, req);
1806 if (req->outbuf == NULL) {
1808 * Request has suspended itself, will come
1813 smb_request_done(req);
1817 * To be called from an async SMB handler that is potentially chained
1818 * when it is finished for shipping.
1821 void smb_request_done(struct smb_request *req)
1823 struct smb_request **reqs = NULL;
1824 struct smb_request *first_req;
1825 size_t i, num_reqs, next_index;
1828 if (req->chain == NULL) {
1834 num_reqs = talloc_array_length(reqs);
1836 for (i=0; i<num_reqs; i++) {
1837 if (reqs[i] == req) {
1841 if (i == num_reqs) {
1843 * Invalid chain, should not happen
1845 status = NT_STATUS_INTERNAL_ERROR;
1850 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1851 struct smb_request *next = reqs[next_index];
1852 struct smbXsrv_tcon *tcon;
1853 NTTIME now = timeval_to_nttime(&req->request_time);
1855 next->vuid = SVAL(req->outbuf, smb_uid);
1856 next->tid = SVAL(req->outbuf, smb_tid);
1857 status = smb1srv_tcon_lookup(req->xconn, next->tid,
1860 if (NT_STATUS_IS_OK(status)) {
1861 next->conn = tcon->compat;
1865 next->chain_fsp = req->chain_fsp;
1866 next->inbuf = req->inbuf;
1869 req->conn = switch_message(req->cmd, req);
1871 if (req->outbuf == NULL) {
1873 * Request has suspended itself, will come
1881 first_req = reqs[0];
1883 for (i=1; i<next_index; i++) {
1886 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1888 status = NT_STATUS_INTERNAL_ERROR;
1893 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1894 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1897 * This scary statement intends to set the
1898 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1899 * to the value last_req->outbuf carries
1901 SSVAL(first_req->outbuf, smb_flg2,
1902 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1903 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1906 * Transfer the error codes from the subrequest to the main one
1908 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1909 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1912 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1915 if (!srv_send_smb(first_req->xconn,
1916 (char *)first_req->outbuf,
1917 true, first_req->seqnum+1,
1918 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1920 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1923 TALLOC_FREE(req); /* non-chained case */
1924 TALLOC_FREE(reqs); /* chained case */
1929 char errbuf[smb_size];
1930 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1931 if (!srv_send_smb(req->xconn, errbuf, true,
1932 req->seqnum+1, req->encrypted,
1934 exit_server_cleanly("construct_reply_chain: "
1935 "srv_send_smb failed.");
1938 TALLOC_FREE(req); /* non-chained case */
1939 TALLOC_FREE(reqs); /* chained case */
1942 /****************************************************************************
1943 Process an smb from the client
1944 ****************************************************************************/
1945 static void process_smb(struct smbXsrv_connection *xconn,
1946 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1947 uint32_t seqnum, bool encrypted,
1948 struct smb_perfcount_data *deferred_pcd)
1950 struct smbd_server_connection *sconn = xconn->client->sconn;
1951 int msg_type = CVAL(inbuf,0);
1953 DO_PROFILE_INC(request);
1955 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1957 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1958 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1960 if (msg_type != NBSSmessage) {
1962 * NetBIOS session request, keepalive, etc.
1964 reply_special(xconn, (char *)inbuf, nread);
1968 if (sconn->using_smb2) {
1969 /* At this point we're not really using smb2,
1970 * we make the decision here.. */
1971 if (smbd_is_smb2_header(inbuf, nread)) {
1972 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1973 size_t pdulen = nread - NBT_HDR_SIZE;
1974 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1977 if (nread >= smb_size && valid_smb_header(inbuf)
1978 && CVAL(inbuf, smb_com) != 0x72) {
1979 /* This is a non-negprot SMB1 packet.
1980 Disable SMB2 from now on. */
1981 sconn->using_smb2 = false;
1985 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1986 * so subtract 4 from it. */
1987 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1988 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1991 /* special magic for immediate exit */
1993 (IVAL(inbuf, 4) == 0x74697865) &&
1994 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1995 uint8_t exitcode = CVAL(inbuf, 8);
1996 DEBUG(1, ("Exiting immediately with code %d\n",
2001 exit_server_cleanly("Non-SMB packet");
2004 show_msg((char *)inbuf);
2006 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
2007 construct_reply_chain(xconn, (char *)inbuf, nread,
2008 seqnum, encrypted, deferred_pcd);
2010 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
2011 seqnum, encrypted, deferred_pcd);
2017 sconn->num_requests++;
2019 /* The timeout_processing function isn't run nearly
2020 often enough to implement 'max log size' without
2021 overrunning the size of the file by many megabytes.
2022 This is especially true if we are running at debug
2023 level 10. Checking every 50 SMBs is a nice
2024 tradeoff of performance vs log file size overrun. */
2026 if ((sconn->num_requests % 50) == 0 &&
2027 need_to_check_log_size()) {
2028 change_to_root_user();
2033 /****************************************************************************
2034 Return a string containing the function name of a SMB command.
2035 ****************************************************************************/
2037 const char *smb_fn_name(int type)
2039 const char *unknown_name = "SMBunknown";
2041 if (smb_messages[type].name == NULL)
2042 return(unknown_name);
2044 return(smb_messages[type].name);
2047 /****************************************************************************
2048 Helper functions for contruct_reply.
2049 ****************************************************************************/
2051 void add_to_common_flags2(uint32_t v)
2056 void remove_from_common_flags2(uint32_t v)
2058 common_flags2 &= ~v;
2061 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
2064 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
2065 uint16_t out_flags2 = common_flags2;
2067 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
2068 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
2069 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
2071 srv_set_message(outbuf,0,0,false);
2073 SCVAL(outbuf, smb_com, cmd);
2074 SIVAL(outbuf,smb_rcls,0);
2075 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
2076 SSVAL(outbuf,smb_flg2, out_flags2);
2077 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
2078 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2080 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2081 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2082 SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
2083 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2084 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2087 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2089 construct_reply_common(req->cmd, req->inbuf, outbuf);
2093 * @brief Find the smb_cmd offset of the last command pushed
2094 * @param[in] buf The buffer we're building up
2095 * @retval Where can we put our next andx cmd?
2097 * While chaining requests, the "next" request we're looking at needs to put
2098 * its SMB_Command before the data the previous request already built up added
2099 * to the chain. Find the offset to the place where we have to put our cmd.
2102 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2107 cmd = CVAL(buf, smb_com);
2109 if (!is_andx_req(cmd)) {
2115 while (CVAL(buf, ofs) != 0xff) {
2117 if (!is_andx_req(CVAL(buf, ofs))) {
2122 * ofs is from start of smb header, so add the 4 length
2123 * bytes. The next cmd is right after the wct field.
2125 ofs = SVAL(buf, ofs+2) + 4 + 1;
2127 if (ofs+4 >= talloc_get_size(buf)) {
2137 * @brief Do the smb chaining at a buffer level
2138 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2139 * @param[in] andx_buf Buffer to be appended
2142 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2144 uint8_t smb_command = CVAL(andx_buf, smb_com);
2145 uint8_t wct = CVAL(andx_buf, smb_wct);
2146 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2147 uint32_t num_bytes = smb_buflen(andx_buf);
2148 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2151 size_t old_size, new_size;
2153 size_t chain_padding = 0;
2154 size_t andx_cmd_ofs;
2157 old_size = talloc_get_size(*poutbuf);
2159 if ((old_size % 4) != 0) {
2161 * Align the wct field of subsequent requests to a 4-byte
2164 chain_padding = 4 - (old_size % 4);
2168 * After the old request comes the new wct field (1 byte), the vwv's
2169 * and the num_bytes field.
2172 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2173 new_size += num_bytes;
2175 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2176 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2177 (unsigned)new_size));
2181 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2182 if (outbuf == NULL) {
2183 DEBUG(0, ("talloc failed\n"));
2188 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2189 DEBUG(1, ("invalid command chain\n"));
2190 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2194 if (chain_padding != 0) {
2195 memset(outbuf + old_size, 0, chain_padding);
2196 old_size += chain_padding;
2199 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2200 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2205 * Push the chained request:
2210 SCVAL(outbuf, ofs, wct);
2217 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2222 * Read&X has an offset into its data buffer at
2223 * vwv[6]. reply_read_andx has no idea anymore that it's
2224 * running from within a chain, so we have to fix up the
2227 * Although it looks disgusting at this place, I want to keep
2228 * it here. The alternative would be to push knowledge about
2229 * the andx chain down into read&x again.
2232 if (smb_command == SMBreadX) {
2233 uint8_t *bytes_addr;
2237 * Invalid read&x response
2242 bytes_addr = outbuf + ofs /* vwv start */
2243 + sizeof(uint16_t) * wct /* vwv array */
2244 + sizeof(uint16_t) /* bcc */
2245 + 1; /* padding byte */
2247 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2248 bytes_addr - outbuf - 4);
2251 ofs += sizeof(uint16_t) * wct;
2257 SSVAL(outbuf, ofs, num_bytes);
2258 ofs += sizeof(uint16_t);
2264 memcpy(outbuf + ofs, bytes, num_bytes);
2269 bool smb1_is_chain(const uint8_t *buf)
2271 uint8_t cmd, wct, andx_cmd;
2273 cmd = CVAL(buf, smb_com);
2274 if (!is_andx_req(cmd)) {
2277 wct = CVAL(buf, smb_wct);
2281 andx_cmd = CVAL(buf, smb_vwv);
2282 return (andx_cmd != 0xFF);
2285 bool smb1_walk_chain(const uint8_t *buf,
2286 bool (*fn)(uint8_t cmd,
2287 uint8_t wct, const uint16_t *vwv,
2288 uint16_t num_bytes, const uint8_t *bytes,
2289 void *private_data),
2292 size_t smblen = smb_len(buf);
2293 const char *smb_buf = smb_base(buf);
2294 uint8_t cmd, chain_cmd;
2296 const uint16_t *vwv;
2298 const uint8_t *bytes;
2300 cmd = CVAL(buf, smb_com);
2301 wct = CVAL(buf, smb_wct);
2302 vwv = (const uint16_t *)(buf + smb_vwv);
2303 num_bytes = smb_buflen(buf);
2304 bytes = (const uint8_t *)smb_buf_const(buf);
2306 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2310 if (!is_andx_req(cmd)) {
2317 chain_cmd = CVAL(vwv, 0);
2319 while (chain_cmd != 0xff) {
2320 uint32_t chain_offset; /* uint32_t to avoid overflow */
2321 size_t length_needed;
2322 ptrdiff_t vwv_offset;
2324 chain_offset = SVAL(vwv+1, 0);
2327 * Check if the client tries to fool us. The chain
2328 * offset needs to point beyond the current request in
2329 * the chain, it needs to strictly grow. Otherwise we
2330 * might be tricked into an endless loop always
2331 * processing the same request over and over again. We
2332 * used to assume that vwv and the byte buffer array
2333 * in a chain are always attached, but OS/2 the
2334 * Write&X/Read&X chain puts the Read&X vwv array
2335 * right behind the Write&X vwv chain. The Write&X bcc
2336 * array is put behind the Read&X vwv array. So now we
2337 * check whether the chain offset points strictly
2338 * behind the previous vwv array. req->buf points
2339 * right after the vwv array of the previous
2341 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2345 vwv_offset = ((const char *)vwv - smb_buf);
2346 if (chain_offset <= vwv_offset) {
2351 * Next check: Make sure the chain offset does not
2352 * point beyond the overall smb request length.
2355 length_needed = chain_offset+1; /* wct */
2356 if (length_needed > smblen) {
2361 * Now comes the pointer magic. Goal here is to set up
2362 * vwv and buf correctly again. The chain offset (the
2363 * former vwv[1]) points at the new wct field.
2366 wct = CVAL(smb_buf, chain_offset);
2368 if (is_andx_req(chain_cmd) && (wct < 2)) {
2373 * Next consistency check: Make the new vwv array fits
2374 * in the overall smb request.
2377 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2378 if (length_needed > smblen) {
2381 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2384 * Now grab the new byte buffer....
2387 num_bytes = SVAL(vwv+wct, 0);
2390 * .. and check that it fits.
2393 length_needed += num_bytes;
2394 if (length_needed > smblen) {
2397 bytes = (const uint8_t *)(vwv+wct+1);
2399 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2403 if (!is_andx_req(chain_cmd)) {
2406 chain_cmd = CVAL(vwv, 0);
2411 static bool smb1_chain_length_cb(uint8_t cmd,
2412 uint8_t wct, const uint16_t *vwv,
2413 uint16_t num_bytes, const uint8_t *bytes,
2416 unsigned *count = (unsigned *)private_data;
2421 unsigned smb1_chain_length(const uint8_t *buf)
2425 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2431 struct smb1_parse_chain_state {
2432 TALLOC_CTX *mem_ctx;
2434 struct smbd_server_connection *sconn;
2435 struct smbXsrv_connection *xconn;
2439 struct smb_request **reqs;
2443 static bool smb1_parse_chain_cb(uint8_t cmd,
2444 uint8_t wct, const uint16_t *vwv,
2445 uint16_t num_bytes, const uint8_t *bytes,
2448 struct smb1_parse_chain_state *state =
2449 (struct smb1_parse_chain_state *)private_data;
2450 struct smb_request **reqs;
2451 struct smb_request *req;
2454 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2455 struct smb_request *, state->num_reqs+1);
2461 req = talloc(reqs, struct smb_request);
2466 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2467 state->encrypted, state->seqnum);
2474 req->buflen = num_bytes;
2477 reqs[state->num_reqs] = req;
2478 state->num_reqs += 1;
2482 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2483 struct smbXsrv_connection *xconn,
2484 bool encrypted, uint32_t seqnum,
2485 struct smb_request ***reqs, unsigned *num_reqs)
2487 struct smbd_server_connection *sconn = NULL;
2488 struct smb1_parse_chain_state state;
2491 if (xconn != NULL) {
2492 sconn = xconn->client->sconn;
2495 state.mem_ctx = mem_ctx;
2497 state.sconn = sconn;
2498 state.xconn = xconn;
2499 state.encrypted = encrypted;
2500 state.seqnum = seqnum;
2504 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2505 TALLOC_FREE(state.reqs);
2508 for (i=0; i<state.num_reqs; i++) {
2509 state.reqs[i]->chain = state.reqs;
2512 *num_reqs = state.num_reqs;
2516 /****************************************************************************
2517 Check if services need reloading.
2518 ****************************************************************************/
2520 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2523 if (last_smb_conf_reload_time == 0) {
2524 last_smb_conf_reload_time = t;
2527 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2528 reload_services(sconn, conn_snum_used, true);
2529 last_smb_conf_reload_time = t;
2533 static bool fd_is_readable(int fd)
2537 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2539 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2543 static void smbd_server_connection_write_handler(
2544 struct smbXsrv_connection *xconn)
2546 /* TODO: make write nonblocking */
2549 static void smbd_server_connection_read_handler(
2550 struct smbXsrv_connection *xconn, int fd)
2552 uint8_t *inbuf = NULL;
2553 size_t inbuf_len = 0;
2554 size_t unread_bytes = 0;
2555 bool encrypted = false;
2556 TALLOC_CTX *mem_ctx = talloc_tos();
2560 bool async_echo = lp_async_smb_echo_handler();
2561 bool from_client = false;
2564 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2566 * This is the super-ugly hack to prefer the packets
2567 * forwarded by the echo handler over the ones by the
2570 fd = xconn->smb1.echo_handler.trusted_fd;
2574 from_client = (xconn->transport.sock == fd);
2576 if (async_echo && from_client) {
2577 smbd_lock_socket(xconn);
2579 if (!fd_is_readable(fd)) {
2580 DEBUG(10,("the echo listener was faster\n"));
2581 smbd_unlock_socket(xconn);
2586 /* TODO: make this completely nonblocking */
2587 status = receive_smb_talloc(mem_ctx, xconn, fd,
2588 (char **)(void *)&inbuf,
2592 &inbuf_len, &seqnum,
2593 !from_client /* trusted channel */);
2595 if (async_echo && from_client) {
2596 smbd_unlock_socket(xconn);
2599 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2602 if (NT_STATUS_IS_ERR(status)) {
2603 exit_server_cleanly("failed to receive smb request");
2605 if (!NT_STATUS_IS_OK(status)) {
2610 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2611 seqnum, encrypted, NULL);
2614 static void smbd_server_connection_handler(struct tevent_context *ev,
2615 struct tevent_fd *fde,
2619 struct smbXsrv_connection *xconn =
2620 talloc_get_type_abort(private_data,
2621 struct smbXsrv_connection);
2623 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2625 * we're not supposed to do any io
2627 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2628 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2632 if (flags & TEVENT_FD_WRITE) {
2633 smbd_server_connection_write_handler(xconn);
2636 if (flags & TEVENT_FD_READ) {
2637 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2642 static void smbd_server_echo_handler(struct tevent_context *ev,
2643 struct tevent_fd *fde,
2647 struct smbXsrv_connection *xconn =
2648 talloc_get_type_abort(private_data,
2649 struct smbXsrv_connection);
2651 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2653 * we're not supposed to do any io
2655 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2656 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2660 if (flags & TEVENT_FD_WRITE) {
2661 smbd_server_connection_write_handler(xconn);
2664 if (flags & TEVENT_FD_READ) {
2665 smbd_server_connection_read_handler(
2666 xconn, xconn->smb1.echo_handler.trusted_fd);
2671 struct smbd_release_ip_state {
2672 struct smbXsrv_connection *xconn;
2673 struct tevent_immediate *im;
2674 char addr[INET6_ADDRSTRLEN];
2677 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2678 struct tevent_immediate *im,
2681 struct smbd_release_ip_state *state =
2682 talloc_get_type_abort(private_data,
2683 struct smbd_release_ip_state);
2684 struct smbXsrv_connection *xconn = state->xconn;
2686 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2688 * smbd_server_connection_terminate() already triggered ?
2693 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2696 /****************************************************************************
2697 received when we should release a specific IP
2698 ****************************************************************************/
2699 static int release_ip(struct tevent_context *ev,
2700 uint32_t src_vnn, uint32_t dst_vnn,
2702 const uint8_t *msg, size_t msglen,
2705 struct smbd_release_ip_state *state =
2706 talloc_get_type_abort(private_data,
2707 struct smbd_release_ip_state);
2708 struct smbXsrv_connection *xconn = state->xconn;
2710 const char *addr = state->addr;
2711 const char *p = addr;
2716 if (msg[msglen-1] != '\0') {
2720 ip = (const char *)msg;
2722 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2723 /* avoid recursion */
2727 if (strncmp("::ffff:", addr, 7) == 0) {
2731 DEBUG(10, ("Got release IP message for %s, "
2732 "our address is %s\n", ip, p));
2734 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2735 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2738 * With SMB2 we should do a clean disconnect,
2739 * the previous_session_id in the session setup
2740 * will cleanup the old session, tcons and opens.
2742 * A clean disconnect is needed in order to support
2745 * Note: typically this is never triggered
2746 * as we got a TCP RST (triggered by ctdb event scripts)
2747 * before we get CTDB_SRVID_RELEASE_IP.
2749 * We used to call _exit(1) here, but as this was mostly never
2750 * triggered and has implication on our process model,
2751 * we can just use smbd_server_connection_terminate()
2754 * We don't call smbd_server_connection_terminate() directly
2755 * as we might be called from within ctdbd_migrate(),
2756 * we need to defer our action to the next event loop
2758 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2759 smbd_release_ip_immediate, state);
2762 * Make sure we don't get any io on the connection.
2764 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2765 return EADDRNOTAVAIL;
2771 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2772 struct sockaddr_storage *srv,
2773 struct sockaddr_storage *clnt)
2775 struct smbd_release_ip_state *state;
2776 struct ctdbd_connection *cconn;
2779 cconn = messaging_ctdb_connection();
2780 if (cconn == NULL) {
2781 return NT_STATUS_NO_MEMORY;
2784 state = talloc_zero(xconn, struct smbd_release_ip_state);
2785 if (state == NULL) {
2786 return NT_STATUS_NO_MEMORY;
2788 state->xconn = xconn;
2789 state->im = tevent_create_immediate(state);
2790 if (state->im == NULL) {
2791 return NT_STATUS_NO_MEMORY;
2793 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2794 return NT_STATUS_NO_MEMORY;
2797 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2799 return map_nt_error_from_unix(ret);
2801 return NT_STATUS_OK;
2804 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2805 void *private_data, uint32_t msg_type,
2806 struct server_id server_id, DATA_BLOB *data)
2808 struct smbd_server_connection *sconn = talloc_get_type_abort(
2809 private_data, struct smbd_server_connection);
2810 const char *ip = (char *) data->data;
2813 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2815 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2817 if (client_ip == NULL) {
2821 if (strequal(ip, client_ip)) {
2822 DBG_WARNING("Got kill client message for %s - "
2823 "exiting immediately\n", ip);
2824 exit_server_cleanly("Forced disconnect for client");
2827 TALLOC_FREE(client_ip);
2831 * Send keepalive packets to our client
2833 static bool keepalive_fn(const struct timeval *now, void *private_data)
2835 struct smbd_server_connection *sconn = talloc_get_type_abort(
2836 private_data, struct smbd_server_connection);
2837 struct smbXsrv_connection *xconn = NULL;
2840 if (sconn->using_smb2) {
2841 /* Don't do keepalives on an SMB2 connection. */
2846 * With SMB1 we only have 1 connection
2848 xconn = sconn->client->connections;
2849 smbd_lock_socket(xconn);
2850 ret = send_keepalive(xconn->transport.sock);
2851 smbd_unlock_socket(xconn);
2854 int saved_errno = errno;
2856 * Try and give an error message saying what
2859 DEBUG(0, ("send_keepalive failed for client %s. "
2860 "Error %s - exiting\n",
2861 smbXsrv_connection_dbg(xconn),
2862 strerror(saved_errno)));
2863 errno = saved_errno;
2870 * Do the recurring check if we're idle
2872 static bool deadtime_fn(const struct timeval *now, void *private_data)
2874 struct smbd_server_connection *sconn =
2875 (struct smbd_server_connection *)private_data;
2877 if ((conn_num_open(sconn) == 0)
2878 || (conn_idle_all(sconn, now->tv_sec))) {
2879 DEBUG( 2, ( "Closing idle connection\n" ) );
2880 messaging_send(sconn->msg_ctx,
2881 messaging_server_id(sconn->msg_ctx),
2882 MSG_SHUTDOWN, &data_blob_null);
2890 * Do the recurring log file and smb.conf reload checks.
2893 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2895 struct smbd_server_connection *sconn = talloc_get_type_abort(
2896 private_data, struct smbd_server_connection);
2898 DEBUG(5, ("housekeeping\n"));
2900 change_to_root_user();
2902 /* update printer queue caches if necessary */
2903 update_monitored_printq_cache(sconn->msg_ctx);
2905 /* check if we need to reload services */
2906 check_reload(sconn, time_mono(NULL));
2909 * Force a log file check.
2911 force_check_log_size();
2917 * Read an smb packet in the echo handler child, giving the parent
2918 * smbd one second to react once the socket becomes readable.
2921 struct smbd_echo_read_state {
2922 struct tevent_context *ev;
2923 struct smbXsrv_connection *xconn;
2930 static void smbd_echo_read_readable(struct tevent_req *subreq);
2931 static void smbd_echo_read_waited(struct tevent_req *subreq);
2933 static struct tevent_req *smbd_echo_read_send(
2934 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2935 struct smbXsrv_connection *xconn)
2937 struct tevent_req *req, *subreq;
2938 struct smbd_echo_read_state *state;
2940 req = tevent_req_create(mem_ctx, &state,
2941 struct smbd_echo_read_state);
2946 state->xconn = xconn;
2948 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2949 if (tevent_req_nomem(subreq, req)) {
2950 return tevent_req_post(req, ev);
2952 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2956 static void smbd_echo_read_readable(struct tevent_req *subreq)
2958 struct tevent_req *req = tevent_req_callback_data(
2959 subreq, struct tevent_req);
2960 struct smbd_echo_read_state *state = tevent_req_data(
2961 req, struct smbd_echo_read_state);
2965 ok = wait_for_read_recv(subreq, &err);
2966 TALLOC_FREE(subreq);
2968 tevent_req_nterror(req, map_nt_error_from_unix(err));
2973 * Give the parent smbd one second to step in
2976 subreq = tevent_wakeup_send(
2977 state, state->ev, timeval_current_ofs(1, 0));
2978 if (tevent_req_nomem(subreq, req)) {
2981 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2984 static void smbd_echo_read_waited(struct tevent_req *subreq)
2986 struct tevent_req *req = tevent_req_callback_data(
2987 subreq, struct tevent_req);
2988 struct smbd_echo_read_state *state = tevent_req_data(
2989 req, struct smbd_echo_read_state);
2990 struct smbXsrv_connection *xconn = state->xconn;
2996 ok = tevent_wakeup_recv(subreq);
2997 TALLOC_FREE(subreq);
2999 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
3003 ok = smbd_lock_socket_internal(xconn);
3005 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3006 DEBUG(0, ("%s: failed to lock socket\n", __location__));
3010 if (!fd_is_readable(xconn->transport.sock)) {
3011 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3014 ok = smbd_unlock_socket_internal(xconn);
3016 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3017 DEBUG(1, ("%s: failed to unlock socket\n",
3022 subreq = wait_for_read_send(state, state->ev,
3023 xconn->transport.sock, false);
3024 if (tevent_req_nomem(subreq, req)) {
3027 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
3031 status = receive_smb_talloc(state, xconn,
3032 xconn->transport.sock,
3039 false /* trusted_channel*/);
3041 if (tevent_req_nterror(req, status)) {
3042 tevent_req_nterror(req, status);
3043 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3044 (int)getpid(), nt_errstr(status)));
3048 ok = smbd_unlock_socket_internal(xconn);
3050 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3051 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
3054 tevent_req_done(req);
3057 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3058 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
3060 struct smbd_echo_read_state *state = tevent_req_data(
3061 req, struct smbd_echo_read_state);
3064 if (tevent_req_is_nterror(req, &status)) {
3067 *pbuf = talloc_move(mem_ctx, &state->buf);
3068 *pbuflen = state->buflen;
3069 *pseqnum = state->seqnum;
3070 return NT_STATUS_OK;
3073 struct smbd_echo_state {
3074 struct tevent_context *ev;
3075 struct iovec *pending;
3076 struct smbd_server_connection *sconn;
3077 struct smbXsrv_connection *xconn;
3080 struct tevent_fd *parent_fde;
3082 struct tevent_req *write_req;
3085 static void smbd_echo_writer_done(struct tevent_req *req);
3087 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3091 if (state->write_req != NULL) {
3095 num_pending = talloc_array_length(state->pending);
3096 if (num_pending == 0) {
3100 state->write_req = writev_send(state, state->ev, NULL,
3101 state->parent_pipe, false,
3102 state->pending, num_pending);
3103 if (state->write_req == NULL) {
3104 DEBUG(1, ("writev_send failed\n"));
3108 talloc_steal(state->write_req, state->pending);
3109 state->pending = NULL;
3111 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3115 static void smbd_echo_writer_done(struct tevent_req *req)
3117 struct smbd_echo_state *state = tevent_req_callback_data(
3118 req, struct smbd_echo_state);
3122 written = writev_recv(req, &err);
3124 state->write_req = NULL;
3125 if (written == -1) {
3126 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3129 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3130 smbd_echo_activate_writer(state);
3133 static bool smbd_echo_reply(struct smbd_echo_state *state,
3134 uint8_t *inbuf, size_t inbuf_len,
3137 struct smb_request req;
3138 uint16_t num_replies;
3142 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3143 DEBUG(10, ("Got netbios keepalive\n"));
3150 if (inbuf_len < smb_size) {
3151 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3154 if (!valid_smb_header(inbuf)) {
3155 DEBUG(10, ("Got invalid SMB header\n"));
3159 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3165 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3166 smb_messages[req.cmd].name
3167 ? smb_messages[req.cmd].name : "unknown"));
3169 if (req.cmd != SMBecho) {
3176 num_replies = SVAL(req.vwv+0, 0);
3177 if (num_replies != 1) {
3178 /* Not a Windows "Hey, you're still there?" request */
3182 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3184 DEBUG(10, ("create_outbuf failed\n"));
3187 req.outbuf = (uint8_t *)outbuf;
3189 SSVAL(req.outbuf, smb_vwv0, num_replies);
3191 if (req.buflen > 0) {
3192 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3195 ok = srv_send_smb(req.xconn,
3199 TALLOC_FREE(outbuf);
3207 static void smbd_echo_exit(struct tevent_context *ev,
3208 struct tevent_fd *fde, uint16_t flags,
3211 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3215 static void smbd_echo_got_packet(struct tevent_req *req);
3217 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3220 struct smbd_echo_state *state;
3221 struct tevent_req *read_req;
3223 state = talloc_zero(xconn, struct smbd_echo_state);
3224 if (state == NULL) {
3225 DEBUG(1, ("talloc failed\n"));
3228 state->xconn = xconn;
3229 state->parent_pipe = parent_pipe;
3230 state->ev = samba_tevent_context_init(state);
3231 if (state->ev == NULL) {
3232 DEBUG(1, ("samba_tevent_context_init failed\n"));
3236 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3237 TEVENT_FD_READ, smbd_echo_exit,
3239 if (state->parent_fde == NULL) {
3240 DEBUG(1, ("tevent_add_fd failed\n"));
3245 read_req = smbd_echo_read_send(state, state->ev, xconn);
3246 if (read_req == NULL) {
3247 DEBUG(1, ("smbd_echo_read_send failed\n"));
3251 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3254 if (tevent_loop_once(state->ev) == -1) {
3255 DEBUG(1, ("tevent_loop_once failed: %s\n",
3263 static void smbd_echo_got_packet(struct tevent_req *req)
3265 struct smbd_echo_state *state = tevent_req_callback_data(
3266 req, struct smbd_echo_state);
3270 uint32_t seqnum = 0;
3273 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3275 if (!NT_STATUS_IS_OK(status)) {
3276 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3277 nt_errstr(status)));
3281 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3287 num_pending = talloc_array_length(state->pending);
3288 tmp = talloc_realloc(state, state->pending, struct iovec,
3291 DEBUG(1, ("talloc_realloc failed\n"));
3294 state->pending = tmp;
3296 if (buflen >= smb_size) {
3298 * place the seqnum in the packet so that the main process
3299 * can reply with signing
3301 SIVAL(buf, smb_ss_field, seqnum);
3302 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3305 iov = &state->pending[num_pending];
3306 iov->iov_base = talloc_move(state->pending, &buf);
3307 iov->iov_len = buflen;
3309 DEBUG(10,("echo_handler[%d]: forward to main\n",
3311 smbd_echo_activate_writer(state);
3314 req = smbd_echo_read_send(state, state->ev, state->xconn);
3316 DEBUG(1, ("smbd_echo_read_send failed\n"));
3319 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3324 * Handle SMBecho requests in a forked child process
3326 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3328 int listener_pipe[2];
3331 bool use_mutex = false;
3333 res = pipe(listener_pipe);
3335 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3339 #ifdef HAVE_ROBUST_MUTEXES
3340 use_mutex = tdb_runtime_check_for_robust_mutexes();
3343 pthread_mutexattr_t a;
3345 xconn->smb1.echo_handler.socket_mutex =
3346 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3347 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3348 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3353 res = pthread_mutexattr_init(&a);
3355 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3359 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3361 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3363 pthread_mutexattr_destroy(&a);
3366 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3368 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3370 pthread_mutexattr_destroy(&a);
3373 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3375 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3376 "%s\n", strerror(res)));
3377 pthread_mutexattr_destroy(&a);
3380 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3382 pthread_mutexattr_destroy(&a);
3384 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3392 xconn->smb1.echo_handler.socket_lock_fd =
3393 create_unlink_tmp(lp_lock_directory());
3394 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3395 DEBUG(1, ("Could not create lock fd: %s\n",
3405 close(listener_pipe[0]);
3406 set_blocking(listener_pipe[1], false);
3408 status = smbd_reinit_after_fork(xconn->msg_ctx, xconn->ev_ctx,
3410 if (!NT_STATUS_IS_OK(status)) {
3411 DEBUG(1, ("reinit_after_fork failed: %s\n",
3412 nt_errstr(status)));
3415 initialize_password_db(true, xconn->ev_ctx);
3416 smbd_echo_loop(xconn, listener_pipe[1]);
3419 close(listener_pipe[1]);
3420 listener_pipe[1] = -1;
3421 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3423 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3426 * Without smb signing this is the same as the normal smbd
3427 * listener. This needs to change once signing comes in.
3429 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3431 xconn->smb1.echo_handler.trusted_fd,
3433 smbd_server_echo_handler,
3435 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3436 DEBUG(1, ("event_add_fd failed\n"));
3443 if (listener_pipe[0] != -1) {
3444 close(listener_pipe[0]);
3446 if (listener_pipe[1] != -1) {
3447 close(listener_pipe[1]);
3449 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3450 close(xconn->smb1.echo_handler.socket_lock_fd);
3452 #ifdef HAVE_ROBUST_MUTEXES
3453 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3454 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3455 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3458 smbd_echo_init(xconn);
3463 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3466 if (user->session_info &&
3467 (user->session_info->unix_token->uid == uid)) {
3475 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3478 if (user->session_info != NULL) {
3480 struct security_unix_token *utok;
3482 utok = user->session_info->unix_token;
3483 if (utok->gid == gid) {
3486 for(i=0; i<utok->ngroups; i++) {
3487 if (utok->groups[i] == gid) {
3497 static bool sid_in_use(const struct user_struct *user,
3498 const struct dom_sid *psid)
3501 struct security_token *tok;
3503 if (user->session_info == NULL) {
3506 tok = user->session_info->security_token;
3509 * Not sure session_info->security_token can
3510 * ever be NULL. This check might be not
3515 if (security_token_has_sid(tok, psid)) {
3523 static bool id_in_use(const struct user_struct *user,
3524 const struct id_cache_ref *id)
3528 return uid_in_use(user, id->id.uid);
3530 return gid_in_use(user, id->id.gid);
3532 return sid_in_use(user, &id->id.sid);
3539 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3542 struct server_id server_id,
3545 const char *msg = (data && data->data)
3546 ? (const char *)data->data : "<NULL>";
3547 struct id_cache_ref id;
3548 struct smbd_server_connection *sconn =
3549 talloc_get_type_abort(private_data,
3550 struct smbd_server_connection);
3552 if (!id_cache_ref_parse(msg, &id)) {
3553 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3557 if (id_in_use(sconn->users, &id)) {
3558 exit_server_cleanly(msg);
3560 id_cache_delete_from_cache(&id);
3563 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3564 enum protocol_types protocol)
3568 conn->protocol = protocol;
3570 if (conn->client->session_table != NULL) {
3571 return NT_STATUS_OK;
3574 if (protocol >= PROTOCOL_SMB2_02) {
3575 status = smb2srv_session_table_init(conn);
3576 if (!NT_STATUS_IS_OK(status)) {
3577 conn->protocol = PROTOCOL_NONE;
3581 status = smb2srv_open_table_init(conn);
3582 if (!NT_STATUS_IS_OK(status)) {
3583 conn->protocol = PROTOCOL_NONE;
3587 status = smb1srv_session_table_init(conn);
3588 if (!NT_STATUS_IS_OK(status)) {
3589 conn->protocol = PROTOCOL_NONE;
3593 status = smb1srv_tcon_table_init(conn);
3594 if (!NT_STATUS_IS_OK(status)) {
3595 conn->protocol = PROTOCOL_NONE;
3599 status = smb1srv_open_table_init(conn);
3600 if (!NT_STATUS_IS_OK(status)) {
3601 conn->protocol = PROTOCOL_NONE;
3606 set_Protocol(protocol);
3607 return NT_STATUS_OK;
3610 struct smbd_tevent_trace_state {
3611 struct tevent_context *ev;
3613 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3616 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3619 struct smbd_tevent_trace_state *state =
3620 (struct smbd_tevent_trace_state *)private_data;
3623 case TEVENT_TRACE_BEFORE_WAIT:
3624 if (!smbprofile_dump_pending()) {
3626 * If there's no dump pending
3627 * we don't want to schedule a new 1 sec timer.
3629 * Instead we want to sleep as long as nothing happens.
3631 smbprofile_dump_setup(NULL);
3633 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3635 case TEVENT_TRACE_AFTER_WAIT:
3636 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3637 if (!smbprofile_dump_pending()) {
3639 * We need to flush our state after sleeping
3640 * (hopefully a long time).
3644 * future profiling events should trigger timers
3645 * on our main event context.
3647 smbprofile_dump_setup(state->ev);
3650 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3651 TALLOC_FREE(state->frame);
3652 state->frame = talloc_stackframe_pool(8192);
3654 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3655 TALLOC_FREE(state->frame);
3663 * Create a debug string for the connection
3665 * This is allocated to talloc_tos() or a string constant
3666 * in certain corner cases. The returned string should
3667 * hence not be free'd directly but only via the talloc stack.
3669 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3674 * TODO: this can be improved later
3675 * maybe including the client guid or more
3677 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3679 return "<tsocket_address_string() failed>";
3685 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3686 struct smbXsrv_connection **_xconn)
3688 TALLOC_CTX *frame = talloc_stackframe();
3689 struct smbXsrv_connection *xconn;
3690 struct sockaddr_storage ss_srv;
3691 void *sp_srv = (void *)&ss_srv;
3692 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3693 struct sockaddr_storage ss_clnt;
3694 void *sp_clnt = (void *)&ss_clnt;
3695 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3696 socklen_t sa_socklen;
3697 struct tsocket_address *local_address = NULL;
3698 struct tsocket_address *remote_address = NULL;
3699 const char *remaddr = NULL;
3701 const char *rhost = NULL;
3707 DO_PROFILE_INC(connect);
3709 xconn = talloc_zero(client, struct smbXsrv_connection);
3710 if (xconn == NULL) {
3711 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3713 return NT_STATUS_NO_MEMORY;
3715 talloc_steal(frame, xconn);
3717 xconn->ev_ctx = client->ev_ctx;
3718 xconn->msg_ctx = client->msg_ctx;
3719 xconn->transport.sock = sock_fd;
3720 smbd_echo_init(xconn);
3721 xconn->protocol = PROTOCOL_NONE;
3723 /* Ensure child is set to blocking mode */
3724 set_blocking(sock_fd,True);
3726 set_socket_options(sock_fd, "SO_KEEPALIVE");
3727 set_socket_options(sock_fd, lp_socket_options());
3729 sa_socklen = sizeof(ss_clnt);
3730 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3732 int saved_errno = errno;
3733 int level = (errno == ENOTCONN)?2:0;
3734 DEBUG(level,("getpeername() failed - %s\n",
3735 strerror(saved_errno)));
3737 return map_nt_error_from_unix_common(saved_errno);
3739 ret = tsocket_address_bsd_from_sockaddr(xconn,
3740 sa_clnt, sa_socklen,
3743 int saved_errno = errno;
3744 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3745 __location__, strerror(saved_errno)));
3747 return map_nt_error_from_unix_common(saved_errno);
3750 sa_socklen = sizeof(ss_srv);
3751 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3753 int saved_errno = errno;
3754 int level = (errno == ENOTCONN)?2:0;
3755 DEBUG(level,("getsockname() failed - %s\n",
3756 strerror(saved_errno)));
3758 return map_nt_error_from_unix_common(saved_errno);
3760 ret = tsocket_address_bsd_from_sockaddr(xconn,
3764 int saved_errno = errno;
3765 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3766 __location__, strerror(saved_errno)));
3768 return map_nt_error_from_unix_common(saved_errno);
3771 if (tsocket_address_is_inet(remote_address, "ip")) {
3772 remaddr = tsocket_address_inet_addr_string(remote_address,
3774 if (remaddr == NULL) {
3775 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3776 __location__, strerror(errno)));
3778 return NT_STATUS_NO_MEMORY;
3781 remaddr = "0.0.0.0";
3785 * Before the first packet, check the global hosts allow/ hosts deny
3786 * parameters before doing any parsing of packets passed to us by the
3787 * client. This prevents attacks on our parsing code from hosts not in
3788 * the hosts allow list.
3791 ret = get_remote_hostname(remote_address,
3794 int saved_errno = errno;
3795 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3796 __location__, strerror(saved_errno)));
3798 return map_nt_error_from_unix_common(saved_errno);
3801 if (strequal(rhost, "UNKNOWN")) {
3805 xconn->local_address = local_address;
3806 xconn->remote_address = remote_address;
3807 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3808 if (xconn->remote_hostname == NULL) {
3809 return NT_STATUS_NO_MEMORY;
3812 if (!srv_init_signing(xconn)) {
3813 DEBUG(0, ("Failed to init smb_signing\n"));
3815 return NT_STATUS_INTERNAL_ERROR;
3818 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3819 xconn->remote_hostname,
3821 DEBUG( 1, ("Connection denied from %s to %s\n",
3822 tsocket_address_string(remote_address, talloc_tos()),
3823 tsocket_address_string(local_address, talloc_tos())));
3826 * We return a valid xconn
3827 * so that the caller can return an error message
3830 client->connections = xconn;
3831 xconn->client = client;
3832 talloc_steal(client, xconn);
3836 return NT_STATUS_NETWORK_ACCESS_DENIED;
3839 DEBUG(10, ("Connection allowed from %s to %s\n",
3840 tsocket_address_string(remote_address, talloc_tos()),
3841 tsocket_address_string(local_address, talloc_tos())));
3843 if (lp_clustering()) {
3845 * We need to tell ctdb about our client's TCP
3846 * connection, so that for failover ctdbd can send
3847 * tickle acks, triggering a reconnection by the
3852 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3853 if (!NT_STATUS_IS_OK(status)) {
3854 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3855 nt_errstr(status)));
3859 tmp = lp_max_xmit();
3860 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3861 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3863 xconn->smb1.negprot.max_recv = tmp;
3865 xconn->smb1.sessions.done_sesssetup = false;
3866 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3868 xconn->transport.fde = tevent_add_fd(client->ev_ctx,
3872 smbd_server_connection_handler,
3874 if (!xconn->transport.fde) {
3876 return NT_STATUS_NO_MEMORY;
3879 /* for now we only have one connection */
3880 DLIST_ADD_END(client->connections, xconn);
3881 xconn->client = client;
3882 talloc_steal(client, xconn);
3886 return NT_STATUS_OK;
3889 /****************************************************************************
3890 Process commands from the client
3891 ****************************************************************************/
3893 void smbd_process(struct tevent_context *ev_ctx,
3894 struct messaging_context *msg_ctx,
3898 struct smbd_tevent_trace_state trace_state = {
3900 .frame = talloc_stackframe(),
3902 struct smbXsrv_client *client = NULL;
3903 struct smbd_server_connection *sconn = NULL;
3904 struct smbXsrv_connection *xconn = NULL;
3905 const char *locaddr = NULL;
3906 const char *remaddr = NULL;
3909 struct timeval tv = timeval_current();
3910 NTTIME now = timeval_to_nttime(&tv);
3911 char *chroot_dir = NULL;
3914 status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
3915 if (!NT_STATUS_IS_OK(status)) {
3916 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
3917 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3921 * TODO: remove this...:-)
3923 global_smbXsrv_client = client;
3925 sconn = talloc_zero(client, struct smbd_server_connection);
3926 if (sconn == NULL) {
3927 exit_server("failed to create smbd_server_connection");
3930 client->sconn = sconn;
3931 sconn->client = client;
3933 sconn->ev_ctx = ev_ctx;
3934 sconn->msg_ctx = msg_ctx;
3936 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3938 * We're not making the decision here,
3939 * we're just allowing the client
3940 * to decide between SMB1 and SMB2
3941 * with the first negprot
3944 sconn->using_smb2 = true;
3948 smbd_setup_sig_term_handler(sconn);
3949 smbd_setup_sig_hup_handler(sconn);
3952 status = smbd_add_connection(client, sock_fd, &xconn);
3953 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3955 * send a negative session response "not listening on calling
3958 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3959 (void)srv_send_smb(xconn,(char *)buf, false,
3961 exit_server_cleanly("connection denied");
3962 } else if (!NT_STATUS_IS_OK(status)) {
3963 exit_server_cleanly(nt_errstr(status));
3966 sconn->local_address =
3967 tsocket_address_copy(xconn->local_address, sconn);
3968 if (sconn->local_address == NULL) {
3969 exit_server_cleanly("tsocket_address_copy() failed");
3971 sconn->remote_address =
3972 tsocket_address_copy(xconn->remote_address, sconn);
3973 if (sconn->remote_address == NULL) {
3974 exit_server_cleanly("tsocket_address_copy() failed");
3976 sconn->remote_hostname =
3977 talloc_strdup(sconn, xconn->remote_hostname);
3978 if (sconn->remote_hostname == NULL) {
3979 exit_server_cleanly("tsocket_strdup() failed");
3982 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3983 locaddr = tsocket_address_inet_addr_string(
3984 sconn->local_address,
3986 if (locaddr == NULL) {
3987 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3988 __location__, strerror(errno)));
3989 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3992 locaddr = "0.0.0.0";
3995 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
3996 remaddr = tsocket_address_inet_addr_string(
3997 sconn->remote_address,
3999 if (remaddr == NULL) {
4000 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4001 __location__, strerror(errno)));
4002 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4005 remaddr = "0.0.0.0";
4008 /* this is needed so that we get decent entries
4009 in smbstatus for port 445 connects */
4010 set_remote_machine_name(remaddr, false);
4011 reload_services(sconn, conn_snum_used, true);
4012 sub_set_socket_ids(remaddr,
4013 sconn->remote_hostname,
4016 if (lp_preload_modules()) {
4017 smb_load_all_modules_absoute_path(lp_preload_modules());
4020 smb_perfcount_init();
4022 if (!init_account_policy()) {
4023 exit_server("Could not open account policy tdb.\n");
4026 chroot_dir = lp_root_directory(talloc_tos());
4027 if (chroot_dir[0] != '\0') {
4028 rc = chdir(chroot_dir);
4030 DBG_ERR("Failed to chdir to %s\n", chroot_dir);
4031 exit_server("Failed to chdir()");
4034 rc = chroot(chroot_dir);
4036 DBG_ERR("Failed to change root to %s\n", chroot_dir);
4037 exit_server("Failed to chroot()");
4039 DBG_WARNING("Changed root to %s\n", chroot_dir);
4041 TALLOC_FREE(chroot_dir);
4044 if (!file_init(sconn)) {
4045 exit_server("file_init() failed");
4049 if (!init_oplocks(sconn))
4050 exit_server("Failed to init oplocks");
4052 /* register our message handlers */
4053 messaging_register(sconn->msg_ctx, sconn,
4054 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4055 messaging_register(sconn->msg_ctx, sconn,
4056 MSG_SMB_CLOSE_FILE, msg_close_file);
4057 messaging_register(sconn->msg_ctx, sconn,
4058 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
4060 id_cache_register_msgs(sconn->msg_ctx);
4061 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
4062 messaging_register(sconn->msg_ctx, sconn,
4063 ID_CACHE_KILL, smbd_id_cache_kill);
4065 messaging_deregister(sconn->msg_ctx,
4066 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
4067 messaging_register(sconn->msg_ctx, sconn,
4068 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
4070 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
4072 messaging_register(sconn->msg_ctx, sconn,
4073 MSG_SMB_KILL_CLIENT_IP,
4074 msg_kill_client_ip);
4076 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
4079 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4080 * MSGs to all child processes
4082 messaging_deregister(sconn->msg_ctx,
4084 messaging_register(sconn->msg_ctx, NULL,
4085 MSG_DEBUG, debug_message);
4087 if ((lp_keepalive() != 0)
4088 && !(event_add_idle(ev_ctx, NULL,
4089 timeval_set(lp_keepalive(), 0),
4090 "keepalive", keepalive_fn,
4092 DEBUG(0, ("Could not add keepalive event\n"));
4096 if (!(event_add_idle(ev_ctx, NULL,
4097 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4098 "deadtime", deadtime_fn, sconn))) {
4099 DEBUG(0, ("Could not add deadtime event\n"));
4103 if (!(event_add_idle(ev_ctx, NULL,
4104 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4105 "housekeeping", housekeeping_fn, sconn))) {
4106 DEBUG(0, ("Could not add housekeeping event\n"));
4110 smbprofile_dump_setup(ev_ctx);
4112 if (!init_dptrs(sconn)) {
4113 exit_server("init_dptrs() failed");
4116 TALLOC_FREE(trace_state.frame);
4118 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4121 ret = tevent_loop_wait(ev_ctx);
4123 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4124 " exiting\n", ret, strerror(errno)));
4127 TALLOC_FREE(trace_state.frame);
4129 exit_server_cleanly(NULL);
4132 bool req_is_in_chain(const struct smb_request *req)
4134 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4136 * We're right now handling a subsequent request, so we must
4142 if (!is_andx_req(req->cmd)) {
4148 * Okay, an illegal request, but definitely not chained :-)
4153 return (CVAL(req->vwv+0, 0) != 0xFF);