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;
620 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
621 if (NT_STATUS_IS_OK(status)) {
622 req->conn = tcon->compat;
626 req->chain_fsp = NULL;
628 req->priv_paths = NULL;
630 smb_init_perfcount_data(&req->pcd);
632 /* Ensure we have at least wct words and 2 bytes of bcc. */
633 if (smb_size + req->wct*2 > req_size) {
634 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
635 (unsigned int)req->wct,
636 (unsigned int)req_size));
639 /* Ensure bcc is correct. */
640 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
641 DEBUG(0,("init_smb_request: invalid bcc number %u "
642 "(wct = %u, size %u)\n",
643 (unsigned int)req->buflen,
644 (unsigned int)req->wct,
645 (unsigned int)req_size));
653 static void process_smb(struct smbXsrv_connection *xconn,
654 uint8_t *inbuf, size_t nread, size_t unread_bytes,
655 uint32_t seqnum, bool encrypted,
656 struct smb_perfcount_data *deferred_pcd);
658 static void smbd_deferred_open_timer(struct tevent_context *ev,
659 struct tevent_timer *te,
660 struct timeval _tval,
663 struct pending_message_list *msg = talloc_get_type(private_data,
664 struct pending_message_list);
665 struct smbd_server_connection *sconn = msg->sconn;
666 struct smbXsrv_connection *xconn = msg->xconn;
667 TALLOC_CTX *mem_ctx = talloc_tos();
668 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
671 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
674 exit_server("smbd_deferred_open_timer: talloc failed\n");
678 /* We leave this message on the queue so the open code can
679 know this is a retry. */
680 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
681 (unsigned long long)mid ));
683 /* Mark the message as processed so this is not
684 * re-processed in error. */
685 msg->processed = true;
687 process_smb(xconn, inbuf,
689 msg->seqnum, msg->encrypted, &msg->pcd);
691 /* If it's still there and was processed, remove it. */
692 msg = get_deferred_open_message_smb(sconn, mid);
693 if (msg && msg->processed) {
694 remove_deferred_open_message_smb(sconn, mid);
698 /****************************************************************************
699 Function to push a message onto the tail of a linked list of smb messages ready
701 ****************************************************************************/
703 static bool push_queued_message(struct smb_request *req,
704 struct timeval request_time,
705 struct timeval end_time,
706 struct deferred_open_record *open_rec)
708 int msg_len = smb_len(req->inbuf) + 4;
709 struct pending_message_list *msg;
711 msg = talloc_zero(NULL, struct pending_message_list);
714 DEBUG(0,("push_message: malloc fail (1)\n"));
717 msg->sconn = req->sconn;
718 msg->xconn = req->xconn;
720 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
721 if(msg->buf.data == NULL) {
722 DEBUG(0,("push_message: malloc fail (2)\n"));
727 msg->request_time = request_time;
728 msg->seqnum = req->seqnum;
729 msg->encrypted = req->encrypted;
730 msg->processed = false;
731 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
734 msg->open_rec = talloc_move(msg, &open_rec);
738 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
741 smbd_deferred_open_timer,
744 DEBUG(0,("push_message: event_add_timed failed\n"));
750 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
751 struct pending_message_list *);
753 DEBUG(10,("push_message: pushed message length %u on "
754 "deferred_open_queue\n", (unsigned int)msg_len));
759 /****************************************************************************
760 Function to delete a sharing violation open message by mid.
761 ****************************************************************************/
763 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
766 struct pending_message_list *pml;
768 if (sconn->using_smb2) {
769 remove_deferred_open_message_smb2(sconn, mid);
773 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
774 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
775 DEBUG(10,("remove_deferred_open_message_smb: "
776 "deleting mid %llu len %u\n",
777 (unsigned long long)mid,
778 (unsigned int)pml->buf.length ));
779 DLIST_REMOVE(sconn->deferred_open_queue, pml);
786 /****************************************************************************
787 Move a sharing violation open retry message to the front of the list and
788 schedule it for immediate processing.
789 ****************************************************************************/
791 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
794 struct pending_message_list *pml;
797 if (sconn->using_smb2) {
798 return schedule_deferred_open_message_smb2(sconn, mid);
801 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
802 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
804 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
807 (unsigned long long)msg_mid ));
809 if (mid == msg_mid) {
810 struct tevent_timer *te;
812 if (pml->processed) {
813 /* A processed message should not be
815 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
816 "message mid %llu was already processed\n",
817 (unsigned long long)msg_mid ));
821 DEBUG(10,("schedule_deferred_open_message_smb: "
822 "scheduling mid %llu\n",
823 (unsigned long long)mid ));
825 te = tevent_add_timer(pml->sconn->ev_ctx,
828 smbd_deferred_open_timer,
831 DEBUG(10,("schedule_deferred_open_message_smb: "
832 "event_add_timed() failed, "
833 "skipping mid %llu\n",
834 (unsigned long long)msg_mid ));
837 TALLOC_FREE(pml->te);
839 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
844 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
845 "find message mid %llu\n",
846 (unsigned long long)mid ));
851 /****************************************************************************
852 Return true if this mid is on the deferred queue and was not yet processed.
853 ****************************************************************************/
855 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
857 struct pending_message_list *pml;
859 if (sconn->using_smb2) {
860 return open_was_deferred_smb2(sconn, mid);
863 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
864 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
871 /****************************************************************************
872 Return the message queued by this mid.
873 ****************************************************************************/
875 static struct pending_message_list *get_deferred_open_message_smb(
876 struct smbd_server_connection *sconn, uint64_t mid)
878 struct pending_message_list *pml;
880 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
881 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
888 /****************************************************************************
889 Get the state data queued by this mid.
890 ****************************************************************************/
892 bool get_deferred_open_message_state(struct smb_request *smbreq,
893 struct timeval *p_request_time,
894 struct deferred_open_record **open_rec)
896 struct pending_message_list *pml;
898 if (smbreq->sconn->using_smb2) {
899 return get_deferred_open_message_state_smb2(smbreq->smb2req,
904 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
908 if (p_request_time) {
909 *p_request_time = pml->request_time;
911 if (open_rec != NULL) {
912 *open_rec = pml->open_rec;
917 /****************************************************************************
918 Function to push a deferred open smb message onto a linked list of local smb
919 messages ready for processing.
920 ****************************************************************************/
922 bool push_deferred_open_message_smb(struct smb_request *req,
923 struct timeval request_time,
924 struct timeval timeout,
926 struct deferred_open_record *open_rec)
928 struct timeval end_time;
931 return push_deferred_open_message_smb2(req->smb2req,
938 if (req->unread_bytes) {
939 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
940 "unread_bytes = %u\n",
941 (unsigned int)req->unread_bytes ));
942 smb_panic("push_deferred_open_message_smb: "
943 "logic error unread_bytes != 0" );
946 end_time = timeval_sum(&request_time, &timeout);
948 DEBUG(10,("push_deferred_open_message_smb: pushing message "
949 "len %u mid %llu timeout time [%u.%06u]\n",
950 (unsigned int) smb_len(req->inbuf)+4,
951 (unsigned long long)req->mid,
952 (unsigned int)end_time.tv_sec,
953 (unsigned int)end_time.tv_usec));
955 return push_queued_message(req, request_time, end_time, open_rec);
958 static void smbd_sig_term_handler(struct tevent_context *ev,
959 struct tevent_signal *se,
965 exit_server_cleanly("termination signal");
968 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
970 struct tevent_signal *se;
972 se = tevent_add_signal(sconn->ev_ctx,
975 smbd_sig_term_handler,
978 exit_server("failed to setup SIGTERM handler");
982 static void smbd_sig_hup_handler(struct tevent_context *ev,
983 struct tevent_signal *se,
989 struct smbd_server_connection *sconn =
990 talloc_get_type_abort(private_data,
991 struct smbd_server_connection);
993 change_to_root_user();
994 DEBUG(1,("Reloading services after SIGHUP\n"));
995 reload_services(sconn, conn_snum_used, false);
998 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1000 struct tevent_signal *se;
1002 se = tevent_add_signal(sconn->ev_ctx,
1005 smbd_sig_hup_handler,
1008 exit_server("failed to setup SIGHUP handler");
1012 static void smbd_conf_updated(struct messaging_context *msg,
1015 struct server_id server_id,
1018 struct smbd_server_connection *sconn =
1019 talloc_get_type_abort(private_data,
1020 struct smbd_server_connection);
1022 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1023 "updated. Reloading.\n"));
1024 change_to_root_user();
1025 reload_services(sconn, conn_snum_used, false);
1029 * Only allow 5 outstanding trans requests. We're allocating memory, so
1033 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1036 for (; list != NULL; list = list->next) {
1038 if (list->mid == mid) {
1039 return NT_STATUS_INVALID_PARAMETER;
1045 return NT_STATUS_INSUFFICIENT_RESOURCES;
1048 return NT_STATUS_OK;
1052 These flags determine some of the permissions required to do an operation
1054 Note that I don't set NEED_WRITE on some write operations because they
1055 are used by some brain-dead clients when printing, and I don't want to
1056 force write permissions on print services.
1058 #define AS_USER (1<<0)
1059 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1060 #define TIME_INIT (1<<2)
1061 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1062 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1063 #define DO_CHDIR (1<<6)
1066 define a list of possible SMB messages and their corresponding
1067 functions. Any message that has a NULL function is unimplemented -
1068 please feel free to contribute implementations!
1070 static const struct smb_message_struct {
1072 void (*fn)(struct smb_request *req);
1074 } smb_messages[256] = {
1076 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1077 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1078 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1079 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1080 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1081 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1082 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1083 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1084 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1085 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1086 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1087 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1088 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1089 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1090 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1091 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1092 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1093 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1094 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1095 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1096 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1097 /* 0x15 */ { NULL, NULL, 0 },
1098 /* 0x16 */ { NULL, NULL, 0 },
1099 /* 0x17 */ { NULL, NULL, 0 },
1100 /* 0x18 */ { NULL, NULL, 0 },
1101 /* 0x19 */ { NULL, NULL, 0 },
1102 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1103 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1104 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1105 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1106 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1107 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1108 /* 0x20 */ { "SMBwritec", NULL,0},
1109 /* 0x21 */ { NULL, NULL, 0 },
1110 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1111 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1112 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1113 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1114 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1115 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1116 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1117 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1118 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1119 /* 0x2b */ { "SMBecho",reply_echo,0},
1120 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1121 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1122 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1123 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1124 /* 0x30 */ { NULL, NULL, 0 },
1125 /* 0x31 */ { NULL, NULL, 0 },
1126 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1127 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1128 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1129 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1130 /* 0x36 */ { NULL, NULL, 0 },
1131 /* 0x37 */ { NULL, NULL, 0 },
1132 /* 0x38 */ { NULL, NULL, 0 },
1133 /* 0x39 */ { NULL, NULL, 0 },
1134 /* 0x3a */ { NULL, NULL, 0 },
1135 /* 0x3b */ { NULL, NULL, 0 },
1136 /* 0x3c */ { NULL, NULL, 0 },
1137 /* 0x3d */ { NULL, NULL, 0 },
1138 /* 0x3e */ { NULL, NULL, 0 },
1139 /* 0x3f */ { NULL, NULL, 0 },
1140 /* 0x40 */ { NULL, NULL, 0 },
1141 /* 0x41 */ { NULL, NULL, 0 },
1142 /* 0x42 */ { NULL, NULL, 0 },
1143 /* 0x43 */ { NULL, NULL, 0 },
1144 /* 0x44 */ { NULL, NULL, 0 },
1145 /* 0x45 */ { NULL, NULL, 0 },
1146 /* 0x46 */ { NULL, NULL, 0 },
1147 /* 0x47 */ { NULL, NULL, 0 },
1148 /* 0x48 */ { NULL, NULL, 0 },
1149 /* 0x49 */ { NULL, NULL, 0 },
1150 /* 0x4a */ { NULL, NULL, 0 },
1151 /* 0x4b */ { NULL, NULL, 0 },
1152 /* 0x4c */ { NULL, NULL, 0 },
1153 /* 0x4d */ { NULL, NULL, 0 },
1154 /* 0x4e */ { NULL, NULL, 0 },
1155 /* 0x4f */ { NULL, NULL, 0 },
1156 /* 0x50 */ { NULL, NULL, 0 },
1157 /* 0x51 */ { NULL, NULL, 0 },
1158 /* 0x52 */ { NULL, NULL, 0 },
1159 /* 0x53 */ { NULL, NULL, 0 },
1160 /* 0x54 */ { NULL, NULL, 0 },
1161 /* 0x55 */ { NULL, NULL, 0 },
1162 /* 0x56 */ { NULL, NULL, 0 },
1163 /* 0x57 */ { NULL, NULL, 0 },
1164 /* 0x58 */ { NULL, NULL, 0 },
1165 /* 0x59 */ { NULL, NULL, 0 },
1166 /* 0x5a */ { NULL, NULL, 0 },
1167 /* 0x5b */ { NULL, NULL, 0 },
1168 /* 0x5c */ { NULL, NULL, 0 },
1169 /* 0x5d */ { NULL, NULL, 0 },
1170 /* 0x5e */ { NULL, NULL, 0 },
1171 /* 0x5f */ { NULL, NULL, 0 },
1172 /* 0x60 */ { NULL, NULL, 0 },
1173 /* 0x61 */ { NULL, NULL, 0 },
1174 /* 0x62 */ { NULL, NULL, 0 },
1175 /* 0x63 */ { NULL, NULL, 0 },
1176 /* 0x64 */ { NULL, NULL, 0 },
1177 /* 0x65 */ { NULL, NULL, 0 },
1178 /* 0x66 */ { NULL, NULL, 0 },
1179 /* 0x67 */ { NULL, NULL, 0 },
1180 /* 0x68 */ { NULL, NULL, 0 },
1181 /* 0x69 */ { NULL, NULL, 0 },
1182 /* 0x6a */ { NULL, NULL, 0 },
1183 /* 0x6b */ { NULL, NULL, 0 },
1184 /* 0x6c */ { NULL, NULL, 0 },
1185 /* 0x6d */ { NULL, NULL, 0 },
1186 /* 0x6e */ { NULL, NULL, 0 },
1187 /* 0x6f */ { NULL, NULL, 0 },
1188 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1189 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1190 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1191 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1192 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1193 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1194 /* 0x76 */ { NULL, NULL, 0 },
1195 /* 0x77 */ { NULL, NULL, 0 },
1196 /* 0x78 */ { NULL, NULL, 0 },
1197 /* 0x79 */ { NULL, NULL, 0 },
1198 /* 0x7a */ { NULL, NULL, 0 },
1199 /* 0x7b */ { NULL, NULL, 0 },
1200 /* 0x7c */ { NULL, NULL, 0 },
1201 /* 0x7d */ { NULL, NULL, 0 },
1202 /* 0x7e */ { NULL, NULL, 0 },
1203 /* 0x7f */ { NULL, NULL, 0 },
1204 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1205 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1206 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1207 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1208 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1209 /* 0x85 */ { NULL, NULL, 0 },
1210 /* 0x86 */ { NULL, NULL, 0 },
1211 /* 0x87 */ { NULL, NULL, 0 },
1212 /* 0x88 */ { NULL, NULL, 0 },
1213 /* 0x89 */ { NULL, NULL, 0 },
1214 /* 0x8a */ { NULL, NULL, 0 },
1215 /* 0x8b */ { NULL, NULL, 0 },
1216 /* 0x8c */ { NULL, NULL, 0 },
1217 /* 0x8d */ { NULL, NULL, 0 },
1218 /* 0x8e */ { NULL, NULL, 0 },
1219 /* 0x8f */ { NULL, NULL, 0 },
1220 /* 0x90 */ { NULL, NULL, 0 },
1221 /* 0x91 */ { NULL, NULL, 0 },
1222 /* 0x92 */ { NULL, NULL, 0 },
1223 /* 0x93 */ { NULL, NULL, 0 },
1224 /* 0x94 */ { NULL, NULL, 0 },
1225 /* 0x95 */ { NULL, NULL, 0 },
1226 /* 0x96 */ { NULL, NULL, 0 },
1227 /* 0x97 */ { NULL, NULL, 0 },
1228 /* 0x98 */ { NULL, NULL, 0 },
1229 /* 0x99 */ { NULL, NULL, 0 },
1230 /* 0x9a */ { NULL, NULL, 0 },
1231 /* 0x9b */ { NULL, NULL, 0 },
1232 /* 0x9c */ { NULL, NULL, 0 },
1233 /* 0x9d */ { NULL, NULL, 0 },
1234 /* 0x9e */ { NULL, NULL, 0 },
1235 /* 0x9f */ { NULL, NULL, 0 },
1236 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1237 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1238 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1239 /* 0xa3 */ { NULL, NULL, 0 },
1240 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1241 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1242 /* 0xa6 */ { NULL, NULL, 0 },
1243 /* 0xa7 */ { NULL, NULL, 0 },
1244 /* 0xa8 */ { NULL, NULL, 0 },
1245 /* 0xa9 */ { NULL, NULL, 0 },
1246 /* 0xaa */ { NULL, NULL, 0 },
1247 /* 0xab */ { NULL, NULL, 0 },
1248 /* 0xac */ { NULL, NULL, 0 },
1249 /* 0xad */ { NULL, NULL, 0 },
1250 /* 0xae */ { NULL, NULL, 0 },
1251 /* 0xaf */ { NULL, NULL, 0 },
1252 /* 0xb0 */ { NULL, NULL, 0 },
1253 /* 0xb1 */ { NULL, NULL, 0 },
1254 /* 0xb2 */ { NULL, NULL, 0 },
1255 /* 0xb3 */ { NULL, NULL, 0 },
1256 /* 0xb4 */ { NULL, NULL, 0 },
1257 /* 0xb5 */ { NULL, NULL, 0 },
1258 /* 0xb6 */ { NULL, NULL, 0 },
1259 /* 0xb7 */ { NULL, NULL, 0 },
1260 /* 0xb8 */ { NULL, NULL, 0 },
1261 /* 0xb9 */ { NULL, NULL, 0 },
1262 /* 0xba */ { NULL, NULL, 0 },
1263 /* 0xbb */ { NULL, NULL, 0 },
1264 /* 0xbc */ { NULL, NULL, 0 },
1265 /* 0xbd */ { NULL, NULL, 0 },
1266 /* 0xbe */ { NULL, NULL, 0 },
1267 /* 0xbf */ { NULL, NULL, 0 },
1268 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1269 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1270 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1271 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1272 /* 0xc4 */ { NULL, NULL, 0 },
1273 /* 0xc5 */ { NULL, NULL, 0 },
1274 /* 0xc6 */ { NULL, NULL, 0 },
1275 /* 0xc7 */ { NULL, NULL, 0 },
1276 /* 0xc8 */ { NULL, NULL, 0 },
1277 /* 0xc9 */ { NULL, NULL, 0 },
1278 /* 0xca */ { NULL, NULL, 0 },
1279 /* 0xcb */ { NULL, NULL, 0 },
1280 /* 0xcc */ { NULL, NULL, 0 },
1281 /* 0xcd */ { NULL, NULL, 0 },
1282 /* 0xce */ { NULL, NULL, 0 },
1283 /* 0xcf */ { NULL, NULL, 0 },
1284 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1285 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1286 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1287 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1288 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1289 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1290 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1291 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1292 /* 0xd8 */ { NULL, NULL, 0 },
1293 /* 0xd9 */ { NULL, NULL, 0 },
1294 /* 0xda */ { NULL, NULL, 0 },
1295 /* 0xdb */ { NULL, NULL, 0 },
1296 /* 0xdc */ { NULL, NULL, 0 },
1297 /* 0xdd */ { NULL, NULL, 0 },
1298 /* 0xde */ { NULL, NULL, 0 },
1299 /* 0xdf */ { NULL, NULL, 0 },
1300 /* 0xe0 */ { NULL, NULL, 0 },
1301 /* 0xe1 */ { NULL, NULL, 0 },
1302 /* 0xe2 */ { NULL, NULL, 0 },
1303 /* 0xe3 */ { NULL, NULL, 0 },
1304 /* 0xe4 */ { NULL, NULL, 0 },
1305 /* 0xe5 */ { NULL, NULL, 0 },
1306 /* 0xe6 */ { NULL, NULL, 0 },
1307 /* 0xe7 */ { NULL, NULL, 0 },
1308 /* 0xe8 */ { NULL, NULL, 0 },
1309 /* 0xe9 */ { NULL, NULL, 0 },
1310 /* 0xea */ { NULL, NULL, 0 },
1311 /* 0xeb */ { NULL, NULL, 0 },
1312 /* 0xec */ { NULL, NULL, 0 },
1313 /* 0xed */ { NULL, NULL, 0 },
1314 /* 0xee */ { NULL, NULL, 0 },
1315 /* 0xef */ { NULL, NULL, 0 },
1316 /* 0xf0 */ { NULL, NULL, 0 },
1317 /* 0xf1 */ { NULL, NULL, 0 },
1318 /* 0xf2 */ { NULL, NULL, 0 },
1319 /* 0xf3 */ { NULL, NULL, 0 },
1320 /* 0xf4 */ { NULL, NULL, 0 },
1321 /* 0xf5 */ { NULL, NULL, 0 },
1322 /* 0xf6 */ { NULL, NULL, 0 },
1323 /* 0xf7 */ { NULL, NULL, 0 },
1324 /* 0xf8 */ { NULL, NULL, 0 },
1325 /* 0xf9 */ { NULL, NULL, 0 },
1326 /* 0xfa */ { NULL, NULL, 0 },
1327 /* 0xfb */ { NULL, NULL, 0 },
1328 /* 0xfc */ { NULL, NULL, 0 },
1329 /* 0xfd */ { NULL, NULL, 0 },
1330 /* 0xfe */ { NULL, NULL, 0 },
1331 /* 0xff */ { NULL, NULL, 0 }
1335 /*******************************************************************
1336 allocate and initialize a reply packet
1337 ********************************************************************/
1339 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1340 const char *inbuf, char **outbuf, uint8_t num_words,
1343 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1346 * Protect against integer wrap.
1347 * The SMB layer reply can be up to 0xFFFFFF bytes.
1349 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1351 if (asprintf(&msg, "num_bytes too large: %u",
1352 (unsigned)num_bytes) == -1) {
1353 msg = discard_const_p(char, "num_bytes too large");
1359 * Here we include the NBT header for now.
1361 *outbuf = talloc_array(mem_ctx, char,
1362 NBT_HDR_SIZE + smb_len);
1363 if (*outbuf == NULL) {
1367 construct_reply_common(req, inbuf, *outbuf);
1368 srv_set_message(*outbuf, num_words, num_bytes, false);
1370 * Zero out the word area, the caller has to take care of the bcc area
1373 if (num_words != 0) {
1374 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1380 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1383 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1385 smb_panic("could not allocate output buffer\n");
1387 req->outbuf = (uint8_t *)outbuf;
1391 /*******************************************************************
1392 Dump a packet to a file.
1393 ********************************************************************/
1395 static void smb_dump(const char *name, int type, const char *data)
1400 if (DEBUGLEVEL < 50) {
1404 len = smb_len_tcp(data)+4;
1405 for (i=1;i<100;i++) {
1406 fname = talloc_asprintf(talloc_tos(),
1410 type ? "req" : "resp");
1411 if (fname == NULL) {
1414 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1415 if (fd != -1 || errno != EEXIST) break;
1419 ssize_t ret = write(fd, data, len);
1421 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1423 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1428 /****************************************************************************
1429 Prepare everything for calling the actual request function, and potentially
1430 call the request function via the "new" interface.
1432 Return False if the "legacy" function needs to be called, everything is
1435 Return True if we're done.
1437 I know this API sucks, but it is the one with the least code change I could
1439 ****************************************************************************/
1441 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1444 uint64_t session_tag;
1445 connection_struct *conn = NULL;
1446 struct smbXsrv_connection *xconn = req->xconn;
1447 NTTIME now = timeval_to_nttime(&req->request_time);
1448 struct smbXsrv_session *session = NULL;
1453 if (!xconn->smb1.negprot.done) {
1456 * Without a negprot the request must
1457 * either be a negprot, or one of the
1458 * evil old SMB mailslot messaging types.
1466 exit_server_cleanly("The first request "
1467 "should be a negprot");
1471 if (smb_messages[type].fn == NULL) {
1472 DEBUG(0,("Unknown message type %d!\n",type));
1473 smb_dump("Unknown", 1, (const char *)req->inbuf);
1474 reply_unknown_new(req, type);
1478 flags = smb_messages[type].flags;
1480 /* In share mode security we must ignore the vuid. */
1481 session_tag = req->vuid;
1484 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1485 (int)getpid(), (unsigned long)conn));
1487 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1489 /* Ensure this value is replaced in the incoming packet. */
1490 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1493 * Ensure the correct username is in current_user_info. This is a
1494 * really ugly bugfix for problems with multiple session_setup_and_X's
1495 * being done and allowing %U and %G substitutions to work correctly.
1496 * There is a reason this code is done here, don't move it unless you
1497 * know what you're doing... :-).
1502 * lookup an existing session
1504 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1505 * here, the main check is still in change_to_user()
1507 status = smb1srv_session_lookup(xconn,
1511 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1514 status = NT_STATUS_OK;
1517 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1518 (unsigned long long)session_tag,
1519 (unsigned long long)req->mid));
1520 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1525 if (session_tag != xconn->last_session_id) {
1526 struct user_struct *vuser = NULL;
1528 xconn->last_session_id = session_tag;
1530 vuser = session->compat;
1533 set_current_user_info(
1534 vuser->session_info->unix_info->sanitized_username,
1535 vuser->session_info->unix_info->unix_name,
1536 vuser->session_info->info->domain_name);
1540 /* Does this call need to be run as the connected user? */
1541 if (flags & AS_USER) {
1543 /* Does this call need a valid tree connection? */
1546 * Amazingly, the error code depends on the command
1549 if (type == SMBntcreateX) {
1550 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1552 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1557 if (!change_to_user(conn,session_tag)) {
1558 DEBUG(0, ("Error: Could not change to user. Removing "
1559 "deferred open, mid=%llu.\n",
1560 (unsigned long long)req->mid));
1561 reply_force_doserror(req, ERRSRV, ERRbaduid);
1565 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1567 /* Does it need write permission? */
1568 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1569 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1573 /* IPC services are limited */
1574 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1575 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1579 /* This call needs to be run as root */
1580 change_to_root_user();
1583 /* load service specific parameters */
1585 if (req->encrypted) {
1586 conn->encrypted_tid = true;
1587 /* encrypted required from now on. */
1588 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1589 } else if (ENCRYPTION_REQUIRED(conn)) {
1590 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1591 DEBUG(1,("service[%s] requires encryption"
1592 "%s ACCESS_DENIED. mid=%llu\n",
1593 lp_servicename(talloc_tos(), SNUM(conn)),
1595 (unsigned long long)req->mid));
1596 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1601 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1602 (flags & (AS_USER|DO_CHDIR)
1604 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1607 conn->num_smb_operations++;
1611 * Does this protocol need to be run as guest? (Only archane
1612 * messenger service requests have this...)
1614 if (flags & AS_GUEST) {
1618 if (!change_to_guest()) {
1619 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1623 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1625 if (raddr == NULL) {
1626 reply_nterror(req, NT_STATUS_NO_MEMORY);
1631 * Haven't we checked this in smbd_process already???
1634 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1635 xconn->remote_hostname, raddr);
1639 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1644 smb_messages[type].fn(req);
1648 /****************************************************************************
1649 Construct a reply to the incoming packet.
1650 ****************************************************************************/
1652 static void construct_reply(struct smbd_server_connection *sconn,
1653 char *inbuf, int size, size_t unread_bytes,
1654 uint32_t seqnum, bool encrypted,
1655 struct smb_perfcount_data *deferred_pcd)
1657 struct smbXsrv_connection *xconn = sconn->conn;
1658 struct smb_request *req;
1660 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1661 smb_panic("could not allocate smb_request");
1664 if (!init_smb_request(req, sconn, xconn, (uint8 *)inbuf, unread_bytes,
1665 encrypted, seqnum)) {
1666 exit_server_cleanly("Invalid SMB request");
1669 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1671 /* we popped this message off the queue - keep original perf data */
1673 req->pcd = *deferred_pcd;
1675 SMB_PERFCOUNT_START(&req->pcd);
1676 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1677 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1680 req->conn = switch_message(req->cmd, req);
1682 if (req->outbuf == NULL) {
1684 * Request has suspended itself, will come
1689 if (CVAL(req->outbuf,0) == 0) {
1690 show_msg((char *)req->outbuf);
1692 smb_request_done(req);
1695 static void construct_reply_chain(struct smbd_server_connection *sconn,
1696 char *inbuf, int size, uint32_t seqnum,
1698 struct smb_perfcount_data *deferred_pcd)
1700 struct smbXsrv_connection *xconn = sconn->conn;
1701 struct smb_request **reqs = NULL;
1702 struct smb_request *req;
1706 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1707 seqnum, &reqs, &num_reqs);
1709 char errbuf[smb_size];
1710 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1711 __LINE__, __FILE__);
1712 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1714 exit_server_cleanly("construct_reply_chain: "
1715 "srv_send_smb failed.");
1721 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1723 req->conn = switch_message(req->cmd, req);
1725 if (req->outbuf == NULL) {
1727 * Request has suspended itself, will come
1732 smb_request_done(req);
1736 * To be called from an async SMB handler that is potentially chained
1737 * when it is finished for shipping.
1740 void smb_request_done(struct smb_request *req)
1742 struct smb_request **reqs = NULL;
1743 struct smb_request *first_req;
1744 size_t i, num_reqs, next_index;
1747 if (req->chain == NULL) {
1753 num_reqs = talloc_array_length(reqs);
1755 for (i=0; i<num_reqs; i++) {
1756 if (reqs[i] == req) {
1760 if (i == num_reqs) {
1762 * Invalid chain, should not happen
1764 status = NT_STATUS_INTERNAL_ERROR;
1769 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1770 struct smb_request *next = reqs[next_index];
1771 struct smbXsrv_tcon *tcon;
1772 NTTIME now = timeval_to_nttime(&req->request_time);
1774 next->vuid = SVAL(req->outbuf, smb_uid);
1775 next->tid = SVAL(req->outbuf, smb_tid);
1776 status = smb1srv_tcon_lookup(req->xconn, req->tid,
1778 if (NT_STATUS_IS_OK(status)) {
1779 req->conn = tcon->compat;
1783 next->chain_fsp = req->chain_fsp;
1784 next->inbuf = req->inbuf;
1787 req->conn = switch_message(req->cmd, req);
1789 if (req->outbuf == NULL) {
1791 * Request has suspended itself, will come
1799 first_req = reqs[0];
1801 for (i=1; i<next_index; i++) {
1804 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1806 status = NT_STATUS_INTERNAL_ERROR;
1811 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1812 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1815 * This scary statement intends to set the
1816 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1817 * to the value last_req->outbuf carries
1819 SSVAL(first_req->outbuf, smb_flg2,
1820 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1821 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1824 * Transfer the error codes from the subrequest to the main one
1826 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1827 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1830 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1833 if (!srv_send_smb(first_req->xconn,
1834 (char *)first_req->outbuf,
1835 true, first_req->seqnum+1,
1836 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1838 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1841 TALLOC_FREE(req); /* non-chained case */
1842 TALLOC_FREE(reqs); /* chained case */
1847 char errbuf[smb_size];
1848 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1849 if (!srv_send_smb(req->xconn, errbuf, true,
1850 req->seqnum+1, req->encrypted,
1852 exit_server_cleanly("construct_reply_chain: "
1853 "srv_send_smb failed.");
1856 TALLOC_FREE(req); /* non-chained case */
1857 TALLOC_FREE(reqs); /* chained case */
1860 /****************************************************************************
1861 Process an smb from the client
1862 ****************************************************************************/
1863 static void process_smb(struct smbXsrv_connection *xconn,
1864 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1865 uint32_t seqnum, bool encrypted,
1866 struct smb_perfcount_data *deferred_pcd)
1868 struct smbd_server_connection *sconn = xconn->sconn;
1869 int msg_type = CVAL(inbuf,0);
1871 DO_PROFILE_INC(smb_count);
1873 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1875 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1876 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1878 if (msg_type != NBSSmessage) {
1880 * NetBIOS session request, keepalive, etc.
1882 reply_special(xconn, (char *)inbuf, nread);
1886 if (sconn->using_smb2) {
1887 /* At this point we're not really using smb2,
1888 * we make the decision here.. */
1889 if (smbd_is_smb2_header(inbuf, nread)) {
1890 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1891 size_t pdulen = nread - NBT_HDR_SIZE;
1892 smbd_smb2_first_negprot(xconn, inpdu, pdulen);
1894 } else if (nread >= smb_size && valid_smb_header(inbuf)
1895 && CVAL(inbuf, smb_com) != 0x72) {
1896 /* This is a non-negprot SMB1 packet.
1897 Disable SMB2 from now on. */
1898 sconn->using_smb2 = false;
1902 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1903 * so subtract 4 from it. */
1904 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1905 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1908 /* special magic for immediate exit */
1910 (IVAL(inbuf, 4) == 0x74697865) &&
1911 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1912 uint8_t exitcode = CVAL(inbuf, 8);
1913 DEBUG(1, ("Exiting immediately with code %d\n",
1918 exit_server_cleanly("Non-SMB packet");
1921 show_msg((char *)inbuf);
1923 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1924 construct_reply_chain(sconn, (char *)inbuf, nread,
1925 seqnum, encrypted, deferred_pcd);
1927 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1928 seqnum, encrypted, deferred_pcd);
1934 sconn->num_requests++;
1936 /* The timeout_processing function isn't run nearly
1937 often enough to implement 'max log size' without
1938 overrunning the size of the file by many megabytes.
1939 This is especially true if we are running at debug
1940 level 10. Checking every 50 SMBs is a nice
1941 tradeoff of performance vs log file size overrun. */
1943 if ((sconn->num_requests % 50) == 0 &&
1944 need_to_check_log_size()) {
1945 change_to_root_user();
1950 /****************************************************************************
1951 Return a string containing the function name of a SMB command.
1952 ****************************************************************************/
1954 const char *smb_fn_name(int type)
1956 const char *unknown_name = "SMBunknown";
1958 if (smb_messages[type].name == NULL)
1959 return(unknown_name);
1961 return(smb_messages[type].name);
1964 /****************************************************************************
1965 Helper functions for contruct_reply.
1966 ****************************************************************************/
1968 void add_to_common_flags2(uint32 v)
1973 void remove_from_common_flags2(uint32 v)
1975 common_flags2 &= ~v;
1978 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1981 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1982 uint16_t out_flags2 = common_flags2;
1984 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1985 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1986 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1988 srv_set_message(outbuf,0,0,false);
1990 SCVAL(outbuf, smb_com, req->cmd);
1991 SIVAL(outbuf,smb_rcls,0);
1992 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1993 SSVAL(outbuf,smb_flg2, out_flags2);
1994 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1995 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1997 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1998 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1999 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2000 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2003 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2005 construct_reply_common(req, (const char *)req->inbuf, outbuf);
2009 * @brief Find the smb_cmd offset of the last command pushed
2010 * @param[in] buf The buffer we're building up
2011 * @retval Where can we put our next andx cmd?
2013 * While chaining requests, the "next" request we're looking at needs to put
2014 * its SMB_Command before the data the previous request already built up added
2015 * to the chain. Find the offset to the place where we have to put our cmd.
2018 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2023 cmd = CVAL(buf, smb_com);
2025 if (!is_andx_req(cmd)) {
2031 while (CVAL(buf, ofs) != 0xff) {
2033 if (!is_andx_req(CVAL(buf, ofs))) {
2038 * ofs is from start of smb header, so add the 4 length
2039 * bytes. The next cmd is right after the wct field.
2041 ofs = SVAL(buf, ofs+2) + 4 + 1;
2043 if (ofs+4 >= talloc_get_size(buf)) {
2053 * @brief Do the smb chaining at a buffer level
2054 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2055 * @param[in] andx_buf Buffer to be appended
2058 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2060 uint8_t smb_command = CVAL(andx_buf, smb_com);
2061 uint8_t wct = CVAL(andx_buf, smb_wct);
2062 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2063 uint32_t num_bytes = smb_buflen(andx_buf);
2064 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2067 size_t old_size, new_size;
2069 size_t chain_padding = 0;
2070 size_t andx_cmd_ofs;
2073 old_size = talloc_get_size(*poutbuf);
2075 if ((old_size % 4) != 0) {
2077 * Align the wct field of subsequent requests to a 4-byte
2080 chain_padding = 4 - (old_size % 4);
2084 * After the old request comes the new wct field (1 byte), the vwv's
2085 * and the num_bytes field.
2088 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2089 new_size += num_bytes;
2091 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2092 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2093 (unsigned)new_size));
2097 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2098 if (outbuf == NULL) {
2099 DEBUG(0, ("talloc failed\n"));
2104 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2105 DEBUG(1, ("invalid command chain\n"));
2106 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2110 if (chain_padding != 0) {
2111 memset(outbuf + old_size, 0, chain_padding);
2112 old_size += chain_padding;
2115 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2116 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2121 * Push the chained request:
2126 SCVAL(outbuf, ofs, wct);
2133 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2138 * Read&X has an offset into its data buffer at
2139 * vwv[6]. reply_read_andx has no idea anymore that it's
2140 * running from within a chain, so we have to fix up the
2143 * Although it looks disgusting at this place, I want to keep
2144 * it here. The alternative would be to push knowledge about
2145 * the andx chain down into read&x again.
2148 if (smb_command == SMBreadX) {
2149 uint8_t *bytes_addr;
2153 * Invalid read&x response
2158 bytes_addr = outbuf + ofs /* vwv start */
2159 + sizeof(uint16_t) * wct /* vwv array */
2160 + sizeof(uint16_t) /* bcc */
2161 + 1; /* padding byte */
2163 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2164 bytes_addr - outbuf - 4);
2167 ofs += sizeof(uint16_t) * wct;
2173 SSVAL(outbuf, ofs, num_bytes);
2174 ofs += sizeof(uint16_t);
2180 memcpy(outbuf + ofs, bytes, num_bytes);
2185 bool smb1_is_chain(const uint8_t *buf)
2187 uint8_t cmd, wct, andx_cmd;
2189 cmd = CVAL(buf, smb_com);
2190 if (!is_andx_req(cmd)) {
2193 wct = CVAL(buf, smb_wct);
2197 andx_cmd = CVAL(buf, smb_vwv);
2198 return (andx_cmd != 0xFF);
2201 bool smb1_walk_chain(const uint8_t *buf,
2202 bool (*fn)(uint8_t cmd,
2203 uint8_t wct, const uint16_t *vwv,
2204 uint16_t num_bytes, const uint8_t *bytes,
2205 void *private_data),
2208 size_t smblen = smb_len(buf);
2209 const char *smb_buf = smb_base(buf);
2210 uint8_t cmd, chain_cmd;
2212 const uint16_t *vwv;
2214 const uint8_t *bytes;
2216 cmd = CVAL(buf, smb_com);
2217 wct = CVAL(buf, smb_wct);
2218 vwv = (const uint16_t *)(buf + smb_vwv);
2219 num_bytes = smb_buflen(buf);
2220 bytes = (const uint8_t *)smb_buf_const(buf);
2222 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2226 if (!is_andx_req(cmd)) {
2233 chain_cmd = CVAL(vwv, 0);
2235 while (chain_cmd != 0xff) {
2236 uint32_t chain_offset; /* uint32_t to avoid overflow */
2237 size_t length_needed;
2238 ptrdiff_t vwv_offset;
2240 chain_offset = SVAL(vwv+1, 0);
2243 * Check if the client tries to fool us. The chain
2244 * offset needs to point beyond the current request in
2245 * the chain, it needs to strictly grow. Otherwise we
2246 * might be tricked into an endless loop always
2247 * processing the same request over and over again. We
2248 * used to assume that vwv and the byte buffer array
2249 * in a chain are always attached, but OS/2 the
2250 * Write&X/Read&X chain puts the Read&X vwv array
2251 * right behind the Write&X vwv chain. The Write&X bcc
2252 * array is put behind the Read&X vwv array. So now we
2253 * check whether the chain offset points strictly
2254 * behind the previous vwv array. req->buf points
2255 * right after the vwv array of the previous
2257 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2261 vwv_offset = ((const char *)vwv - smb_buf);
2262 if (chain_offset <= vwv_offset) {
2267 * Next check: Make sure the chain offset does not
2268 * point beyond the overall smb request length.
2271 length_needed = chain_offset+1; /* wct */
2272 if (length_needed > smblen) {
2277 * Now comes the pointer magic. Goal here is to set up
2278 * vwv and buf correctly again. The chain offset (the
2279 * former vwv[1]) points at the new wct field.
2282 wct = CVAL(smb_buf, chain_offset);
2284 if (is_andx_req(chain_cmd) && (wct < 2)) {
2289 * Next consistency check: Make the new vwv array fits
2290 * in the overall smb request.
2293 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2294 if (length_needed > smblen) {
2297 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2300 * Now grab the new byte buffer....
2303 num_bytes = SVAL(vwv+wct, 0);
2306 * .. and check that it fits.
2309 length_needed += num_bytes;
2310 if (length_needed > smblen) {
2313 bytes = (const uint8_t *)(vwv+wct+1);
2315 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2319 if (!is_andx_req(chain_cmd)) {
2322 chain_cmd = CVAL(vwv, 0);
2327 static bool smb1_chain_length_cb(uint8_t cmd,
2328 uint8_t wct, const uint16_t *vwv,
2329 uint16_t num_bytes, const uint8_t *bytes,
2332 unsigned *count = (unsigned *)private_data;
2337 unsigned smb1_chain_length(const uint8_t *buf)
2341 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2347 struct smb1_parse_chain_state {
2348 TALLOC_CTX *mem_ctx;
2350 struct smbd_server_connection *sconn;
2351 struct smbXsrv_connection *xconn;
2355 struct smb_request **reqs;
2359 static bool smb1_parse_chain_cb(uint8_t cmd,
2360 uint8_t wct, const uint16_t *vwv,
2361 uint16_t num_bytes, const uint8_t *bytes,
2364 struct smb1_parse_chain_state *state =
2365 (struct smb1_parse_chain_state *)private_data;
2366 struct smb_request **reqs;
2367 struct smb_request *req;
2370 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2371 struct smb_request *, state->num_reqs+1);
2377 req = talloc(reqs, struct smb_request);
2382 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2383 state->encrypted, state->seqnum);
2390 req->buflen = num_bytes;
2393 reqs[state->num_reqs] = req;
2394 state->num_reqs += 1;
2398 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2399 struct smbd_server_connection *sconn,
2400 bool encrypted, uint32_t seqnum,
2401 struct smb_request ***reqs, unsigned *num_reqs)
2403 struct smbXsrv_connection *xconn = sconn->conn;
2404 struct smb1_parse_chain_state state;
2407 state.mem_ctx = mem_ctx;
2409 state.sconn = sconn;
2410 state.xconn = xconn;
2411 state.encrypted = encrypted;
2412 state.seqnum = seqnum;
2416 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2417 TALLOC_FREE(state.reqs);
2420 for (i=0; i<state.num_reqs; i++) {
2421 state.reqs[i]->chain = state.reqs;
2424 *num_reqs = state.num_reqs;
2428 /****************************************************************************
2429 Check if services need reloading.
2430 ****************************************************************************/
2432 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2435 if (last_smb_conf_reload_time == 0) {
2436 last_smb_conf_reload_time = t;
2439 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2440 reload_services(sconn, conn_snum_used, true);
2441 last_smb_conf_reload_time = t;
2445 static bool fd_is_readable(int fd)
2449 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2451 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2455 static void smbd_server_connection_write_handler(
2456 struct smbXsrv_connection *xconn)
2458 /* TODO: make write nonblocking */
2461 static void smbd_server_connection_read_handler(
2462 struct smbXsrv_connection *xconn, int fd)
2464 uint8_t *inbuf = NULL;
2465 size_t inbuf_len = 0;
2466 size_t unread_bytes = 0;
2467 bool encrypted = false;
2468 TALLOC_CTX *mem_ctx = talloc_tos();
2472 bool async_echo = lp_async_smb_echo_handler();
2473 bool from_client = false;
2476 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2478 * This is the super-ugly hack to prefer the packets
2479 * forwarded by the echo handler over the ones by the
2482 fd = xconn->smb1.echo_handler.trusted_fd;
2486 from_client = (xconn->transport.sock == fd);
2488 if (async_echo && from_client) {
2489 smbd_lock_socket(xconn);
2491 if (!fd_is_readable(fd)) {
2492 DEBUG(10,("the echo listener was faster\n"));
2493 smbd_unlock_socket(xconn);
2498 /* TODO: make this completely nonblocking */
2499 status = receive_smb_talloc(mem_ctx, xconn, fd,
2500 (char **)(void *)&inbuf,
2504 &inbuf_len, &seqnum,
2505 !from_client /* trusted channel */);
2507 if (async_echo && from_client) {
2508 smbd_unlock_socket(xconn);
2511 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2514 if (NT_STATUS_IS_ERR(status)) {
2515 exit_server_cleanly("failed to receive smb request");
2517 if (!NT_STATUS_IS_OK(status)) {
2522 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2523 seqnum, encrypted, NULL);
2526 static void smbd_server_connection_handler(struct tevent_context *ev,
2527 struct tevent_fd *fde,
2531 struct smbXsrv_connection *xconn =
2532 talloc_get_type_abort(private_data,
2533 struct smbXsrv_connection);
2535 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2537 * we're not supposed to do any io
2539 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2540 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2544 if (flags & TEVENT_FD_WRITE) {
2545 smbd_server_connection_write_handler(xconn);
2548 if (flags & TEVENT_FD_READ) {
2549 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2554 static void smbd_server_echo_handler(struct tevent_context *ev,
2555 struct tevent_fd *fde,
2559 struct smbXsrv_connection *xconn =
2560 talloc_get_type_abort(private_data,
2561 struct smbXsrv_connection);
2563 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2565 * we're not supposed to do any io
2567 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2568 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2572 if (flags & TEVENT_FD_WRITE) {
2573 smbd_server_connection_write_handler(xconn);
2576 if (flags & TEVENT_FD_READ) {
2577 smbd_server_connection_read_handler(
2578 xconn, xconn->smb1.echo_handler.trusted_fd);
2583 struct smbd_release_ip_state {
2584 struct smbXsrv_connection *xconn;
2585 struct tevent_immediate *im;
2586 char addr[INET6_ADDRSTRLEN];
2589 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2590 struct tevent_immediate *im,
2593 struct smbd_release_ip_state *state =
2594 talloc_get_type_abort(private_data,
2595 struct smbd_release_ip_state);
2596 struct smbXsrv_connection *xconn = state->xconn;
2598 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2600 * smbd_server_connection_terminate() already triggered ?
2605 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2608 /****************************************************************************
2609 received when we should release a specific IP
2610 ****************************************************************************/
2611 static bool release_ip(const char *ip, void *priv)
2613 struct smbd_release_ip_state *state =
2614 talloc_get_type_abort(priv,
2615 struct smbd_release_ip_state);
2616 struct smbXsrv_connection *xconn = state->xconn;
2617 const char *addr = state->addr;
2618 const char *p = addr;
2620 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2621 /* avoid recursion */
2625 if (strncmp("::ffff:", addr, 7) == 0) {
2629 DEBUG(10, ("Got release IP message for %s, "
2630 "our address is %s\n", ip, p));
2632 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2633 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2636 * With SMB2 we should do a clean disconnect,
2637 * the previous_session_id in the session setup
2638 * will cleanup the old session, tcons and opens.
2640 * A clean disconnect is needed in order to support
2643 * Note: typically this is never triggered
2644 * as we got a TCP RST (triggered by ctdb event scripts)
2645 * before we get CTDB_SRVID_RELEASE_IP.
2647 * We used to call _exit(1) here, but as this was mostly never
2648 * triggered and has implication on our process model,
2649 * we can just use smbd_server_connection_terminate()
2652 * We don't call smbd_server_connection_terminate() directly
2653 * as we might be called from within ctdbd_migrate(),
2654 * we need to defer our action to the next event loop
2656 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2657 smbd_release_ip_immediate, state);
2660 * Make sure we don't get any io on the connection.
2662 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2669 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2670 struct sockaddr_storage *srv,
2671 struct sockaddr_storage *clnt)
2673 struct smbd_release_ip_state *state;
2674 struct ctdbd_connection *cconn;
2676 cconn = messaging_ctdbd_connection();
2677 if (cconn == NULL) {
2678 return NT_STATUS_NO_MEMORY;
2681 state = talloc_zero(xconn, struct smbd_release_ip_state);
2682 if (state == NULL) {
2683 return NT_STATUS_NO_MEMORY;
2685 state->xconn = xconn;
2686 state->im = tevent_create_immediate(state);
2687 if (state->im == NULL) {
2688 return NT_STATUS_NO_MEMORY;
2690 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2691 return NT_STATUS_NO_MEMORY;
2694 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2697 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2698 void *private_data, uint32_t msg_type,
2699 struct server_id server_id, DATA_BLOB *data)
2701 struct smbd_server_connection *sconn = talloc_get_type_abort(
2702 private_data, struct smbd_server_connection);
2703 const char *ip = (char *) data->data;
2706 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2708 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2710 if (client_ip == NULL) {
2714 if (strequal(ip, client_ip)) {
2715 DEBUG(1, ("Got kill client message for %s - "
2716 "exiting immediately\n", ip));
2717 exit_server_cleanly("Forced disconnect for client");
2720 TALLOC_FREE(client_ip);
2724 * Send keepalive packets to our client
2726 static bool keepalive_fn(const struct timeval *now, void *private_data)
2728 struct smbd_server_connection *sconn = talloc_get_type_abort(
2729 private_data, struct smbd_server_connection);
2730 struct smbXsrv_connection *xconn = sconn->conn;
2733 if (sconn->using_smb2) {
2734 /* Don't do keepalives on an SMB2 connection. */
2738 smbd_lock_socket(xconn);
2739 ret = send_keepalive(xconn->transport.sock);
2740 smbd_unlock_socket(xconn);
2743 int saved_errno = errno;
2745 * Try and give an error message saying what
2748 DEBUG(0, ("send_keepalive failed for client %s. "
2749 "Error %s - exiting\n",
2750 smbXsrv_connection_dbg(xconn),
2751 strerror(saved_errno)));
2752 errno = saved_errno;
2759 * Do the recurring check if we're idle
2761 static bool deadtime_fn(const struct timeval *now, void *private_data)
2763 struct smbd_server_connection *sconn =
2764 (struct smbd_server_connection *)private_data;
2766 if ((conn_num_open(sconn) == 0)
2767 || (conn_idle_all(sconn, now->tv_sec))) {
2768 DEBUG( 2, ( "Closing idle connection\n" ) );
2769 messaging_send(sconn->msg_ctx,
2770 messaging_server_id(sconn->msg_ctx),
2771 MSG_SHUTDOWN, &data_blob_null);
2779 * Do the recurring log file and smb.conf reload checks.
2782 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2784 struct smbd_server_connection *sconn = talloc_get_type_abort(
2785 private_data, struct smbd_server_connection);
2787 DEBUG(5, ("housekeeping\n"));
2789 change_to_root_user();
2791 /* update printer queue caches if necessary */
2792 update_monitored_printq_cache(sconn->msg_ctx);
2794 /* check if we need to reload services */
2795 check_reload(sconn, time_mono(NULL));
2798 * Force a log file check.
2800 force_check_log_size();
2806 * Read an smb packet in the echo handler child, giving the parent
2807 * smbd one second to react once the socket becomes readable.
2810 struct smbd_echo_read_state {
2811 struct tevent_context *ev;
2812 struct smbd_server_connection *sconn;
2819 static void smbd_echo_read_readable(struct tevent_req *subreq);
2820 static void smbd_echo_read_waited(struct tevent_req *subreq);
2822 static struct tevent_req *smbd_echo_read_send(
2823 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2824 struct smbd_server_connection *sconn)
2826 struct tevent_req *req, *subreq;
2827 struct smbd_echo_read_state *state;
2828 struct smbXsrv_connection *xconn = sconn->conn;
2830 req = tevent_req_create(mem_ctx, &state,
2831 struct smbd_echo_read_state);
2836 state->sconn = sconn;
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 smbd_server_connection *sconn = state->sconn;
2881 struct smbXsrv_connection *xconn = sconn->conn;
2887 ok = tevent_wakeup_recv(subreq);
2888 TALLOC_FREE(subreq);
2890 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2894 ok = smbd_lock_socket_internal(xconn);
2896 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2897 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2901 if (!fd_is_readable(xconn->transport.sock)) {
2902 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2905 ok = smbd_unlock_socket_internal(xconn);
2907 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2908 DEBUG(1, ("%s: failed to unlock socket\n",
2913 subreq = wait_for_read_send(state, state->ev,
2914 xconn->transport.sock);
2915 if (tevent_req_nomem(subreq, req)) {
2918 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2922 status = receive_smb_talloc(state, xconn,
2923 xconn->transport.sock,
2930 false /* trusted_channel*/);
2932 if (tevent_req_nterror(req, status)) {
2933 tevent_req_nterror(req, status);
2934 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2935 (int)getpid(), nt_errstr(status)));
2939 ok = smbd_unlock_socket_internal(xconn);
2941 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2942 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2945 tevent_req_done(req);
2948 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2949 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2951 struct smbd_echo_read_state *state = tevent_req_data(
2952 req, struct smbd_echo_read_state);
2955 if (tevent_req_is_nterror(req, &status)) {
2958 *pbuf = talloc_move(mem_ctx, &state->buf);
2959 *pbuflen = state->buflen;
2960 *pseqnum = state->seqnum;
2961 return NT_STATUS_OK;
2964 struct smbd_echo_state {
2965 struct tevent_context *ev;
2966 struct iovec *pending;
2967 struct smbd_server_connection *sconn;
2968 struct smbXsrv_connection *xconn;
2971 struct tevent_fd *parent_fde;
2973 struct tevent_req *write_req;
2976 static void smbd_echo_writer_done(struct tevent_req *req);
2978 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2982 if (state->write_req != NULL) {
2986 num_pending = talloc_array_length(state->pending);
2987 if (num_pending == 0) {
2991 state->write_req = writev_send(state, state->ev, NULL,
2992 state->parent_pipe, false,
2993 state->pending, num_pending);
2994 if (state->write_req == NULL) {
2995 DEBUG(1, ("writev_send failed\n"));
2999 talloc_steal(state->write_req, state->pending);
3000 state->pending = NULL;
3002 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3006 static void smbd_echo_writer_done(struct tevent_req *req)
3008 struct smbd_echo_state *state = tevent_req_callback_data(
3009 req, struct smbd_echo_state);
3013 written = writev_recv(req, &err);
3015 state->write_req = NULL;
3016 if (written == -1) {
3017 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3020 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3021 smbd_echo_activate_writer(state);
3024 static bool smbd_echo_reply(struct smbd_echo_state *state,
3025 uint8_t *inbuf, size_t inbuf_len,
3028 struct smb_request req;
3029 uint16_t num_replies;
3033 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3034 DEBUG(10, ("Got netbios keepalive\n"));
3041 if (inbuf_len < smb_size) {
3042 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3045 if (!valid_smb_header(inbuf)) {
3046 DEBUG(10, ("Got invalid SMB header\n"));
3050 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3056 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3057 smb_messages[req.cmd].name
3058 ? smb_messages[req.cmd].name : "unknown"));
3060 if (req.cmd != SMBecho) {
3067 num_replies = SVAL(req.vwv+0, 0);
3068 if (num_replies != 1) {
3069 /* Not a Windows "Hey, you're still there?" request */
3073 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3075 DEBUG(10, ("create_outbuf failed\n"));
3078 req.outbuf = (uint8_t *)outbuf;
3080 SSVAL(req.outbuf, smb_vwv0, num_replies);
3082 if (req.buflen > 0) {
3083 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3086 ok = srv_send_smb(req.xconn,
3090 TALLOC_FREE(outbuf);
3098 static void smbd_echo_exit(struct tevent_context *ev,
3099 struct tevent_fd *fde, uint16_t flags,
3102 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3106 static void smbd_echo_got_packet(struct tevent_req *req);
3108 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3111 struct smbXsrv_connection *xconn = sconn->conn;
3112 struct smbd_echo_state *state;
3113 struct tevent_req *read_req;
3115 state = talloc_zero(sconn, struct smbd_echo_state);
3116 if (state == NULL) {
3117 DEBUG(1, ("talloc failed\n"));
3120 state->sconn = sconn;
3121 state->xconn = xconn;
3122 state->parent_pipe = parent_pipe;
3123 state->ev = s3_tevent_context_init(state);
3124 if (state->ev == NULL) {
3125 DEBUG(1, ("tevent_context_init failed\n"));
3129 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3130 TEVENT_FD_READ, smbd_echo_exit,
3132 if (state->parent_fde == NULL) {
3133 DEBUG(1, ("tevent_add_fd failed\n"));
3138 read_req = smbd_echo_read_send(state, state->ev, sconn);
3139 if (read_req == NULL) {
3140 DEBUG(1, ("smbd_echo_read_send failed\n"));
3144 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3147 if (tevent_loop_once(state->ev) == -1) {
3148 DEBUG(1, ("tevent_loop_once failed: %s\n",
3156 static void smbd_echo_got_packet(struct tevent_req *req)
3158 struct smbd_echo_state *state = tevent_req_callback_data(
3159 req, struct smbd_echo_state);
3163 uint32_t seqnum = 0;
3166 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3168 if (!NT_STATUS_IS_OK(status)) {
3169 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3170 nt_errstr(status)));
3174 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3180 num_pending = talloc_array_length(state->pending);
3181 tmp = talloc_realloc(state, state->pending, struct iovec,
3184 DEBUG(1, ("talloc_realloc failed\n"));
3187 state->pending = tmp;
3189 if (buflen >= smb_size) {
3191 * place the seqnum in the packet so that the main process
3192 * can reply with signing
3194 SIVAL(buf, smb_ss_field, seqnum);
3195 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3198 iov = &state->pending[num_pending];
3199 iov->iov_base = talloc_move(state->pending, &buf);
3200 iov->iov_len = buflen;
3202 DEBUG(10,("echo_handler[%d]: forward to main\n",
3204 smbd_echo_activate_writer(state);
3207 req = smbd_echo_read_send(state, state->ev, state->sconn);
3209 DEBUG(1, ("smbd_echo_read_send failed\n"));
3212 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3217 * Handle SMBecho requests in a forked child process
3219 bool fork_echo_handler(struct smbd_server_connection *sconn)
3221 struct smbXsrv_connection *xconn = sconn->conn;
3222 int listener_pipe[2];
3225 bool use_mutex = false;
3227 res = pipe(listener_pipe);
3229 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3233 #ifdef HAVE_ROBUST_MUTEXES
3234 use_mutex = tdb_runtime_check_for_robust_mutexes();
3237 pthread_mutexattr_t a;
3239 xconn->smb1.echo_handler.socket_mutex =
3240 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3241 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3242 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3247 res = pthread_mutexattr_init(&a);
3249 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3253 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3255 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3257 pthread_mutexattr_destroy(&a);
3260 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3262 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3264 pthread_mutexattr_destroy(&a);
3267 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3269 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3270 "%s\n", strerror(res)));
3271 pthread_mutexattr_destroy(&a);
3274 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3276 pthread_mutexattr_destroy(&a);
3278 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3286 xconn->smb1.echo_handler.socket_lock_fd =
3287 create_unlink_tmp(lp_lock_directory());
3288 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3289 DEBUG(1, ("Could not create lock fd: %s\n",
3299 close(listener_pipe[0]);
3300 set_blocking(listener_pipe[1], false);
3302 status = reinit_after_fork(sconn->msg_ctx,
3305 if (!NT_STATUS_IS_OK(status)) {
3306 DEBUG(1, ("reinit_after_fork failed: %s\n",
3307 nt_errstr(status)));
3310 smbd_echo_loop(sconn, listener_pipe[1]);
3313 close(listener_pipe[1]);
3314 listener_pipe[1] = -1;
3315 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3317 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3320 * Without smb signing this is the same as the normal smbd
3321 * listener. This needs to change once signing comes in.
3323 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3325 xconn->smb1.echo_handler.trusted_fd,
3327 smbd_server_echo_handler,
3329 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3330 DEBUG(1, ("event_add_fd failed\n"));
3337 if (listener_pipe[0] != -1) {
3338 close(listener_pipe[0]);
3340 if (listener_pipe[1] != -1) {
3341 close(listener_pipe[1]);
3343 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3344 close(xconn->smb1.echo_handler.socket_lock_fd);
3346 #ifdef HAVE_ROBUST_MUTEXES
3347 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3348 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3349 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3352 smbd_echo_init(xconn);
3357 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3360 if (user->session_info &&
3361 (user->session_info->unix_token->uid == uid)) {
3369 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3372 if (user->session_info != NULL) {
3374 struct security_unix_token *utok;
3376 utok = user->session_info->unix_token;
3377 if (utok->gid == gid) {
3380 for(i=0; i<utok->ngroups; i++) {
3381 if (utok->groups[i] == gid) {
3391 static bool sid_in_use(const struct user_struct *user,
3392 const struct dom_sid *psid)
3395 struct security_token *tok;
3397 if (user->session_info == NULL) {
3400 tok = user->session_info->security_token;
3403 * Not sure session_info->security_token can
3404 * ever be NULL. This check might be not
3409 if (security_token_has_sid(tok, psid)) {
3417 static bool id_in_use(const struct user_struct *user,
3418 const struct id_cache_ref *id)
3422 return uid_in_use(user, id->id.uid);
3424 return gid_in_use(user, id->id.gid);
3426 return sid_in_use(user, &id->id.sid);
3433 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3436 struct server_id server_id,
3439 const char *msg = (data && data->data)
3440 ? (const char *)data->data : "<NULL>";
3441 struct id_cache_ref id;
3442 struct smbd_server_connection *sconn =
3443 talloc_get_type_abort(private_data,
3444 struct smbd_server_connection);
3446 if (!id_cache_ref_parse(msg, &id)) {
3447 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3451 if (id_in_use(sconn->users, &id)) {
3452 exit_server_cleanly(msg);
3454 id_cache_delete_from_cache(&id);
3457 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3458 enum protocol_types protocol)
3462 set_Protocol(protocol);
3463 conn->protocol = protocol;
3465 if (protocol >= PROTOCOL_SMB2_02) {
3466 status = smb2srv_session_table_init(conn);
3467 if (!NT_STATUS_IS_OK(status)) {
3471 status = smb2srv_open_table_init(conn);
3472 if (!NT_STATUS_IS_OK(status)) {
3476 status = smb1srv_session_table_init(conn);
3477 if (!NT_STATUS_IS_OK(status)) {
3481 status = smb1srv_tcon_table_init(conn);
3482 if (!NT_STATUS_IS_OK(status)) {
3486 status = smb1srv_open_table_init(conn);
3487 if (!NT_STATUS_IS_OK(status)) {
3492 return NT_STATUS_OK;
3495 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3498 struct smbXsrv_connection *conn =
3499 talloc_get_type_abort(private_data,
3500 struct smbXsrv_connection);
3503 case TEVENT_TRACE_BEFORE_WAIT:
3505 * This just removes compiler warning
3506 * without profile support
3508 conn->smbd_idle_profstamp = 0;
3509 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3511 case TEVENT_TRACE_AFTER_WAIT:
3512 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3514 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3515 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3516 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3523 * Create a debug string for the connection
3525 * This is allocated to talloc_tos() or a string constant
3526 * in certain corner cases. The returned string should
3527 * hence not be free'd directly but only via the talloc stack.
3529 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3534 * TODO: this can be improved later
3535 * maybe including the client guid or more
3537 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3539 return "<tsocket_address_string() failed>";
3545 /****************************************************************************
3546 Process commands from the client
3547 ****************************************************************************/
3549 void smbd_process(struct tevent_context *ev_ctx,
3550 struct messaging_context *msg_ctx,
3554 TALLOC_CTX *frame = talloc_stackframe();
3555 struct smbXsrv_connection *xconn;
3556 struct smbd_server_connection *sconn;
3557 struct sockaddr_storage ss_srv;
3558 void *sp_srv = (void *)&ss_srv;
3559 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3560 struct sockaddr_storage ss_clnt;
3561 void *sp_clnt = (void *)&ss_clnt;
3562 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3563 socklen_t sa_socklen;
3564 struct tsocket_address *local_address = NULL;
3565 struct tsocket_address *remote_address = NULL;
3566 const char *locaddr = NULL;
3567 const char *remaddr = NULL;
3572 xconn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3573 if (xconn == NULL) {
3574 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3575 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3578 xconn->ev_ctx = ev_ctx;
3579 xconn->msg_ctx = msg_ctx;
3580 xconn->transport.sock = sock_fd;
3581 smbd_echo_init(xconn);
3583 sconn = talloc_zero(xconn, struct smbd_server_connection);
3585 exit_server("failed to create smbd_server_connection");
3588 xconn->sconn = sconn;
3589 sconn->conn = xconn;
3592 * TODO: remove this...:-)
3594 global_smbXsrv_connection = xconn;
3596 sconn->ev_ctx = ev_ctx;
3597 sconn->msg_ctx = msg_ctx;
3600 smbd_setup_sig_term_handler(sconn);
3601 smbd_setup_sig_hup_handler(sconn);
3603 if (!serverid_register(messaging_server_id(msg_ctx),
3604 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3606 |FLAG_MSG_PRINT_GENERAL)) {
3607 exit_server_cleanly("Could not register myself in "
3612 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3614 * We're not making the decision here,
3615 * we're just allowing the client
3616 * to decide between SMB1 and SMB2
3617 * with the first negprot
3620 sconn->using_smb2 = true;
3623 /* Ensure child is set to blocking mode */
3624 set_blocking(sock_fd,True);
3626 set_socket_options(sock_fd, "SO_KEEPALIVE");
3627 set_socket_options(sock_fd, lp_socket_options());
3629 sa_socklen = sizeof(ss_clnt);
3630 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3632 int level = (errno == ENOTCONN)?2:0;
3633 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3634 exit_server_cleanly("getpeername() failed.\n");
3636 ret = tsocket_address_bsd_from_sockaddr(sconn,
3637 sa_clnt, sa_socklen,
3640 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3641 __location__, strerror(errno)));
3642 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3645 sa_socklen = sizeof(ss_srv);
3646 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3648 int level = (errno == ENOTCONN)?2:0;
3649 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3650 exit_server_cleanly("getsockname() failed.\n");
3652 ret = tsocket_address_bsd_from_sockaddr(sconn,
3656 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3657 __location__, strerror(errno)));
3658 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3661 sconn->local_address = local_address;
3662 sconn->remote_address = remote_address;
3664 if (tsocket_address_is_inet(local_address, "ip")) {
3665 locaddr = tsocket_address_inet_addr_string(
3666 sconn->local_address,
3668 if (locaddr == NULL) {
3669 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3670 __location__, strerror(errno)));
3671 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3674 locaddr = "0.0.0.0";
3677 if (tsocket_address_is_inet(remote_address, "ip")) {
3678 remaddr = tsocket_address_inet_addr_string(
3679 sconn->remote_address,
3681 if (remaddr == NULL) {
3682 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3683 __location__, strerror(errno)));
3684 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3687 remaddr = "0.0.0.0";
3690 /* this is needed so that we get decent entries
3691 in smbstatus for port 445 connects */
3692 set_remote_machine_name(remaddr, false);
3693 reload_services(sconn, conn_snum_used, true);
3696 * Before the first packet, check the global hosts allow/ hosts deny
3697 * parameters before doing any parsing of packets passed to us by the
3698 * client. This prevents attacks on our parsing code from hosts not in
3699 * the hosts allow list.
3702 ret = get_remote_hostname(remote_address,
3706 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3707 __location__, strerror(errno)));
3708 exit_server_cleanly("get_remote_hostname failed.\n");
3710 if (strequal(rhost, "UNKNOWN")) {
3711 rhost = talloc_strdup(talloc_tos(), remaddr);
3713 sconn->remote_hostname = talloc_move(sconn, &rhost);
3715 sub_set_socket_ids(remaddr,
3716 sconn->remote_hostname,
3719 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3720 sconn->remote_hostname,
3723 * send a negative session response "not listening on calling
3726 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3727 DEBUG( 1, ("Connection denied from %s to %s\n",
3728 tsocket_address_string(remote_address, talloc_tos()),
3729 tsocket_address_string(local_address, talloc_tos())));
3730 (void)srv_send_smb(xconn,(char *)buf, false,
3732 exit_server_cleanly("connection denied");
3735 DEBUG(10, ("Connection allowed from %s to %s\n",
3736 tsocket_address_string(remote_address, talloc_tos()),
3737 tsocket_address_string(local_address, talloc_tos())));
3739 if (lp_preload_modules()) {
3740 smb_load_modules(lp_preload_modules());
3743 smb_perfcount_init();
3745 if (!init_account_policy()) {
3746 exit_server("Could not open account policy tdb.\n");
3749 if (*lp_root_directory(talloc_tos())) {
3750 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3751 DEBUG(0,("Failed to change root to %s\n",
3752 lp_root_directory(talloc_tos())));
3753 exit_server("Failed to chroot()");
3755 if (chdir("/") == -1) {
3756 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3757 exit_server("Failed to chroot()");
3759 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3762 if (!srv_init_signing(xconn)) {
3763 exit_server("Failed to init smb_signing");
3766 if (!file_init(sconn)) {
3767 exit_server("file_init() failed");
3771 if (!init_oplocks(sconn))
3772 exit_server("Failed to init oplocks");
3774 /* register our message handlers */
3775 messaging_register(sconn->msg_ctx, sconn,
3776 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3777 messaging_register(sconn->msg_ctx, sconn,
3778 MSG_SMB_CLOSE_FILE, msg_close_file);
3779 messaging_register(sconn->msg_ctx, sconn,
3780 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3782 id_cache_register_msgs(sconn->msg_ctx);
3783 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3784 messaging_register(sconn->msg_ctx, sconn,
3785 ID_CACHE_KILL, smbd_id_cache_kill);
3787 messaging_deregister(sconn->msg_ctx,
3788 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3789 messaging_register(sconn->msg_ctx, sconn,
3790 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3792 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3794 messaging_register(sconn->msg_ctx, sconn,
3795 MSG_SMB_KILL_CLIENT_IP,
3796 msg_kill_client_ip);
3798 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3801 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3802 * MSGs to all child processes
3804 messaging_deregister(sconn->msg_ctx,
3806 messaging_register(sconn->msg_ctx, NULL,
3807 MSG_DEBUG, debug_message);
3809 if ((lp_keepalive() != 0)
3810 && !(event_add_idle(ev_ctx, NULL,
3811 timeval_set(lp_keepalive(), 0),
3812 "keepalive", keepalive_fn,
3814 DEBUG(0, ("Could not add keepalive event\n"));
3818 if (!(event_add_idle(ev_ctx, NULL,
3819 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3820 "deadtime", deadtime_fn, sconn))) {
3821 DEBUG(0, ("Could not add deadtime event\n"));
3825 if (!(event_add_idle(ev_ctx, NULL,
3826 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3827 "housekeeping", housekeeping_fn, sconn))) {
3828 DEBUG(0, ("Could not add housekeeping event\n"));
3832 if (lp_clustering()) {
3834 * We need to tell ctdb about our client's TCP
3835 * connection, so that for failover ctdbd can send
3836 * tickle acks, triggering a reconnection by the
3841 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3842 if (!NT_STATUS_IS_OK(status)) {
3843 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3844 nt_errstr(status)));
3848 tmp = lp_max_xmit();
3849 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3850 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3852 xconn->smb1.negprot.max_recv = tmp;
3854 xconn->smb1.sessions.done_sesssetup = false;
3855 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3857 if (!init_dptrs(sconn)) {
3858 exit_server("init_dptrs() failed");
3861 xconn->transport.fde = tevent_add_fd(ev_ctx,
3865 smbd_server_connection_handler,
3867 if (!xconn->transport.fde) {
3868 exit_server("failed to create smbd_server_connection fde");
3871 sconn->conn->local_address = sconn->local_address;
3872 sconn->conn->remote_address = sconn->remote_address;
3873 sconn->conn->remote_hostname = sconn->remote_hostname;
3874 sconn->conn->protocol = PROTOCOL_NONE;
3878 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, xconn);
3881 frame = talloc_stackframe_pool(8192);
3884 if (tevent_loop_once(ev_ctx) == -1) {
3885 if (errno != EINTR) {
3886 DEBUG(3, ("tevent_loop_once failed: %s,"
3887 " exiting\n", strerror(errno) ));
3895 exit_server_cleanly(NULL);
3898 bool req_is_in_chain(const struct smb_request *req)
3900 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3902 * We're right now handling a subsequent request, so we must
3908 if (!is_andx_req(req->cmd)) {
3914 * Okay, an illegal request, but definitely not chained :-)
3919 return (CVAL(req->vwv+0, 0) != 0xFF);