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 "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
43 #include "system/threads.h"
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list {
47 struct pending_message_list *next, *prev;
48 struct timeval request_time; /* When was this first issued? */
49 struct smbd_server_connection *sconn;
50 struct smbXsrv_connection *xconn;
51 struct tevent_timer *te;
52 struct smb_perfcount_data pcd;
57 struct deferred_open_record *open_rec;
60 static void construct_reply_common(struct smb_request *req, const char *inbuf,
62 static struct pending_message_list *get_deferred_open_message_smb(
63 struct smbd_server_connection *sconn, uint64_t mid);
64 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
66 static void smbd_echo_init(struct smbXsrv_connection *xconn)
68 xconn->smb1.echo_handler.trusted_fd = -1;
69 xconn->smb1.echo_handler.socket_lock_fd = -1;
70 #ifdef HAVE_ROBUST_MUTEXES
71 xconn->smb1.echo_handler.socket_mutex = NULL;
75 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
77 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
81 #ifdef HAVE_ROBUST_MUTEXES
82 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
90 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
92 if (!smbd_echo_active(xconn)) {
96 xconn->smb1.echo_handler.ref_count++;
98 if (xconn->smb1.echo_handler.ref_count > 1) {
102 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
104 #ifdef HAVE_ROBUST_MUTEXES
105 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
108 while (ret == EINTR) {
109 ret = pthread_mutex_lock(
110 xconn->smb1.echo_handler.socket_mutex);
116 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
123 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
128 xconn->smb1.echo_handler.socket_lock_fd,
129 F_SETLKW, 0, 0, F_WRLCK);
130 } while (!ok && (errno == EINTR));
133 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
138 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
143 void smbd_lock_socket(struct smbXsrv_connection *xconn)
145 if (!smbd_lock_socket_internal(xconn)) {
146 exit_server_cleanly("failed to lock socket");
150 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
152 if (!smbd_echo_active(xconn)) {
156 xconn->smb1.echo_handler.ref_count--;
158 if (xconn->smb1.echo_handler.ref_count > 0) {
162 #ifdef HAVE_ROBUST_MUTEXES
163 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
166 while (ret == EINTR) {
167 ret = pthread_mutex_unlock(
168 xconn->smb1.echo_handler.socket_mutex);
174 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
181 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
186 xconn->smb1.echo_handler.socket_lock_fd,
187 F_SETLKW, 0, 0, F_UNLCK);
188 } while (!ok && (errno == EINTR));
191 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
196 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
201 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
203 if (!smbd_unlock_socket_internal(xconn)) {
204 exit_server_cleanly("failed to unlock socket");
208 /* Accessor function for smb_read_error for smbd functions. */
210 /****************************************************************************
212 ****************************************************************************/
214 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
215 bool do_signing, uint32_t seqnum,
217 struct smb_perfcount_data *pcd)
221 char *buf_out = buffer;
223 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
225 * we're not supposed to do any io
230 smbd_lock_socket(xconn);
233 /* Sign the outgoing packet if required. */
234 srv_calculate_sign_mac(xconn, buf_out, seqnum);
238 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
239 if (!NT_STATUS_IS_OK(status)) {
240 DEBUG(0, ("send_smb: SMB encryption failed "
241 "on outgoing packet! Error %s\n",
242 nt_errstr(status) ));
248 len = smb_len_large(buf_out) + 4;
250 ret = write_data(xconn->transport.sock, buf_out, len);
252 int saved_errno = errno;
254 * Try and give an error message saying what
257 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
258 (int)getpid(), (int)len,
259 smbXsrv_connection_dbg(xconn),
260 (int)ret, strerror(saved_errno)));
263 srv_free_enc_buffer(xconn, buf_out);
267 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
268 srv_free_enc_buffer(xconn, buf_out);
270 SMB_PERFCOUNT_END(pcd);
272 smbd_unlock_socket(xconn);
276 /*******************************************************************
277 Setup the word count and byte count for a smb message.
278 ********************************************************************/
280 int srv_set_message(char *buf,
285 if (zero && (num_words || num_bytes)) {
286 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
288 SCVAL(buf,smb_wct,num_words);
289 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
290 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
291 return (smb_size + num_words*2 + num_bytes);
294 static bool valid_smb_header(const uint8_t *inbuf)
296 if (is_encrypted_packet(inbuf)) {
300 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
301 * but it just looks weird to call strncmp for this one.
303 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
306 /* Socket functions for smbd packet processing. */
308 static bool valid_packet_size(size_t len)
311 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
312 * of header. Don't print the error if this fits.... JRA.
315 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
316 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
317 (unsigned long)len));
323 static NTSTATUS read_packet_remainder(int fd, char *buffer,
324 unsigned int timeout, ssize_t len)
332 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
333 if (!NT_STATUS_IS_OK(status)) {
334 char addr[INET6_ADDRSTRLEN];
335 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
337 get_peer_addr(fd, addr, sizeof(addr)),
343 /****************************************************************************
344 Attempt a zerocopy writeX read. We know here that len > smb_size-4
345 ****************************************************************************/
348 * Unfortunately, earlier versions of smbclient/libsmbclient
349 * don't send this "standard" writeX header. I've fixed this
350 * for 3.2 but we'll use the old method with earlier versions.
351 * Windows and CIFSFS at least use this standard size. Not
355 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
356 (2*14) + /* word count (including bcc) */ \
359 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
360 const char lenbuf[4],
361 struct smbXsrv_connection *xconn,
364 unsigned int timeout,
368 /* Size of a WRITEX call (+4 byte len). */
369 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
370 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
374 memcpy(writeX_header, lenbuf, 4);
376 status = read_fd_with_timeout(
377 sock, writeX_header + 4,
378 STANDARD_WRITE_AND_X_HEADER_SIZE,
379 STANDARD_WRITE_AND_X_HEADER_SIZE,
382 if (!NT_STATUS_IS_OK(status)) {
383 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
385 smbXsrv_connection_dbg(xconn),
391 * Ok - now try and see if this is a possible
395 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
397 * If the data offset is beyond what
398 * we've read, drain the extra bytes.
400 uint16_t doff = SVAL(writeX_header,smb_vwv11);
403 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
404 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
405 if (drain_socket(sock, drain) != drain) {
406 smb_panic("receive_smb_raw_talloc_partial_read:"
407 " failed to drain pending bytes");
410 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
413 /* Spoof down the length and null out the bcc. */
414 set_message_bcc(writeX_header, 0);
415 newlen = smb_len(writeX_header);
417 /* Copy the header we've written. */
419 *buffer = (char *)talloc_memdup(mem_ctx,
421 sizeof(writeX_header));
423 if (*buffer == NULL) {
424 DEBUG(0, ("Could not allocate inbuf of length %d\n",
425 (int)sizeof(writeX_header)));
426 return NT_STATUS_NO_MEMORY;
429 /* Work out the remaining bytes. */
430 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
431 *len_ret = newlen + 4;
435 if (!valid_packet_size(len)) {
436 return NT_STATUS_INVALID_PARAMETER;
440 * Not a valid writeX call. Just do the standard
444 *buffer = talloc_array(mem_ctx, char, len+4);
446 if (*buffer == NULL) {
447 DEBUG(0, ("Could not allocate inbuf of length %d\n",
449 return NT_STATUS_NO_MEMORY;
452 /* Copy in what we already read. */
455 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
456 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
459 status = read_packet_remainder(
461 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
464 if (!NT_STATUS_IS_OK(status)) {
465 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
475 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
476 struct smbXsrv_connection *xconn,
478 char **buffer, unsigned int timeout,
479 size_t *p_unread, size_t *plen)
483 int min_recv_size = lp_min_receive_file_size();
488 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
490 if (!NT_STATUS_IS_OK(status)) {
494 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
495 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
496 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
497 !srv_is_signing_active(xconn) &&
498 xconn->smb1.echo_handler.trusted_fde == NULL) {
500 return receive_smb_raw_talloc_partial_read(
501 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
505 if (!valid_packet_size(len)) {
506 return NT_STATUS_INVALID_PARAMETER;
510 * The +4 here can't wrap, we've checked the length above already.
513 *buffer = talloc_array(mem_ctx, char, len+4);
515 if (*buffer == NULL) {
516 DEBUG(0, ("Could not allocate inbuf of length %d\n",
518 return NT_STATUS_NO_MEMORY;
521 memcpy(*buffer, lenbuf, sizeof(lenbuf));
523 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
524 if (!NT_STATUS_IS_OK(status)) {
532 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
533 struct smbXsrv_connection *xconn,
535 char **buffer, unsigned int timeout,
536 size_t *p_unread, bool *p_encrypted,
539 bool trusted_channel)
544 *p_encrypted = false;
546 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
548 if (!NT_STATUS_IS_OK(status)) {
549 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
550 ("receive_smb_raw_talloc failed for client %s "
551 "read error = %s.\n",
552 smbXsrv_connection_dbg(xconn),
553 nt_errstr(status)) );
557 if (is_encrypted_packet((uint8_t *)*buffer)) {
558 status = srv_decrypt_buffer(xconn, *buffer);
559 if (!NT_STATUS_IS_OK(status)) {
560 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
561 "incoming packet! Error %s\n",
562 nt_errstr(status) ));
568 /* Check the incoming SMB signature. */
569 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
570 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
571 "incoming packet!\n"));
572 return NT_STATUS_INVALID_NETWORK_RESPONSE;
580 * Initialize a struct smb_request from an inbuf
583 static bool init_smb_request(struct smb_request *req,
584 struct smbd_server_connection *sconn,
585 struct smbXsrv_connection *xconn,
587 size_t unread_bytes, bool encrypted,
590 struct smbXsrv_tcon *tcon;
593 size_t req_size = smb_len(inbuf) + 4;
595 /* Ensure we have at least smb_size bytes. */
596 if (req_size < smb_size) {
597 DEBUG(0,("init_smb_request: invalid request size %u\n",
598 (unsigned int)req_size ));
602 req->request_time = timeval_current();
603 now = timeval_to_nttime(&req->request_time);
605 req->cmd = CVAL(inbuf, smb_com);
606 req->flags2 = SVAL(inbuf, smb_flg2);
607 req->smbpid = SVAL(inbuf, smb_pid);
608 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
609 req->seqnum = seqnum;
610 req->vuid = SVAL(inbuf, smb_uid);
611 req->tid = SVAL(inbuf, smb_tid);
612 req->wct = CVAL(inbuf, smb_wct);
613 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
614 req->buflen = smb_buflen(inbuf);
615 req->buf = (const uint8_t *)smb_buf_const(inbuf);
616 req->unread_bytes = unread_bytes;
617 req->encrypted = encrypted;
622 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
623 if (NT_STATUS_IS_OK(status)) {
624 req->conn = tcon->compat;
627 req->chain_fsp = NULL;
629 req->priv_paths = NULL;
631 smb_init_perfcount_data(&req->pcd);
633 /* Ensure we have at least wct words and 2 bytes of bcc. */
634 if (smb_size + req->wct*2 > req_size) {
635 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
636 (unsigned int)req->wct,
637 (unsigned int)req_size));
640 /* Ensure bcc is correct. */
641 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
642 DEBUG(0,("init_smb_request: invalid bcc number %u "
643 "(wct = %u, size %u)\n",
644 (unsigned int)req->buflen,
645 (unsigned int)req->wct,
646 (unsigned int)req_size));
654 static void process_smb(struct smbXsrv_connection *xconn,
655 uint8_t *inbuf, size_t nread, size_t unread_bytes,
656 uint32_t seqnum, bool encrypted,
657 struct smb_perfcount_data *deferred_pcd);
659 static void smbd_deferred_open_timer(struct tevent_context *ev,
660 struct tevent_timer *te,
661 struct timeval _tval,
664 struct pending_message_list *msg = talloc_get_type(private_data,
665 struct pending_message_list);
666 struct smbd_server_connection *sconn = msg->sconn;
667 struct smbXsrv_connection *xconn = msg->xconn;
668 TALLOC_CTX *mem_ctx = talloc_tos();
669 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
672 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
675 exit_server("smbd_deferred_open_timer: talloc failed\n");
679 /* We leave this message on the queue so the open code can
680 know this is a retry. */
681 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
682 (unsigned long long)mid ));
684 /* Mark the message as processed so this is not
685 * re-processed in error. */
686 msg->processed = true;
688 process_smb(xconn, inbuf,
690 msg->seqnum, msg->encrypted, &msg->pcd);
692 /* If it's still there and was processed, remove it. */
693 msg = get_deferred_open_message_smb(sconn, mid);
694 if (msg && msg->processed) {
695 remove_deferred_open_message_smb(sconn, mid);
699 /****************************************************************************
700 Function to push a message onto the tail of a linked list of smb messages ready
702 ****************************************************************************/
704 static bool push_queued_message(struct smb_request *req,
705 struct timeval request_time,
706 struct timeval end_time,
707 struct deferred_open_record *open_rec)
709 int msg_len = smb_len(req->inbuf) + 4;
710 struct pending_message_list *msg;
712 msg = talloc_zero(NULL, struct pending_message_list);
715 DEBUG(0,("push_message: malloc fail (1)\n"));
718 msg->sconn = req->sconn;
719 msg->xconn = req->xconn;
721 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
722 if(msg->buf.data == NULL) {
723 DEBUG(0,("push_message: malloc fail (2)\n"));
728 msg->request_time = request_time;
729 msg->seqnum = req->seqnum;
730 msg->encrypted = req->encrypted;
731 msg->processed = false;
732 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
735 msg->open_rec = talloc_move(msg, &open_rec);
739 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
742 smbd_deferred_open_timer,
745 DEBUG(0,("push_message: event_add_timed failed\n"));
751 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
752 struct pending_message_list *);
754 DEBUG(10,("push_message: pushed message length %u on "
755 "deferred_open_queue\n", (unsigned int)msg_len));
760 /****************************************************************************
761 Function to delete a sharing violation open message by mid.
762 ****************************************************************************/
764 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
767 struct pending_message_list *pml;
769 if (sconn->using_smb2) {
770 remove_deferred_open_message_smb2(sconn, mid);
774 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
775 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
776 DEBUG(10,("remove_deferred_open_message_smb: "
777 "deleting mid %llu len %u\n",
778 (unsigned long long)mid,
779 (unsigned int)pml->buf.length ));
780 DLIST_REMOVE(sconn->deferred_open_queue, pml);
787 /****************************************************************************
788 Move a sharing violation open retry message to the front of the list and
789 schedule it for immediate processing.
790 ****************************************************************************/
792 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
795 struct pending_message_list *pml;
798 if (sconn->using_smb2) {
799 return schedule_deferred_open_message_smb2(sconn, mid);
802 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
803 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
805 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
808 (unsigned long long)msg_mid ));
810 if (mid == msg_mid) {
811 struct tevent_timer *te;
813 if (pml->processed) {
814 /* A processed message should not be
816 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
817 "message mid %llu was already processed\n",
818 (unsigned long long)msg_mid ));
822 DEBUG(10,("schedule_deferred_open_message_smb: "
823 "scheduling mid %llu\n",
824 (unsigned long long)mid ));
826 te = tevent_add_timer(pml->sconn->ev_ctx,
829 smbd_deferred_open_timer,
832 DEBUG(10,("schedule_deferred_open_message_smb: "
833 "event_add_timed() failed, "
834 "skipping mid %llu\n",
835 (unsigned long long)msg_mid ));
838 TALLOC_FREE(pml->te);
840 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
845 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
846 "find message mid %llu\n",
847 (unsigned long long)mid ));
852 /****************************************************************************
853 Return true if this mid is on the deferred queue and was not yet processed.
854 ****************************************************************************/
856 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
858 struct smbd_server_connection *sconn = xconn->client->sconn;
859 struct pending_message_list *pml;
861 if (sconn->using_smb2) {
862 return open_was_deferred_smb2(sconn, mid);
865 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
866 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
873 /****************************************************************************
874 Return the message queued by this mid.
875 ****************************************************************************/
877 static struct pending_message_list *get_deferred_open_message_smb(
878 struct smbd_server_connection *sconn, uint64_t mid)
880 struct pending_message_list *pml;
882 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
883 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
890 /****************************************************************************
891 Get the state data queued by this mid.
892 ****************************************************************************/
894 bool get_deferred_open_message_state(struct smb_request *smbreq,
895 struct timeval *p_request_time,
896 struct deferred_open_record **open_rec)
898 struct pending_message_list *pml;
900 if (smbreq->sconn->using_smb2) {
901 return get_deferred_open_message_state_smb2(smbreq->smb2req,
906 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
910 if (p_request_time) {
911 *p_request_time = pml->request_time;
913 if (open_rec != NULL) {
914 *open_rec = pml->open_rec;
919 /****************************************************************************
920 Function to push a deferred open smb message onto a linked list of local smb
921 messages ready for processing.
922 ****************************************************************************/
924 bool push_deferred_open_message_smb(struct smb_request *req,
925 struct timeval request_time,
926 struct timeval timeout,
928 struct deferred_open_record *open_rec)
930 struct timeval end_time;
933 return push_deferred_open_message_smb2(req->smb2req,
940 if (req->unread_bytes) {
941 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
942 "unread_bytes = %u\n",
943 (unsigned int)req->unread_bytes ));
944 smb_panic("push_deferred_open_message_smb: "
945 "logic error unread_bytes != 0" );
948 end_time = timeval_sum(&request_time, &timeout);
950 DEBUG(10,("push_deferred_open_message_smb: pushing message "
951 "len %u mid %llu timeout time [%u.%06u]\n",
952 (unsigned int) smb_len(req->inbuf)+4,
953 (unsigned long long)req->mid,
954 (unsigned int)end_time.tv_sec,
955 (unsigned int)end_time.tv_usec));
957 return push_queued_message(req, request_time, end_time, open_rec);
960 static void smbd_sig_term_handler(struct tevent_context *ev,
961 struct tevent_signal *se,
967 exit_server_cleanly("termination signal");
970 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
972 struct tevent_signal *se;
974 se = tevent_add_signal(sconn->ev_ctx,
977 smbd_sig_term_handler,
980 exit_server("failed to setup SIGTERM handler");
984 static void smbd_sig_hup_handler(struct tevent_context *ev,
985 struct tevent_signal *se,
991 struct smbd_server_connection *sconn =
992 talloc_get_type_abort(private_data,
993 struct smbd_server_connection);
995 change_to_root_user();
996 DEBUG(1,("Reloading services after SIGHUP\n"));
997 reload_services(sconn, conn_snum_used, false);
1000 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1002 struct tevent_signal *se;
1004 se = tevent_add_signal(sconn->ev_ctx,
1007 smbd_sig_hup_handler,
1010 exit_server("failed to setup SIGHUP handler");
1014 static void smbd_conf_updated(struct messaging_context *msg,
1017 struct server_id server_id,
1020 struct smbd_server_connection *sconn =
1021 talloc_get_type_abort(private_data,
1022 struct smbd_server_connection);
1024 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1025 "updated. Reloading.\n"));
1026 change_to_root_user();
1027 reload_services(sconn, conn_snum_used, false);
1031 * Only allow 5 outstanding trans requests. We're allocating memory, so
1035 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1038 for (; list != NULL; list = list->next) {
1040 if (list->mid == mid) {
1041 return NT_STATUS_INVALID_PARAMETER;
1047 return NT_STATUS_INSUFFICIENT_RESOURCES;
1050 return NT_STATUS_OK;
1054 These flags determine some of the permissions required to do an operation
1056 Note that I don't set NEED_WRITE on some write operations because they
1057 are used by some brain-dead clients when printing, and I don't want to
1058 force write permissions on print services.
1060 #define AS_USER (1<<0)
1061 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1062 #define TIME_INIT (1<<2)
1063 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1064 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1065 #define DO_CHDIR (1<<6)
1068 define a list of possible SMB messages and their corresponding
1069 functions. Any message that has a NULL function is unimplemented -
1070 please feel free to contribute implementations!
1072 static const struct smb_message_struct {
1074 void (*fn)(struct smb_request *req);
1076 } smb_messages[256] = {
1078 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1079 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1080 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1081 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1082 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1083 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1084 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1085 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1086 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1087 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1088 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1089 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1090 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1091 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1092 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1093 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1094 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1095 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1096 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1097 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1098 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1099 /* 0x15 */ { NULL, NULL, 0 },
1100 /* 0x16 */ { NULL, NULL, 0 },
1101 /* 0x17 */ { NULL, NULL, 0 },
1102 /* 0x18 */ { NULL, NULL, 0 },
1103 /* 0x19 */ { NULL, NULL, 0 },
1104 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1105 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1106 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1107 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1108 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1109 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1110 /* 0x20 */ { "SMBwritec", NULL,0},
1111 /* 0x21 */ { NULL, NULL, 0 },
1112 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1113 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1114 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1115 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1116 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1117 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1118 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1119 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1120 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1121 /* 0x2b */ { "SMBecho",reply_echo,0},
1122 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1123 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1124 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1125 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1126 /* 0x30 */ { NULL, NULL, 0 },
1127 /* 0x31 */ { NULL, NULL, 0 },
1128 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1129 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1130 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1131 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1132 /* 0x36 */ { NULL, NULL, 0 },
1133 /* 0x37 */ { NULL, NULL, 0 },
1134 /* 0x38 */ { NULL, NULL, 0 },
1135 /* 0x39 */ { NULL, NULL, 0 },
1136 /* 0x3a */ { NULL, NULL, 0 },
1137 /* 0x3b */ { NULL, NULL, 0 },
1138 /* 0x3c */ { NULL, NULL, 0 },
1139 /* 0x3d */ { NULL, NULL, 0 },
1140 /* 0x3e */ { NULL, NULL, 0 },
1141 /* 0x3f */ { NULL, NULL, 0 },
1142 /* 0x40 */ { NULL, NULL, 0 },
1143 /* 0x41 */ { NULL, NULL, 0 },
1144 /* 0x42 */ { NULL, NULL, 0 },
1145 /* 0x43 */ { NULL, NULL, 0 },
1146 /* 0x44 */ { NULL, NULL, 0 },
1147 /* 0x45 */ { NULL, NULL, 0 },
1148 /* 0x46 */ { NULL, NULL, 0 },
1149 /* 0x47 */ { NULL, NULL, 0 },
1150 /* 0x48 */ { NULL, NULL, 0 },
1151 /* 0x49 */ { NULL, NULL, 0 },
1152 /* 0x4a */ { NULL, NULL, 0 },
1153 /* 0x4b */ { NULL, NULL, 0 },
1154 /* 0x4c */ { NULL, NULL, 0 },
1155 /* 0x4d */ { NULL, NULL, 0 },
1156 /* 0x4e */ { NULL, NULL, 0 },
1157 /* 0x4f */ { NULL, NULL, 0 },
1158 /* 0x50 */ { NULL, NULL, 0 },
1159 /* 0x51 */ { NULL, NULL, 0 },
1160 /* 0x52 */ { NULL, NULL, 0 },
1161 /* 0x53 */ { NULL, NULL, 0 },
1162 /* 0x54 */ { NULL, NULL, 0 },
1163 /* 0x55 */ { NULL, NULL, 0 },
1164 /* 0x56 */ { NULL, NULL, 0 },
1165 /* 0x57 */ { NULL, NULL, 0 },
1166 /* 0x58 */ { NULL, NULL, 0 },
1167 /* 0x59 */ { NULL, NULL, 0 },
1168 /* 0x5a */ { NULL, NULL, 0 },
1169 /* 0x5b */ { NULL, NULL, 0 },
1170 /* 0x5c */ { NULL, NULL, 0 },
1171 /* 0x5d */ { NULL, NULL, 0 },
1172 /* 0x5e */ { NULL, NULL, 0 },
1173 /* 0x5f */ { NULL, NULL, 0 },
1174 /* 0x60 */ { NULL, NULL, 0 },
1175 /* 0x61 */ { NULL, NULL, 0 },
1176 /* 0x62 */ { NULL, NULL, 0 },
1177 /* 0x63 */ { NULL, NULL, 0 },
1178 /* 0x64 */ { NULL, NULL, 0 },
1179 /* 0x65 */ { NULL, NULL, 0 },
1180 /* 0x66 */ { NULL, NULL, 0 },
1181 /* 0x67 */ { NULL, NULL, 0 },
1182 /* 0x68 */ { NULL, NULL, 0 },
1183 /* 0x69 */ { NULL, NULL, 0 },
1184 /* 0x6a */ { NULL, NULL, 0 },
1185 /* 0x6b */ { NULL, NULL, 0 },
1186 /* 0x6c */ { NULL, NULL, 0 },
1187 /* 0x6d */ { NULL, NULL, 0 },
1188 /* 0x6e */ { NULL, NULL, 0 },
1189 /* 0x6f */ { NULL, NULL, 0 },
1190 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1191 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1192 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1193 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1194 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1195 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1196 /* 0x76 */ { NULL, NULL, 0 },
1197 /* 0x77 */ { NULL, NULL, 0 },
1198 /* 0x78 */ { NULL, NULL, 0 },
1199 /* 0x79 */ { NULL, NULL, 0 },
1200 /* 0x7a */ { NULL, NULL, 0 },
1201 /* 0x7b */ { NULL, NULL, 0 },
1202 /* 0x7c */ { NULL, NULL, 0 },
1203 /* 0x7d */ { NULL, NULL, 0 },
1204 /* 0x7e */ { NULL, NULL, 0 },
1205 /* 0x7f */ { NULL, NULL, 0 },
1206 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1207 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1208 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1209 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1210 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1211 /* 0x85 */ { NULL, NULL, 0 },
1212 /* 0x86 */ { NULL, NULL, 0 },
1213 /* 0x87 */ { NULL, NULL, 0 },
1214 /* 0x88 */ { NULL, NULL, 0 },
1215 /* 0x89 */ { NULL, NULL, 0 },
1216 /* 0x8a */ { NULL, NULL, 0 },
1217 /* 0x8b */ { NULL, NULL, 0 },
1218 /* 0x8c */ { NULL, NULL, 0 },
1219 /* 0x8d */ { NULL, NULL, 0 },
1220 /* 0x8e */ { NULL, NULL, 0 },
1221 /* 0x8f */ { NULL, NULL, 0 },
1222 /* 0x90 */ { NULL, NULL, 0 },
1223 /* 0x91 */ { NULL, NULL, 0 },
1224 /* 0x92 */ { NULL, NULL, 0 },
1225 /* 0x93 */ { NULL, NULL, 0 },
1226 /* 0x94 */ { NULL, NULL, 0 },
1227 /* 0x95 */ { NULL, NULL, 0 },
1228 /* 0x96 */ { NULL, NULL, 0 },
1229 /* 0x97 */ { NULL, NULL, 0 },
1230 /* 0x98 */ { NULL, NULL, 0 },
1231 /* 0x99 */ { NULL, NULL, 0 },
1232 /* 0x9a */ { NULL, NULL, 0 },
1233 /* 0x9b */ { NULL, NULL, 0 },
1234 /* 0x9c */ { NULL, NULL, 0 },
1235 /* 0x9d */ { NULL, NULL, 0 },
1236 /* 0x9e */ { NULL, NULL, 0 },
1237 /* 0x9f */ { NULL, NULL, 0 },
1238 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1239 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1240 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1241 /* 0xa3 */ { NULL, NULL, 0 },
1242 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1243 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1244 /* 0xa6 */ { NULL, NULL, 0 },
1245 /* 0xa7 */ { NULL, NULL, 0 },
1246 /* 0xa8 */ { NULL, NULL, 0 },
1247 /* 0xa9 */ { NULL, NULL, 0 },
1248 /* 0xaa */ { NULL, NULL, 0 },
1249 /* 0xab */ { NULL, NULL, 0 },
1250 /* 0xac */ { NULL, NULL, 0 },
1251 /* 0xad */ { NULL, NULL, 0 },
1252 /* 0xae */ { NULL, NULL, 0 },
1253 /* 0xaf */ { NULL, NULL, 0 },
1254 /* 0xb0 */ { NULL, NULL, 0 },
1255 /* 0xb1 */ { NULL, NULL, 0 },
1256 /* 0xb2 */ { NULL, NULL, 0 },
1257 /* 0xb3 */ { NULL, NULL, 0 },
1258 /* 0xb4 */ { NULL, NULL, 0 },
1259 /* 0xb5 */ { NULL, NULL, 0 },
1260 /* 0xb6 */ { NULL, NULL, 0 },
1261 /* 0xb7 */ { NULL, NULL, 0 },
1262 /* 0xb8 */ { NULL, NULL, 0 },
1263 /* 0xb9 */ { NULL, NULL, 0 },
1264 /* 0xba */ { NULL, NULL, 0 },
1265 /* 0xbb */ { NULL, NULL, 0 },
1266 /* 0xbc */ { NULL, NULL, 0 },
1267 /* 0xbd */ { NULL, NULL, 0 },
1268 /* 0xbe */ { NULL, NULL, 0 },
1269 /* 0xbf */ { NULL, NULL, 0 },
1270 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1271 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1272 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1273 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1274 /* 0xc4 */ { NULL, NULL, 0 },
1275 /* 0xc5 */ { NULL, NULL, 0 },
1276 /* 0xc6 */ { NULL, NULL, 0 },
1277 /* 0xc7 */ { NULL, NULL, 0 },
1278 /* 0xc8 */ { NULL, NULL, 0 },
1279 /* 0xc9 */ { NULL, NULL, 0 },
1280 /* 0xca */ { NULL, NULL, 0 },
1281 /* 0xcb */ { NULL, NULL, 0 },
1282 /* 0xcc */ { NULL, NULL, 0 },
1283 /* 0xcd */ { NULL, NULL, 0 },
1284 /* 0xce */ { NULL, NULL, 0 },
1285 /* 0xcf */ { NULL, NULL, 0 },
1286 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1287 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1288 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1289 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1290 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1291 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1292 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1293 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1294 /* 0xd8 */ { NULL, NULL, 0 },
1295 /* 0xd9 */ { NULL, NULL, 0 },
1296 /* 0xda */ { NULL, NULL, 0 },
1297 /* 0xdb */ { NULL, NULL, 0 },
1298 /* 0xdc */ { NULL, NULL, 0 },
1299 /* 0xdd */ { NULL, NULL, 0 },
1300 /* 0xde */ { NULL, NULL, 0 },
1301 /* 0xdf */ { NULL, NULL, 0 },
1302 /* 0xe0 */ { NULL, NULL, 0 },
1303 /* 0xe1 */ { NULL, NULL, 0 },
1304 /* 0xe2 */ { NULL, NULL, 0 },
1305 /* 0xe3 */ { NULL, NULL, 0 },
1306 /* 0xe4 */ { NULL, NULL, 0 },
1307 /* 0xe5 */ { NULL, NULL, 0 },
1308 /* 0xe6 */ { NULL, NULL, 0 },
1309 /* 0xe7 */ { NULL, NULL, 0 },
1310 /* 0xe8 */ { NULL, NULL, 0 },
1311 /* 0xe9 */ { NULL, NULL, 0 },
1312 /* 0xea */ { NULL, NULL, 0 },
1313 /* 0xeb */ { NULL, NULL, 0 },
1314 /* 0xec */ { NULL, NULL, 0 },
1315 /* 0xed */ { NULL, NULL, 0 },
1316 /* 0xee */ { NULL, NULL, 0 },
1317 /* 0xef */ { NULL, NULL, 0 },
1318 /* 0xf0 */ { NULL, NULL, 0 },
1319 /* 0xf1 */ { NULL, NULL, 0 },
1320 /* 0xf2 */ { NULL, NULL, 0 },
1321 /* 0xf3 */ { NULL, NULL, 0 },
1322 /* 0xf4 */ { NULL, NULL, 0 },
1323 /* 0xf5 */ { NULL, NULL, 0 },
1324 /* 0xf6 */ { NULL, NULL, 0 },
1325 /* 0xf7 */ { NULL, NULL, 0 },
1326 /* 0xf8 */ { NULL, NULL, 0 },
1327 /* 0xf9 */ { NULL, NULL, 0 },
1328 /* 0xfa */ { NULL, NULL, 0 },
1329 /* 0xfb */ { NULL, NULL, 0 },
1330 /* 0xfc */ { NULL, NULL, 0 },
1331 /* 0xfd */ { NULL, NULL, 0 },
1332 /* 0xfe */ { NULL, NULL, 0 },
1333 /* 0xff */ { NULL, NULL, 0 }
1337 /*******************************************************************
1338 allocate and initialize a reply packet
1339 ********************************************************************/
1341 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1342 const char *inbuf, char **outbuf, uint8_t num_words,
1345 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1348 * Protect against integer wrap.
1349 * The SMB layer reply can be up to 0xFFFFFF bytes.
1351 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1353 if (asprintf(&msg, "num_bytes too large: %u",
1354 (unsigned)num_bytes) == -1) {
1355 msg = discard_const_p(char, "num_bytes too large");
1361 * Here we include the NBT header for now.
1363 *outbuf = talloc_array(mem_ctx, char,
1364 NBT_HDR_SIZE + smb_len);
1365 if (*outbuf == NULL) {
1369 construct_reply_common(req, inbuf, *outbuf);
1370 srv_set_message(*outbuf, num_words, num_bytes, false);
1372 * Zero out the word area, the caller has to take care of the bcc area
1375 if (num_words != 0) {
1376 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1382 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1385 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1387 smb_panic("could not allocate output buffer\n");
1389 req->outbuf = (uint8_t *)outbuf;
1393 /*******************************************************************
1394 Dump a packet to a file.
1395 ********************************************************************/
1397 static void smb_dump(const char *name, int type, const char *data)
1402 if (DEBUGLEVEL < 50) {
1406 len = smb_len_tcp(data)+4;
1407 for (i=1;i<100;i++) {
1408 fname = talloc_asprintf(talloc_tos(),
1412 type ? "req" : "resp");
1413 if (fname == NULL) {
1416 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1417 if (fd != -1 || errno != EEXIST) break;
1421 ssize_t ret = write(fd, data, len);
1423 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1425 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1430 /****************************************************************************
1431 Prepare everything for calling the actual request function, and potentially
1432 call the request function via the "new" interface.
1434 Return False if the "legacy" function needs to be called, everything is
1437 Return True if we're done.
1439 I know this API sucks, but it is the one with the least code change I could
1441 ****************************************************************************/
1443 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1446 uint64_t session_tag;
1447 connection_struct *conn = NULL;
1448 struct smbXsrv_connection *xconn = req->xconn;
1449 NTTIME now = timeval_to_nttime(&req->request_time);
1450 struct smbXsrv_session *session = NULL;
1455 if (!xconn->smb1.negprot.done) {
1458 * Without a negprot the request must
1459 * either be a negprot, or one of the
1460 * evil old SMB mailslot messaging types.
1468 exit_server_cleanly("The first request "
1469 "should be a negprot");
1473 if (smb_messages[type].fn == NULL) {
1474 DEBUG(0,("Unknown message type %d!\n",type));
1475 smb_dump("Unknown", 1, (const char *)req->inbuf);
1476 reply_unknown_new(req, type);
1480 flags = smb_messages[type].flags;
1482 /* In share mode security we must ignore the vuid. */
1483 session_tag = req->vuid;
1486 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1487 (int)getpid(), (unsigned long)conn));
1489 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1491 /* Ensure this value is replaced in the incoming packet. */
1492 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1495 * Ensure the correct username is in current_user_info. This is a
1496 * really ugly bugfix for problems with multiple session_setup_and_X's
1497 * being done and allowing %U and %G substitutions to work correctly.
1498 * There is a reason this code is done here, don't move it unless you
1499 * know what you're doing... :-).
1504 * lookup an existing session
1506 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1507 * here, the main check is still in change_to_user()
1509 status = smb1srv_session_lookup(xconn,
1513 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1516 status = NT_STATUS_OK;
1519 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1520 (unsigned long long)session_tag,
1521 (unsigned long long)req->mid));
1522 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1527 if (session_tag != xconn->client->last_session_id) {
1528 struct user_struct *vuser = NULL;
1530 xconn->client->last_session_id = session_tag;
1532 vuser = session->compat;
1535 set_current_user_info(
1536 vuser->session_info->unix_info->sanitized_username,
1537 vuser->session_info->unix_info->unix_name,
1538 vuser->session_info->info->domain_name);
1542 /* Does this call need to be run as the connected user? */
1543 if (flags & AS_USER) {
1545 /* Does this call need a valid tree connection? */
1548 * Amazingly, the error code depends on the command
1551 if (type == SMBntcreateX) {
1552 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1554 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1559 if (!change_to_user(conn,session_tag)) {
1560 DEBUG(0, ("Error: Could not change to user. Removing "
1561 "deferred open, mid=%llu.\n",
1562 (unsigned long long)req->mid));
1563 reply_force_doserror(req, ERRSRV, ERRbaduid);
1567 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1569 /* Does it need write permission? */
1570 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1571 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1575 /* IPC services are limited */
1576 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1577 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1581 /* This call needs to be run as root */
1582 change_to_root_user();
1585 /* load service specific parameters */
1587 if (req->encrypted) {
1588 conn->encrypted_tid = true;
1589 /* encrypted required from now on. */
1590 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1591 } else if (ENCRYPTION_REQUIRED(conn)) {
1592 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1593 DEBUG(1,("service[%s] requires encryption"
1594 "%s ACCESS_DENIED. mid=%llu\n",
1595 lp_servicename(talloc_tos(), SNUM(conn)),
1597 (unsigned long long)req->mid));
1598 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1603 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1604 (flags & (AS_USER|DO_CHDIR)
1606 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1609 conn->num_smb_operations++;
1613 * Does this protocol need to be run as guest? (Only archane
1614 * messenger service requests have this...)
1616 if (flags & AS_GUEST) {
1620 if (!change_to_guest()) {
1621 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1625 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1627 if (raddr == NULL) {
1628 reply_nterror(req, NT_STATUS_NO_MEMORY);
1633 * Haven't we checked this in smbd_process already???
1636 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1637 xconn->remote_hostname, raddr);
1641 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1646 smb_messages[type].fn(req);
1650 /****************************************************************************
1651 Construct a reply to the incoming packet.
1652 ****************************************************************************/
1654 static void construct_reply(struct smbXsrv_connection *xconn,
1655 char *inbuf, int size, size_t unread_bytes,
1656 uint32_t seqnum, bool encrypted,
1657 struct smb_perfcount_data *deferred_pcd)
1659 struct smbd_server_connection *sconn = xconn->client->sconn;
1660 struct smb_request *req;
1662 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1663 smb_panic("could not allocate smb_request");
1666 if (!init_smb_request(req, sconn, xconn, (uint8 *)inbuf, unread_bytes,
1667 encrypted, seqnum)) {
1668 exit_server_cleanly("Invalid SMB request");
1671 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1673 /* we popped this message off the queue - keep original perf data */
1675 req->pcd = *deferred_pcd;
1677 SMB_PERFCOUNT_START(&req->pcd);
1678 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1679 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1682 req->conn = switch_message(req->cmd, req);
1684 if (req->outbuf == NULL) {
1686 * Request has suspended itself, will come
1691 if (CVAL(req->outbuf,0) == 0) {
1692 show_msg((char *)req->outbuf);
1694 smb_request_done(req);
1697 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1698 char *inbuf, int size, uint32_t seqnum,
1700 struct smb_perfcount_data *deferred_pcd)
1702 struct smb_request **reqs = NULL;
1703 struct smb_request *req;
1707 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, xconn, encrypted,
1708 seqnum, &reqs, &num_reqs);
1710 char errbuf[smb_size];
1711 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1712 __LINE__, __FILE__);
1713 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1715 exit_server_cleanly("construct_reply_chain: "
1716 "srv_send_smb failed.");
1722 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1724 req->conn = switch_message(req->cmd, req);
1726 if (req->outbuf == NULL) {
1728 * Request has suspended itself, will come
1733 smb_request_done(req);
1737 * To be called from an async SMB handler that is potentially chained
1738 * when it is finished for shipping.
1741 void smb_request_done(struct smb_request *req)
1743 struct smb_request **reqs = NULL;
1744 struct smb_request *first_req;
1745 size_t i, num_reqs, next_index;
1748 if (req->chain == NULL) {
1754 num_reqs = talloc_array_length(reqs);
1756 for (i=0; i<num_reqs; i++) {
1757 if (reqs[i] == req) {
1761 if (i == num_reqs) {
1763 * Invalid chain, should not happen
1765 status = NT_STATUS_INTERNAL_ERROR;
1770 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1771 struct smb_request *next = reqs[next_index];
1772 struct smbXsrv_tcon *tcon;
1773 NTTIME now = timeval_to_nttime(&req->request_time);
1775 next->vuid = SVAL(req->outbuf, smb_uid);
1776 next->tid = SVAL(req->outbuf, smb_tid);
1777 status = smb1srv_tcon_lookup(req->xconn, req->tid,
1779 if (NT_STATUS_IS_OK(status)) {
1780 req->conn = tcon->compat;
1784 next->chain_fsp = req->chain_fsp;
1785 next->inbuf = req->inbuf;
1788 req->conn = switch_message(req->cmd, req);
1790 if (req->outbuf == NULL) {
1792 * Request has suspended itself, will come
1800 first_req = reqs[0];
1802 for (i=1; i<next_index; i++) {
1805 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1807 status = NT_STATUS_INTERNAL_ERROR;
1812 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1813 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1816 * This scary statement intends to set the
1817 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1818 * to the value last_req->outbuf carries
1820 SSVAL(first_req->outbuf, smb_flg2,
1821 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1822 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1825 * Transfer the error codes from the subrequest to the main one
1827 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1828 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1831 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1834 if (!srv_send_smb(first_req->xconn,
1835 (char *)first_req->outbuf,
1836 true, first_req->seqnum+1,
1837 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1839 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1842 TALLOC_FREE(req); /* non-chained case */
1843 TALLOC_FREE(reqs); /* chained case */
1848 char errbuf[smb_size];
1849 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1850 if (!srv_send_smb(req->xconn, errbuf, true,
1851 req->seqnum+1, req->encrypted,
1853 exit_server_cleanly("construct_reply_chain: "
1854 "srv_send_smb failed.");
1857 TALLOC_FREE(req); /* non-chained case */
1858 TALLOC_FREE(reqs); /* chained case */
1861 /****************************************************************************
1862 Process an smb from the client
1863 ****************************************************************************/
1864 static void process_smb(struct smbXsrv_connection *xconn,
1865 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1866 uint32_t seqnum, bool encrypted,
1867 struct smb_perfcount_data *deferred_pcd)
1869 struct smbd_server_connection *sconn = xconn->client->sconn;
1870 int msg_type = CVAL(inbuf,0);
1872 DO_PROFILE_INC(smb_count);
1874 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1876 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1877 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1879 if (msg_type != NBSSmessage) {
1881 * NetBIOS session request, keepalive, etc.
1883 reply_special(xconn, (char *)inbuf, nread);
1887 if (sconn->using_smb2) {
1888 /* At this point we're not really using smb2,
1889 * we make the decision here.. */
1890 if (smbd_is_smb2_header(inbuf, nread)) {
1891 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1892 size_t pdulen = nread - NBT_HDR_SIZE;
1893 smbd_smb2_first_negprot(xconn, inpdu, pdulen);
1895 } else if (nread >= smb_size && valid_smb_header(inbuf)
1896 && CVAL(inbuf, smb_com) != 0x72) {
1897 /* This is a non-negprot SMB1 packet.
1898 Disable SMB2 from now on. */
1899 sconn->using_smb2 = false;
1903 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1904 * so subtract 4 from it. */
1905 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1906 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1909 /* special magic for immediate exit */
1911 (IVAL(inbuf, 4) == 0x74697865) &&
1912 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1913 uint8_t exitcode = CVAL(inbuf, 8);
1914 DEBUG(1, ("Exiting immediately with code %d\n",
1919 exit_server_cleanly("Non-SMB packet");
1922 show_msg((char *)inbuf);
1924 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1925 construct_reply_chain(xconn, (char *)inbuf, nread,
1926 seqnum, encrypted, deferred_pcd);
1928 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
1929 seqnum, encrypted, deferred_pcd);
1935 sconn->num_requests++;
1937 /* The timeout_processing function isn't run nearly
1938 often enough to implement 'max log size' without
1939 overrunning the size of the file by many megabytes.
1940 This is especially true if we are running at debug
1941 level 10. Checking every 50 SMBs is a nice
1942 tradeoff of performance vs log file size overrun. */
1944 if ((sconn->num_requests % 50) == 0 &&
1945 need_to_check_log_size()) {
1946 change_to_root_user();
1951 /****************************************************************************
1952 Return a string containing the function name of a SMB command.
1953 ****************************************************************************/
1955 const char *smb_fn_name(int type)
1957 const char *unknown_name = "SMBunknown";
1959 if (smb_messages[type].name == NULL)
1960 return(unknown_name);
1962 return(smb_messages[type].name);
1965 /****************************************************************************
1966 Helper functions for contruct_reply.
1967 ****************************************************************************/
1969 void add_to_common_flags2(uint32 v)
1974 void remove_from_common_flags2(uint32 v)
1976 common_flags2 &= ~v;
1979 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1982 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1983 uint16_t out_flags2 = common_flags2;
1985 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1986 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1987 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1989 srv_set_message(outbuf,0,0,false);
1991 SCVAL(outbuf, smb_com, req->cmd);
1992 SIVAL(outbuf,smb_rcls,0);
1993 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1994 SSVAL(outbuf,smb_flg2, out_flags2);
1995 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1996 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1998 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1999 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2000 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2001 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2004 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2006 construct_reply_common(req, (const char *)req->inbuf, outbuf);
2010 * @brief Find the smb_cmd offset of the last command pushed
2011 * @param[in] buf The buffer we're building up
2012 * @retval Where can we put our next andx cmd?
2014 * While chaining requests, the "next" request we're looking at needs to put
2015 * its SMB_Command before the data the previous request already built up added
2016 * to the chain. Find the offset to the place where we have to put our cmd.
2019 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2024 cmd = CVAL(buf, smb_com);
2026 if (!is_andx_req(cmd)) {
2032 while (CVAL(buf, ofs) != 0xff) {
2034 if (!is_andx_req(CVAL(buf, ofs))) {
2039 * ofs is from start of smb header, so add the 4 length
2040 * bytes. The next cmd is right after the wct field.
2042 ofs = SVAL(buf, ofs+2) + 4 + 1;
2044 if (ofs+4 >= talloc_get_size(buf)) {
2054 * @brief Do the smb chaining at a buffer level
2055 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2056 * @param[in] andx_buf Buffer to be appended
2059 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2061 uint8_t smb_command = CVAL(andx_buf, smb_com);
2062 uint8_t wct = CVAL(andx_buf, smb_wct);
2063 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2064 uint32_t num_bytes = smb_buflen(andx_buf);
2065 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2068 size_t old_size, new_size;
2070 size_t chain_padding = 0;
2071 size_t andx_cmd_ofs;
2074 old_size = talloc_get_size(*poutbuf);
2076 if ((old_size % 4) != 0) {
2078 * Align the wct field of subsequent requests to a 4-byte
2081 chain_padding = 4 - (old_size % 4);
2085 * After the old request comes the new wct field (1 byte), the vwv's
2086 * and the num_bytes field.
2089 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2090 new_size += num_bytes;
2092 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2093 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2094 (unsigned)new_size));
2098 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2099 if (outbuf == NULL) {
2100 DEBUG(0, ("talloc failed\n"));
2105 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2106 DEBUG(1, ("invalid command chain\n"));
2107 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2111 if (chain_padding != 0) {
2112 memset(outbuf + old_size, 0, chain_padding);
2113 old_size += chain_padding;
2116 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2117 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2122 * Push the chained request:
2127 SCVAL(outbuf, ofs, wct);
2134 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2139 * Read&X has an offset into its data buffer at
2140 * vwv[6]. reply_read_andx has no idea anymore that it's
2141 * running from within a chain, so we have to fix up the
2144 * Although it looks disgusting at this place, I want to keep
2145 * it here. The alternative would be to push knowledge about
2146 * the andx chain down into read&x again.
2149 if (smb_command == SMBreadX) {
2150 uint8_t *bytes_addr;
2154 * Invalid read&x response
2159 bytes_addr = outbuf + ofs /* vwv start */
2160 + sizeof(uint16_t) * wct /* vwv array */
2161 + sizeof(uint16_t) /* bcc */
2162 + 1; /* padding byte */
2164 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2165 bytes_addr - outbuf - 4);
2168 ofs += sizeof(uint16_t) * wct;
2174 SSVAL(outbuf, ofs, num_bytes);
2175 ofs += sizeof(uint16_t);
2181 memcpy(outbuf + ofs, bytes, num_bytes);
2186 bool smb1_is_chain(const uint8_t *buf)
2188 uint8_t cmd, wct, andx_cmd;
2190 cmd = CVAL(buf, smb_com);
2191 if (!is_andx_req(cmd)) {
2194 wct = CVAL(buf, smb_wct);
2198 andx_cmd = CVAL(buf, smb_vwv);
2199 return (andx_cmd != 0xFF);
2202 bool smb1_walk_chain(const uint8_t *buf,
2203 bool (*fn)(uint8_t cmd,
2204 uint8_t wct, const uint16_t *vwv,
2205 uint16_t num_bytes, const uint8_t *bytes,
2206 void *private_data),
2209 size_t smblen = smb_len(buf);
2210 const char *smb_buf = smb_base(buf);
2211 uint8_t cmd, chain_cmd;
2213 const uint16_t *vwv;
2215 const uint8_t *bytes;
2217 cmd = CVAL(buf, smb_com);
2218 wct = CVAL(buf, smb_wct);
2219 vwv = (const uint16_t *)(buf + smb_vwv);
2220 num_bytes = smb_buflen(buf);
2221 bytes = (const uint8_t *)smb_buf_const(buf);
2223 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2227 if (!is_andx_req(cmd)) {
2234 chain_cmd = CVAL(vwv, 0);
2236 while (chain_cmd != 0xff) {
2237 uint32_t chain_offset; /* uint32_t to avoid overflow */
2238 size_t length_needed;
2239 ptrdiff_t vwv_offset;
2241 chain_offset = SVAL(vwv+1, 0);
2244 * Check if the client tries to fool us. The chain
2245 * offset needs to point beyond the current request in
2246 * the chain, it needs to strictly grow. Otherwise we
2247 * might be tricked into an endless loop always
2248 * processing the same request over and over again. We
2249 * used to assume that vwv and the byte buffer array
2250 * in a chain are always attached, but OS/2 the
2251 * Write&X/Read&X chain puts the Read&X vwv array
2252 * right behind the Write&X vwv chain. The Write&X bcc
2253 * array is put behind the Read&X vwv array. So now we
2254 * check whether the chain offset points strictly
2255 * behind the previous vwv array. req->buf points
2256 * right after the vwv array of the previous
2258 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2262 vwv_offset = ((const char *)vwv - smb_buf);
2263 if (chain_offset <= vwv_offset) {
2268 * Next check: Make sure the chain offset does not
2269 * point beyond the overall smb request length.
2272 length_needed = chain_offset+1; /* wct */
2273 if (length_needed > smblen) {
2278 * Now comes the pointer magic. Goal here is to set up
2279 * vwv and buf correctly again. The chain offset (the
2280 * former vwv[1]) points at the new wct field.
2283 wct = CVAL(smb_buf, chain_offset);
2285 if (is_andx_req(chain_cmd) && (wct < 2)) {
2290 * Next consistency check: Make the new vwv array fits
2291 * in the overall smb request.
2294 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2295 if (length_needed > smblen) {
2298 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2301 * Now grab the new byte buffer....
2304 num_bytes = SVAL(vwv+wct, 0);
2307 * .. and check that it fits.
2310 length_needed += num_bytes;
2311 if (length_needed > smblen) {
2314 bytes = (const uint8_t *)(vwv+wct+1);
2316 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2320 if (!is_andx_req(chain_cmd)) {
2323 chain_cmd = CVAL(vwv, 0);
2328 static bool smb1_chain_length_cb(uint8_t cmd,
2329 uint8_t wct, const uint16_t *vwv,
2330 uint16_t num_bytes, const uint8_t *bytes,
2333 unsigned *count = (unsigned *)private_data;
2338 unsigned smb1_chain_length(const uint8_t *buf)
2342 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2348 struct smb1_parse_chain_state {
2349 TALLOC_CTX *mem_ctx;
2351 struct smbd_server_connection *sconn;
2352 struct smbXsrv_connection *xconn;
2356 struct smb_request **reqs;
2360 static bool smb1_parse_chain_cb(uint8_t cmd,
2361 uint8_t wct, const uint16_t *vwv,
2362 uint16_t num_bytes, const uint8_t *bytes,
2365 struct smb1_parse_chain_state *state =
2366 (struct smb1_parse_chain_state *)private_data;
2367 struct smb_request **reqs;
2368 struct smb_request *req;
2371 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2372 struct smb_request *, state->num_reqs+1);
2378 req = talloc(reqs, struct smb_request);
2383 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2384 state->encrypted, state->seqnum);
2391 req->buflen = num_bytes;
2394 reqs[state->num_reqs] = req;
2395 state->num_reqs += 1;
2399 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2400 struct smbXsrv_connection *xconn,
2401 bool encrypted, uint32_t seqnum,
2402 struct smb_request ***reqs, unsigned *num_reqs)
2404 struct smbd_server_connection *sconn = NULL;
2405 struct smb1_parse_chain_state state;
2408 if (xconn != NULL) {
2409 sconn = xconn->client->sconn;
2412 state.mem_ctx = mem_ctx;
2414 state.sconn = sconn;
2415 state.xconn = xconn;
2416 state.encrypted = encrypted;
2417 state.seqnum = seqnum;
2421 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2422 TALLOC_FREE(state.reqs);
2425 for (i=0; i<state.num_reqs; i++) {
2426 state.reqs[i]->chain = state.reqs;
2429 *num_reqs = state.num_reqs;
2433 /****************************************************************************
2434 Check if services need reloading.
2435 ****************************************************************************/
2437 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2440 if (last_smb_conf_reload_time == 0) {
2441 last_smb_conf_reload_time = t;
2444 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2445 reload_services(sconn, conn_snum_used, true);
2446 last_smb_conf_reload_time = t;
2450 static bool fd_is_readable(int fd)
2454 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2456 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2460 static void smbd_server_connection_write_handler(
2461 struct smbXsrv_connection *xconn)
2463 /* TODO: make write nonblocking */
2466 static void smbd_server_connection_read_handler(
2467 struct smbXsrv_connection *xconn, int fd)
2469 uint8_t *inbuf = NULL;
2470 size_t inbuf_len = 0;
2471 size_t unread_bytes = 0;
2472 bool encrypted = false;
2473 TALLOC_CTX *mem_ctx = talloc_tos();
2477 bool async_echo = lp_async_smb_echo_handler();
2478 bool from_client = false;
2481 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2483 * This is the super-ugly hack to prefer the packets
2484 * forwarded by the echo handler over the ones by the
2487 fd = xconn->smb1.echo_handler.trusted_fd;
2491 from_client = (xconn->transport.sock == fd);
2493 if (async_echo && from_client) {
2494 smbd_lock_socket(xconn);
2496 if (!fd_is_readable(fd)) {
2497 DEBUG(10,("the echo listener was faster\n"));
2498 smbd_unlock_socket(xconn);
2503 /* TODO: make this completely nonblocking */
2504 status = receive_smb_talloc(mem_ctx, xconn, fd,
2505 (char **)(void *)&inbuf,
2509 &inbuf_len, &seqnum,
2510 !from_client /* trusted channel */);
2512 if (async_echo && from_client) {
2513 smbd_unlock_socket(xconn);
2516 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2519 if (NT_STATUS_IS_ERR(status)) {
2520 exit_server_cleanly("failed to receive smb request");
2522 if (!NT_STATUS_IS_OK(status)) {
2527 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2528 seqnum, encrypted, NULL);
2531 static void smbd_server_connection_handler(struct tevent_context *ev,
2532 struct tevent_fd *fde,
2536 struct smbXsrv_connection *xconn =
2537 talloc_get_type_abort(private_data,
2538 struct smbXsrv_connection);
2540 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2542 * we're not supposed to do any io
2544 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2545 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2549 if (flags & TEVENT_FD_WRITE) {
2550 smbd_server_connection_write_handler(xconn);
2553 if (flags & TEVENT_FD_READ) {
2554 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2559 static void smbd_server_echo_handler(struct tevent_context *ev,
2560 struct tevent_fd *fde,
2564 struct smbXsrv_connection *xconn =
2565 talloc_get_type_abort(private_data,
2566 struct smbXsrv_connection);
2568 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2570 * we're not supposed to do any io
2572 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2573 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2577 if (flags & TEVENT_FD_WRITE) {
2578 smbd_server_connection_write_handler(xconn);
2581 if (flags & TEVENT_FD_READ) {
2582 smbd_server_connection_read_handler(
2583 xconn, xconn->smb1.echo_handler.trusted_fd);
2588 struct smbd_release_ip_state {
2589 struct smbXsrv_connection *xconn;
2590 struct tevent_immediate *im;
2591 char addr[INET6_ADDRSTRLEN];
2594 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2595 struct tevent_immediate *im,
2598 struct smbd_release_ip_state *state =
2599 talloc_get_type_abort(private_data,
2600 struct smbd_release_ip_state);
2601 struct smbXsrv_connection *xconn = state->xconn;
2603 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2605 * smbd_server_connection_terminate() already triggered ?
2610 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2613 /****************************************************************************
2614 received when we should release a specific IP
2615 ****************************************************************************/
2616 static bool release_ip(const char *ip, void *priv)
2618 struct smbd_release_ip_state *state =
2619 talloc_get_type_abort(priv,
2620 struct smbd_release_ip_state);
2621 struct smbXsrv_connection *xconn = state->xconn;
2622 const char *addr = state->addr;
2623 const char *p = addr;
2625 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2626 /* avoid recursion */
2630 if (strncmp("::ffff:", addr, 7) == 0) {
2634 DEBUG(10, ("Got release IP message for %s, "
2635 "our address is %s\n", ip, p));
2637 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2638 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2641 * With SMB2 we should do a clean disconnect,
2642 * the previous_session_id in the session setup
2643 * will cleanup the old session, tcons and opens.
2645 * A clean disconnect is needed in order to support
2648 * Note: typically this is never triggered
2649 * as we got a TCP RST (triggered by ctdb event scripts)
2650 * before we get CTDB_SRVID_RELEASE_IP.
2652 * We used to call _exit(1) here, but as this was mostly never
2653 * triggered and has implication on our process model,
2654 * we can just use smbd_server_connection_terminate()
2657 * We don't call smbd_server_connection_terminate() directly
2658 * as we might be called from within ctdbd_migrate(),
2659 * we need to defer our action to the next event loop
2661 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2662 smbd_release_ip_immediate, state);
2665 * Make sure we don't get any io on the connection.
2667 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2674 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2675 struct sockaddr_storage *srv,
2676 struct sockaddr_storage *clnt)
2678 struct smbd_release_ip_state *state;
2679 struct ctdbd_connection *cconn;
2681 cconn = messaging_ctdbd_connection();
2682 if (cconn == NULL) {
2683 return NT_STATUS_NO_MEMORY;
2686 state = talloc_zero(xconn, struct smbd_release_ip_state);
2687 if (state == NULL) {
2688 return NT_STATUS_NO_MEMORY;
2690 state->xconn = xconn;
2691 state->im = tevent_create_immediate(state);
2692 if (state->im == NULL) {
2693 return NT_STATUS_NO_MEMORY;
2695 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2696 return NT_STATUS_NO_MEMORY;
2699 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2702 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2703 void *private_data, uint32_t msg_type,
2704 struct server_id server_id, DATA_BLOB *data)
2706 struct smbd_server_connection *sconn = talloc_get_type_abort(
2707 private_data, struct smbd_server_connection);
2708 const char *ip = (char *) data->data;
2711 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2713 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2715 if (client_ip == NULL) {
2719 if (strequal(ip, client_ip)) {
2720 DEBUG(1, ("Got kill client message for %s - "
2721 "exiting immediately\n", ip));
2722 exit_server_cleanly("Forced disconnect for client");
2725 TALLOC_FREE(client_ip);
2729 * Send keepalive packets to our client
2731 static bool keepalive_fn(const struct timeval *now, void *private_data)
2733 struct smbd_server_connection *sconn = talloc_get_type_abort(
2734 private_data, struct smbd_server_connection);
2735 struct smbXsrv_connection *xconn = NULL;
2738 if (sconn->using_smb2) {
2739 /* Don't do keepalives on an SMB2 connection. */
2744 * With SMB1 we only have 1 connection
2746 xconn = sconn->client->connections;
2747 smbd_lock_socket(xconn);
2748 ret = send_keepalive(xconn->transport.sock);
2749 smbd_unlock_socket(xconn);
2752 int saved_errno = errno;
2754 * Try and give an error message saying what
2757 DEBUG(0, ("send_keepalive failed for client %s. "
2758 "Error %s - exiting\n",
2759 smbXsrv_connection_dbg(xconn),
2760 strerror(saved_errno)));
2761 errno = saved_errno;
2768 * Do the recurring check if we're idle
2770 static bool deadtime_fn(const struct timeval *now, void *private_data)
2772 struct smbd_server_connection *sconn =
2773 (struct smbd_server_connection *)private_data;
2775 if ((conn_num_open(sconn) == 0)
2776 || (conn_idle_all(sconn, now->tv_sec))) {
2777 DEBUG( 2, ( "Closing idle connection\n" ) );
2778 messaging_send(sconn->msg_ctx,
2779 messaging_server_id(sconn->msg_ctx),
2780 MSG_SHUTDOWN, &data_blob_null);
2788 * Do the recurring log file and smb.conf reload checks.
2791 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2793 struct smbd_server_connection *sconn = talloc_get_type_abort(
2794 private_data, struct smbd_server_connection);
2796 DEBUG(5, ("housekeeping\n"));
2798 change_to_root_user();
2800 /* update printer queue caches if necessary */
2801 update_monitored_printq_cache(sconn->msg_ctx);
2803 /* check if we need to reload services */
2804 check_reload(sconn, time_mono(NULL));
2807 * Force a log file check.
2809 force_check_log_size();
2815 * Read an smb packet in the echo handler child, giving the parent
2816 * smbd one second to react once the socket becomes readable.
2819 struct smbd_echo_read_state {
2820 struct tevent_context *ev;
2821 struct smbXsrv_connection *xconn;
2828 static void smbd_echo_read_readable(struct tevent_req *subreq);
2829 static void smbd_echo_read_waited(struct tevent_req *subreq);
2831 static struct tevent_req *smbd_echo_read_send(
2832 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2833 struct smbXsrv_connection *xconn)
2835 struct tevent_req *req, *subreq;
2836 struct smbd_echo_read_state *state;
2838 req = tevent_req_create(mem_ctx, &state,
2839 struct smbd_echo_read_state);
2844 state->xconn = xconn;
2846 subreq = wait_for_read_send(state, ev, xconn->transport.sock);
2847 if (tevent_req_nomem(subreq, req)) {
2848 return tevent_req_post(req, ev);
2850 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2854 static void smbd_echo_read_readable(struct tevent_req *subreq)
2856 struct tevent_req *req = tevent_req_callback_data(
2857 subreq, struct tevent_req);
2858 struct smbd_echo_read_state *state = tevent_req_data(
2859 req, struct smbd_echo_read_state);
2863 ok = wait_for_read_recv(subreq, &err);
2864 TALLOC_FREE(subreq);
2866 tevent_req_nterror(req, map_nt_error_from_unix(err));
2871 * Give the parent smbd one second to step in
2874 subreq = tevent_wakeup_send(
2875 state, state->ev, timeval_current_ofs(1, 0));
2876 if (tevent_req_nomem(subreq, req)) {
2879 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2882 static void smbd_echo_read_waited(struct tevent_req *subreq)
2884 struct tevent_req *req = tevent_req_callback_data(
2885 subreq, struct tevent_req);
2886 struct smbd_echo_read_state *state = tevent_req_data(
2887 req, struct smbd_echo_read_state);
2888 struct smbXsrv_connection *xconn = state->xconn;
2894 ok = tevent_wakeup_recv(subreq);
2895 TALLOC_FREE(subreq);
2897 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2901 ok = smbd_lock_socket_internal(xconn);
2903 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2904 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2908 if (!fd_is_readable(xconn->transport.sock)) {
2909 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2912 ok = smbd_unlock_socket_internal(xconn);
2914 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2915 DEBUG(1, ("%s: failed to unlock socket\n",
2920 subreq = wait_for_read_send(state, state->ev,
2921 xconn->transport.sock);
2922 if (tevent_req_nomem(subreq, req)) {
2925 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2929 status = receive_smb_talloc(state, xconn,
2930 xconn->transport.sock,
2937 false /* trusted_channel*/);
2939 if (tevent_req_nterror(req, status)) {
2940 tevent_req_nterror(req, status);
2941 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2942 (int)getpid(), nt_errstr(status)));
2946 ok = smbd_unlock_socket_internal(xconn);
2948 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2949 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2952 tevent_req_done(req);
2955 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2956 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2958 struct smbd_echo_read_state *state = tevent_req_data(
2959 req, struct smbd_echo_read_state);
2962 if (tevent_req_is_nterror(req, &status)) {
2965 *pbuf = talloc_move(mem_ctx, &state->buf);
2966 *pbuflen = state->buflen;
2967 *pseqnum = state->seqnum;
2968 return NT_STATUS_OK;
2971 struct smbd_echo_state {
2972 struct tevent_context *ev;
2973 struct iovec *pending;
2974 struct smbd_server_connection *sconn;
2975 struct smbXsrv_connection *xconn;
2978 struct tevent_fd *parent_fde;
2980 struct tevent_req *write_req;
2983 static void smbd_echo_writer_done(struct tevent_req *req);
2985 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2989 if (state->write_req != NULL) {
2993 num_pending = talloc_array_length(state->pending);
2994 if (num_pending == 0) {
2998 state->write_req = writev_send(state, state->ev, NULL,
2999 state->parent_pipe, false,
3000 state->pending, num_pending);
3001 if (state->write_req == NULL) {
3002 DEBUG(1, ("writev_send failed\n"));
3006 talloc_steal(state->write_req, state->pending);
3007 state->pending = NULL;
3009 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3013 static void smbd_echo_writer_done(struct tevent_req *req)
3015 struct smbd_echo_state *state = tevent_req_callback_data(
3016 req, struct smbd_echo_state);
3020 written = writev_recv(req, &err);
3022 state->write_req = NULL;
3023 if (written == -1) {
3024 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3027 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3028 smbd_echo_activate_writer(state);
3031 static bool smbd_echo_reply(struct smbd_echo_state *state,
3032 uint8_t *inbuf, size_t inbuf_len,
3035 struct smb_request req;
3036 uint16_t num_replies;
3040 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3041 DEBUG(10, ("Got netbios keepalive\n"));
3048 if (inbuf_len < smb_size) {
3049 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3052 if (!valid_smb_header(inbuf)) {
3053 DEBUG(10, ("Got invalid SMB header\n"));
3057 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3063 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3064 smb_messages[req.cmd].name
3065 ? smb_messages[req.cmd].name : "unknown"));
3067 if (req.cmd != SMBecho) {
3074 num_replies = SVAL(req.vwv+0, 0);
3075 if (num_replies != 1) {
3076 /* Not a Windows "Hey, you're still there?" request */
3080 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3082 DEBUG(10, ("create_outbuf failed\n"));
3085 req.outbuf = (uint8_t *)outbuf;
3087 SSVAL(req.outbuf, smb_vwv0, num_replies);
3089 if (req.buflen > 0) {
3090 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3093 ok = srv_send_smb(req.xconn,
3097 TALLOC_FREE(outbuf);
3105 static void smbd_echo_exit(struct tevent_context *ev,
3106 struct tevent_fd *fde, uint16_t flags,
3109 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3113 static void smbd_echo_got_packet(struct tevent_req *req);
3115 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3118 struct smbd_echo_state *state;
3119 struct tevent_req *read_req;
3121 state = talloc_zero(xconn, struct smbd_echo_state);
3122 if (state == NULL) {
3123 DEBUG(1, ("talloc failed\n"));
3126 state->xconn = xconn;
3127 state->parent_pipe = parent_pipe;
3128 state->ev = s3_tevent_context_init(state);
3129 if (state->ev == NULL) {
3130 DEBUG(1, ("tevent_context_init failed\n"));
3134 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3135 TEVENT_FD_READ, smbd_echo_exit,
3137 if (state->parent_fde == NULL) {
3138 DEBUG(1, ("tevent_add_fd failed\n"));
3143 read_req = smbd_echo_read_send(state, state->ev, xconn);
3144 if (read_req == NULL) {
3145 DEBUG(1, ("smbd_echo_read_send failed\n"));
3149 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3152 if (tevent_loop_once(state->ev) == -1) {
3153 DEBUG(1, ("tevent_loop_once failed: %s\n",
3161 static void smbd_echo_got_packet(struct tevent_req *req)
3163 struct smbd_echo_state *state = tevent_req_callback_data(
3164 req, struct smbd_echo_state);
3168 uint32_t seqnum = 0;
3171 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3173 if (!NT_STATUS_IS_OK(status)) {
3174 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3175 nt_errstr(status)));
3179 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3185 num_pending = talloc_array_length(state->pending);
3186 tmp = talloc_realloc(state, state->pending, struct iovec,
3189 DEBUG(1, ("talloc_realloc failed\n"));
3192 state->pending = tmp;
3194 if (buflen >= smb_size) {
3196 * place the seqnum in the packet so that the main process
3197 * can reply with signing
3199 SIVAL(buf, smb_ss_field, seqnum);
3200 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3203 iov = &state->pending[num_pending];
3204 iov->iov_base = talloc_move(state->pending, &buf);
3205 iov->iov_len = buflen;
3207 DEBUG(10,("echo_handler[%d]: forward to main\n",
3209 smbd_echo_activate_writer(state);
3212 req = smbd_echo_read_send(state, state->ev, state->xconn);
3214 DEBUG(1, ("smbd_echo_read_send failed\n"));
3217 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3222 * Handle SMBecho requests in a forked child process
3224 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3226 int listener_pipe[2];
3229 bool use_mutex = false;
3231 res = pipe(listener_pipe);
3233 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3237 #ifdef HAVE_ROBUST_MUTEXES
3238 use_mutex = tdb_runtime_check_for_robust_mutexes();
3241 pthread_mutexattr_t a;
3243 xconn->smb1.echo_handler.socket_mutex =
3244 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3245 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3246 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3251 res = pthread_mutexattr_init(&a);
3253 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3257 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3259 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3261 pthread_mutexattr_destroy(&a);
3264 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3266 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3268 pthread_mutexattr_destroy(&a);
3271 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3273 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3274 "%s\n", strerror(res)));
3275 pthread_mutexattr_destroy(&a);
3278 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3280 pthread_mutexattr_destroy(&a);
3282 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3290 xconn->smb1.echo_handler.socket_lock_fd =
3291 create_unlink_tmp(lp_lock_directory());
3292 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3293 DEBUG(1, ("Could not create lock fd: %s\n",
3303 close(listener_pipe[0]);
3304 set_blocking(listener_pipe[1], false);
3306 status = reinit_after_fork(xconn->msg_ctx,
3309 if (!NT_STATUS_IS_OK(status)) {
3310 DEBUG(1, ("reinit_after_fork failed: %s\n",
3311 nt_errstr(status)));
3314 smbd_echo_loop(xconn, listener_pipe[1]);
3317 close(listener_pipe[1]);
3318 listener_pipe[1] = -1;
3319 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3321 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3324 * Without smb signing this is the same as the normal smbd
3325 * listener. This needs to change once signing comes in.
3327 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3329 xconn->smb1.echo_handler.trusted_fd,
3331 smbd_server_echo_handler,
3333 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3334 DEBUG(1, ("event_add_fd failed\n"));
3341 if (listener_pipe[0] != -1) {
3342 close(listener_pipe[0]);
3344 if (listener_pipe[1] != -1) {
3345 close(listener_pipe[1]);
3347 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3348 close(xconn->smb1.echo_handler.socket_lock_fd);
3350 #ifdef HAVE_ROBUST_MUTEXES
3351 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3352 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3353 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3356 smbd_echo_init(xconn);
3361 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3364 if (user->session_info &&
3365 (user->session_info->unix_token->uid == uid)) {
3373 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3376 if (user->session_info != NULL) {
3378 struct security_unix_token *utok;
3380 utok = user->session_info->unix_token;
3381 if (utok->gid == gid) {
3384 for(i=0; i<utok->ngroups; i++) {
3385 if (utok->groups[i] == gid) {
3395 static bool sid_in_use(const struct user_struct *user,
3396 const struct dom_sid *psid)
3399 struct security_token *tok;
3401 if (user->session_info == NULL) {
3404 tok = user->session_info->security_token;
3407 * Not sure session_info->security_token can
3408 * ever be NULL. This check might be not
3413 if (security_token_has_sid(tok, psid)) {
3421 static bool id_in_use(const struct user_struct *user,
3422 const struct id_cache_ref *id)
3426 return uid_in_use(user, id->id.uid);
3428 return gid_in_use(user, id->id.gid);
3430 return sid_in_use(user, &id->id.sid);
3437 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3440 struct server_id server_id,
3443 const char *msg = (data && data->data)
3444 ? (const char *)data->data : "<NULL>";
3445 struct id_cache_ref id;
3446 struct smbd_server_connection *sconn =
3447 talloc_get_type_abort(private_data,
3448 struct smbd_server_connection);
3450 if (!id_cache_ref_parse(msg, &id)) {
3451 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3455 if (id_in_use(sconn->users, &id)) {
3456 exit_server_cleanly(msg);
3458 id_cache_delete_from_cache(&id);
3461 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3462 enum protocol_types protocol)
3466 set_Protocol(protocol);
3467 conn->protocol = protocol;
3469 if (protocol >= PROTOCOL_SMB2_02) {
3470 status = smb2srv_session_table_init(conn);
3471 if (!NT_STATUS_IS_OK(status)) {
3475 status = smb2srv_open_table_init(conn);
3476 if (!NT_STATUS_IS_OK(status)) {
3480 status = smb1srv_session_table_init(conn);
3481 if (!NT_STATUS_IS_OK(status)) {
3485 status = smb1srv_tcon_table_init(conn);
3486 if (!NT_STATUS_IS_OK(status)) {
3490 status = smb1srv_open_table_init(conn);
3491 if (!NT_STATUS_IS_OK(status)) {
3496 return NT_STATUS_OK;
3499 struct smbd_tevent_trace_state {
3501 uint64_t smbd_idle_profstamp;
3504 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3507 struct smbd_tevent_trace_state *state =
3508 (struct smbd_tevent_trace_state *)private_data;
3511 case TEVENT_TRACE_BEFORE_WAIT:
3513 * This just removes compiler warning
3514 * without profile support
3516 state->smbd_idle_profstamp = 0;
3517 START_PROFILE_STAMP(smbd_idle, state->smbd_idle_profstamp);
3519 case TEVENT_TRACE_AFTER_WAIT:
3520 END_PROFILE_STAMP(smbd_idle, state->smbd_idle_profstamp);
3522 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3523 TALLOC_FREE(state->frame);
3524 state->frame = talloc_stackframe_pool(8192);
3526 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3527 TALLOC_FREE(state->frame);
3535 * Create a debug string for the connection
3537 * This is allocated to talloc_tos() or a string constant
3538 * in certain corner cases. The returned string should
3539 * hence not be free'd directly but only via the talloc stack.
3541 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3546 * TODO: this can be improved later
3547 * maybe including the client guid or more
3549 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3551 return "<tsocket_address_string() failed>";
3557 /****************************************************************************
3558 Process commands from the client
3559 ****************************************************************************/
3561 void smbd_process(struct tevent_context *ev_ctx,
3562 struct messaging_context *msg_ctx,
3566 struct smbd_tevent_trace_state trace_state = {
3567 .frame = talloc_stackframe(),
3569 struct smbXsrv_client *client;
3570 struct smbXsrv_connection *xconn;
3571 struct smbd_server_connection *sconn;
3572 struct sockaddr_storage ss_srv;
3573 void *sp_srv = (void *)&ss_srv;
3574 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3575 struct sockaddr_storage ss_clnt;
3576 void *sp_clnt = (void *)&ss_clnt;
3577 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3578 socklen_t sa_socklen;
3579 struct tsocket_address *local_address = NULL;
3580 struct tsocket_address *remote_address = NULL;
3581 const char *locaddr = NULL;
3582 const char *remaddr = NULL;
3587 client = talloc_zero(ev_ctx, struct smbXsrv_client);
3588 if (client == NULL) {
3589 DEBUG(0,("talloc_zero(struct smbXsrv_client)\n"));
3590 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3594 * TODO: remove this...:-)
3596 global_smbXsrv_client = client;
3598 client->ev_ctx = ev_ctx;
3599 client->msg_ctx = msg_ctx;
3601 sconn = talloc_zero(client, struct smbd_server_connection);
3602 if (sconn == NULL) {
3603 exit_server("failed to create smbd_server_connection");
3606 client->sconn = sconn;
3607 sconn->client = client;
3609 sconn->ev_ctx = ev_ctx;
3610 sconn->msg_ctx = msg_ctx;
3612 xconn = talloc_zero(client, struct smbXsrv_connection);
3613 if (xconn == NULL) {
3614 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3615 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3617 /* for now we only have one connection */
3618 DLIST_ADD_END(client->connections, xconn, NULL);
3619 xconn->client = client;
3621 xconn->ev_ctx = ev_ctx;
3622 xconn->msg_ctx = msg_ctx;
3623 xconn->transport.sock = sock_fd;
3624 smbd_echo_init(xconn);
3627 * TODO: remove this...:-)
3629 sconn->conn = xconn;
3632 smbd_setup_sig_term_handler(sconn);
3633 smbd_setup_sig_hup_handler(sconn);
3635 if (!serverid_register(messaging_server_id(msg_ctx),
3636 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3638 |FLAG_MSG_PRINT_GENERAL)) {
3639 exit_server_cleanly("Could not register myself in "
3644 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3646 * We're not making the decision here,
3647 * we're just allowing the client
3648 * to decide between SMB1 and SMB2
3649 * with the first negprot
3652 sconn->using_smb2 = true;
3655 /* Ensure child is set to blocking mode */
3656 set_blocking(sock_fd,True);
3658 set_socket_options(sock_fd, "SO_KEEPALIVE");
3659 set_socket_options(sock_fd, lp_socket_options());
3661 sa_socklen = sizeof(ss_clnt);
3662 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3664 int level = (errno == ENOTCONN)?2:0;
3665 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3666 exit_server_cleanly("getpeername() failed.\n");
3668 ret = tsocket_address_bsd_from_sockaddr(sconn,
3669 sa_clnt, sa_socklen,
3672 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3673 __location__, strerror(errno)));
3674 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3677 sa_socklen = sizeof(ss_srv);
3678 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3680 int level = (errno == ENOTCONN)?2:0;
3681 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3682 exit_server_cleanly("getsockname() failed.\n");
3684 ret = tsocket_address_bsd_from_sockaddr(sconn,
3688 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3689 __location__, strerror(errno)));
3690 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3693 sconn->local_address = local_address;
3694 sconn->remote_address = remote_address;
3696 if (tsocket_address_is_inet(local_address, "ip")) {
3697 locaddr = tsocket_address_inet_addr_string(
3698 sconn->local_address,
3700 if (locaddr == NULL) {
3701 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3702 __location__, strerror(errno)));
3703 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3706 locaddr = "0.0.0.0";
3709 if (tsocket_address_is_inet(remote_address, "ip")) {
3710 remaddr = tsocket_address_inet_addr_string(
3711 sconn->remote_address,
3713 if (remaddr == NULL) {
3714 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3715 __location__, strerror(errno)));
3716 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3719 remaddr = "0.0.0.0";
3722 /* this is needed so that we get decent entries
3723 in smbstatus for port 445 connects */
3724 set_remote_machine_name(remaddr, false);
3725 reload_services(sconn, conn_snum_used, true);
3728 * Before the first packet, check the global hosts allow/ hosts deny
3729 * parameters before doing any parsing of packets passed to us by the
3730 * client. This prevents attacks on our parsing code from hosts not in
3731 * the hosts allow list.
3734 ret = get_remote_hostname(remote_address,
3738 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3739 __location__, strerror(errno)));
3740 exit_server_cleanly("get_remote_hostname failed.\n");
3742 if (strequal(rhost, "UNKNOWN")) {
3743 rhost = talloc_strdup(talloc_tos(), remaddr);
3745 sconn->remote_hostname = talloc_move(sconn, &rhost);
3747 sub_set_socket_ids(remaddr,
3748 sconn->remote_hostname,
3751 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3752 sconn->remote_hostname,
3755 * send a negative session response "not listening on calling
3758 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3759 DEBUG( 1, ("Connection denied from %s to %s\n",
3760 tsocket_address_string(remote_address, talloc_tos()),
3761 tsocket_address_string(local_address, talloc_tos())));
3762 (void)srv_send_smb(xconn,(char *)buf, false,
3764 exit_server_cleanly("connection denied");
3767 DEBUG(10, ("Connection allowed from %s to %s\n",
3768 tsocket_address_string(remote_address, talloc_tos()),
3769 tsocket_address_string(local_address, talloc_tos())));
3771 if (lp_preload_modules()) {
3772 smb_load_modules(lp_preload_modules());
3775 smb_perfcount_init();
3777 if (!init_account_policy()) {
3778 exit_server("Could not open account policy tdb.\n");
3781 if (*lp_root_directory(talloc_tos())) {
3782 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3783 DEBUG(0,("Failed to change root to %s\n",
3784 lp_root_directory(talloc_tos())));
3785 exit_server("Failed to chroot()");
3787 if (chdir("/") == -1) {
3788 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3789 exit_server("Failed to chroot()");
3791 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3794 if (!srv_init_signing(xconn)) {
3795 exit_server("Failed to init smb_signing");
3798 if (!file_init(sconn)) {
3799 exit_server("file_init() failed");
3803 if (!init_oplocks(sconn))
3804 exit_server("Failed to init oplocks");
3806 /* register our message handlers */
3807 messaging_register(sconn->msg_ctx, sconn,
3808 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3809 messaging_register(sconn->msg_ctx, sconn,
3810 MSG_SMB_CLOSE_FILE, msg_close_file);
3811 messaging_register(sconn->msg_ctx, sconn,
3812 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3814 id_cache_register_msgs(sconn->msg_ctx);
3815 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3816 messaging_register(sconn->msg_ctx, sconn,
3817 ID_CACHE_KILL, smbd_id_cache_kill);
3819 messaging_deregister(sconn->msg_ctx,
3820 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3821 messaging_register(sconn->msg_ctx, sconn,
3822 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3824 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3826 messaging_register(sconn->msg_ctx, sconn,
3827 MSG_SMB_KILL_CLIENT_IP,
3828 msg_kill_client_ip);
3830 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3833 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3834 * MSGs to all child processes
3836 messaging_deregister(sconn->msg_ctx,
3838 messaging_register(sconn->msg_ctx, NULL,
3839 MSG_DEBUG, debug_message);
3841 if ((lp_keepalive() != 0)
3842 && !(event_add_idle(ev_ctx, NULL,
3843 timeval_set(lp_keepalive(), 0),
3844 "keepalive", keepalive_fn,
3846 DEBUG(0, ("Could not add keepalive event\n"));
3850 if (!(event_add_idle(ev_ctx, NULL,
3851 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3852 "deadtime", deadtime_fn, sconn))) {
3853 DEBUG(0, ("Could not add deadtime event\n"));
3857 if (!(event_add_idle(ev_ctx, NULL,
3858 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3859 "housekeeping", housekeeping_fn, sconn))) {
3860 DEBUG(0, ("Could not add housekeeping event\n"));
3864 if (lp_clustering()) {
3866 * We need to tell ctdb about our client's TCP
3867 * connection, so that for failover ctdbd can send
3868 * tickle acks, triggering a reconnection by the
3873 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3874 if (!NT_STATUS_IS_OK(status)) {
3875 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3876 nt_errstr(status)));
3880 tmp = lp_max_xmit();
3881 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3882 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3884 xconn->smb1.negprot.max_recv = tmp;
3886 xconn->smb1.sessions.done_sesssetup = false;
3887 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3889 if (!init_dptrs(sconn)) {
3890 exit_server("init_dptrs() failed");
3893 xconn->transport.fde = tevent_add_fd(ev_ctx,
3897 smbd_server_connection_handler,
3899 if (!xconn->transport.fde) {
3900 exit_server("failed to create smbd_server_connection fde");
3903 xconn->local_address = sconn->local_address;
3904 xconn->remote_address = sconn->remote_address;
3905 xconn->remote_hostname = sconn->remote_hostname;
3906 xconn->protocol = PROTOCOL_NONE;
3908 TALLOC_FREE(trace_state.frame);
3910 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
3913 ret = tevent_loop_wait(ev_ctx);
3915 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
3916 " exiting\n", ret, strerror(errno)));
3919 TALLOC_FREE(trace_state.frame);
3921 exit_server_cleanly(NULL);
3924 bool req_is_in_chain(const struct smb_request *req)
3926 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3928 * We're right now handling a subsequent request, so we must
3934 if (!is_andx_req(req->cmd)) {
3940 * Okay, an illegal request, but definitely not chained :-)
3945 return (CVAL(req->vwv+0, 0) != 0xFF);