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 smbd_server_connection *sconn, uint64_t mid)
858 struct pending_message_list *pml;
860 if (sconn->using_smb2) {
861 return open_was_deferred_smb2(sconn, mid);
864 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
865 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
872 /****************************************************************************
873 Return the message queued by this mid.
874 ****************************************************************************/
876 static struct pending_message_list *get_deferred_open_message_smb(
877 struct smbd_server_connection *sconn, uint64_t mid)
879 struct pending_message_list *pml;
881 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
882 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
889 /****************************************************************************
890 Get the state data queued by this mid.
891 ****************************************************************************/
893 bool get_deferred_open_message_state(struct smb_request *smbreq,
894 struct timeval *p_request_time,
895 struct deferred_open_record **open_rec)
897 struct pending_message_list *pml;
899 if (smbreq->sconn->using_smb2) {
900 return get_deferred_open_message_state_smb2(smbreq->smb2req,
905 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
909 if (p_request_time) {
910 *p_request_time = pml->request_time;
912 if (open_rec != NULL) {
913 *open_rec = pml->open_rec;
918 /****************************************************************************
919 Function to push a deferred open smb message onto a linked list of local smb
920 messages ready for processing.
921 ****************************************************************************/
923 bool push_deferred_open_message_smb(struct smb_request *req,
924 struct timeval request_time,
925 struct timeval timeout,
927 struct deferred_open_record *open_rec)
929 struct timeval end_time;
932 return push_deferred_open_message_smb2(req->smb2req,
939 if (req->unread_bytes) {
940 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
941 "unread_bytes = %u\n",
942 (unsigned int)req->unread_bytes ));
943 smb_panic("push_deferred_open_message_smb: "
944 "logic error unread_bytes != 0" );
947 end_time = timeval_sum(&request_time, &timeout);
949 DEBUG(10,("push_deferred_open_message_smb: pushing message "
950 "len %u mid %llu timeout time [%u.%06u]\n",
951 (unsigned int) smb_len(req->inbuf)+4,
952 (unsigned long long)req->mid,
953 (unsigned int)end_time.tv_sec,
954 (unsigned int)end_time.tv_usec));
956 return push_queued_message(req, request_time, end_time, open_rec);
959 static void smbd_sig_term_handler(struct tevent_context *ev,
960 struct tevent_signal *se,
966 exit_server_cleanly("termination signal");
969 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
971 struct tevent_signal *se;
973 se = tevent_add_signal(sconn->ev_ctx,
976 smbd_sig_term_handler,
979 exit_server("failed to setup SIGTERM handler");
983 static void smbd_sig_hup_handler(struct tevent_context *ev,
984 struct tevent_signal *se,
990 struct smbd_server_connection *sconn =
991 talloc_get_type_abort(private_data,
992 struct smbd_server_connection);
994 change_to_root_user();
995 DEBUG(1,("Reloading services after SIGHUP\n"));
996 reload_services(sconn, conn_snum_used, false);
999 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1001 struct tevent_signal *se;
1003 se = tevent_add_signal(sconn->ev_ctx,
1006 smbd_sig_hup_handler,
1009 exit_server("failed to setup SIGHUP handler");
1013 static void smbd_conf_updated(struct messaging_context *msg,
1016 struct server_id server_id,
1019 struct smbd_server_connection *sconn =
1020 talloc_get_type_abort(private_data,
1021 struct smbd_server_connection);
1023 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1024 "updated. Reloading.\n"));
1025 change_to_root_user();
1026 reload_services(sconn, conn_snum_used, false);
1030 * Only allow 5 outstanding trans requests. We're allocating memory, so
1034 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1037 for (; list != NULL; list = list->next) {
1039 if (list->mid == mid) {
1040 return NT_STATUS_INVALID_PARAMETER;
1046 return NT_STATUS_INSUFFICIENT_RESOURCES;
1049 return NT_STATUS_OK;
1053 These flags determine some of the permissions required to do an operation
1055 Note that I don't set NEED_WRITE on some write operations because they
1056 are used by some brain-dead clients when printing, and I don't want to
1057 force write permissions on print services.
1059 #define AS_USER (1<<0)
1060 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1061 #define TIME_INIT (1<<2)
1062 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1063 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1064 #define DO_CHDIR (1<<6)
1067 define a list of possible SMB messages and their corresponding
1068 functions. Any message that has a NULL function is unimplemented -
1069 please feel free to contribute implementations!
1071 static const struct smb_message_struct {
1073 void (*fn)(struct smb_request *req);
1075 } smb_messages[256] = {
1077 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1078 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1079 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1080 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1081 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1082 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1083 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1084 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1085 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1086 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1087 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1088 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1089 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1090 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1091 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1092 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1093 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1094 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1095 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1096 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1097 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1098 /* 0x15 */ { NULL, NULL, 0 },
1099 /* 0x16 */ { NULL, NULL, 0 },
1100 /* 0x17 */ { NULL, NULL, 0 },
1101 /* 0x18 */ { NULL, NULL, 0 },
1102 /* 0x19 */ { NULL, NULL, 0 },
1103 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1104 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1105 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1106 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1107 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1108 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1109 /* 0x20 */ { "SMBwritec", NULL,0},
1110 /* 0x21 */ { NULL, NULL, 0 },
1111 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1112 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1113 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1114 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1115 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1116 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1117 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1118 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1119 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1120 /* 0x2b */ { "SMBecho",reply_echo,0},
1121 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1122 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1123 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1124 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1125 /* 0x30 */ { NULL, NULL, 0 },
1126 /* 0x31 */ { NULL, NULL, 0 },
1127 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1128 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1129 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1130 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1131 /* 0x36 */ { NULL, NULL, 0 },
1132 /* 0x37 */ { NULL, NULL, 0 },
1133 /* 0x38 */ { NULL, NULL, 0 },
1134 /* 0x39 */ { NULL, NULL, 0 },
1135 /* 0x3a */ { NULL, NULL, 0 },
1136 /* 0x3b */ { NULL, NULL, 0 },
1137 /* 0x3c */ { NULL, NULL, 0 },
1138 /* 0x3d */ { NULL, NULL, 0 },
1139 /* 0x3e */ { NULL, NULL, 0 },
1140 /* 0x3f */ { NULL, NULL, 0 },
1141 /* 0x40 */ { NULL, NULL, 0 },
1142 /* 0x41 */ { NULL, NULL, 0 },
1143 /* 0x42 */ { NULL, NULL, 0 },
1144 /* 0x43 */ { NULL, NULL, 0 },
1145 /* 0x44 */ { NULL, NULL, 0 },
1146 /* 0x45 */ { NULL, NULL, 0 },
1147 /* 0x46 */ { NULL, NULL, 0 },
1148 /* 0x47 */ { NULL, NULL, 0 },
1149 /* 0x48 */ { NULL, NULL, 0 },
1150 /* 0x49 */ { NULL, NULL, 0 },
1151 /* 0x4a */ { NULL, NULL, 0 },
1152 /* 0x4b */ { NULL, NULL, 0 },
1153 /* 0x4c */ { NULL, NULL, 0 },
1154 /* 0x4d */ { NULL, NULL, 0 },
1155 /* 0x4e */ { NULL, NULL, 0 },
1156 /* 0x4f */ { NULL, NULL, 0 },
1157 /* 0x50 */ { NULL, NULL, 0 },
1158 /* 0x51 */ { NULL, NULL, 0 },
1159 /* 0x52 */ { NULL, NULL, 0 },
1160 /* 0x53 */ { NULL, NULL, 0 },
1161 /* 0x54 */ { NULL, NULL, 0 },
1162 /* 0x55 */ { NULL, NULL, 0 },
1163 /* 0x56 */ { NULL, NULL, 0 },
1164 /* 0x57 */ { NULL, NULL, 0 },
1165 /* 0x58 */ { NULL, NULL, 0 },
1166 /* 0x59 */ { NULL, NULL, 0 },
1167 /* 0x5a */ { NULL, NULL, 0 },
1168 /* 0x5b */ { NULL, NULL, 0 },
1169 /* 0x5c */ { NULL, NULL, 0 },
1170 /* 0x5d */ { NULL, NULL, 0 },
1171 /* 0x5e */ { NULL, NULL, 0 },
1172 /* 0x5f */ { NULL, NULL, 0 },
1173 /* 0x60 */ { NULL, NULL, 0 },
1174 /* 0x61 */ { NULL, NULL, 0 },
1175 /* 0x62 */ { NULL, NULL, 0 },
1176 /* 0x63 */ { NULL, NULL, 0 },
1177 /* 0x64 */ { NULL, NULL, 0 },
1178 /* 0x65 */ { NULL, NULL, 0 },
1179 /* 0x66 */ { NULL, NULL, 0 },
1180 /* 0x67 */ { NULL, NULL, 0 },
1181 /* 0x68 */ { NULL, NULL, 0 },
1182 /* 0x69 */ { NULL, NULL, 0 },
1183 /* 0x6a */ { NULL, NULL, 0 },
1184 /* 0x6b */ { NULL, NULL, 0 },
1185 /* 0x6c */ { NULL, NULL, 0 },
1186 /* 0x6d */ { NULL, NULL, 0 },
1187 /* 0x6e */ { NULL, NULL, 0 },
1188 /* 0x6f */ { NULL, NULL, 0 },
1189 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1190 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1191 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1192 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1193 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1194 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1195 /* 0x76 */ { NULL, NULL, 0 },
1196 /* 0x77 */ { NULL, NULL, 0 },
1197 /* 0x78 */ { NULL, NULL, 0 },
1198 /* 0x79 */ { NULL, NULL, 0 },
1199 /* 0x7a */ { NULL, NULL, 0 },
1200 /* 0x7b */ { NULL, NULL, 0 },
1201 /* 0x7c */ { NULL, NULL, 0 },
1202 /* 0x7d */ { NULL, NULL, 0 },
1203 /* 0x7e */ { NULL, NULL, 0 },
1204 /* 0x7f */ { NULL, NULL, 0 },
1205 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1206 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1207 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1208 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1209 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1210 /* 0x85 */ { NULL, NULL, 0 },
1211 /* 0x86 */ { NULL, NULL, 0 },
1212 /* 0x87 */ { NULL, NULL, 0 },
1213 /* 0x88 */ { NULL, NULL, 0 },
1214 /* 0x89 */ { NULL, NULL, 0 },
1215 /* 0x8a */ { NULL, NULL, 0 },
1216 /* 0x8b */ { NULL, NULL, 0 },
1217 /* 0x8c */ { NULL, NULL, 0 },
1218 /* 0x8d */ { NULL, NULL, 0 },
1219 /* 0x8e */ { NULL, NULL, 0 },
1220 /* 0x8f */ { NULL, NULL, 0 },
1221 /* 0x90 */ { NULL, NULL, 0 },
1222 /* 0x91 */ { NULL, NULL, 0 },
1223 /* 0x92 */ { NULL, NULL, 0 },
1224 /* 0x93 */ { NULL, NULL, 0 },
1225 /* 0x94 */ { NULL, NULL, 0 },
1226 /* 0x95 */ { NULL, NULL, 0 },
1227 /* 0x96 */ { NULL, NULL, 0 },
1228 /* 0x97 */ { NULL, NULL, 0 },
1229 /* 0x98 */ { NULL, NULL, 0 },
1230 /* 0x99 */ { NULL, NULL, 0 },
1231 /* 0x9a */ { NULL, NULL, 0 },
1232 /* 0x9b */ { NULL, NULL, 0 },
1233 /* 0x9c */ { NULL, NULL, 0 },
1234 /* 0x9d */ { NULL, NULL, 0 },
1235 /* 0x9e */ { NULL, NULL, 0 },
1236 /* 0x9f */ { NULL, NULL, 0 },
1237 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1238 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1239 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1240 /* 0xa3 */ { NULL, NULL, 0 },
1241 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1242 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1243 /* 0xa6 */ { NULL, NULL, 0 },
1244 /* 0xa7 */ { NULL, NULL, 0 },
1245 /* 0xa8 */ { NULL, NULL, 0 },
1246 /* 0xa9 */ { NULL, NULL, 0 },
1247 /* 0xaa */ { NULL, NULL, 0 },
1248 /* 0xab */ { NULL, NULL, 0 },
1249 /* 0xac */ { NULL, NULL, 0 },
1250 /* 0xad */ { NULL, NULL, 0 },
1251 /* 0xae */ { NULL, NULL, 0 },
1252 /* 0xaf */ { NULL, NULL, 0 },
1253 /* 0xb0 */ { NULL, NULL, 0 },
1254 /* 0xb1 */ { NULL, NULL, 0 },
1255 /* 0xb2 */ { NULL, NULL, 0 },
1256 /* 0xb3 */ { NULL, NULL, 0 },
1257 /* 0xb4 */ { NULL, NULL, 0 },
1258 /* 0xb5 */ { NULL, NULL, 0 },
1259 /* 0xb6 */ { NULL, NULL, 0 },
1260 /* 0xb7 */ { NULL, NULL, 0 },
1261 /* 0xb8 */ { NULL, NULL, 0 },
1262 /* 0xb9 */ { NULL, NULL, 0 },
1263 /* 0xba */ { NULL, NULL, 0 },
1264 /* 0xbb */ { NULL, NULL, 0 },
1265 /* 0xbc */ { NULL, NULL, 0 },
1266 /* 0xbd */ { NULL, NULL, 0 },
1267 /* 0xbe */ { NULL, NULL, 0 },
1268 /* 0xbf */ { NULL, NULL, 0 },
1269 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1270 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1271 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1272 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1273 /* 0xc4 */ { NULL, NULL, 0 },
1274 /* 0xc5 */ { NULL, NULL, 0 },
1275 /* 0xc6 */ { NULL, NULL, 0 },
1276 /* 0xc7 */ { NULL, NULL, 0 },
1277 /* 0xc8 */ { NULL, NULL, 0 },
1278 /* 0xc9 */ { NULL, NULL, 0 },
1279 /* 0xca */ { NULL, NULL, 0 },
1280 /* 0xcb */ { NULL, NULL, 0 },
1281 /* 0xcc */ { NULL, NULL, 0 },
1282 /* 0xcd */ { NULL, NULL, 0 },
1283 /* 0xce */ { NULL, NULL, 0 },
1284 /* 0xcf */ { NULL, NULL, 0 },
1285 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1286 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1287 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1288 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1289 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1290 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1291 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1292 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1293 /* 0xd8 */ { NULL, NULL, 0 },
1294 /* 0xd9 */ { NULL, NULL, 0 },
1295 /* 0xda */ { NULL, NULL, 0 },
1296 /* 0xdb */ { NULL, NULL, 0 },
1297 /* 0xdc */ { NULL, NULL, 0 },
1298 /* 0xdd */ { NULL, NULL, 0 },
1299 /* 0xde */ { NULL, NULL, 0 },
1300 /* 0xdf */ { NULL, NULL, 0 },
1301 /* 0xe0 */ { NULL, NULL, 0 },
1302 /* 0xe1 */ { NULL, NULL, 0 },
1303 /* 0xe2 */ { NULL, NULL, 0 },
1304 /* 0xe3 */ { NULL, NULL, 0 },
1305 /* 0xe4 */ { NULL, NULL, 0 },
1306 /* 0xe5 */ { NULL, NULL, 0 },
1307 /* 0xe6 */ { NULL, NULL, 0 },
1308 /* 0xe7 */ { NULL, NULL, 0 },
1309 /* 0xe8 */ { NULL, NULL, 0 },
1310 /* 0xe9 */ { NULL, NULL, 0 },
1311 /* 0xea */ { NULL, NULL, 0 },
1312 /* 0xeb */ { NULL, NULL, 0 },
1313 /* 0xec */ { NULL, NULL, 0 },
1314 /* 0xed */ { NULL, NULL, 0 },
1315 /* 0xee */ { NULL, NULL, 0 },
1316 /* 0xef */ { NULL, NULL, 0 },
1317 /* 0xf0 */ { NULL, NULL, 0 },
1318 /* 0xf1 */ { NULL, NULL, 0 },
1319 /* 0xf2 */ { NULL, NULL, 0 },
1320 /* 0xf3 */ { NULL, NULL, 0 },
1321 /* 0xf4 */ { NULL, NULL, 0 },
1322 /* 0xf5 */ { NULL, NULL, 0 },
1323 /* 0xf6 */ { NULL, NULL, 0 },
1324 /* 0xf7 */ { NULL, NULL, 0 },
1325 /* 0xf8 */ { NULL, NULL, 0 },
1326 /* 0xf9 */ { NULL, NULL, 0 },
1327 /* 0xfa */ { NULL, NULL, 0 },
1328 /* 0xfb */ { NULL, NULL, 0 },
1329 /* 0xfc */ { NULL, NULL, 0 },
1330 /* 0xfd */ { NULL, NULL, 0 },
1331 /* 0xfe */ { NULL, NULL, 0 },
1332 /* 0xff */ { NULL, NULL, 0 }
1336 /*******************************************************************
1337 allocate and initialize a reply packet
1338 ********************************************************************/
1340 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1341 const char *inbuf, char **outbuf, uint8_t num_words,
1344 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1347 * Protect against integer wrap.
1348 * The SMB layer reply can be up to 0xFFFFFF bytes.
1350 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1352 if (asprintf(&msg, "num_bytes too large: %u",
1353 (unsigned)num_bytes) == -1) {
1354 msg = discard_const_p(char, "num_bytes too large");
1360 * Here we include the NBT header for now.
1362 *outbuf = talloc_array(mem_ctx, char,
1363 NBT_HDR_SIZE + smb_len);
1364 if (*outbuf == NULL) {
1368 construct_reply_common(req, inbuf, *outbuf);
1369 srv_set_message(*outbuf, num_words, num_bytes, false);
1371 * Zero out the word area, the caller has to take care of the bcc area
1374 if (num_words != 0) {
1375 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1381 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1384 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1386 smb_panic("could not allocate output buffer\n");
1388 req->outbuf = (uint8_t *)outbuf;
1392 /*******************************************************************
1393 Dump a packet to a file.
1394 ********************************************************************/
1396 static void smb_dump(const char *name, int type, const char *data)
1401 if (DEBUGLEVEL < 50) {
1405 len = smb_len_tcp(data)+4;
1406 for (i=1;i<100;i++) {
1407 fname = talloc_asprintf(talloc_tos(),
1411 type ? "req" : "resp");
1412 if (fname == NULL) {
1415 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1416 if (fd != -1 || errno != EEXIST) break;
1420 ssize_t ret = write(fd, data, len);
1422 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1424 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1429 /****************************************************************************
1430 Prepare everything for calling the actual request function, and potentially
1431 call the request function via the "new" interface.
1433 Return False if the "legacy" function needs to be called, everything is
1436 Return True if we're done.
1438 I know this API sucks, but it is the one with the least code change I could
1440 ****************************************************************************/
1442 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1445 uint64_t session_tag;
1446 connection_struct *conn = NULL;
1447 struct smbXsrv_connection *xconn = req->xconn;
1448 NTTIME now = timeval_to_nttime(&req->request_time);
1449 struct smbXsrv_session *session = NULL;
1454 if (!xconn->smb1.negprot.done) {
1457 * Without a negprot the request must
1458 * either be a negprot, or one of the
1459 * evil old SMB mailslot messaging types.
1467 exit_server_cleanly("The first request "
1468 "should be a negprot");
1472 if (smb_messages[type].fn == NULL) {
1473 DEBUG(0,("Unknown message type %d!\n",type));
1474 smb_dump("Unknown", 1, (const char *)req->inbuf);
1475 reply_unknown_new(req, type);
1479 flags = smb_messages[type].flags;
1481 /* In share mode security we must ignore the vuid. */
1482 session_tag = req->vuid;
1485 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1486 (int)getpid(), (unsigned long)conn));
1488 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1490 /* Ensure this value is replaced in the incoming packet. */
1491 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1494 * Ensure the correct username is in current_user_info. This is a
1495 * really ugly bugfix for problems with multiple session_setup_and_X's
1496 * being done and allowing %U and %G substitutions to work correctly.
1497 * There is a reason this code is done here, don't move it unless you
1498 * know what you're doing... :-).
1503 * lookup an existing session
1505 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1506 * here, the main check is still in change_to_user()
1508 status = smb1srv_session_lookup(xconn,
1512 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1515 status = NT_STATUS_OK;
1518 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1519 (unsigned long long)session_tag,
1520 (unsigned long long)req->mid));
1521 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1526 if (session_tag != xconn->last_session_id) {
1527 struct user_struct *vuser = NULL;
1529 xconn->last_session_id = session_tag;
1531 vuser = session->compat;
1534 set_current_user_info(
1535 vuser->session_info->unix_info->sanitized_username,
1536 vuser->session_info->unix_info->unix_name,
1537 vuser->session_info->info->domain_name);
1541 /* Does this call need to be run as the connected user? */
1542 if (flags & AS_USER) {
1544 /* Does this call need a valid tree connection? */
1547 * Amazingly, the error code depends on the command
1550 if (type == SMBntcreateX) {
1551 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1553 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1558 if (!change_to_user(conn,session_tag)) {
1559 DEBUG(0, ("Error: Could not change to user. Removing "
1560 "deferred open, mid=%llu.\n",
1561 (unsigned long long)req->mid));
1562 reply_force_doserror(req, ERRSRV, ERRbaduid);
1566 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1568 /* Does it need write permission? */
1569 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1570 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1574 /* IPC services are limited */
1575 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1576 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1580 /* This call needs to be run as root */
1581 change_to_root_user();
1584 /* load service specific parameters */
1586 if (req->encrypted) {
1587 conn->encrypted_tid = true;
1588 /* encrypted required from now on. */
1589 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1590 } else if (ENCRYPTION_REQUIRED(conn)) {
1591 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1592 DEBUG(1,("service[%s] requires encryption"
1593 "%s ACCESS_DENIED. mid=%llu\n",
1594 lp_servicename(talloc_tos(), SNUM(conn)),
1596 (unsigned long long)req->mid));
1597 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1602 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1603 (flags & (AS_USER|DO_CHDIR)
1605 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1608 conn->num_smb_operations++;
1612 * Does this protocol need to be run as guest? (Only archane
1613 * messenger service requests have this...)
1615 if (flags & AS_GUEST) {
1619 if (!change_to_guest()) {
1620 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1624 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1626 if (raddr == NULL) {
1627 reply_nterror(req, NT_STATUS_NO_MEMORY);
1632 * Haven't we checked this in smbd_process already???
1635 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1636 xconn->remote_hostname, raddr);
1640 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1645 smb_messages[type].fn(req);
1649 /****************************************************************************
1650 Construct a reply to the incoming packet.
1651 ****************************************************************************/
1653 static void construct_reply(struct smbd_server_connection *sconn,
1654 char *inbuf, int size, size_t unread_bytes,
1655 uint32_t seqnum, bool encrypted,
1656 struct smb_perfcount_data *deferred_pcd)
1658 struct smbXsrv_connection *xconn = sconn->conn;
1659 struct smb_request *req;
1661 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1662 smb_panic("could not allocate smb_request");
1665 if (!init_smb_request(req, sconn, xconn, (uint8 *)inbuf, unread_bytes,
1666 encrypted, seqnum)) {
1667 exit_server_cleanly("Invalid SMB request");
1670 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1672 /* we popped this message off the queue - keep original perf data */
1674 req->pcd = *deferred_pcd;
1676 SMB_PERFCOUNT_START(&req->pcd);
1677 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1678 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1681 req->conn = switch_message(req->cmd, req);
1683 if (req->outbuf == NULL) {
1685 * Request has suspended itself, will come
1690 if (CVAL(req->outbuf,0) == 0) {
1691 show_msg((char *)req->outbuf);
1693 smb_request_done(req);
1696 static void construct_reply_chain(struct smbd_server_connection *sconn,
1697 char *inbuf, int size, uint32_t seqnum,
1699 struct smb_perfcount_data *deferred_pcd)
1701 struct smbXsrv_connection *xconn = sconn->conn;
1702 struct smb_request **reqs = NULL;
1703 struct smb_request *req;
1707 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, 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->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(sconn, (char *)inbuf, nread,
1926 seqnum, encrypted, deferred_pcd);
1928 construct_reply(sconn, (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 smbd_server_connection *sconn,
2401 bool encrypted, uint32_t seqnum,
2402 struct smb_request ***reqs, unsigned *num_reqs)
2404 struct smbXsrv_connection *xconn = sconn->conn;
2405 struct smb1_parse_chain_state state;
2408 state.mem_ctx = mem_ctx;
2410 state.sconn = sconn;
2411 state.xconn = xconn;
2412 state.encrypted = encrypted;
2413 state.seqnum = seqnum;
2417 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2418 TALLOC_FREE(state.reqs);
2421 for (i=0; i<state.num_reqs; i++) {
2422 state.reqs[i]->chain = state.reqs;
2425 *num_reqs = state.num_reqs;
2429 /****************************************************************************
2430 Check if services need reloading.
2431 ****************************************************************************/
2433 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2436 if (last_smb_conf_reload_time == 0) {
2437 last_smb_conf_reload_time = t;
2440 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2441 reload_services(sconn, conn_snum_used, true);
2442 last_smb_conf_reload_time = t;
2446 static bool fd_is_readable(int fd)
2450 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2452 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2456 static void smbd_server_connection_write_handler(
2457 struct smbXsrv_connection *xconn)
2459 /* TODO: make write nonblocking */
2462 static void smbd_server_connection_read_handler(
2463 struct smbXsrv_connection *xconn, int fd)
2465 uint8_t *inbuf = NULL;
2466 size_t inbuf_len = 0;
2467 size_t unread_bytes = 0;
2468 bool encrypted = false;
2469 TALLOC_CTX *mem_ctx = talloc_tos();
2473 bool async_echo = lp_async_smb_echo_handler();
2474 bool from_client = false;
2477 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2479 * This is the super-ugly hack to prefer the packets
2480 * forwarded by the echo handler over the ones by the
2483 fd = xconn->smb1.echo_handler.trusted_fd;
2487 from_client = (xconn->transport.sock == fd);
2489 if (async_echo && from_client) {
2490 smbd_lock_socket(xconn);
2492 if (!fd_is_readable(fd)) {
2493 DEBUG(10,("the echo listener was faster\n"));
2494 smbd_unlock_socket(xconn);
2499 /* TODO: make this completely nonblocking */
2500 status = receive_smb_talloc(mem_ctx, xconn, fd,
2501 (char **)(void *)&inbuf,
2505 &inbuf_len, &seqnum,
2506 !from_client /* trusted channel */);
2508 if (async_echo && from_client) {
2509 smbd_unlock_socket(xconn);
2512 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2515 if (NT_STATUS_IS_ERR(status)) {
2516 exit_server_cleanly("failed to receive smb request");
2518 if (!NT_STATUS_IS_OK(status)) {
2523 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2524 seqnum, encrypted, NULL);
2527 static void smbd_server_connection_handler(struct tevent_context *ev,
2528 struct tevent_fd *fde,
2532 struct smbXsrv_connection *xconn =
2533 talloc_get_type_abort(private_data,
2534 struct smbXsrv_connection);
2536 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2538 * we're not supposed to do any io
2540 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2541 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2545 if (flags & TEVENT_FD_WRITE) {
2546 smbd_server_connection_write_handler(xconn);
2549 if (flags & TEVENT_FD_READ) {
2550 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2555 static void smbd_server_echo_handler(struct tevent_context *ev,
2556 struct tevent_fd *fde,
2560 struct smbXsrv_connection *xconn =
2561 talloc_get_type_abort(private_data,
2562 struct smbXsrv_connection);
2564 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2566 * we're not supposed to do any io
2568 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2569 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2573 if (flags & TEVENT_FD_WRITE) {
2574 smbd_server_connection_write_handler(xconn);
2577 if (flags & TEVENT_FD_READ) {
2578 smbd_server_connection_read_handler(
2579 xconn, xconn->smb1.echo_handler.trusted_fd);
2584 struct smbd_release_ip_state {
2585 struct smbXsrv_connection *xconn;
2586 struct tevent_immediate *im;
2587 char addr[INET6_ADDRSTRLEN];
2590 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2591 struct tevent_immediate *im,
2594 struct smbd_release_ip_state *state =
2595 talloc_get_type_abort(private_data,
2596 struct smbd_release_ip_state);
2597 struct smbXsrv_connection *xconn = state->xconn;
2599 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2601 * smbd_server_connection_terminate() already triggered ?
2606 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2609 /****************************************************************************
2610 received when we should release a specific IP
2611 ****************************************************************************/
2612 static bool release_ip(const char *ip, void *priv)
2614 struct smbd_release_ip_state *state =
2615 talloc_get_type_abort(priv,
2616 struct smbd_release_ip_state);
2617 struct smbXsrv_connection *xconn = state->xconn;
2618 const char *addr = state->addr;
2619 const char *p = addr;
2621 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2622 /* avoid recursion */
2626 if (strncmp("::ffff:", addr, 7) == 0) {
2630 DEBUG(10, ("Got release IP message for %s, "
2631 "our address is %s\n", ip, p));
2633 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2634 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2637 * With SMB2 we should do a clean disconnect,
2638 * the previous_session_id in the session setup
2639 * will cleanup the old session, tcons and opens.
2641 * A clean disconnect is needed in order to support
2644 * Note: typically this is never triggered
2645 * as we got a TCP RST (triggered by ctdb event scripts)
2646 * before we get CTDB_SRVID_RELEASE_IP.
2648 * We used to call _exit(1) here, but as this was mostly never
2649 * triggered and has implication on our process model,
2650 * we can just use smbd_server_connection_terminate()
2653 * We don't call smbd_server_connection_terminate() directly
2654 * as we might be called from within ctdbd_migrate(),
2655 * we need to defer our action to the next event loop
2657 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2658 smbd_release_ip_immediate, state);
2661 * Make sure we don't get any io on the connection.
2663 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2670 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2671 struct sockaddr_storage *srv,
2672 struct sockaddr_storage *clnt)
2674 struct smbd_release_ip_state *state;
2675 struct ctdbd_connection *cconn;
2677 cconn = messaging_ctdbd_connection();
2678 if (cconn == NULL) {
2679 return NT_STATUS_NO_MEMORY;
2682 state = talloc_zero(xconn, struct smbd_release_ip_state);
2683 if (state == NULL) {
2684 return NT_STATUS_NO_MEMORY;
2686 state->xconn = xconn;
2687 state->im = tevent_create_immediate(state);
2688 if (state->im == NULL) {
2689 return NT_STATUS_NO_MEMORY;
2691 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2692 return NT_STATUS_NO_MEMORY;
2695 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2698 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2699 void *private_data, uint32_t msg_type,
2700 struct server_id server_id, DATA_BLOB *data)
2702 struct smbd_server_connection *sconn = talloc_get_type_abort(
2703 private_data, struct smbd_server_connection);
2704 const char *ip = (char *) data->data;
2707 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2709 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2711 if (client_ip == NULL) {
2715 if (strequal(ip, client_ip)) {
2716 DEBUG(1, ("Got kill client message for %s - "
2717 "exiting immediately\n", ip));
2718 exit_server_cleanly("Forced disconnect for client");
2721 TALLOC_FREE(client_ip);
2725 * Send keepalive packets to our client
2727 static bool keepalive_fn(const struct timeval *now, void *private_data)
2729 struct smbd_server_connection *sconn = talloc_get_type_abort(
2730 private_data, struct smbd_server_connection);
2731 struct smbXsrv_connection *xconn = sconn->conn;
2734 if (sconn->using_smb2) {
2735 /* Don't do keepalives on an SMB2 connection. */
2739 smbd_lock_socket(xconn);
2740 ret = send_keepalive(xconn->transport.sock);
2741 smbd_unlock_socket(xconn);
2744 int saved_errno = errno;
2746 * Try and give an error message saying what
2749 DEBUG(0, ("send_keepalive failed for client %s. "
2750 "Error %s - exiting\n",
2751 smbXsrv_connection_dbg(xconn),
2752 strerror(saved_errno)));
2753 errno = saved_errno;
2760 * Do the recurring check if we're idle
2762 static bool deadtime_fn(const struct timeval *now, void *private_data)
2764 struct smbd_server_connection *sconn =
2765 (struct smbd_server_connection *)private_data;
2767 if ((conn_num_open(sconn) == 0)
2768 || (conn_idle_all(sconn, now->tv_sec))) {
2769 DEBUG( 2, ( "Closing idle connection\n" ) );
2770 messaging_send(sconn->msg_ctx,
2771 messaging_server_id(sconn->msg_ctx),
2772 MSG_SHUTDOWN, &data_blob_null);
2780 * Do the recurring log file and smb.conf reload checks.
2783 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2785 struct smbd_server_connection *sconn = talloc_get_type_abort(
2786 private_data, struct smbd_server_connection);
2788 DEBUG(5, ("housekeeping\n"));
2790 change_to_root_user();
2792 /* update printer queue caches if necessary */
2793 update_monitored_printq_cache(sconn->msg_ctx);
2795 /* check if we need to reload services */
2796 check_reload(sconn, time_mono(NULL));
2799 * Force a log file check.
2801 force_check_log_size();
2807 * Read an smb packet in the echo handler child, giving the parent
2808 * smbd one second to react once the socket becomes readable.
2811 struct smbd_echo_read_state {
2812 struct tevent_context *ev;
2813 struct smbXsrv_connection *xconn;
2820 static void smbd_echo_read_readable(struct tevent_req *subreq);
2821 static void smbd_echo_read_waited(struct tevent_req *subreq);
2823 static struct tevent_req *smbd_echo_read_send(
2824 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2825 struct smbXsrv_connection *xconn)
2827 struct tevent_req *req, *subreq;
2828 struct smbd_echo_read_state *state;
2830 req = tevent_req_create(mem_ctx, &state,
2831 struct smbd_echo_read_state);
2836 state->xconn = xconn;
2838 subreq = wait_for_read_send(state, ev, xconn->transport.sock);
2839 if (tevent_req_nomem(subreq, req)) {
2840 return tevent_req_post(req, ev);
2842 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2846 static void smbd_echo_read_readable(struct tevent_req *subreq)
2848 struct tevent_req *req = tevent_req_callback_data(
2849 subreq, struct tevent_req);
2850 struct smbd_echo_read_state *state = tevent_req_data(
2851 req, struct smbd_echo_read_state);
2855 ok = wait_for_read_recv(subreq, &err);
2856 TALLOC_FREE(subreq);
2858 tevent_req_nterror(req, map_nt_error_from_unix(err));
2863 * Give the parent smbd one second to step in
2866 subreq = tevent_wakeup_send(
2867 state, state->ev, timeval_current_ofs(1, 0));
2868 if (tevent_req_nomem(subreq, req)) {
2871 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2874 static void smbd_echo_read_waited(struct tevent_req *subreq)
2876 struct tevent_req *req = tevent_req_callback_data(
2877 subreq, struct tevent_req);
2878 struct smbd_echo_read_state *state = tevent_req_data(
2879 req, struct smbd_echo_read_state);
2880 struct smbXsrv_connection *xconn = state->xconn;
2886 ok = tevent_wakeup_recv(subreq);
2887 TALLOC_FREE(subreq);
2889 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2893 ok = smbd_lock_socket_internal(xconn);
2895 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2896 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2900 if (!fd_is_readable(xconn->transport.sock)) {
2901 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2904 ok = smbd_unlock_socket_internal(xconn);
2906 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2907 DEBUG(1, ("%s: failed to unlock socket\n",
2912 subreq = wait_for_read_send(state, state->ev,
2913 xconn->transport.sock);
2914 if (tevent_req_nomem(subreq, req)) {
2917 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2921 status = receive_smb_talloc(state, xconn,
2922 xconn->transport.sock,
2929 false /* trusted_channel*/);
2931 if (tevent_req_nterror(req, status)) {
2932 tevent_req_nterror(req, status);
2933 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2934 (int)getpid(), nt_errstr(status)));
2938 ok = smbd_unlock_socket_internal(xconn);
2940 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2941 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2944 tevent_req_done(req);
2947 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2948 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2950 struct smbd_echo_read_state *state = tevent_req_data(
2951 req, struct smbd_echo_read_state);
2954 if (tevent_req_is_nterror(req, &status)) {
2957 *pbuf = talloc_move(mem_ctx, &state->buf);
2958 *pbuflen = state->buflen;
2959 *pseqnum = state->seqnum;
2960 return NT_STATUS_OK;
2963 struct smbd_echo_state {
2964 struct tevent_context *ev;
2965 struct iovec *pending;
2966 struct smbd_server_connection *sconn;
2967 struct smbXsrv_connection *xconn;
2970 struct tevent_fd *parent_fde;
2972 struct tevent_req *write_req;
2975 static void smbd_echo_writer_done(struct tevent_req *req);
2977 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2981 if (state->write_req != NULL) {
2985 num_pending = talloc_array_length(state->pending);
2986 if (num_pending == 0) {
2990 state->write_req = writev_send(state, state->ev, NULL,
2991 state->parent_pipe, false,
2992 state->pending, num_pending);
2993 if (state->write_req == NULL) {
2994 DEBUG(1, ("writev_send failed\n"));
2998 talloc_steal(state->write_req, state->pending);
2999 state->pending = NULL;
3001 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3005 static void smbd_echo_writer_done(struct tevent_req *req)
3007 struct smbd_echo_state *state = tevent_req_callback_data(
3008 req, struct smbd_echo_state);
3012 written = writev_recv(req, &err);
3014 state->write_req = NULL;
3015 if (written == -1) {
3016 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3019 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3020 smbd_echo_activate_writer(state);
3023 static bool smbd_echo_reply(struct smbd_echo_state *state,
3024 uint8_t *inbuf, size_t inbuf_len,
3027 struct smb_request req;
3028 uint16_t num_replies;
3032 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3033 DEBUG(10, ("Got netbios keepalive\n"));
3040 if (inbuf_len < smb_size) {
3041 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3044 if (!valid_smb_header(inbuf)) {
3045 DEBUG(10, ("Got invalid SMB header\n"));
3049 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3055 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3056 smb_messages[req.cmd].name
3057 ? smb_messages[req.cmd].name : "unknown"));
3059 if (req.cmd != SMBecho) {
3066 num_replies = SVAL(req.vwv+0, 0);
3067 if (num_replies != 1) {
3068 /* Not a Windows "Hey, you're still there?" request */
3072 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3074 DEBUG(10, ("create_outbuf failed\n"));
3077 req.outbuf = (uint8_t *)outbuf;
3079 SSVAL(req.outbuf, smb_vwv0, num_replies);
3081 if (req.buflen > 0) {
3082 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3085 ok = srv_send_smb(req.xconn,
3089 TALLOC_FREE(outbuf);
3097 static void smbd_echo_exit(struct tevent_context *ev,
3098 struct tevent_fd *fde, uint16_t flags,
3101 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3105 static void smbd_echo_got_packet(struct tevent_req *req);
3107 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3110 struct smbd_echo_state *state;
3111 struct tevent_req *read_req;
3113 state = talloc_zero(xconn, struct smbd_echo_state);
3114 if (state == NULL) {
3115 DEBUG(1, ("talloc failed\n"));
3118 state->xconn = xconn;
3119 state->parent_pipe = parent_pipe;
3120 state->ev = s3_tevent_context_init(state);
3121 if (state->ev == NULL) {
3122 DEBUG(1, ("tevent_context_init failed\n"));
3126 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3127 TEVENT_FD_READ, smbd_echo_exit,
3129 if (state->parent_fde == NULL) {
3130 DEBUG(1, ("tevent_add_fd failed\n"));
3135 read_req = smbd_echo_read_send(state, state->ev, xconn);
3136 if (read_req == NULL) {
3137 DEBUG(1, ("smbd_echo_read_send failed\n"));
3141 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3144 if (tevent_loop_once(state->ev) == -1) {
3145 DEBUG(1, ("tevent_loop_once failed: %s\n",
3153 static void smbd_echo_got_packet(struct tevent_req *req)
3155 struct smbd_echo_state *state = tevent_req_callback_data(
3156 req, struct smbd_echo_state);
3160 uint32_t seqnum = 0;
3163 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3165 if (!NT_STATUS_IS_OK(status)) {
3166 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3167 nt_errstr(status)));
3171 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3177 num_pending = talloc_array_length(state->pending);
3178 tmp = talloc_realloc(state, state->pending, struct iovec,
3181 DEBUG(1, ("talloc_realloc failed\n"));
3184 state->pending = tmp;
3186 if (buflen >= smb_size) {
3188 * place the seqnum in the packet so that the main process
3189 * can reply with signing
3191 SIVAL(buf, smb_ss_field, seqnum);
3192 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3195 iov = &state->pending[num_pending];
3196 iov->iov_base = talloc_move(state->pending, &buf);
3197 iov->iov_len = buflen;
3199 DEBUG(10,("echo_handler[%d]: forward to main\n",
3201 smbd_echo_activate_writer(state);
3204 req = smbd_echo_read_send(state, state->ev, state->xconn);
3206 DEBUG(1, ("smbd_echo_read_send failed\n"));
3209 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3214 * Handle SMBecho requests in a forked child process
3216 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3218 int listener_pipe[2];
3221 bool use_mutex = false;
3223 res = pipe(listener_pipe);
3225 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3229 #ifdef HAVE_ROBUST_MUTEXES
3230 use_mutex = tdb_runtime_check_for_robust_mutexes();
3233 pthread_mutexattr_t a;
3235 xconn->smb1.echo_handler.socket_mutex =
3236 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3237 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3238 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3243 res = pthread_mutexattr_init(&a);
3245 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3249 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3251 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3253 pthread_mutexattr_destroy(&a);
3256 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3258 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3260 pthread_mutexattr_destroy(&a);
3263 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3265 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3266 "%s\n", strerror(res)));
3267 pthread_mutexattr_destroy(&a);
3270 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3272 pthread_mutexattr_destroy(&a);
3274 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3282 xconn->smb1.echo_handler.socket_lock_fd =
3283 create_unlink_tmp(lp_lock_directory());
3284 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3285 DEBUG(1, ("Could not create lock fd: %s\n",
3295 close(listener_pipe[0]);
3296 set_blocking(listener_pipe[1], false);
3298 status = reinit_after_fork(xconn->msg_ctx,
3301 if (!NT_STATUS_IS_OK(status)) {
3302 DEBUG(1, ("reinit_after_fork failed: %s\n",
3303 nt_errstr(status)));
3306 smbd_echo_loop(xconn, listener_pipe[1]);
3309 close(listener_pipe[1]);
3310 listener_pipe[1] = -1;
3311 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3313 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3316 * Without smb signing this is the same as the normal smbd
3317 * listener. This needs to change once signing comes in.
3319 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3321 xconn->smb1.echo_handler.trusted_fd,
3323 smbd_server_echo_handler,
3325 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3326 DEBUG(1, ("event_add_fd failed\n"));
3333 if (listener_pipe[0] != -1) {
3334 close(listener_pipe[0]);
3336 if (listener_pipe[1] != -1) {
3337 close(listener_pipe[1]);
3339 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3340 close(xconn->smb1.echo_handler.socket_lock_fd);
3342 #ifdef HAVE_ROBUST_MUTEXES
3343 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3344 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3345 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3348 smbd_echo_init(xconn);
3353 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3356 if (user->session_info &&
3357 (user->session_info->unix_token->uid == uid)) {
3365 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3368 if (user->session_info != NULL) {
3370 struct security_unix_token *utok;
3372 utok = user->session_info->unix_token;
3373 if (utok->gid == gid) {
3376 for(i=0; i<utok->ngroups; i++) {
3377 if (utok->groups[i] == gid) {
3387 static bool sid_in_use(const struct user_struct *user,
3388 const struct dom_sid *psid)
3391 struct security_token *tok;
3393 if (user->session_info == NULL) {
3396 tok = user->session_info->security_token;
3399 * Not sure session_info->security_token can
3400 * ever be NULL. This check might be not
3405 if (security_token_has_sid(tok, psid)) {
3413 static bool id_in_use(const struct user_struct *user,
3414 const struct id_cache_ref *id)
3418 return uid_in_use(user, id->id.uid);
3420 return gid_in_use(user, id->id.gid);
3422 return sid_in_use(user, &id->id.sid);
3429 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3432 struct server_id server_id,
3435 const char *msg = (data && data->data)
3436 ? (const char *)data->data : "<NULL>";
3437 struct id_cache_ref id;
3438 struct smbd_server_connection *sconn =
3439 talloc_get_type_abort(private_data,
3440 struct smbd_server_connection);
3442 if (!id_cache_ref_parse(msg, &id)) {
3443 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3447 if (id_in_use(sconn->users, &id)) {
3448 exit_server_cleanly(msg);
3450 id_cache_delete_from_cache(&id);
3453 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3454 enum protocol_types protocol)
3458 set_Protocol(protocol);
3459 conn->protocol = protocol;
3461 if (protocol >= PROTOCOL_SMB2_02) {
3462 status = smb2srv_session_table_init(conn);
3463 if (!NT_STATUS_IS_OK(status)) {
3467 status = smb2srv_open_table_init(conn);
3468 if (!NT_STATUS_IS_OK(status)) {
3472 status = smb1srv_session_table_init(conn);
3473 if (!NT_STATUS_IS_OK(status)) {
3477 status = smb1srv_tcon_table_init(conn);
3478 if (!NT_STATUS_IS_OK(status)) {
3482 status = smb1srv_open_table_init(conn);
3483 if (!NT_STATUS_IS_OK(status)) {
3488 return NT_STATUS_OK;
3491 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3494 struct smbXsrv_connection *conn =
3495 talloc_get_type_abort(private_data,
3496 struct smbXsrv_connection);
3499 case TEVENT_TRACE_BEFORE_WAIT:
3501 * This just removes compiler warning
3502 * without profile support
3504 conn->smbd_idle_profstamp = 0;
3505 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3507 case TEVENT_TRACE_AFTER_WAIT:
3508 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3510 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3511 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3512 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3519 * Create a debug string for the connection
3521 * This is allocated to talloc_tos() or a string constant
3522 * in certain corner cases. The returned string should
3523 * hence not be free'd directly but only via the talloc stack.
3525 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3530 * TODO: this can be improved later
3531 * maybe including the client guid or more
3533 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3535 return "<tsocket_address_string() failed>";
3541 /****************************************************************************
3542 Process commands from the client
3543 ****************************************************************************/
3545 void smbd_process(struct tevent_context *ev_ctx,
3546 struct messaging_context *msg_ctx,
3550 TALLOC_CTX *frame = talloc_stackframe();
3551 struct smbXsrv_connection *xconn;
3552 struct smbd_server_connection *sconn;
3553 struct sockaddr_storage ss_srv;
3554 void *sp_srv = (void *)&ss_srv;
3555 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3556 struct sockaddr_storage ss_clnt;
3557 void *sp_clnt = (void *)&ss_clnt;
3558 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3559 socklen_t sa_socklen;
3560 struct tsocket_address *local_address = NULL;
3561 struct tsocket_address *remote_address = NULL;
3562 const char *locaddr = NULL;
3563 const char *remaddr = NULL;
3568 xconn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3569 if (xconn == NULL) {
3570 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3571 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3574 xconn->ev_ctx = ev_ctx;
3575 xconn->msg_ctx = msg_ctx;
3576 xconn->transport.sock = sock_fd;
3577 smbd_echo_init(xconn);
3579 sconn = talloc_zero(xconn, struct smbd_server_connection);
3581 exit_server("failed to create smbd_server_connection");
3584 xconn->sconn = sconn;
3585 sconn->conn = xconn;
3588 * TODO: remove this...:-)
3590 global_smbXsrv_connection = xconn;
3592 sconn->ev_ctx = ev_ctx;
3593 sconn->msg_ctx = msg_ctx;
3596 smbd_setup_sig_term_handler(sconn);
3597 smbd_setup_sig_hup_handler(sconn);
3599 if (!serverid_register(messaging_server_id(msg_ctx),
3600 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3602 |FLAG_MSG_PRINT_GENERAL)) {
3603 exit_server_cleanly("Could not register myself in "
3608 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3610 * We're not making the decision here,
3611 * we're just allowing the client
3612 * to decide between SMB1 and SMB2
3613 * with the first negprot
3616 sconn->using_smb2 = true;
3619 /* Ensure child is set to blocking mode */
3620 set_blocking(sock_fd,True);
3622 set_socket_options(sock_fd, "SO_KEEPALIVE");
3623 set_socket_options(sock_fd, lp_socket_options());
3625 sa_socklen = sizeof(ss_clnt);
3626 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3628 int level = (errno == ENOTCONN)?2:0;
3629 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3630 exit_server_cleanly("getpeername() failed.\n");
3632 ret = tsocket_address_bsd_from_sockaddr(sconn,
3633 sa_clnt, sa_socklen,
3636 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3637 __location__, strerror(errno)));
3638 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3641 sa_socklen = sizeof(ss_srv);
3642 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3644 int level = (errno == ENOTCONN)?2:0;
3645 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3646 exit_server_cleanly("getsockname() failed.\n");
3648 ret = tsocket_address_bsd_from_sockaddr(sconn,
3652 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3653 __location__, strerror(errno)));
3654 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3657 sconn->local_address = local_address;
3658 sconn->remote_address = remote_address;
3660 if (tsocket_address_is_inet(local_address, "ip")) {
3661 locaddr = tsocket_address_inet_addr_string(
3662 sconn->local_address,
3664 if (locaddr == NULL) {
3665 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3666 __location__, strerror(errno)));
3667 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3670 locaddr = "0.0.0.0";
3673 if (tsocket_address_is_inet(remote_address, "ip")) {
3674 remaddr = tsocket_address_inet_addr_string(
3675 sconn->remote_address,
3677 if (remaddr == NULL) {
3678 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3679 __location__, strerror(errno)));
3680 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3683 remaddr = "0.0.0.0";
3686 /* this is needed so that we get decent entries
3687 in smbstatus for port 445 connects */
3688 set_remote_machine_name(remaddr, false);
3689 reload_services(sconn, conn_snum_used, true);
3692 * Before the first packet, check the global hosts allow/ hosts deny
3693 * parameters before doing any parsing of packets passed to us by the
3694 * client. This prevents attacks on our parsing code from hosts not in
3695 * the hosts allow list.
3698 ret = get_remote_hostname(remote_address,
3702 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3703 __location__, strerror(errno)));
3704 exit_server_cleanly("get_remote_hostname failed.\n");
3706 if (strequal(rhost, "UNKNOWN")) {
3707 rhost = talloc_strdup(talloc_tos(), remaddr);
3709 sconn->remote_hostname = talloc_move(sconn, &rhost);
3711 sub_set_socket_ids(remaddr,
3712 sconn->remote_hostname,
3715 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3716 sconn->remote_hostname,
3719 * send a negative session response "not listening on calling
3722 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3723 DEBUG( 1, ("Connection denied from %s to %s\n",
3724 tsocket_address_string(remote_address, talloc_tos()),
3725 tsocket_address_string(local_address, talloc_tos())));
3726 (void)srv_send_smb(xconn,(char *)buf, false,
3728 exit_server_cleanly("connection denied");
3731 DEBUG(10, ("Connection allowed from %s to %s\n",
3732 tsocket_address_string(remote_address, talloc_tos()),
3733 tsocket_address_string(local_address, talloc_tos())));
3735 if (lp_preload_modules()) {
3736 smb_load_modules(lp_preload_modules());
3739 smb_perfcount_init();
3741 if (!init_account_policy()) {
3742 exit_server("Could not open account policy tdb.\n");
3745 if (*lp_root_directory(talloc_tos())) {
3746 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3747 DEBUG(0,("Failed to change root to %s\n",
3748 lp_root_directory(talloc_tos())));
3749 exit_server("Failed to chroot()");
3751 if (chdir("/") == -1) {
3752 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3753 exit_server("Failed to chroot()");
3755 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3758 if (!srv_init_signing(xconn)) {
3759 exit_server("Failed to init smb_signing");
3762 if (!file_init(sconn)) {
3763 exit_server("file_init() failed");
3767 if (!init_oplocks(sconn))
3768 exit_server("Failed to init oplocks");
3770 /* register our message handlers */
3771 messaging_register(sconn->msg_ctx, sconn,
3772 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3773 messaging_register(sconn->msg_ctx, sconn,
3774 MSG_SMB_CLOSE_FILE, msg_close_file);
3775 messaging_register(sconn->msg_ctx, sconn,
3776 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3778 id_cache_register_msgs(sconn->msg_ctx);
3779 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3780 messaging_register(sconn->msg_ctx, sconn,
3781 ID_CACHE_KILL, smbd_id_cache_kill);
3783 messaging_deregister(sconn->msg_ctx,
3784 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3785 messaging_register(sconn->msg_ctx, sconn,
3786 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3788 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3790 messaging_register(sconn->msg_ctx, sconn,
3791 MSG_SMB_KILL_CLIENT_IP,
3792 msg_kill_client_ip);
3794 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3797 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3798 * MSGs to all child processes
3800 messaging_deregister(sconn->msg_ctx,
3802 messaging_register(sconn->msg_ctx, NULL,
3803 MSG_DEBUG, debug_message);
3805 if ((lp_keepalive() != 0)
3806 && !(event_add_idle(ev_ctx, NULL,
3807 timeval_set(lp_keepalive(), 0),
3808 "keepalive", keepalive_fn,
3810 DEBUG(0, ("Could not add keepalive event\n"));
3814 if (!(event_add_idle(ev_ctx, NULL,
3815 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3816 "deadtime", deadtime_fn, sconn))) {
3817 DEBUG(0, ("Could not add deadtime event\n"));
3821 if (!(event_add_idle(ev_ctx, NULL,
3822 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3823 "housekeeping", housekeeping_fn, sconn))) {
3824 DEBUG(0, ("Could not add housekeeping event\n"));
3828 if (lp_clustering()) {
3830 * We need to tell ctdb about our client's TCP
3831 * connection, so that for failover ctdbd can send
3832 * tickle acks, triggering a reconnection by the
3837 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3838 if (!NT_STATUS_IS_OK(status)) {
3839 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3840 nt_errstr(status)));
3844 tmp = lp_max_xmit();
3845 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3846 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3848 xconn->smb1.negprot.max_recv = tmp;
3850 xconn->smb1.sessions.done_sesssetup = false;
3851 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3853 if (!init_dptrs(sconn)) {
3854 exit_server("init_dptrs() failed");
3857 xconn->transport.fde = tevent_add_fd(ev_ctx,
3861 smbd_server_connection_handler,
3863 if (!xconn->transport.fde) {
3864 exit_server("failed to create smbd_server_connection fde");
3867 sconn->conn->local_address = sconn->local_address;
3868 sconn->conn->remote_address = sconn->remote_address;
3869 sconn->conn->remote_hostname = sconn->remote_hostname;
3870 sconn->conn->protocol = PROTOCOL_NONE;
3874 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, xconn);
3877 frame = talloc_stackframe_pool(8192);
3880 if (tevent_loop_once(ev_ctx) == -1) {
3881 if (errno != EINTR) {
3882 DEBUG(3, ("tevent_loop_once failed: %s,"
3883 " exiting\n", strerror(errno) ));
3891 exit_server_cleanly(NULL);
3894 bool req_is_in_chain(const struct smb_request *req)
3896 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3898 * We're right now handling a subsequent request, so we must
3904 if (!is_andx_req(req->cmd)) {
3910 * Okay, an illegal request, but definitely not chained :-)
3915 return (CVAL(req->vwv+0, 0) != 0xFF);