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 tevent_timer *te;
51 struct smb_perfcount_data pcd;
56 struct deferred_open_record *open_rec;
59 static void construct_reply_common(struct smb_request *req, const char *inbuf,
61 static struct pending_message_list *get_deferred_open_message_smb(
62 struct smbd_server_connection *sconn, uint64_t mid);
63 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
65 void smbd_echo_init(struct smbd_server_connection *sconn)
67 sconn->smb1.echo_handler.trusted_fd = -1;
68 sconn->smb1.echo_handler.socket_lock_fd = -1;
69 #ifdef HAVE_ROBUST_MUTEXES
70 sconn->smb1.echo_handler.socket_mutex = NULL;
74 static bool smbd_echo_active(struct smbd_server_connection *sconn)
76 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
80 #ifdef HAVE_ROBUST_MUTEXES
81 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
89 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
91 if (!smbd_echo_active(sconn)) {
95 sconn->smb1.echo_handler.ref_count++;
97 if (sconn->smb1.echo_handler.ref_count > 1) {
101 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
103 #ifdef HAVE_ROBUST_MUTEXES
104 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
107 while (ret == EINTR) {
108 ret = pthread_mutex_lock(
109 sconn->smb1.echo_handler.socket_mutex);
115 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
122 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
127 sconn->smb1.echo_handler.socket_lock_fd,
128 F_SETLKW, 0, 0, F_WRLCK);
129 } while (!ok && (errno == EINTR));
132 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
137 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
142 void smbd_lock_socket(struct smbd_server_connection *sconn)
144 if (!smbd_lock_socket_internal(sconn)) {
145 exit_server_cleanly("failed to lock socket");
149 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
151 if (!smbd_echo_active(sconn)) {
155 sconn->smb1.echo_handler.ref_count--;
157 if (sconn->smb1.echo_handler.ref_count > 0) {
161 #ifdef HAVE_ROBUST_MUTEXES
162 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
165 while (ret == EINTR) {
166 ret = pthread_mutex_unlock(
167 sconn->smb1.echo_handler.socket_mutex);
173 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
180 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
185 sconn->smb1.echo_handler.socket_lock_fd,
186 F_SETLKW, 0, 0, F_UNLCK);
187 } while (!ok && (errno == EINTR));
190 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
195 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
200 void smbd_unlock_socket(struct smbd_server_connection *sconn)
202 if (!smbd_unlock_socket_internal(sconn)) {
203 exit_server_cleanly("failed to unlock socket");
207 /* Accessor function for smb_read_error for smbd functions. */
209 /****************************************************************************
211 ****************************************************************************/
213 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
214 bool do_signing, uint32_t seqnum,
216 struct smb_perfcount_data *pcd)
218 struct smbXsrv_connection *xconn = sconn->conn;
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(sconn);
233 /* Sign the outgoing packet if required. */
234 srv_calculate_sign_mac(xconn, buf_out, seqnum);
238 NTSTATUS status = srv_encrypt_buffer(sconn, 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(sconn, buf_out);
267 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
268 srv_free_enc_buffer(sconn, buf_out);
270 SMB_PERFCOUNT_END(pcd);
272 smbd_unlock_socket(sconn);
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(struct smbd_server_connection *sconn,
295 const uint8_t *inbuf)
297 if (is_encrypted_packet(sconn, inbuf)) {
301 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
302 * but it just looks weird to call strncmp for this one.
304 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
307 /* Socket functions for smbd packet processing. */
309 static bool valid_packet_size(size_t len)
312 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
313 * of header. Don't print the error if this fits.... JRA.
316 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
317 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
318 (unsigned long)len));
324 static NTSTATUS read_packet_remainder(int fd, char *buffer,
325 unsigned int timeout, ssize_t len)
333 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
334 if (!NT_STATUS_IS_OK(status)) {
335 char addr[INET6_ADDRSTRLEN];
336 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
338 get_peer_addr(fd, addr, sizeof(addr)),
344 /****************************************************************************
345 Attempt a zerocopy writeX read. We know here that len > smb_size-4
346 ****************************************************************************/
349 * Unfortunately, earlier versions of smbclient/libsmbclient
350 * don't send this "standard" writeX header. I've fixed this
351 * for 3.2 but we'll use the old method with earlier versions.
352 * Windows and CIFSFS at least use this standard size. Not
356 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
357 (2*14) + /* word count (including bcc) */ \
360 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
361 const char lenbuf[4],
362 struct smbd_server_connection *sconn,
365 unsigned int timeout,
369 /* Size of a WRITEX call (+4 byte len). */
370 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
371 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
375 memcpy(writeX_header, lenbuf, 4);
377 status = read_fd_with_timeout(
378 sock, writeX_header + 4,
379 STANDARD_WRITE_AND_X_HEADER_SIZE,
380 STANDARD_WRITE_AND_X_HEADER_SIZE,
383 if (!NT_STATUS_IS_OK(status)) {
384 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
386 tsocket_address_string(sconn->remote_address,
393 * Ok - now try and see if this is a possible
397 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
399 * If the data offset is beyond what
400 * we've read, drain the extra bytes.
402 uint16_t doff = SVAL(writeX_header,smb_vwv11);
405 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
406 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
407 if (drain_socket(sock, drain) != drain) {
408 smb_panic("receive_smb_raw_talloc_partial_read:"
409 " failed to drain pending bytes");
412 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
415 /* Spoof down the length and null out the bcc. */
416 set_message_bcc(writeX_header, 0);
417 newlen = smb_len(writeX_header);
419 /* Copy the header we've written. */
421 *buffer = (char *)talloc_memdup(mem_ctx,
423 sizeof(writeX_header));
425 if (*buffer == NULL) {
426 DEBUG(0, ("Could not allocate inbuf of length %d\n",
427 (int)sizeof(writeX_header)));
428 return NT_STATUS_NO_MEMORY;
431 /* Work out the remaining bytes. */
432 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
433 *len_ret = newlen + 4;
437 if (!valid_packet_size(len)) {
438 return NT_STATUS_INVALID_PARAMETER;
442 * Not a valid writeX call. Just do the standard
446 *buffer = talloc_array(mem_ctx, char, len+4);
448 if (*buffer == NULL) {
449 DEBUG(0, ("Could not allocate inbuf of length %d\n",
451 return NT_STATUS_NO_MEMORY;
454 /* Copy in what we already read. */
457 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
458 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
461 status = read_packet_remainder(
463 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
466 if (!NT_STATUS_IS_OK(status)) {
467 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
477 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
478 struct smbd_server_connection *sconn,
480 char **buffer, unsigned int timeout,
481 size_t *p_unread, size_t *plen)
483 struct smbXsrv_connection *xconn = sconn->conn;
486 int min_recv_size = lp_min_receive_file_size();
491 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
493 if (!NT_STATUS_IS_OK(status)) {
497 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
498 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
499 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
500 !srv_is_signing_active(xconn) &&
501 sconn->smb1.echo_handler.trusted_fde == NULL) {
503 return receive_smb_raw_talloc_partial_read(
504 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
508 if (!valid_packet_size(len)) {
509 return NT_STATUS_INVALID_PARAMETER;
513 * The +4 here can't wrap, we've checked the length above already.
516 *buffer = talloc_array(mem_ctx, char, len+4);
518 if (*buffer == NULL) {
519 DEBUG(0, ("Could not allocate inbuf of length %d\n",
521 return NT_STATUS_NO_MEMORY;
524 memcpy(*buffer, lenbuf, sizeof(lenbuf));
526 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
527 if (!NT_STATUS_IS_OK(status)) {
535 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
536 struct smbd_server_connection *sconn,
538 char **buffer, unsigned int timeout,
539 size_t *p_unread, bool *p_encrypted,
542 bool trusted_channel)
544 struct smbXsrv_connection *xconn = sconn->conn;
548 *p_encrypted = false;
550 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
552 if (!NT_STATUS_IS_OK(status)) {
553 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
554 ("receive_smb_raw_talloc failed for client %s "
555 "read error = %s.\n",
556 tsocket_address_string(sconn->remote_address,
558 nt_errstr(status)) );
562 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
563 status = srv_decrypt_buffer(sconn, *buffer);
564 if (!NT_STATUS_IS_OK(status)) {
565 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
566 "incoming packet! Error %s\n",
567 nt_errstr(status) ));
573 /* Check the incoming SMB signature. */
574 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
575 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
576 "incoming packet!\n"));
577 return NT_STATUS_INVALID_NETWORK_RESPONSE;
585 * Initialize a struct smb_request from an inbuf
588 static bool init_smb_request(struct smb_request *req,
589 struct smbd_server_connection *sconn,
591 size_t unread_bytes, bool encrypted,
594 struct smbXsrv_tcon *tcon;
597 size_t req_size = smb_len(inbuf) + 4;
599 /* Ensure we have at least smb_size bytes. */
600 if (req_size < smb_size) {
601 DEBUG(0,("init_smb_request: invalid request size %u\n",
602 (unsigned int)req_size ));
606 req->request_time = timeval_current();
607 now = timeval_to_nttime(&req->request_time);
609 req->cmd = CVAL(inbuf, smb_com);
610 req->flags2 = SVAL(inbuf, smb_flg2);
611 req->smbpid = SVAL(inbuf, smb_pid);
612 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
613 req->seqnum = seqnum;
614 req->vuid = SVAL(inbuf, smb_uid);
615 req->tid = SVAL(inbuf, smb_tid);
616 req->wct = CVAL(inbuf, smb_wct);
617 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
618 req->buflen = smb_buflen(inbuf);
619 req->buf = (const uint8_t *)smb_buf_const(inbuf);
620 req->unread_bytes = unread_bytes;
621 req->encrypted = encrypted;
623 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
624 if (NT_STATUS_IS_OK(status)) {
625 req->conn = tcon->compat;
629 req->chain_fsp = NULL;
631 req->priv_paths = NULL;
633 smb_init_perfcount_data(&req->pcd);
635 /* Ensure we have at least wct words and 2 bytes of bcc. */
636 if (smb_size + req->wct*2 > req_size) {
637 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
638 (unsigned int)req->wct,
639 (unsigned int)req_size));
642 /* Ensure bcc is correct. */
643 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
644 DEBUG(0,("init_smb_request: invalid bcc number %u "
645 "(wct = %u, size %u)\n",
646 (unsigned int)req->buflen,
647 (unsigned int)req->wct,
648 (unsigned int)req_size));
656 static void process_smb(struct smbd_server_connection *conn,
657 uint8_t *inbuf, size_t nread, size_t unread_bytes,
658 uint32_t seqnum, bool encrypted,
659 struct smb_perfcount_data *deferred_pcd);
661 static void smbd_deferred_open_timer(struct tevent_context *ev,
662 struct tevent_timer *te,
663 struct timeval _tval,
666 struct pending_message_list *msg = talloc_get_type(private_data,
667 struct pending_message_list);
668 struct smbd_server_connection *sconn = msg->sconn;
669 TALLOC_CTX *mem_ctx = talloc_tos();
670 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
673 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
676 exit_server("smbd_deferred_open_timer: talloc failed\n");
680 /* We leave this message on the queue so the open code can
681 know this is a retry. */
682 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
683 (unsigned long long)mid ));
685 /* Mark the message as processed so this is not
686 * re-processed in error. */
687 msg->processed = true;
689 process_smb(sconn, inbuf,
691 msg->seqnum, msg->encrypted, &msg->pcd);
693 /* If it's still there and was processed, remove it. */
694 msg = get_deferred_open_message_smb(sconn, mid);
695 if (msg && msg->processed) {
696 remove_deferred_open_message_smb(sconn, mid);
700 /****************************************************************************
701 Function to push a message onto the tail of a linked list of smb messages ready
703 ****************************************************************************/
705 static bool push_queued_message(struct smb_request *req,
706 struct timeval request_time,
707 struct timeval end_time,
708 struct deferred_open_record *open_rec)
710 int msg_len = smb_len(req->inbuf) + 4;
711 struct pending_message_list *msg;
713 msg = talloc_zero(NULL, struct pending_message_list);
716 DEBUG(0,("push_message: malloc fail (1)\n"));
719 msg->sconn = req->sconn;
721 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
722 if(msg->buf.data == NULL) {
723 DEBUG(0,("push_message: malloc fail (2)\n"));
728 msg->request_time = request_time;
729 msg->seqnum = req->seqnum;
730 msg->encrypted = req->encrypted;
731 msg->processed = false;
732 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
735 msg->open_rec = talloc_move(msg, &open_rec);
739 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
742 smbd_deferred_open_timer,
745 DEBUG(0,("push_message: event_add_timed failed\n"));
751 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
752 struct pending_message_list *);
754 DEBUG(10,("push_message: pushed message length %u on "
755 "deferred_open_queue\n", (unsigned int)msg_len));
760 /****************************************************************************
761 Function to delete a sharing violation open message by mid.
762 ****************************************************************************/
764 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
767 struct pending_message_list *pml;
769 if (sconn->using_smb2) {
770 remove_deferred_open_message_smb2(sconn, mid);
774 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
775 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
776 DEBUG(10,("remove_deferred_open_message_smb: "
777 "deleting mid %llu len %u\n",
778 (unsigned long long)mid,
779 (unsigned int)pml->buf.length ));
780 DLIST_REMOVE(sconn->deferred_open_queue, pml);
787 /****************************************************************************
788 Move a sharing violation open retry message to the front of the list and
789 schedule it for immediate processing.
790 ****************************************************************************/
792 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
795 struct pending_message_list *pml;
798 if (sconn->using_smb2) {
799 return schedule_deferred_open_message_smb2(sconn, mid);
802 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
803 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
805 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
808 (unsigned long long)msg_mid ));
810 if (mid == msg_mid) {
811 struct tevent_timer *te;
813 if (pml->processed) {
814 /* A processed message should not be
816 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
817 "message mid %llu was already processed\n",
818 (unsigned long long)msg_mid ));
822 DEBUG(10,("schedule_deferred_open_message_smb: "
823 "scheduling mid %llu\n",
824 (unsigned long long)mid ));
826 te = tevent_add_timer(pml->sconn->ev_ctx,
829 smbd_deferred_open_timer,
832 DEBUG(10,("schedule_deferred_open_message_smb: "
833 "event_add_timed() failed, "
834 "skipping mid %llu\n",
835 (unsigned long long)msg_mid ));
838 TALLOC_FREE(pml->te);
840 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
845 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
846 "find message mid %llu\n",
847 (unsigned long long)mid ));
852 /****************************************************************************
853 Return true if this mid is on the deferred queue and was not yet processed.
854 ****************************************************************************/
856 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
858 struct pending_message_list *pml;
860 if (sconn->using_smb2) {
861 return open_was_deferred_smb2(sconn, mid);
864 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
865 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
872 /****************************************************************************
873 Return the message queued by this mid.
874 ****************************************************************************/
876 static struct pending_message_list *get_deferred_open_message_smb(
877 struct smbd_server_connection *sconn, uint64_t mid)
879 struct pending_message_list *pml;
881 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
882 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
889 /****************************************************************************
890 Get the state data queued by this mid.
891 ****************************************************************************/
893 bool get_deferred_open_message_state(struct smb_request *smbreq,
894 struct timeval *p_request_time,
895 struct deferred_open_record **open_rec)
897 struct pending_message_list *pml;
899 if (smbreq->sconn->using_smb2) {
900 return get_deferred_open_message_state_smb2(smbreq->smb2req,
905 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
909 if (p_request_time) {
910 *p_request_time = pml->request_time;
912 if (open_rec != NULL) {
913 *open_rec = pml->open_rec;
918 /****************************************************************************
919 Function to push a deferred open smb message onto a linked list of local smb
920 messages ready for processing.
921 ****************************************************************************/
923 bool push_deferred_open_message_smb(struct smb_request *req,
924 struct timeval request_time,
925 struct timeval timeout,
927 struct deferred_open_record *open_rec)
929 struct timeval end_time;
932 return push_deferred_open_message_smb2(req->smb2req,
939 if (req->unread_bytes) {
940 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
941 "unread_bytes = %u\n",
942 (unsigned int)req->unread_bytes ));
943 smb_panic("push_deferred_open_message_smb: "
944 "logic error unread_bytes != 0" );
947 end_time = timeval_sum(&request_time, &timeout);
949 DEBUG(10,("push_deferred_open_message_smb: pushing message "
950 "len %u mid %llu timeout time [%u.%06u]\n",
951 (unsigned int) smb_len(req->inbuf)+4,
952 (unsigned long long)req->mid,
953 (unsigned int)end_time.tv_sec,
954 (unsigned int)end_time.tv_usec));
956 return push_queued_message(req, request_time, end_time, open_rec);
959 static void smbd_sig_term_handler(struct tevent_context *ev,
960 struct tevent_signal *se,
966 exit_server_cleanly("termination signal");
969 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
971 struct tevent_signal *se;
973 se = tevent_add_signal(sconn->ev_ctx,
976 smbd_sig_term_handler,
979 exit_server("failed to setup SIGTERM handler");
983 static void smbd_sig_hup_handler(struct tevent_context *ev,
984 struct tevent_signal *se,
990 struct smbd_server_connection *sconn =
991 talloc_get_type_abort(private_data,
992 struct smbd_server_connection);
994 change_to_root_user();
995 DEBUG(1,("Reloading services after SIGHUP\n"));
996 reload_services(sconn, conn_snum_used, false);
999 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1001 struct tevent_signal *se;
1003 se = tevent_add_signal(sconn->ev_ctx,
1006 smbd_sig_hup_handler,
1009 exit_server("failed to setup SIGHUP handler");
1013 static void smbd_conf_updated(struct messaging_context *msg,
1016 struct server_id server_id,
1019 struct smbd_server_connection *sconn =
1020 talloc_get_type_abort(private_data,
1021 struct smbd_server_connection);
1023 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1024 "updated. Reloading.\n"));
1025 change_to_root_user();
1026 reload_services(sconn, conn_snum_used, false);
1030 * Only allow 5 outstanding trans requests. We're allocating memory, so
1034 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1037 for (; list != NULL; list = list->next) {
1039 if (list->mid == mid) {
1040 return NT_STATUS_INVALID_PARAMETER;
1046 return NT_STATUS_INSUFFICIENT_RESOURCES;
1049 return NT_STATUS_OK;
1053 These flags determine some of the permissions required to do an operation
1055 Note that I don't set NEED_WRITE on some write operations because they
1056 are used by some brain-dead clients when printing, and I don't want to
1057 force write permissions on print services.
1059 #define AS_USER (1<<0)
1060 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1061 #define TIME_INIT (1<<2)
1062 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1063 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1064 #define DO_CHDIR (1<<6)
1067 define a list of possible SMB messages and their corresponding
1068 functions. Any message that has a NULL function is unimplemented -
1069 please feel free to contribute implementations!
1071 static const struct smb_message_struct {
1073 void (*fn)(struct smb_request *req);
1075 } smb_messages[256] = {
1077 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1078 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1079 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1080 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1081 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1082 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1083 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1084 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1085 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1086 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1087 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1088 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1089 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1090 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1091 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1092 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1093 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1094 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1095 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1096 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1097 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1098 /* 0x15 */ { NULL, NULL, 0 },
1099 /* 0x16 */ { NULL, NULL, 0 },
1100 /* 0x17 */ { NULL, NULL, 0 },
1101 /* 0x18 */ { NULL, NULL, 0 },
1102 /* 0x19 */ { NULL, NULL, 0 },
1103 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1104 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1105 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1106 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1107 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1108 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1109 /* 0x20 */ { "SMBwritec", NULL,0},
1110 /* 0x21 */ { NULL, NULL, 0 },
1111 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1112 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1113 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1114 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1115 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1116 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1117 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1118 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1119 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1120 /* 0x2b */ { "SMBecho",reply_echo,0},
1121 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1122 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1123 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1124 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1125 /* 0x30 */ { NULL, NULL, 0 },
1126 /* 0x31 */ { NULL, NULL, 0 },
1127 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1128 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1129 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1130 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1131 /* 0x36 */ { NULL, NULL, 0 },
1132 /* 0x37 */ { NULL, NULL, 0 },
1133 /* 0x38 */ { NULL, NULL, 0 },
1134 /* 0x39 */ { NULL, NULL, 0 },
1135 /* 0x3a */ { NULL, NULL, 0 },
1136 /* 0x3b */ { NULL, NULL, 0 },
1137 /* 0x3c */ { NULL, NULL, 0 },
1138 /* 0x3d */ { NULL, NULL, 0 },
1139 /* 0x3e */ { NULL, NULL, 0 },
1140 /* 0x3f */ { NULL, NULL, 0 },
1141 /* 0x40 */ { NULL, NULL, 0 },
1142 /* 0x41 */ { NULL, NULL, 0 },
1143 /* 0x42 */ { NULL, NULL, 0 },
1144 /* 0x43 */ { NULL, NULL, 0 },
1145 /* 0x44 */ { NULL, NULL, 0 },
1146 /* 0x45 */ { NULL, NULL, 0 },
1147 /* 0x46 */ { NULL, NULL, 0 },
1148 /* 0x47 */ { NULL, NULL, 0 },
1149 /* 0x48 */ { NULL, NULL, 0 },
1150 /* 0x49 */ { NULL, NULL, 0 },
1151 /* 0x4a */ { NULL, NULL, 0 },
1152 /* 0x4b */ { NULL, NULL, 0 },
1153 /* 0x4c */ { NULL, NULL, 0 },
1154 /* 0x4d */ { NULL, NULL, 0 },
1155 /* 0x4e */ { NULL, NULL, 0 },
1156 /* 0x4f */ { NULL, NULL, 0 },
1157 /* 0x50 */ { NULL, NULL, 0 },
1158 /* 0x51 */ { NULL, NULL, 0 },
1159 /* 0x52 */ { NULL, NULL, 0 },
1160 /* 0x53 */ { NULL, NULL, 0 },
1161 /* 0x54 */ { NULL, NULL, 0 },
1162 /* 0x55 */ { NULL, NULL, 0 },
1163 /* 0x56 */ { NULL, NULL, 0 },
1164 /* 0x57 */ { NULL, NULL, 0 },
1165 /* 0x58 */ { NULL, NULL, 0 },
1166 /* 0x59 */ { NULL, NULL, 0 },
1167 /* 0x5a */ { NULL, NULL, 0 },
1168 /* 0x5b */ { NULL, NULL, 0 },
1169 /* 0x5c */ { NULL, NULL, 0 },
1170 /* 0x5d */ { NULL, NULL, 0 },
1171 /* 0x5e */ { NULL, NULL, 0 },
1172 /* 0x5f */ { NULL, NULL, 0 },
1173 /* 0x60 */ { NULL, NULL, 0 },
1174 /* 0x61 */ { NULL, NULL, 0 },
1175 /* 0x62 */ { NULL, NULL, 0 },
1176 /* 0x63 */ { NULL, NULL, 0 },
1177 /* 0x64 */ { NULL, NULL, 0 },
1178 /* 0x65 */ { NULL, NULL, 0 },
1179 /* 0x66 */ { NULL, NULL, 0 },
1180 /* 0x67 */ { NULL, NULL, 0 },
1181 /* 0x68 */ { NULL, NULL, 0 },
1182 /* 0x69 */ { NULL, NULL, 0 },
1183 /* 0x6a */ { NULL, NULL, 0 },
1184 /* 0x6b */ { NULL, NULL, 0 },
1185 /* 0x6c */ { NULL, NULL, 0 },
1186 /* 0x6d */ { NULL, NULL, 0 },
1187 /* 0x6e */ { NULL, NULL, 0 },
1188 /* 0x6f */ { NULL, NULL, 0 },
1189 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1190 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1191 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1192 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1193 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1194 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1195 /* 0x76 */ { NULL, NULL, 0 },
1196 /* 0x77 */ { NULL, NULL, 0 },
1197 /* 0x78 */ { NULL, NULL, 0 },
1198 /* 0x79 */ { NULL, NULL, 0 },
1199 /* 0x7a */ { NULL, NULL, 0 },
1200 /* 0x7b */ { NULL, NULL, 0 },
1201 /* 0x7c */ { NULL, NULL, 0 },
1202 /* 0x7d */ { NULL, NULL, 0 },
1203 /* 0x7e */ { NULL, NULL, 0 },
1204 /* 0x7f */ { NULL, NULL, 0 },
1205 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1206 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1207 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1208 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1209 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1210 /* 0x85 */ { NULL, NULL, 0 },
1211 /* 0x86 */ { NULL, NULL, 0 },
1212 /* 0x87 */ { NULL, NULL, 0 },
1213 /* 0x88 */ { NULL, NULL, 0 },
1214 /* 0x89 */ { NULL, NULL, 0 },
1215 /* 0x8a */ { NULL, NULL, 0 },
1216 /* 0x8b */ { NULL, NULL, 0 },
1217 /* 0x8c */ { NULL, NULL, 0 },
1218 /* 0x8d */ { NULL, NULL, 0 },
1219 /* 0x8e */ { NULL, NULL, 0 },
1220 /* 0x8f */ { NULL, NULL, 0 },
1221 /* 0x90 */ { NULL, NULL, 0 },
1222 /* 0x91 */ { NULL, NULL, 0 },
1223 /* 0x92 */ { NULL, NULL, 0 },
1224 /* 0x93 */ { NULL, NULL, 0 },
1225 /* 0x94 */ { NULL, NULL, 0 },
1226 /* 0x95 */ { NULL, NULL, 0 },
1227 /* 0x96 */ { NULL, NULL, 0 },
1228 /* 0x97 */ { NULL, NULL, 0 },
1229 /* 0x98 */ { NULL, NULL, 0 },
1230 /* 0x99 */ { NULL, NULL, 0 },
1231 /* 0x9a */ { NULL, NULL, 0 },
1232 /* 0x9b */ { NULL, NULL, 0 },
1233 /* 0x9c */ { NULL, NULL, 0 },
1234 /* 0x9d */ { NULL, NULL, 0 },
1235 /* 0x9e */ { NULL, NULL, 0 },
1236 /* 0x9f */ { NULL, NULL, 0 },
1237 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1238 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1239 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1240 /* 0xa3 */ { NULL, NULL, 0 },
1241 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1242 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1243 /* 0xa6 */ { NULL, NULL, 0 },
1244 /* 0xa7 */ { NULL, NULL, 0 },
1245 /* 0xa8 */ { NULL, NULL, 0 },
1246 /* 0xa9 */ { NULL, NULL, 0 },
1247 /* 0xaa */ { NULL, NULL, 0 },
1248 /* 0xab */ { NULL, NULL, 0 },
1249 /* 0xac */ { NULL, NULL, 0 },
1250 /* 0xad */ { NULL, NULL, 0 },
1251 /* 0xae */ { NULL, NULL, 0 },
1252 /* 0xaf */ { NULL, NULL, 0 },
1253 /* 0xb0 */ { NULL, NULL, 0 },
1254 /* 0xb1 */ { NULL, NULL, 0 },
1255 /* 0xb2 */ { NULL, NULL, 0 },
1256 /* 0xb3 */ { NULL, NULL, 0 },
1257 /* 0xb4 */ { NULL, NULL, 0 },
1258 /* 0xb5 */ { NULL, NULL, 0 },
1259 /* 0xb6 */ { NULL, NULL, 0 },
1260 /* 0xb7 */ { NULL, NULL, 0 },
1261 /* 0xb8 */ { NULL, NULL, 0 },
1262 /* 0xb9 */ { NULL, NULL, 0 },
1263 /* 0xba */ { NULL, NULL, 0 },
1264 /* 0xbb */ { NULL, NULL, 0 },
1265 /* 0xbc */ { NULL, NULL, 0 },
1266 /* 0xbd */ { NULL, NULL, 0 },
1267 /* 0xbe */ { NULL, NULL, 0 },
1268 /* 0xbf */ { NULL, NULL, 0 },
1269 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1270 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1271 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1272 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1273 /* 0xc4 */ { NULL, NULL, 0 },
1274 /* 0xc5 */ { NULL, NULL, 0 },
1275 /* 0xc6 */ { NULL, NULL, 0 },
1276 /* 0xc7 */ { NULL, NULL, 0 },
1277 /* 0xc8 */ { NULL, NULL, 0 },
1278 /* 0xc9 */ { NULL, NULL, 0 },
1279 /* 0xca */ { NULL, NULL, 0 },
1280 /* 0xcb */ { NULL, NULL, 0 },
1281 /* 0xcc */ { NULL, NULL, 0 },
1282 /* 0xcd */ { NULL, NULL, 0 },
1283 /* 0xce */ { NULL, NULL, 0 },
1284 /* 0xcf */ { NULL, NULL, 0 },
1285 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1286 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1287 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1288 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1289 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1290 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1291 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1292 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1293 /* 0xd8 */ { NULL, NULL, 0 },
1294 /* 0xd9 */ { NULL, NULL, 0 },
1295 /* 0xda */ { NULL, NULL, 0 },
1296 /* 0xdb */ { NULL, NULL, 0 },
1297 /* 0xdc */ { NULL, NULL, 0 },
1298 /* 0xdd */ { NULL, NULL, 0 },
1299 /* 0xde */ { NULL, NULL, 0 },
1300 /* 0xdf */ { NULL, NULL, 0 },
1301 /* 0xe0 */ { NULL, NULL, 0 },
1302 /* 0xe1 */ { NULL, NULL, 0 },
1303 /* 0xe2 */ { NULL, NULL, 0 },
1304 /* 0xe3 */ { NULL, NULL, 0 },
1305 /* 0xe4 */ { NULL, NULL, 0 },
1306 /* 0xe5 */ { NULL, NULL, 0 },
1307 /* 0xe6 */ { NULL, NULL, 0 },
1308 /* 0xe7 */ { NULL, NULL, 0 },
1309 /* 0xe8 */ { NULL, NULL, 0 },
1310 /* 0xe9 */ { NULL, NULL, 0 },
1311 /* 0xea */ { NULL, NULL, 0 },
1312 /* 0xeb */ { NULL, NULL, 0 },
1313 /* 0xec */ { NULL, NULL, 0 },
1314 /* 0xed */ { NULL, NULL, 0 },
1315 /* 0xee */ { NULL, NULL, 0 },
1316 /* 0xef */ { NULL, NULL, 0 },
1317 /* 0xf0 */ { NULL, NULL, 0 },
1318 /* 0xf1 */ { NULL, NULL, 0 },
1319 /* 0xf2 */ { NULL, NULL, 0 },
1320 /* 0xf3 */ { NULL, NULL, 0 },
1321 /* 0xf4 */ { NULL, NULL, 0 },
1322 /* 0xf5 */ { NULL, NULL, 0 },
1323 /* 0xf6 */ { NULL, NULL, 0 },
1324 /* 0xf7 */ { NULL, NULL, 0 },
1325 /* 0xf8 */ { NULL, NULL, 0 },
1326 /* 0xf9 */ { NULL, NULL, 0 },
1327 /* 0xfa */ { NULL, NULL, 0 },
1328 /* 0xfb */ { NULL, NULL, 0 },
1329 /* 0xfc */ { NULL, NULL, 0 },
1330 /* 0xfd */ { NULL, NULL, 0 },
1331 /* 0xfe */ { NULL, NULL, 0 },
1332 /* 0xff */ { NULL, NULL, 0 }
1336 /*******************************************************************
1337 allocate and initialize a reply packet
1338 ********************************************************************/
1340 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1341 const char *inbuf, char **outbuf, uint8_t num_words,
1344 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1347 * Protect against integer wrap.
1348 * The SMB layer reply can be up to 0xFFFFFF bytes.
1350 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1352 if (asprintf(&msg, "num_bytes too large: %u",
1353 (unsigned)num_bytes) == -1) {
1354 msg = discard_const_p(char, "num_bytes too large");
1360 * Here we include the NBT header for now.
1362 *outbuf = talloc_array(mem_ctx, char,
1363 NBT_HDR_SIZE + smb_len);
1364 if (*outbuf == NULL) {
1368 construct_reply_common(req, inbuf, *outbuf);
1369 srv_set_message(*outbuf, num_words, num_bytes, false);
1371 * Zero out the word area, the caller has to take care of the bcc area
1374 if (num_words != 0) {
1375 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1381 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1384 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1386 smb_panic("could not allocate output buffer\n");
1388 req->outbuf = (uint8_t *)outbuf;
1392 /*******************************************************************
1393 Dump a packet to a file.
1394 ********************************************************************/
1396 static void smb_dump(const char *name, int type, const char *data)
1401 if (DEBUGLEVEL < 50) {
1405 len = smb_len_tcp(data)+4;
1406 for (i=1;i<100;i++) {
1407 fname = talloc_asprintf(talloc_tos(),
1411 type ? "req" : "resp");
1412 if (fname == NULL) {
1415 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1416 if (fd != -1 || errno != EEXIST) break;
1420 ssize_t ret = write(fd, data, len);
1422 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1424 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1429 /****************************************************************************
1430 Prepare everything for calling the actual request function, and potentially
1431 call the request function via the "new" interface.
1433 Return False if the "legacy" function needs to be called, everything is
1436 Return True if we're done.
1438 I know this API sucks, but it is the one with the least code change I could
1440 ****************************************************************************/
1442 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1445 uint64_t session_tag;
1446 connection_struct *conn = NULL;
1447 struct smbd_server_connection *sconn = req->sconn;
1448 NTTIME now = timeval_to_nttime(&req->request_time);
1449 struct smbXsrv_session *session = NULL;
1454 if (smb_messages[type].fn == NULL) {
1455 DEBUG(0,("Unknown message type %d!\n",type));
1456 smb_dump("Unknown", 1, (const char *)req->inbuf);
1457 reply_unknown_new(req, type);
1461 flags = smb_messages[type].flags;
1463 /* In share mode security we must ignore the vuid. */
1464 session_tag = req->vuid;
1467 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1468 (int)getpid(), (unsigned long)conn));
1470 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1472 /* Ensure this value is replaced in the incoming packet. */
1473 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1476 * Ensure the correct username is in current_user_info. This is a
1477 * really ugly bugfix for problems with multiple session_setup_and_X's
1478 * being done and allowing %U and %G substitutions to work correctly.
1479 * There is a reason this code is done here, don't move it unless you
1480 * know what you're doing... :-).
1485 * lookup an existing session
1487 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1488 * here, the main check is still in change_to_user()
1490 status = smb1srv_session_lookup(sconn->conn,
1494 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1497 status = NT_STATUS_OK;
1500 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1501 (unsigned long long)session_tag,
1502 (unsigned long long)req->mid));
1503 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1508 if (session_tag != sconn->conn->last_session_id) {
1509 struct user_struct *vuser = NULL;
1511 sconn->conn->last_session_id = session_tag;
1513 vuser = session->compat;
1516 set_current_user_info(
1517 vuser->session_info->unix_info->sanitized_username,
1518 vuser->session_info->unix_info->unix_name,
1519 vuser->session_info->info->domain_name);
1523 /* Does this call need to be run as the connected user? */
1524 if (flags & AS_USER) {
1526 /* Does this call need a valid tree connection? */
1529 * Amazingly, the error code depends on the command
1532 if (type == SMBntcreateX) {
1533 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1535 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1540 if (!change_to_user(conn,session_tag)) {
1541 DEBUG(0, ("Error: Could not change to user. Removing "
1542 "deferred open, mid=%llu.\n",
1543 (unsigned long long)req->mid));
1544 reply_force_doserror(req, ERRSRV, ERRbaduid);
1548 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1550 /* Does it need write permission? */
1551 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1552 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1556 /* IPC services are limited */
1557 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1558 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1562 /* This call needs to be run as root */
1563 change_to_root_user();
1566 /* load service specific parameters */
1568 if (req->encrypted) {
1569 conn->encrypted_tid = true;
1570 /* encrypted required from now on. */
1571 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1572 } else if (ENCRYPTION_REQUIRED(conn)) {
1573 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1574 DEBUG(1,("service[%s] requires encryption"
1575 "%s ACCESS_DENIED. mid=%llu\n",
1576 lp_servicename(talloc_tos(), SNUM(conn)),
1578 (unsigned long long)req->mid));
1579 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1584 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1585 (flags & (AS_USER|DO_CHDIR)
1587 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1590 conn->num_smb_operations++;
1594 * Does this protocol need to be run as guest? (Only archane
1595 * messenger service requests have this...)
1597 if (flags & AS_GUEST) {
1601 if (!change_to_guest()) {
1602 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1606 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1608 if (raddr == NULL) {
1609 reply_nterror(req, NT_STATUS_NO_MEMORY);
1614 * Haven't we checked this in smbd_process already???
1617 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1618 sconn->remote_hostname, raddr);
1622 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1627 smb_messages[type].fn(req);
1631 /****************************************************************************
1632 Construct a reply to the incoming packet.
1633 ****************************************************************************/
1635 static void construct_reply(struct smbd_server_connection *sconn,
1636 char *inbuf, int size, size_t unread_bytes,
1637 uint32_t seqnum, bool encrypted,
1638 struct smb_perfcount_data *deferred_pcd)
1640 connection_struct *conn;
1641 struct smb_request *req;
1643 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1644 smb_panic("could not allocate smb_request");
1647 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1648 encrypted, seqnum)) {
1649 exit_server_cleanly("Invalid SMB request");
1652 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1654 /* we popped this message off the queue - keep original perf data */
1656 req->pcd = *deferred_pcd;
1658 SMB_PERFCOUNT_START(&req->pcd);
1659 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1660 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1663 conn = switch_message(req->cmd, req);
1665 if (req->outbuf == NULL) {
1669 if (CVAL(req->outbuf,0) == 0) {
1670 show_msg((char *)req->outbuf);
1673 if (!srv_send_smb(req->sconn,
1674 (char *)req->outbuf,
1675 true, req->seqnum+1,
1676 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1678 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1686 static void construct_reply_chain(struct smbd_server_connection *sconn,
1687 char *inbuf, int size, uint32_t seqnum,
1689 struct smb_perfcount_data *deferred_pcd)
1691 struct smb_request **reqs = NULL;
1692 struct smb_request *req;
1696 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1697 seqnum, &reqs, &num_reqs);
1699 char errbuf[smb_size];
1700 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1701 __LINE__, __FILE__);
1702 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1704 exit_server_cleanly("construct_reply_chain: "
1705 "srv_send_smb failed.");
1711 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1713 req->conn = switch_message(req->cmd, req);
1715 if (req->outbuf == NULL) {
1717 * Request has suspended itself, will come
1722 smb_request_done(req);
1726 * To be called from an async SMB handler that is potentially chained
1727 * when it is finished for shipping.
1730 void smb_request_done(struct smb_request *req)
1732 struct smb_request **reqs = NULL;
1733 struct smb_request *first_req;
1734 size_t i, num_reqs, next_index;
1737 if (req->chain == NULL) {
1743 num_reqs = talloc_array_length(reqs);
1745 for (i=0; i<num_reqs; i++) {
1746 if (reqs[i] == req) {
1750 if (i == num_reqs) {
1752 * Invalid chain, should not happen
1754 status = NT_STATUS_INTERNAL_ERROR;
1759 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1760 struct smb_request *next = reqs[next_index];
1761 struct smbXsrv_tcon *tcon;
1762 NTTIME now = timeval_to_nttime(&req->request_time);
1764 next->vuid = SVAL(req->outbuf, smb_uid);
1765 next->tid = SVAL(req->outbuf, smb_tid);
1766 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1768 if (NT_STATUS_IS_OK(status)) {
1769 req->conn = tcon->compat;
1773 next->chain_fsp = req->chain_fsp;
1774 next->inbuf = req->inbuf;
1777 req->conn = switch_message(req->cmd, req);
1779 if (req->outbuf == NULL) {
1781 * Request has suspended itself, will come
1789 first_req = reqs[0];
1791 for (i=1; i<next_index; i++) {
1794 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1796 status = NT_STATUS_INTERNAL_ERROR;
1801 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1802 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1805 * This scary statement intends to set the
1806 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1807 * to the value last_req->outbuf carries
1809 SSVAL(first_req->outbuf, smb_flg2,
1810 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1811 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1814 * Transfer the error codes from the subrequest to the main one
1816 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1817 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1820 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1823 if (!srv_send_smb(first_req->sconn,
1824 (char *)first_req->outbuf,
1825 true, first_req->seqnum+1,
1826 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1828 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1831 TALLOC_FREE(req); /* non-chained case */
1832 TALLOC_FREE(reqs); /* chained case */
1837 char errbuf[smb_size];
1838 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1839 if (!srv_send_smb(req->sconn, errbuf, true,
1840 req->seqnum+1, req->encrypted,
1842 exit_server_cleanly("construct_reply_chain: "
1843 "srv_send_smb failed.");
1846 TALLOC_FREE(req); /* non-chained case */
1847 TALLOC_FREE(reqs); /* chained case */
1850 /****************************************************************************
1851 Process an smb from the client
1852 ****************************************************************************/
1853 static void process_smb(struct smbd_server_connection *sconn,
1854 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1855 uint32_t seqnum, bool encrypted,
1856 struct smb_perfcount_data *deferred_pcd)
1858 int msg_type = CVAL(inbuf,0);
1860 DO_PROFILE_INC(smb_count);
1862 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1864 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1865 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1867 if (msg_type != NBSSmessage) {
1869 * NetBIOS session request, keepalive, etc.
1871 reply_special(sconn, (char *)inbuf, nread);
1875 if (sconn->using_smb2) {
1876 /* At this point we're not really using smb2,
1877 * we make the decision here.. */
1878 if (smbd_is_smb2_header(inbuf, nread)) {
1879 smbd_smb2_first_negprot(sconn, inbuf, nread);
1881 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1882 && CVAL(inbuf, smb_com) != 0x72) {
1883 /* This is a non-negprot SMB1 packet.
1884 Disable SMB2 from now on. */
1885 sconn->using_smb2 = false;
1889 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1890 * so subtract 4 from it. */
1891 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1892 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1895 /* special magic for immediate exit */
1897 (IVAL(inbuf, 4) == 0x74697865) &&
1898 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1899 uint8_t exitcode = CVAL(inbuf, 8);
1900 DEBUG(1, ("Exiting immediately with code %d\n",
1905 exit_server_cleanly("Non-SMB packet");
1908 show_msg((char *)inbuf);
1910 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1911 construct_reply_chain(sconn, (char *)inbuf, nread,
1912 seqnum, encrypted, deferred_pcd);
1914 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1915 seqnum, encrypted, deferred_pcd);
1921 sconn->num_requests++;
1923 /* The timeout_processing function isn't run nearly
1924 often enough to implement 'max log size' without
1925 overrunning the size of the file by many megabytes.
1926 This is especially true if we are running at debug
1927 level 10. Checking every 50 SMBs is a nice
1928 tradeoff of performance vs log file size overrun. */
1930 if ((sconn->num_requests % 50) == 0 &&
1931 need_to_check_log_size()) {
1932 change_to_root_user();
1937 /****************************************************************************
1938 Return a string containing the function name of a SMB command.
1939 ****************************************************************************/
1941 const char *smb_fn_name(int type)
1943 const char *unknown_name = "SMBunknown";
1945 if (smb_messages[type].name == NULL)
1946 return(unknown_name);
1948 return(smb_messages[type].name);
1951 /****************************************************************************
1952 Helper functions for contruct_reply.
1953 ****************************************************************************/
1955 void add_to_common_flags2(uint32 v)
1960 void remove_from_common_flags2(uint32 v)
1962 common_flags2 &= ~v;
1965 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1968 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1969 uint16_t out_flags2 = common_flags2;
1971 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1972 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1973 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1975 srv_set_message(outbuf,0,0,false);
1977 SCVAL(outbuf, smb_com, req->cmd);
1978 SIVAL(outbuf,smb_rcls,0);
1979 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1980 SSVAL(outbuf,smb_flg2, out_flags2);
1981 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1982 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1984 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1985 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1986 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1987 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1990 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1992 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1996 * @brief Find the smb_cmd offset of the last command pushed
1997 * @param[in] buf The buffer we're building up
1998 * @retval Where can we put our next andx cmd?
2000 * While chaining requests, the "next" request we're looking at needs to put
2001 * its SMB_Command before the data the previous request already built up added
2002 * to the chain. Find the offset to the place where we have to put our cmd.
2005 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2010 cmd = CVAL(buf, smb_com);
2012 if (!is_andx_req(cmd)) {
2018 while (CVAL(buf, ofs) != 0xff) {
2020 if (!is_andx_req(CVAL(buf, ofs))) {
2025 * ofs is from start of smb header, so add the 4 length
2026 * bytes. The next cmd is right after the wct field.
2028 ofs = SVAL(buf, ofs+2) + 4 + 1;
2030 if (ofs+4 >= talloc_get_size(buf)) {
2040 * @brief Do the smb chaining at a buffer level
2041 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2042 * @param[in] andx_buf Buffer to be appended
2045 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2047 uint8_t smb_command = CVAL(andx_buf, smb_com);
2048 uint8_t wct = CVAL(andx_buf, smb_wct);
2049 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2050 uint32_t num_bytes = smb_buflen(andx_buf);
2051 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2054 size_t old_size, new_size;
2056 size_t chain_padding = 0;
2057 size_t andx_cmd_ofs;
2060 old_size = talloc_get_size(*poutbuf);
2062 if ((old_size % 4) != 0) {
2064 * Align the wct field of subsequent requests to a 4-byte
2067 chain_padding = 4 - (old_size % 4);
2071 * After the old request comes the new wct field (1 byte), the vwv's
2072 * and the num_bytes field.
2075 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2076 new_size += num_bytes;
2078 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2079 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2080 (unsigned)new_size));
2084 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2085 if (outbuf == NULL) {
2086 DEBUG(0, ("talloc failed\n"));
2091 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2092 DEBUG(1, ("invalid command chain\n"));
2093 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2097 if (chain_padding != 0) {
2098 memset(outbuf + old_size, 0, chain_padding);
2099 old_size += chain_padding;
2102 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2103 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2108 * Push the chained request:
2113 SCVAL(outbuf, ofs, wct);
2120 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2125 * Read&X has an offset into its data buffer at
2126 * vwv[6]. reply_read_andx has no idea anymore that it's
2127 * running from within a chain, so we have to fix up the
2130 * Although it looks disgusting at this place, I want to keep
2131 * it here. The alternative would be to push knowledge about
2132 * the andx chain down into read&x again.
2135 if (smb_command == SMBreadX) {
2136 uint8_t *bytes_addr;
2140 * Invalid read&x response
2145 bytes_addr = outbuf + ofs /* vwv start */
2146 + sizeof(uint16_t) * wct /* vwv array */
2147 + sizeof(uint16_t); /* bcc */
2149 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2150 bytes_addr - outbuf - 4);
2153 ofs += sizeof(uint16_t) * wct;
2159 SSVAL(outbuf, ofs, num_bytes);
2160 ofs += sizeof(uint16_t);
2166 memcpy(outbuf + ofs, bytes, num_bytes);
2171 bool smb1_is_chain(const uint8_t *buf)
2173 uint8_t cmd, wct, andx_cmd;
2175 cmd = CVAL(buf, smb_com);
2176 if (!is_andx_req(cmd)) {
2179 wct = CVAL(buf, smb_wct);
2183 andx_cmd = CVAL(buf, smb_vwv);
2184 return (andx_cmd != 0xFF);
2187 bool smb1_walk_chain(const uint8_t *buf,
2188 bool (*fn)(uint8_t cmd,
2189 uint8_t wct, const uint16_t *vwv,
2190 uint16_t num_bytes, const uint8_t *bytes,
2191 void *private_data),
2194 size_t smblen = smb_len(buf);
2195 const char *smb_buf = smb_base(buf);
2196 uint8_t cmd, chain_cmd;
2198 const uint16_t *vwv;
2200 const uint8_t *bytes;
2202 cmd = CVAL(buf, smb_com);
2203 wct = CVAL(buf, smb_wct);
2204 vwv = (const uint16_t *)(buf + smb_vwv);
2205 num_bytes = smb_buflen(buf);
2206 bytes = (const uint8_t *)smb_buf_const(buf);
2208 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2212 if (!is_andx_req(cmd)) {
2219 chain_cmd = CVAL(vwv, 0);
2221 while (chain_cmd != 0xff) {
2222 uint32_t chain_offset; /* uint32_t to avoid overflow */
2223 size_t length_needed;
2224 ptrdiff_t vwv_offset;
2226 chain_offset = SVAL(vwv+1, 0);
2229 * Check if the client tries to fool us. The chain
2230 * offset needs to point beyond the current request in
2231 * the chain, it needs to strictly grow. Otherwise we
2232 * might be tricked into an endless loop always
2233 * processing the same request over and over again. We
2234 * used to assume that vwv and the byte buffer array
2235 * in a chain are always attached, but OS/2 the
2236 * Write&X/Read&X chain puts the Read&X vwv array
2237 * right behind the Write&X vwv chain. The Write&X bcc
2238 * array is put behind the Read&X vwv array. So now we
2239 * check whether the chain offset points strictly
2240 * behind the previous vwv array. req->buf points
2241 * right after the vwv array of the previous
2243 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2247 vwv_offset = ((const char *)vwv - smb_buf);
2248 if (chain_offset <= vwv_offset) {
2253 * Next check: Make sure the chain offset does not
2254 * point beyond the overall smb request length.
2257 length_needed = chain_offset+1; /* wct */
2258 if (length_needed > smblen) {
2263 * Now comes the pointer magic. Goal here is to set up
2264 * vwv and buf correctly again. The chain offset (the
2265 * former vwv[1]) points at the new wct field.
2268 wct = CVAL(smb_buf, chain_offset);
2270 if (is_andx_req(chain_cmd) && (wct < 2)) {
2275 * Next consistency check: Make the new vwv array fits
2276 * in the overall smb request.
2279 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2280 if (length_needed > smblen) {
2283 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2286 * Now grab the new byte buffer....
2289 num_bytes = SVAL(vwv+wct, 0);
2292 * .. and check that it fits.
2295 length_needed += num_bytes;
2296 if (length_needed > smblen) {
2299 bytes = (const uint8_t *)(vwv+wct+1);
2301 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2305 if (!is_andx_req(chain_cmd)) {
2308 chain_cmd = CVAL(vwv, 0);
2313 static bool smb1_chain_length_cb(uint8_t cmd,
2314 uint8_t wct, const uint16_t *vwv,
2315 uint16_t num_bytes, const uint8_t *bytes,
2318 unsigned *count = (unsigned *)private_data;
2323 unsigned smb1_chain_length(const uint8_t *buf)
2327 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2333 struct smb1_parse_chain_state {
2334 TALLOC_CTX *mem_ctx;
2336 struct smbd_server_connection *sconn;
2340 struct smb_request **reqs;
2344 static bool smb1_parse_chain_cb(uint8_t cmd,
2345 uint8_t wct, const uint16_t *vwv,
2346 uint16_t num_bytes, const uint8_t *bytes,
2349 struct smb1_parse_chain_state *state =
2350 (struct smb1_parse_chain_state *)private_data;
2351 struct smb_request **reqs;
2352 struct smb_request *req;
2355 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2356 struct smb_request *, state->num_reqs+1);
2362 req = talloc(reqs, struct smb_request);
2367 ok = init_smb_request(req, state->sconn, state->buf, 0,
2368 state->encrypted, state->seqnum);
2375 req->buflen = num_bytes;
2378 reqs[state->num_reqs] = req;
2379 state->num_reqs += 1;
2383 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2384 struct smbd_server_connection *sconn,
2385 bool encrypted, uint32_t seqnum,
2386 struct smb_request ***reqs, unsigned *num_reqs)
2388 struct smb1_parse_chain_state state;
2391 state.mem_ctx = mem_ctx;
2393 state.sconn = sconn;
2394 state.encrypted = encrypted;
2395 state.seqnum = seqnum;
2399 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2400 TALLOC_FREE(state.reqs);
2403 for (i=0; i<state.num_reqs; i++) {
2404 state.reqs[i]->chain = state.reqs;
2407 *num_reqs = state.num_reqs;
2411 /****************************************************************************
2412 Check if services need reloading.
2413 ****************************************************************************/
2415 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2418 if (last_smb_conf_reload_time == 0) {
2419 last_smb_conf_reload_time = t;
2422 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2423 reload_services(sconn, conn_snum_used, true);
2424 last_smb_conf_reload_time = t;
2428 static bool fd_is_readable(int fd)
2432 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2434 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2438 static void smbd_server_connection_write_handler(
2439 struct smbd_server_connection *sconn)
2441 /* TODO: make write nonblocking */
2444 static void smbd_server_connection_read_handler(
2445 struct smbd_server_connection *sconn, int fd)
2447 struct smbXsrv_connection *xconn = sconn->conn;
2448 uint8_t *inbuf = NULL;
2449 size_t inbuf_len = 0;
2450 size_t unread_bytes = 0;
2451 bool encrypted = false;
2452 TALLOC_CTX *mem_ctx = talloc_tos();
2456 bool async_echo = lp_async_smb_echo_handler();
2457 bool from_client = false;
2460 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2462 * This is the super-ugly hack to prefer the packets
2463 * forwarded by the echo handler over the ones by the
2466 fd = sconn->smb1.echo_handler.trusted_fd;
2470 from_client = (xconn->transport.sock == fd);
2472 if (async_echo && from_client) {
2473 smbd_lock_socket(sconn);
2475 if (!fd_is_readable(fd)) {
2476 DEBUG(10,("the echo listener was faster\n"));
2477 smbd_unlock_socket(sconn);
2482 /* TODO: make this completely nonblocking */
2483 status = receive_smb_talloc(mem_ctx, sconn, fd,
2484 (char **)(void *)&inbuf,
2488 &inbuf_len, &seqnum,
2489 !from_client /* trusted channel */);
2491 if (async_echo && from_client) {
2492 smbd_unlock_socket(sconn);
2495 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2498 if (NT_STATUS_IS_ERR(status)) {
2499 exit_server_cleanly("failed to receive smb request");
2501 if (!NT_STATUS_IS_OK(status)) {
2506 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2507 seqnum, encrypted, NULL);
2510 static void smbd_server_connection_handler(struct tevent_context *ev,
2511 struct tevent_fd *fde,
2515 struct smbd_server_connection *conn = talloc_get_type(private_data,
2516 struct smbd_server_connection);
2517 struct smbXsrv_connection *xconn = conn->conn;
2519 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2521 * we're not supposed to do any io
2523 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2524 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2528 if (flags & TEVENT_FD_WRITE) {
2529 smbd_server_connection_write_handler(conn);
2532 if (flags & TEVENT_FD_READ) {
2533 smbd_server_connection_read_handler(conn, xconn->transport.sock);
2538 static void smbd_server_echo_handler(struct tevent_context *ev,
2539 struct tevent_fd *fde,
2543 struct smbd_server_connection *conn = talloc_get_type(private_data,
2544 struct smbd_server_connection);
2545 struct smbXsrv_connection *xconn = conn->conn;
2547 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2549 * we're not supposed to do any io
2551 TEVENT_FD_NOT_READABLE(conn->smb1.echo_handler.trusted_fde);
2552 TEVENT_FD_NOT_WRITEABLE(conn->smb1.echo_handler.trusted_fde);
2556 if (flags & TEVENT_FD_WRITE) {
2557 smbd_server_connection_write_handler(conn);
2560 if (flags & TEVENT_FD_READ) {
2561 smbd_server_connection_read_handler(
2562 conn, conn->smb1.echo_handler.trusted_fd);
2567 struct smbd_release_ip_state {
2568 struct smbd_server_connection *sconn;
2569 struct tevent_immediate *im;
2570 char addr[INET6_ADDRSTRLEN];
2573 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2574 struct tevent_immediate *im,
2577 struct smbd_release_ip_state *state =
2578 talloc_get_type_abort(private_data,
2579 struct smbd_release_ip_state);
2580 struct smbXsrv_connection *xconn = state->sconn->conn;
2582 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2584 * smbd_server_connection_terminate() already triggered ?
2589 smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
2592 /****************************************************************************
2593 received when we should release a specific IP
2594 ****************************************************************************/
2595 static bool release_ip(const char *ip, void *priv)
2597 struct smbd_release_ip_state *state =
2598 talloc_get_type_abort(priv,
2599 struct smbd_release_ip_state);
2600 struct smbXsrv_connection *xconn = state->sconn->conn;
2601 const char *addr = state->addr;
2602 const char *p = addr;
2604 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2605 /* avoid recursion */
2609 if (strncmp("::ffff:", addr, 7) == 0) {
2613 DEBUG(10, ("Got release IP message for %s, "
2614 "our address is %s\n", ip, p));
2616 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2617 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2620 * With SMB2 we should do a clean disconnect,
2621 * the previous_session_id in the session setup
2622 * will cleanup the old session, tcons and opens.
2624 * A clean disconnect is needed in order to support
2627 * Note: typically this is never triggered
2628 * as we got a TCP RST (triggered by ctdb event scripts)
2629 * before we get CTDB_SRVID_RELEASE_IP.
2631 * We used to call _exit(1) here, but as this was mostly never
2632 * triggered and has implication on our process model,
2633 * we can just use smbd_server_connection_terminate()
2636 * We don't call smbd_server_connection_terminate() directly
2637 * as we might be called from within ctdbd_migrate(),
2638 * we need to defer our action to the next event loop
2640 tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
2641 smbd_release_ip_immediate, state);
2644 * Make sure we don't get any io on the connection.
2646 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2653 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2654 struct sockaddr_storage *srv,
2655 struct sockaddr_storage *clnt)
2657 struct smbd_release_ip_state *state;
2658 struct ctdbd_connection *cconn;
2660 cconn = messaging_ctdbd_connection();
2661 if (cconn == NULL) {
2662 return NT_STATUS_NO_MEMORY;
2665 state = talloc_zero(sconn, struct smbd_release_ip_state);
2666 if (state == NULL) {
2667 return NT_STATUS_NO_MEMORY;
2669 state->sconn = sconn;
2670 state->im = tevent_create_immediate(state);
2671 if (state->im == NULL) {
2672 return NT_STATUS_NO_MEMORY;
2674 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2675 return NT_STATUS_NO_MEMORY;
2678 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2681 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2682 void *private_data, uint32_t msg_type,
2683 struct server_id server_id, DATA_BLOB *data)
2685 struct smbd_server_connection *sconn = talloc_get_type_abort(
2686 private_data, struct smbd_server_connection);
2687 const char *ip = (char *) data->data;
2690 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2692 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2694 if (client_ip == NULL) {
2698 if (strequal(ip, client_ip)) {
2699 DEBUG(1, ("Got kill client message for %s - "
2700 "exiting immediately\n", ip));
2701 exit_server_cleanly("Forced disconnect for client");
2704 TALLOC_FREE(client_ip);
2708 * Send keepalive packets to our client
2710 static bool keepalive_fn(const struct timeval *now, void *private_data)
2712 struct smbd_server_connection *sconn = talloc_get_type_abort(
2713 private_data, struct smbd_server_connection);
2714 struct smbXsrv_connection *xconn = sconn->conn;
2717 if (sconn->using_smb2) {
2718 /* Don't do keepalives on an SMB2 connection. */
2722 smbd_lock_socket(sconn);
2723 ret = send_keepalive(xconn->transport.sock);
2724 smbd_unlock_socket(sconn);
2727 int saved_errno = errno;
2729 * Try and give an error message saying what
2732 DEBUG(0, ("send_keepalive failed for client %s. "
2733 "Error %s - exiting\n",
2734 smbXsrv_connection_dbg(xconn),
2735 strerror(saved_errno)));
2736 errno = saved_errno;
2743 * Do the recurring check if we're idle
2745 static bool deadtime_fn(const struct timeval *now, void *private_data)
2747 struct smbd_server_connection *sconn =
2748 (struct smbd_server_connection *)private_data;
2750 if ((conn_num_open(sconn) == 0)
2751 || (conn_idle_all(sconn, now->tv_sec))) {
2752 DEBUG( 2, ( "Closing idle connection\n" ) );
2753 messaging_send(sconn->msg_ctx,
2754 messaging_server_id(sconn->msg_ctx),
2755 MSG_SHUTDOWN, &data_blob_null);
2763 * Do the recurring log file and smb.conf reload checks.
2766 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2768 struct smbd_server_connection *sconn = talloc_get_type_abort(
2769 private_data, struct smbd_server_connection);
2771 DEBUG(5, ("housekeeping\n"));
2773 change_to_root_user();
2775 /* update printer queue caches if necessary */
2776 update_monitored_printq_cache(sconn->msg_ctx);
2778 /* check if we need to reload services */
2779 check_reload(sconn, time_mono(NULL));
2782 * Force a log file check.
2784 force_check_log_size();
2790 * Read an smb packet in the echo handler child, giving the parent
2791 * smbd one second to react once the socket becomes readable.
2794 struct smbd_echo_read_state {
2795 struct tevent_context *ev;
2796 struct smbd_server_connection *sconn;
2803 static void smbd_echo_read_readable(struct tevent_req *subreq);
2804 static void smbd_echo_read_waited(struct tevent_req *subreq);
2806 static struct tevent_req *smbd_echo_read_send(
2807 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2808 struct smbd_server_connection *sconn)
2810 struct tevent_req *req, *subreq;
2811 struct smbd_echo_read_state *state;
2812 struct smbXsrv_connection *xconn = sconn->conn;
2814 req = tevent_req_create(mem_ctx, &state,
2815 struct smbd_echo_read_state);
2820 state->sconn = sconn;
2822 subreq = wait_for_read_send(state, ev, xconn->transport.sock);
2823 if (tevent_req_nomem(subreq, req)) {
2824 return tevent_req_post(req, ev);
2826 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2830 static void smbd_echo_read_readable(struct tevent_req *subreq)
2832 struct tevent_req *req = tevent_req_callback_data(
2833 subreq, struct tevent_req);
2834 struct smbd_echo_read_state *state = tevent_req_data(
2835 req, struct smbd_echo_read_state);
2839 ok = wait_for_read_recv(subreq, &err);
2840 TALLOC_FREE(subreq);
2842 tevent_req_nterror(req, map_nt_error_from_unix(err));
2847 * Give the parent smbd one second to step in
2850 subreq = tevent_wakeup_send(
2851 state, state->ev, timeval_current_ofs(1, 0));
2852 if (tevent_req_nomem(subreq, req)) {
2855 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2858 static void smbd_echo_read_waited(struct tevent_req *subreq)
2860 struct tevent_req *req = tevent_req_callback_data(
2861 subreq, struct tevent_req);
2862 struct smbd_echo_read_state *state = tevent_req_data(
2863 req, struct smbd_echo_read_state);
2864 struct smbd_server_connection *sconn = state->sconn;
2865 struct smbXsrv_connection *xconn = sconn->conn;
2871 ok = tevent_wakeup_recv(subreq);
2872 TALLOC_FREE(subreq);
2874 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2878 ok = smbd_lock_socket_internal(sconn);
2880 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2881 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2885 if (!fd_is_readable(xconn->transport.sock)) {
2886 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2889 ok = smbd_unlock_socket_internal(sconn);
2891 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2892 DEBUG(1, ("%s: failed to unlock socket\n",
2897 subreq = wait_for_read_send(state, state->ev,
2898 xconn->transport.sock);
2899 if (tevent_req_nomem(subreq, req)) {
2902 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2906 status = receive_smb_talloc(state, sconn,
2907 xconn->transport.sock,
2914 false /* trusted_channel*/);
2916 if (tevent_req_nterror(req, status)) {
2917 tevent_req_nterror(req, status);
2918 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2919 (int)getpid(), nt_errstr(status)));
2923 ok = smbd_unlock_socket_internal(sconn);
2925 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2926 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2929 tevent_req_done(req);
2932 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2933 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2935 struct smbd_echo_read_state *state = tevent_req_data(
2936 req, struct smbd_echo_read_state);
2939 if (tevent_req_is_nterror(req, &status)) {
2942 *pbuf = talloc_move(mem_ctx, &state->buf);
2943 *pbuflen = state->buflen;
2944 *pseqnum = state->seqnum;
2945 return NT_STATUS_OK;
2948 struct smbd_echo_state {
2949 struct tevent_context *ev;
2950 struct iovec *pending;
2951 struct smbd_server_connection *sconn;
2954 struct tevent_fd *parent_fde;
2956 struct tevent_req *write_req;
2959 static void smbd_echo_writer_done(struct tevent_req *req);
2961 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2965 if (state->write_req != NULL) {
2969 num_pending = talloc_array_length(state->pending);
2970 if (num_pending == 0) {
2974 state->write_req = writev_send(state, state->ev, NULL,
2975 state->parent_pipe, false,
2976 state->pending, num_pending);
2977 if (state->write_req == NULL) {
2978 DEBUG(1, ("writev_send failed\n"));
2982 talloc_steal(state->write_req, state->pending);
2983 state->pending = NULL;
2985 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2989 static void smbd_echo_writer_done(struct tevent_req *req)
2991 struct smbd_echo_state *state = tevent_req_callback_data(
2992 req, struct smbd_echo_state);
2996 written = writev_recv(req, &err);
2998 state->write_req = NULL;
2999 if (written == -1) {
3000 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3003 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3004 smbd_echo_activate_writer(state);
3007 static bool smbd_echo_reply(struct smbd_echo_state *state,
3008 uint8_t *inbuf, size_t inbuf_len,
3011 struct smb_request req;
3012 uint16_t num_replies;
3016 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3017 DEBUG(10, ("Got netbios keepalive\n"));
3024 if (inbuf_len < smb_size) {
3025 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3028 if (!valid_smb_header(state->sconn, inbuf)) {
3029 DEBUG(10, ("Got invalid SMB header\n"));
3033 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
3039 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3040 smb_messages[req.cmd].name
3041 ? smb_messages[req.cmd].name : "unknown"));
3043 if (req.cmd != SMBecho) {
3050 num_replies = SVAL(req.vwv+0, 0);
3051 if (num_replies != 1) {
3052 /* Not a Windows "Hey, you're still there?" request */
3056 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3058 DEBUG(10, ("create_outbuf failed\n"));
3061 req.outbuf = (uint8_t *)outbuf;
3063 SSVAL(req.outbuf, smb_vwv0, num_replies);
3065 if (req.buflen > 0) {
3066 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3069 ok = srv_send_smb(req.sconn,
3073 TALLOC_FREE(outbuf);
3081 static void smbd_echo_exit(struct tevent_context *ev,
3082 struct tevent_fd *fde, uint16_t flags,
3085 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3089 static void smbd_echo_got_packet(struct tevent_req *req);
3091 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3094 struct smbd_echo_state *state;
3095 struct tevent_req *read_req;
3097 state = talloc_zero(sconn, struct smbd_echo_state);
3098 if (state == NULL) {
3099 DEBUG(1, ("talloc failed\n"));
3102 state->sconn = sconn;
3103 state->parent_pipe = parent_pipe;
3104 state->ev = s3_tevent_context_init(state);
3105 if (state->ev == NULL) {
3106 DEBUG(1, ("tevent_context_init failed\n"));
3110 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3111 TEVENT_FD_READ, smbd_echo_exit,
3113 if (state->parent_fde == NULL) {
3114 DEBUG(1, ("tevent_add_fd failed\n"));
3119 read_req = smbd_echo_read_send(state, state->ev, sconn);
3120 if (read_req == NULL) {
3121 DEBUG(1, ("smbd_echo_read_send failed\n"));
3125 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3128 if (tevent_loop_once(state->ev) == -1) {
3129 DEBUG(1, ("tevent_loop_once failed: %s\n",
3137 static void smbd_echo_got_packet(struct tevent_req *req)
3139 struct smbd_echo_state *state = tevent_req_callback_data(
3140 req, struct smbd_echo_state);
3144 uint32_t seqnum = 0;
3147 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3149 if (!NT_STATUS_IS_OK(status)) {
3150 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3151 nt_errstr(status)));
3155 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3161 num_pending = talloc_array_length(state->pending);
3162 tmp = talloc_realloc(state, state->pending, struct iovec,
3165 DEBUG(1, ("talloc_realloc failed\n"));
3168 state->pending = tmp;
3170 if (buflen >= smb_size) {
3172 * place the seqnum in the packet so that the main process
3173 * can reply with signing
3175 SIVAL(buf, smb_ss_field, seqnum);
3176 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3179 iov = &state->pending[num_pending];
3180 iov->iov_base = talloc_move(state->pending, &buf);
3181 iov->iov_len = buflen;
3183 DEBUG(10,("echo_handler[%d]: forward to main\n",
3185 smbd_echo_activate_writer(state);
3188 req = smbd_echo_read_send(state, state->ev, state->sconn);
3190 DEBUG(1, ("smbd_echo_read_send failed\n"));
3193 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3198 * Handle SMBecho requests in a forked child process
3200 bool fork_echo_handler(struct smbd_server_connection *sconn)
3202 int listener_pipe[2];
3205 bool use_mutex = false;
3207 res = pipe(listener_pipe);
3209 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3213 #ifdef HAVE_ROBUST_MUTEXES
3214 use_mutex = tdb_runtime_check_for_robust_mutexes();
3217 pthread_mutexattr_t a;
3219 sconn->smb1.echo_handler.socket_mutex =
3220 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3221 if (sconn->smb1.echo_handler.socket_mutex == NULL) {
3222 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3227 res = pthread_mutexattr_init(&a);
3229 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3233 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3235 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3237 pthread_mutexattr_destroy(&a);
3240 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3242 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3244 pthread_mutexattr_destroy(&a);
3247 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3249 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3250 "%s\n", strerror(res)));
3251 pthread_mutexattr_destroy(&a);
3254 res = pthread_mutex_init(sconn->smb1.echo_handler.socket_mutex,
3256 pthread_mutexattr_destroy(&a);
3258 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3266 sconn->smb1.echo_handler.socket_lock_fd =
3267 create_unlink_tmp(lp_lock_directory());
3268 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3269 DEBUG(1, ("Could not create lock fd: %s\n",
3279 close(listener_pipe[0]);
3280 set_blocking(listener_pipe[1], false);
3282 status = reinit_after_fork(sconn->msg_ctx,
3285 if (!NT_STATUS_IS_OK(status)) {
3286 DEBUG(1, ("reinit_after_fork failed: %s\n",
3287 nt_errstr(status)));
3290 smbd_echo_loop(sconn, listener_pipe[1]);
3293 close(listener_pipe[1]);
3294 listener_pipe[1] = -1;
3295 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3297 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3300 * Without smb signing this is the same as the normal smbd
3301 * listener. This needs to change once signing comes in.
3303 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3305 sconn->smb1.echo_handler.trusted_fd,
3307 smbd_server_echo_handler,
3309 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3310 DEBUG(1, ("event_add_fd failed\n"));
3317 if (listener_pipe[0] != -1) {
3318 close(listener_pipe[0]);
3320 if (listener_pipe[1] != -1) {
3321 close(listener_pipe[1]);
3323 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3324 close(sconn->smb1.echo_handler.socket_lock_fd);
3327 #ifdef HAVE_ROBUST_MUTEXES
3328 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
3329 pthread_mutex_destroy(sconn->smb1.echo_handler.socket_mutex);
3330 anonymous_shared_free(sconn->smb1.echo_handler.socket_mutex);
3333 smbd_echo_init(sconn);
3338 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3341 if (user->session_info &&
3342 (user->session_info->unix_token->uid == uid)) {
3350 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3353 if (user->session_info != NULL) {
3355 struct security_unix_token *utok;
3357 utok = user->session_info->unix_token;
3358 if (utok->gid == gid) {
3361 for(i=0; i<utok->ngroups; i++) {
3362 if (utok->groups[i] == gid) {
3372 static bool sid_in_use(const struct user_struct *user,
3373 const struct dom_sid *psid)
3376 struct security_token *tok;
3378 if (user->session_info == NULL) {
3381 tok = user->session_info->security_token;
3384 * Not sure session_info->security_token can
3385 * ever be NULL. This check might be not
3390 if (security_token_has_sid(tok, psid)) {
3398 static bool id_in_use(const struct user_struct *user,
3399 const struct id_cache_ref *id)
3403 return uid_in_use(user, id->id.uid);
3405 return gid_in_use(user, id->id.gid);
3407 return sid_in_use(user, &id->id.sid);
3414 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3417 struct server_id server_id,
3420 const char *msg = (data && data->data)
3421 ? (const char *)data->data : "<NULL>";
3422 struct id_cache_ref id;
3423 struct smbd_server_connection *sconn =
3424 talloc_get_type_abort(private_data,
3425 struct smbd_server_connection);
3427 if (!id_cache_ref_parse(msg, &id)) {
3428 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3432 if (id_in_use(sconn->users, &id)) {
3433 exit_server_cleanly(msg);
3435 id_cache_delete_from_cache(&id);
3438 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3439 enum protocol_types protocol)
3443 set_Protocol(protocol);
3444 conn->protocol = protocol;
3446 if (protocol >= PROTOCOL_SMB2_02) {
3447 status = smb2srv_session_table_init(conn);
3448 if (!NT_STATUS_IS_OK(status)) {
3452 status = smb2srv_open_table_init(conn);
3453 if (!NT_STATUS_IS_OK(status)) {
3457 status = smb1srv_session_table_init(conn);
3458 if (!NT_STATUS_IS_OK(status)) {
3462 status = smb1srv_tcon_table_init(conn);
3463 if (!NT_STATUS_IS_OK(status)) {
3467 status = smb1srv_open_table_init(conn);
3468 if (!NT_STATUS_IS_OK(status)) {
3473 return NT_STATUS_OK;
3476 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3479 struct smbXsrv_connection *conn =
3480 talloc_get_type_abort(private_data,
3481 struct smbXsrv_connection);
3484 case TEVENT_TRACE_BEFORE_WAIT:
3486 * This just removes compiler warning
3487 * without profile support
3489 conn->smbd_idle_profstamp = 0;
3490 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3492 case TEVENT_TRACE_AFTER_WAIT:
3493 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3495 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3496 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3497 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3504 * Create a debug string for the connection
3506 * This is allocated to talloc_tos() or a string constant
3507 * in certain corner cases. The returned string should
3508 * hence not be free'd directly but only via the talloc stack.
3510 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3515 * TODO: this can be improved later
3516 * maybe including the client guid or more
3518 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3520 return "<tsocket_address_string() failed>";
3526 /****************************************************************************
3527 Process commands from the client
3528 ****************************************************************************/
3530 void smbd_process(struct tevent_context *ev_ctx,
3531 struct messaging_context *msg_ctx,
3535 TALLOC_CTX *frame = talloc_stackframe();
3536 struct smbXsrv_connection *conn;
3537 struct smbd_server_connection *sconn;
3538 struct sockaddr_storage ss_srv;
3539 void *sp_srv = (void *)&ss_srv;
3540 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3541 struct sockaddr_storage ss_clnt;
3542 void *sp_clnt = (void *)&ss_clnt;
3543 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3544 socklen_t sa_socklen;
3545 struct tsocket_address *local_address = NULL;
3546 struct tsocket_address *remote_address = NULL;
3547 const char *locaddr = NULL;
3548 const char *remaddr = NULL;
3553 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3555 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3556 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3559 conn->ev_ctx = ev_ctx;
3560 conn->msg_ctx = msg_ctx;
3561 conn->transport.sock = sock_fd;
3563 sconn = talloc_zero(conn, struct smbd_server_connection);
3565 exit_server("failed to create smbd_server_connection");
3568 conn->sconn = sconn;
3572 * TODO: remove this...:-)
3574 global_smbXsrv_connection = conn;
3576 sconn->ev_ctx = ev_ctx;
3577 sconn->msg_ctx = msg_ctx;
3578 smbd_echo_init(sconn);
3581 smbd_setup_sig_term_handler(sconn);
3582 smbd_setup_sig_hup_handler(sconn);
3584 if (!serverid_register(messaging_server_id(msg_ctx),
3585 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3587 |FLAG_MSG_PRINT_GENERAL)) {
3588 exit_server_cleanly("Could not register myself in "
3593 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3595 * We're not making the decision here,
3596 * we're just allowing the client
3597 * to decide between SMB1 and SMB2
3598 * with the first negprot
3601 sconn->using_smb2 = true;
3604 /* Ensure child is set to blocking mode */
3605 set_blocking(sock_fd,True);
3607 set_socket_options(sock_fd, "SO_KEEPALIVE");
3608 set_socket_options(sock_fd, lp_socket_options());
3610 sa_socklen = sizeof(ss_clnt);
3611 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3613 int level = (errno == ENOTCONN)?2:0;
3614 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3615 exit_server_cleanly("getpeername() failed.\n");
3617 ret = tsocket_address_bsd_from_sockaddr(sconn,
3618 sa_clnt, sa_socklen,
3621 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3622 __location__, strerror(errno)));
3623 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3626 sa_socklen = sizeof(ss_srv);
3627 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3629 int level = (errno == ENOTCONN)?2:0;
3630 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3631 exit_server_cleanly("getsockname() failed.\n");
3633 ret = tsocket_address_bsd_from_sockaddr(sconn,
3637 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3638 __location__, strerror(errno)));
3639 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3642 sconn->local_address = local_address;
3643 sconn->remote_address = remote_address;
3645 if (tsocket_address_is_inet(local_address, "ip")) {
3646 locaddr = tsocket_address_inet_addr_string(
3647 sconn->local_address,
3649 if (locaddr == NULL) {
3650 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3651 __location__, strerror(errno)));
3652 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3655 locaddr = "0.0.0.0";
3658 if (tsocket_address_is_inet(remote_address, "ip")) {
3659 remaddr = tsocket_address_inet_addr_string(
3660 sconn->remote_address,
3662 if (remaddr == NULL) {
3663 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3664 __location__, strerror(errno)));
3665 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3668 remaddr = "0.0.0.0";
3671 /* this is needed so that we get decent entries
3672 in smbstatus for port 445 connects */
3673 set_remote_machine_name(remaddr, false);
3674 reload_services(sconn, conn_snum_used, true);
3677 * Before the first packet, check the global hosts allow/ hosts deny
3678 * parameters before doing any parsing of packets passed to us by the
3679 * client. This prevents attacks on our parsing code from hosts not in
3680 * the hosts allow list.
3683 ret = get_remote_hostname(remote_address,
3687 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3688 __location__, strerror(errno)));
3689 exit_server_cleanly("get_remote_hostname failed.\n");
3691 if (strequal(rhost, "UNKNOWN")) {
3692 rhost = talloc_strdup(talloc_tos(), remaddr);
3694 sconn->remote_hostname = talloc_move(sconn, &rhost);
3696 sub_set_socket_ids(remaddr,
3697 sconn->remote_hostname,
3700 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3701 sconn->remote_hostname,
3704 * send a negative session response "not listening on calling
3707 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3708 DEBUG( 1, ("Connection denied from %s to %s\n",
3709 tsocket_address_string(remote_address, talloc_tos()),
3710 tsocket_address_string(local_address, talloc_tos())));
3711 (void)srv_send_smb(sconn,(char *)buf, false,
3713 exit_server_cleanly("connection denied");
3716 DEBUG(10, ("Connection allowed from %s to %s\n",
3717 tsocket_address_string(remote_address, talloc_tos()),
3718 tsocket_address_string(local_address, talloc_tos())));
3720 if (lp_preload_modules()) {
3721 smb_load_modules(lp_preload_modules());
3724 smb_perfcount_init();
3726 if (!init_account_policy()) {
3727 exit_server("Could not open account policy tdb.\n");
3730 if (*lp_root_directory(talloc_tos())) {
3731 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3732 DEBUG(0,("Failed to change root to %s\n",
3733 lp_root_directory(talloc_tos())));
3734 exit_server("Failed to chroot()");
3736 if (chdir("/") == -1) {
3737 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3738 exit_server("Failed to chroot()");
3740 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3743 if (!srv_init_signing(conn)) {
3744 exit_server("Failed to init smb_signing");
3747 if (!file_init(sconn)) {
3748 exit_server("file_init() failed");
3752 if (!init_oplocks(sconn))
3753 exit_server("Failed to init oplocks");
3755 /* register our message handlers */
3756 messaging_register(sconn->msg_ctx, sconn,
3757 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3758 messaging_register(sconn->msg_ctx, sconn,
3759 MSG_SMB_CLOSE_FILE, msg_close_file);
3760 messaging_register(sconn->msg_ctx, sconn,
3761 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3763 id_cache_register_msgs(sconn->msg_ctx);
3764 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3765 messaging_register(sconn->msg_ctx, sconn,
3766 ID_CACHE_KILL, smbd_id_cache_kill);
3768 messaging_deregister(sconn->msg_ctx,
3769 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3770 messaging_register(sconn->msg_ctx, sconn,
3771 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3773 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3775 messaging_register(sconn->msg_ctx, sconn,
3776 MSG_SMB_KILL_CLIENT_IP,
3777 msg_kill_client_ip);
3779 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3782 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3783 * MSGs to all child processes
3785 messaging_deregister(sconn->msg_ctx,
3787 messaging_register(sconn->msg_ctx, NULL,
3788 MSG_DEBUG, debug_message);
3790 if ((lp_keepalive() != 0)
3791 && !(event_add_idle(ev_ctx, NULL,
3792 timeval_set(lp_keepalive(), 0),
3793 "keepalive", keepalive_fn,
3795 DEBUG(0, ("Could not add keepalive event\n"));
3799 if (!(event_add_idle(ev_ctx, NULL,
3800 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3801 "deadtime", deadtime_fn, sconn))) {
3802 DEBUG(0, ("Could not add deadtime event\n"));
3806 if (!(event_add_idle(ev_ctx, NULL,
3807 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3808 "housekeeping", housekeeping_fn, sconn))) {
3809 DEBUG(0, ("Could not add housekeeping event\n"));
3813 if (lp_clustering()) {
3815 * We need to tell ctdb about our client's TCP
3816 * connection, so that for failover ctdbd can send
3817 * tickle acks, triggering a reconnection by the
3822 status = smbd_register_ips(sconn, &ss_srv, &ss_clnt);
3823 if (!NT_STATUS_IS_OK(status)) {
3824 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3825 nt_errstr(status)));
3829 tmp = lp_max_xmit();
3830 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3831 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3833 conn->smb1.negprot.max_recv = tmp;
3835 conn->smb1.sessions.done_sesssetup = false;
3836 conn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3838 if (!init_dptrs(sconn)) {
3839 exit_server("init_dptrs() failed");
3842 conn->transport.fde = tevent_add_fd(ev_ctx,
3846 smbd_server_connection_handler,
3848 if (!conn->transport.fde) {
3849 exit_server("failed to create smbd_server_connection fde");
3852 sconn->conn->local_address = sconn->local_address;
3853 sconn->conn->remote_address = sconn->remote_address;
3854 sconn->conn->remote_hostname = sconn->remote_hostname;
3855 sconn->conn->protocol = PROTOCOL_NONE;
3859 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3862 frame = talloc_stackframe_pool(8192);
3865 if (tevent_loop_once(ev_ctx) == -1) {
3866 if (errno != EINTR) {
3867 DEBUG(3, ("tevent_loop_once failed: %s,"
3868 " exiting\n", strerror(errno) ));
3876 exit_server_cleanly(NULL);
3879 bool req_is_in_chain(const struct smb_request *req)
3881 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3883 * We're right now handling a subsequent request, so we must
3889 if (!is_andx_req(req->cmd)) {
3895 * Okay, an illegal request, but definitely not chained :-)
3900 return (CVAL(req->vwv+0, 0) != 0xFF);