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"
42 #include "lib/util/sys_rw_data.h"
44 #include "system/threads.h"
46 /* Internal message queue for deferred opens. */
47 struct pending_message_list {
48 struct pending_message_list *next, *prev;
49 struct timeval request_time; /* When was this first issued? */
50 struct smbd_server_connection *sconn;
51 struct smbXsrv_connection *xconn;
52 struct tevent_timer *te;
53 struct smb_perfcount_data pcd;
58 struct deferred_open_record *open_rec;
61 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
63 static struct pending_message_list *get_deferred_open_message_smb(
64 struct smbd_server_connection *sconn, uint64_t mid);
65 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
67 static void smbd_echo_init(struct smbXsrv_connection *xconn)
69 xconn->smb1.echo_handler.trusted_fd = -1;
70 xconn->smb1.echo_handler.socket_lock_fd = -1;
71 #ifdef HAVE_ROBUST_MUTEXES
72 xconn->smb1.echo_handler.socket_mutex = NULL;
76 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
78 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
82 #ifdef HAVE_ROBUST_MUTEXES
83 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
91 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
93 if (!smbd_echo_active(xconn)) {
97 xconn->smb1.echo_handler.ref_count++;
99 if (xconn->smb1.echo_handler.ref_count > 1) {
103 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
105 #ifdef HAVE_ROBUST_MUTEXES
106 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
109 while (ret == EINTR) {
110 ret = pthread_mutex_lock(
111 xconn->smb1.echo_handler.socket_mutex);
117 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
124 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
129 xconn->smb1.echo_handler.socket_lock_fd,
130 F_SETLKW, 0, 0, F_WRLCK);
131 } while (!ok && (errno == EINTR));
134 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
139 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
144 void smbd_lock_socket(struct smbXsrv_connection *xconn)
146 if (!smbd_lock_socket_internal(xconn)) {
147 exit_server_cleanly("failed to lock socket");
151 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
153 if (!smbd_echo_active(xconn)) {
157 xconn->smb1.echo_handler.ref_count--;
159 if (xconn->smb1.echo_handler.ref_count > 0) {
163 #ifdef HAVE_ROBUST_MUTEXES
164 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
167 while (ret == EINTR) {
168 ret = pthread_mutex_unlock(
169 xconn->smb1.echo_handler.socket_mutex);
175 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
182 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
187 xconn->smb1.echo_handler.socket_lock_fd,
188 F_SETLKW, 0, 0, F_UNLCK);
189 } while (!ok && (errno == EINTR));
192 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
197 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
202 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
204 if (!smbd_unlock_socket_internal(xconn)) {
205 exit_server_cleanly("failed to unlock socket");
209 /* Accessor function for smb_read_error for smbd functions. */
211 /****************************************************************************
213 ****************************************************************************/
215 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
216 bool do_signing, uint32_t seqnum,
218 struct smb_perfcount_data *pcd)
222 char *buf_out = buffer;
224 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
226 * we're not supposed to do any io
231 smbd_lock_socket(xconn);
234 /* Sign the outgoing packet if required. */
235 srv_calculate_sign_mac(xconn, buf_out, seqnum);
239 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
240 if (!NT_STATUS_IS_OK(status)) {
241 DEBUG(0, ("send_smb: SMB encryption failed "
242 "on outgoing packet! Error %s\n",
243 nt_errstr(status) ));
249 len = smb_len_large(buf_out) + 4;
251 ret = write_data(xconn->transport.sock, buf_out, len);
253 int saved_errno = errno;
255 * Try and give an error message saying what
258 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
259 (int)getpid(), (int)len,
260 smbXsrv_connection_dbg(xconn),
261 (int)ret, strerror(saved_errno)));
264 srv_free_enc_buffer(xconn, buf_out);
268 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
269 srv_free_enc_buffer(xconn, buf_out);
271 SMB_PERFCOUNT_END(pcd);
273 smbd_unlock_socket(xconn);
277 /*******************************************************************
278 Setup the word count and byte count for a smb message.
279 ********************************************************************/
281 int srv_set_message(char *buf,
286 if (zero && (num_words || num_bytes)) {
287 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
289 SCVAL(buf,smb_wct,num_words);
290 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
291 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
292 return (smb_size + num_words*2 + num_bytes);
295 static bool valid_smb_header(const uint8_t *inbuf)
297 if (is_encrypted_packet(inbuf)) {
301 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
302 * but it just looks weird to call strncmp for this one.
304 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
307 /* Socket functions for smbd packet processing. */
309 static bool valid_packet_size(size_t len)
312 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
313 * of header. Don't print the error if this fits.... JRA.
316 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
317 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
318 (unsigned long)len));
324 static NTSTATUS read_packet_remainder(int fd, char *buffer,
325 unsigned int timeout, ssize_t len)
333 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
334 if (!NT_STATUS_IS_OK(status)) {
335 char addr[INET6_ADDRSTRLEN];
336 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
338 get_peer_addr(fd, addr, sizeof(addr)),
344 /****************************************************************************
345 Attempt a zerocopy writeX read. We know here that len > smb_size-4
346 ****************************************************************************/
349 * Unfortunately, earlier versions of smbclient/libsmbclient
350 * don't send this "standard" writeX header. I've fixed this
351 * for 3.2 but we'll use the old method with earlier versions.
352 * Windows and CIFSFS at least use this standard size. Not
356 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
357 (2*14) + /* word count (including bcc) */ \
360 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
361 const char lenbuf[4],
362 struct smbXsrv_connection *xconn,
365 unsigned int timeout,
369 /* Size of a WRITEX call (+4 byte len). */
370 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
371 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
375 memcpy(writeX_header, lenbuf, 4);
377 status = read_fd_with_timeout(
378 sock, writeX_header + 4,
379 STANDARD_WRITE_AND_X_HEADER_SIZE,
380 STANDARD_WRITE_AND_X_HEADER_SIZE,
383 if (!NT_STATUS_IS_OK(status)) {
384 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
386 smbXsrv_connection_dbg(xconn),
392 * Ok - now try and see if this is a possible
396 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
398 * If the data offset is beyond what
399 * we've read, drain the extra bytes.
401 uint16_t doff = SVAL(writeX_header,smb_vwv11);
404 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
405 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
406 if (drain_socket(sock, drain) != drain) {
407 smb_panic("receive_smb_raw_talloc_partial_read:"
408 " failed to drain pending bytes");
411 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
414 /* Spoof down the length and null out the bcc. */
415 set_message_bcc(writeX_header, 0);
416 newlen = smb_len(writeX_header);
418 /* Copy the header we've written. */
420 *buffer = (char *)talloc_memdup(mem_ctx,
422 sizeof(writeX_header));
424 if (*buffer == NULL) {
425 DEBUG(0, ("Could not allocate inbuf of length %d\n",
426 (int)sizeof(writeX_header)));
427 return NT_STATUS_NO_MEMORY;
430 /* Work out the remaining bytes. */
431 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
432 *len_ret = newlen + 4;
436 if (!valid_packet_size(len)) {
437 return NT_STATUS_INVALID_PARAMETER;
441 * Not a valid writeX call. Just do the standard
445 *buffer = talloc_array(mem_ctx, char, len+4);
447 if (*buffer == NULL) {
448 DEBUG(0, ("Could not allocate inbuf of length %d\n",
450 return NT_STATUS_NO_MEMORY;
453 /* Copy in what we already read. */
456 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
457 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
460 status = read_packet_remainder(
462 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
465 if (!NT_STATUS_IS_OK(status)) {
466 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
476 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
477 struct smbXsrv_connection *xconn,
479 char **buffer, unsigned int timeout,
480 size_t *p_unread, size_t *plen)
484 int min_recv_size = lp_min_receive_file_size();
489 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
491 if (!NT_STATUS_IS_OK(status)) {
495 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
496 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
497 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
498 !srv_is_signing_active(xconn) &&
499 xconn->smb1.echo_handler.trusted_fde == NULL) {
501 return receive_smb_raw_talloc_partial_read(
502 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
506 if (!valid_packet_size(len)) {
507 return NT_STATUS_INVALID_PARAMETER;
511 * The +4 here can't wrap, we've checked the length above already.
514 *buffer = talloc_array(mem_ctx, char, len+4);
516 if (*buffer == NULL) {
517 DEBUG(0, ("Could not allocate inbuf of length %d\n",
519 return NT_STATUS_NO_MEMORY;
522 memcpy(*buffer, lenbuf, sizeof(lenbuf));
524 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
525 if (!NT_STATUS_IS_OK(status)) {
533 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
534 struct smbXsrv_connection *xconn,
536 char **buffer, unsigned int timeout,
537 size_t *p_unread, bool *p_encrypted,
540 bool trusted_channel)
545 *p_encrypted = false;
547 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
549 if (!NT_STATUS_IS_OK(status)) {
550 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
551 ("receive_smb_raw_talloc failed for client %s "
552 "read error = %s.\n",
553 smbXsrv_connection_dbg(xconn),
554 nt_errstr(status)) );
558 if (is_encrypted_packet((uint8_t *)*buffer)) {
559 status = srv_decrypt_buffer(xconn, *buffer);
560 if (!NT_STATUS_IS_OK(status)) {
561 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
562 "incoming packet! Error %s\n",
563 nt_errstr(status) ));
569 /* Check the incoming SMB signature. */
570 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
571 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
572 "incoming packet!\n"));
573 return NT_STATUS_INVALID_NETWORK_RESPONSE;
581 * Initialize a struct smb_request from an inbuf
584 static bool init_smb_request(struct smb_request *req,
585 struct smbd_server_connection *sconn,
586 struct smbXsrv_connection *xconn,
587 const uint8_t *inbuf,
588 size_t unread_bytes, bool encrypted,
591 struct smbXsrv_tcon *tcon;
594 size_t req_size = smb_len(inbuf) + 4;
596 /* Ensure we have at least smb_size bytes. */
597 if (req_size < smb_size) {
598 DEBUG(0,("init_smb_request: invalid request size %u\n",
599 (unsigned int)req_size ));
603 req->request_time = timeval_current();
604 now = timeval_to_nttime(&req->request_time);
606 req->cmd = CVAL(inbuf, smb_com);
607 req->flags2 = SVAL(inbuf, smb_flg2);
608 req->smbpid = SVAL(inbuf, smb_pid);
609 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
610 req->seqnum = seqnum;
611 req->vuid = SVAL(inbuf, smb_uid);
612 req->tid = SVAL(inbuf, smb_tid);
613 req->wct = CVAL(inbuf, smb_wct);
614 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
615 req->buflen = smb_buflen(inbuf);
616 req->buf = (const uint8_t *)smb_buf_const(inbuf);
617 req->unread_bytes = unread_bytes;
618 req->encrypted = encrypted;
623 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
624 if (NT_STATUS_IS_OK(status)) {
625 req->conn = tcon->compat;
628 req->chain_fsp = NULL;
630 req->priv_paths = NULL;
632 req->posix_pathnames = lp_posix_pathnames();
633 smb_init_perfcount_data(&req->pcd);
635 /* Ensure we have at least wct words and 2 bytes of bcc. */
636 if (smb_size + req->wct*2 > req_size) {
637 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
638 (unsigned int)req->wct,
639 (unsigned int)req_size));
642 /* Ensure bcc is correct. */
643 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
644 DEBUG(0,("init_smb_request: invalid bcc number %u "
645 "(wct = %u, size %u)\n",
646 (unsigned int)req->buflen,
647 (unsigned int)req->wct,
648 (unsigned int)req_size));
656 static void process_smb(struct smbXsrv_connection *xconn,
657 uint8_t *inbuf, size_t nread, size_t unread_bytes,
658 uint32_t seqnum, bool encrypted,
659 struct smb_perfcount_data *deferred_pcd);
661 static void smbd_deferred_open_timer(struct tevent_context *ev,
662 struct tevent_timer *te,
663 struct timeval _tval,
666 struct pending_message_list *msg = talloc_get_type(private_data,
667 struct pending_message_list);
668 struct smbd_server_connection *sconn = msg->sconn;
669 struct smbXsrv_connection *xconn = msg->xconn;
670 TALLOC_CTX *mem_ctx = talloc_tos();
671 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
674 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
677 exit_server("smbd_deferred_open_timer: talloc failed\n");
681 /* We leave this message on the queue so the open code can
682 know this is a retry. */
683 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
684 (unsigned long long)mid ));
686 /* Mark the message as processed so this is not
687 * re-processed in error. */
688 msg->processed = true;
690 process_smb(xconn, inbuf,
692 msg->seqnum, msg->encrypted, &msg->pcd);
694 /* If it's still there and was processed, remove it. */
695 msg = get_deferred_open_message_smb(sconn, mid);
696 if (msg && msg->processed) {
697 remove_deferred_open_message_smb(xconn, mid);
701 /****************************************************************************
702 Function to push a message onto the tail of a linked list of smb messages ready
704 ****************************************************************************/
706 static bool push_queued_message(struct smb_request *req,
707 struct timeval request_time,
708 struct timeval end_time,
709 struct deferred_open_record *open_rec)
711 int msg_len = smb_len(req->inbuf) + 4;
712 struct pending_message_list *msg;
714 msg = talloc_zero(NULL, struct pending_message_list);
717 DEBUG(0,("push_message: malloc fail (1)\n"));
720 msg->sconn = req->sconn;
721 msg->xconn = req->xconn;
723 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
724 if(msg->buf.data == NULL) {
725 DEBUG(0,("push_message: malloc fail (2)\n"));
730 msg->request_time = request_time;
731 msg->seqnum = req->seqnum;
732 msg->encrypted = req->encrypted;
733 msg->processed = false;
734 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
737 msg->open_rec = talloc_move(msg, &open_rec);
741 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
744 smbd_deferred_open_timer,
747 DEBUG(0,("push_message: event_add_timed failed\n"));
753 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
754 struct pending_message_list *);
756 DEBUG(10,("push_message: pushed message length %u on "
757 "deferred_open_queue\n", (unsigned int)msg_len));
762 /****************************************************************************
763 Function to delete a sharing violation open message by mid.
764 ****************************************************************************/
766 void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
769 struct smbd_server_connection *sconn = xconn->client->sconn;
770 struct pending_message_list *pml;
772 if (sconn->using_smb2) {
773 remove_deferred_open_message_smb2(xconn, mid);
777 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
778 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
779 DEBUG(10,("remove_deferred_open_message_smb: "
780 "deleting mid %llu len %u\n",
781 (unsigned long long)mid,
782 (unsigned int)pml->buf.length ));
783 DLIST_REMOVE(sconn->deferred_open_queue, pml);
790 /****************************************************************************
791 Move a sharing violation open retry message to the front of the list and
792 schedule it for immediate processing.
793 ****************************************************************************/
795 bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
798 struct smbd_server_connection *sconn = xconn->client->sconn;
799 struct pending_message_list *pml;
802 if (sconn->using_smb2) {
803 return schedule_deferred_open_message_smb2(xconn, mid);
806 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
807 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
809 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
812 (unsigned long long)msg_mid ));
814 if (mid == msg_mid) {
815 struct tevent_timer *te;
817 if (pml->processed) {
818 /* A processed message should not be
820 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
821 "message mid %llu was already processed\n",
822 (unsigned long long)msg_mid ));
826 DEBUG(10,("schedule_deferred_open_message_smb: "
827 "scheduling mid %llu\n",
828 (unsigned long long)mid ));
830 te = tevent_add_timer(pml->sconn->ev_ctx,
833 smbd_deferred_open_timer,
836 DEBUG(10,("schedule_deferred_open_message_smb: "
837 "event_add_timed() failed, "
838 "skipping mid %llu\n",
839 (unsigned long long)msg_mid ));
842 TALLOC_FREE(pml->te);
844 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
849 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
850 "find message mid %llu\n",
851 (unsigned long long)mid ));
856 /****************************************************************************
857 Return true if this mid is on the deferred queue and was not yet processed.
858 ****************************************************************************/
860 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
862 struct smbd_server_connection *sconn = xconn->client->sconn;
863 struct pending_message_list *pml;
865 if (sconn->using_smb2) {
866 return open_was_deferred_smb2(xconn, mid);
869 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
870 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
877 /****************************************************************************
878 Return the message queued by this mid.
879 ****************************************************************************/
881 static struct pending_message_list *get_deferred_open_message_smb(
882 struct smbd_server_connection *sconn, uint64_t mid)
884 struct pending_message_list *pml;
886 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
887 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
894 /****************************************************************************
895 Get the state data queued by this mid.
896 ****************************************************************************/
898 bool get_deferred_open_message_state(struct smb_request *smbreq,
899 struct timeval *p_request_time,
900 struct deferred_open_record **open_rec)
902 struct pending_message_list *pml;
904 if (smbreq->sconn->using_smb2) {
905 return get_deferred_open_message_state_smb2(smbreq->smb2req,
910 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
914 if (p_request_time) {
915 *p_request_time = pml->request_time;
917 if (open_rec != NULL) {
918 *open_rec = pml->open_rec;
923 /****************************************************************************
924 Function to push a deferred open smb message onto a linked list of local smb
925 messages ready for processing.
926 ****************************************************************************/
928 bool push_deferred_open_message_smb(struct smb_request *req,
929 struct timeval request_time,
930 struct timeval timeout,
932 struct deferred_open_record *open_rec)
934 struct timeval end_time;
937 return push_deferred_open_message_smb2(req->smb2req,
944 if (req->unread_bytes) {
945 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
946 "unread_bytes = %u\n",
947 (unsigned int)req->unread_bytes ));
948 smb_panic("push_deferred_open_message_smb: "
949 "logic error unread_bytes != 0" );
952 end_time = timeval_sum(&request_time, &timeout);
954 DEBUG(10,("push_deferred_open_message_smb: pushing message "
955 "len %u mid %llu timeout time [%u.%06u]\n",
956 (unsigned int) smb_len(req->inbuf)+4,
957 (unsigned long long)req->mid,
958 (unsigned int)end_time.tv_sec,
959 (unsigned int)end_time.tv_usec));
961 return push_queued_message(req, request_time, end_time, open_rec);
964 static void smbd_sig_term_handler(struct tevent_context *ev,
965 struct tevent_signal *se,
971 exit_server_cleanly("termination signal");
974 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
976 struct tevent_signal *se;
978 se = tevent_add_signal(sconn->ev_ctx,
981 smbd_sig_term_handler,
984 exit_server("failed to setup SIGTERM handler");
988 static void smbd_sig_hup_handler(struct tevent_context *ev,
989 struct tevent_signal *se,
995 struct smbd_server_connection *sconn =
996 talloc_get_type_abort(private_data,
997 struct smbd_server_connection);
999 change_to_root_user();
1000 DEBUG(1,("Reloading services after SIGHUP\n"));
1001 reload_services(sconn, conn_snum_used, false);
1004 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1006 struct tevent_signal *se;
1008 se = tevent_add_signal(sconn->ev_ctx,
1011 smbd_sig_hup_handler,
1014 exit_server("failed to setup SIGHUP handler");
1018 static void smbd_conf_updated(struct messaging_context *msg,
1021 struct server_id server_id,
1024 struct smbd_server_connection *sconn =
1025 talloc_get_type_abort(private_data,
1026 struct smbd_server_connection);
1028 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1029 "updated. Reloading.\n"));
1030 change_to_root_user();
1031 reload_services(sconn, conn_snum_used, false);
1035 * Only allow 5 outstanding trans requests. We're allocating memory, so
1039 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1042 for (; list != NULL; list = list->next) {
1044 if (list->mid == mid) {
1045 return NT_STATUS_INVALID_PARAMETER;
1051 return NT_STATUS_INSUFFICIENT_RESOURCES;
1054 return NT_STATUS_OK;
1058 These flags determine some of the permissions required to do an operation
1060 Note that I don't set NEED_WRITE on some write operations because they
1061 are used by some brain-dead clients when printing, and I don't want to
1062 force write permissions on print services.
1064 #define AS_USER (1<<0)
1065 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1066 #define TIME_INIT (1<<2)
1067 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1068 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1069 #define DO_CHDIR (1<<6)
1072 define a list of possible SMB messages and their corresponding
1073 functions. Any message that has a NULL function is unimplemented -
1074 please feel free to contribute implementations!
1076 static const struct smb_message_struct {
1078 void (*fn)(struct smb_request *req);
1080 } smb_messages[256] = {
1082 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1083 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1084 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1085 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1086 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1087 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1088 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1089 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1090 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1091 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1092 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1093 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1094 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1095 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1096 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1097 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1098 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1099 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1100 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1101 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1102 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1103 /* 0x15 */ { NULL, NULL, 0 },
1104 /* 0x16 */ { NULL, NULL, 0 },
1105 /* 0x17 */ { NULL, NULL, 0 },
1106 /* 0x18 */ { NULL, NULL, 0 },
1107 /* 0x19 */ { NULL, NULL, 0 },
1108 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1109 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1110 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1111 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1112 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1113 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1114 /* 0x20 */ { "SMBwritec", NULL,0},
1115 /* 0x21 */ { NULL, NULL, 0 },
1116 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1117 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1118 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1119 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1120 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1121 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1122 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1123 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1124 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1125 /* 0x2b */ { "SMBecho",reply_echo,0},
1126 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1127 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1128 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1129 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1130 /* 0x30 */ { NULL, NULL, 0 },
1131 /* 0x31 */ { NULL, NULL, 0 },
1132 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1133 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1134 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1135 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1136 /* 0x36 */ { NULL, NULL, 0 },
1137 /* 0x37 */ { NULL, NULL, 0 },
1138 /* 0x38 */ { NULL, NULL, 0 },
1139 /* 0x39 */ { NULL, NULL, 0 },
1140 /* 0x3a */ { NULL, NULL, 0 },
1141 /* 0x3b */ { NULL, NULL, 0 },
1142 /* 0x3c */ { NULL, NULL, 0 },
1143 /* 0x3d */ { NULL, NULL, 0 },
1144 /* 0x3e */ { NULL, NULL, 0 },
1145 /* 0x3f */ { NULL, NULL, 0 },
1146 /* 0x40 */ { NULL, NULL, 0 },
1147 /* 0x41 */ { NULL, NULL, 0 },
1148 /* 0x42 */ { NULL, NULL, 0 },
1149 /* 0x43 */ { NULL, NULL, 0 },
1150 /* 0x44 */ { NULL, NULL, 0 },
1151 /* 0x45 */ { NULL, NULL, 0 },
1152 /* 0x46 */ { NULL, NULL, 0 },
1153 /* 0x47 */ { NULL, NULL, 0 },
1154 /* 0x48 */ { NULL, NULL, 0 },
1155 /* 0x49 */ { NULL, NULL, 0 },
1156 /* 0x4a */ { NULL, NULL, 0 },
1157 /* 0x4b */ { NULL, NULL, 0 },
1158 /* 0x4c */ { NULL, NULL, 0 },
1159 /* 0x4d */ { NULL, NULL, 0 },
1160 /* 0x4e */ { NULL, NULL, 0 },
1161 /* 0x4f */ { NULL, NULL, 0 },
1162 /* 0x50 */ { NULL, NULL, 0 },
1163 /* 0x51 */ { NULL, NULL, 0 },
1164 /* 0x52 */ { NULL, NULL, 0 },
1165 /* 0x53 */ { NULL, NULL, 0 },
1166 /* 0x54 */ { NULL, NULL, 0 },
1167 /* 0x55 */ { NULL, NULL, 0 },
1168 /* 0x56 */ { NULL, NULL, 0 },
1169 /* 0x57 */ { NULL, NULL, 0 },
1170 /* 0x58 */ { NULL, NULL, 0 },
1171 /* 0x59 */ { NULL, NULL, 0 },
1172 /* 0x5a */ { NULL, NULL, 0 },
1173 /* 0x5b */ { NULL, NULL, 0 },
1174 /* 0x5c */ { NULL, NULL, 0 },
1175 /* 0x5d */ { NULL, NULL, 0 },
1176 /* 0x5e */ { NULL, NULL, 0 },
1177 /* 0x5f */ { NULL, NULL, 0 },
1178 /* 0x60 */ { NULL, NULL, 0 },
1179 /* 0x61 */ { NULL, NULL, 0 },
1180 /* 0x62 */ { NULL, NULL, 0 },
1181 /* 0x63 */ { NULL, NULL, 0 },
1182 /* 0x64 */ { NULL, NULL, 0 },
1183 /* 0x65 */ { NULL, NULL, 0 },
1184 /* 0x66 */ { NULL, NULL, 0 },
1185 /* 0x67 */ { NULL, NULL, 0 },
1186 /* 0x68 */ { NULL, NULL, 0 },
1187 /* 0x69 */ { NULL, NULL, 0 },
1188 /* 0x6a */ { NULL, NULL, 0 },
1189 /* 0x6b */ { NULL, NULL, 0 },
1190 /* 0x6c */ { NULL, NULL, 0 },
1191 /* 0x6d */ { NULL, NULL, 0 },
1192 /* 0x6e */ { NULL, NULL, 0 },
1193 /* 0x6f */ { NULL, NULL, 0 },
1194 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1195 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1196 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1197 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1198 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1199 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1200 /* 0x76 */ { NULL, NULL, 0 },
1201 /* 0x77 */ { NULL, NULL, 0 },
1202 /* 0x78 */ { NULL, NULL, 0 },
1203 /* 0x79 */ { NULL, NULL, 0 },
1204 /* 0x7a */ { NULL, NULL, 0 },
1205 /* 0x7b */ { NULL, NULL, 0 },
1206 /* 0x7c */ { NULL, NULL, 0 },
1207 /* 0x7d */ { NULL, NULL, 0 },
1208 /* 0x7e */ { NULL, NULL, 0 },
1209 /* 0x7f */ { NULL, NULL, 0 },
1210 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1211 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1212 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1213 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1214 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1215 /* 0x85 */ { NULL, NULL, 0 },
1216 /* 0x86 */ { NULL, NULL, 0 },
1217 /* 0x87 */ { NULL, NULL, 0 },
1218 /* 0x88 */ { NULL, NULL, 0 },
1219 /* 0x89 */ { NULL, NULL, 0 },
1220 /* 0x8a */ { NULL, NULL, 0 },
1221 /* 0x8b */ { NULL, NULL, 0 },
1222 /* 0x8c */ { NULL, NULL, 0 },
1223 /* 0x8d */ { NULL, NULL, 0 },
1224 /* 0x8e */ { NULL, NULL, 0 },
1225 /* 0x8f */ { NULL, NULL, 0 },
1226 /* 0x90 */ { NULL, NULL, 0 },
1227 /* 0x91 */ { NULL, NULL, 0 },
1228 /* 0x92 */ { NULL, NULL, 0 },
1229 /* 0x93 */ { NULL, NULL, 0 },
1230 /* 0x94 */ { NULL, NULL, 0 },
1231 /* 0x95 */ { NULL, NULL, 0 },
1232 /* 0x96 */ { NULL, NULL, 0 },
1233 /* 0x97 */ { NULL, NULL, 0 },
1234 /* 0x98 */ { NULL, NULL, 0 },
1235 /* 0x99 */ { NULL, NULL, 0 },
1236 /* 0x9a */ { NULL, NULL, 0 },
1237 /* 0x9b */ { NULL, NULL, 0 },
1238 /* 0x9c */ { NULL, NULL, 0 },
1239 /* 0x9d */ { NULL, NULL, 0 },
1240 /* 0x9e */ { NULL, NULL, 0 },
1241 /* 0x9f */ { NULL, NULL, 0 },
1242 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1243 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1244 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1245 /* 0xa3 */ { NULL, NULL, 0 },
1246 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1247 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1248 /* 0xa6 */ { NULL, NULL, 0 },
1249 /* 0xa7 */ { NULL, NULL, 0 },
1250 /* 0xa8 */ { NULL, NULL, 0 },
1251 /* 0xa9 */ { NULL, NULL, 0 },
1252 /* 0xaa */ { NULL, NULL, 0 },
1253 /* 0xab */ { NULL, NULL, 0 },
1254 /* 0xac */ { NULL, NULL, 0 },
1255 /* 0xad */ { NULL, NULL, 0 },
1256 /* 0xae */ { NULL, NULL, 0 },
1257 /* 0xaf */ { NULL, NULL, 0 },
1258 /* 0xb0 */ { NULL, NULL, 0 },
1259 /* 0xb1 */ { NULL, NULL, 0 },
1260 /* 0xb2 */ { NULL, NULL, 0 },
1261 /* 0xb3 */ { NULL, NULL, 0 },
1262 /* 0xb4 */ { NULL, NULL, 0 },
1263 /* 0xb5 */ { NULL, NULL, 0 },
1264 /* 0xb6 */ { NULL, NULL, 0 },
1265 /* 0xb7 */ { NULL, NULL, 0 },
1266 /* 0xb8 */ { NULL, NULL, 0 },
1267 /* 0xb9 */ { NULL, NULL, 0 },
1268 /* 0xba */ { NULL, NULL, 0 },
1269 /* 0xbb */ { NULL, NULL, 0 },
1270 /* 0xbc */ { NULL, NULL, 0 },
1271 /* 0xbd */ { NULL, NULL, 0 },
1272 /* 0xbe */ { NULL, NULL, 0 },
1273 /* 0xbf */ { NULL, NULL, 0 },
1274 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1275 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1276 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1277 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1278 /* 0xc4 */ { NULL, NULL, 0 },
1279 /* 0xc5 */ { NULL, NULL, 0 },
1280 /* 0xc6 */ { NULL, NULL, 0 },
1281 /* 0xc7 */ { NULL, NULL, 0 },
1282 /* 0xc8 */ { NULL, NULL, 0 },
1283 /* 0xc9 */ { NULL, NULL, 0 },
1284 /* 0xca */ { NULL, NULL, 0 },
1285 /* 0xcb */ { NULL, NULL, 0 },
1286 /* 0xcc */ { NULL, NULL, 0 },
1287 /* 0xcd */ { NULL, NULL, 0 },
1288 /* 0xce */ { NULL, NULL, 0 },
1289 /* 0xcf */ { NULL, NULL, 0 },
1290 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1291 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1292 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1293 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1294 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1295 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1296 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1297 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1298 /* 0xd8 */ { NULL, NULL, 0 },
1299 /* 0xd9 */ { NULL, NULL, 0 },
1300 /* 0xda */ { NULL, NULL, 0 },
1301 /* 0xdb */ { NULL, NULL, 0 },
1302 /* 0xdc */ { NULL, NULL, 0 },
1303 /* 0xdd */ { NULL, NULL, 0 },
1304 /* 0xde */ { NULL, NULL, 0 },
1305 /* 0xdf */ { NULL, NULL, 0 },
1306 /* 0xe0 */ { NULL, NULL, 0 },
1307 /* 0xe1 */ { NULL, NULL, 0 },
1308 /* 0xe2 */ { NULL, NULL, 0 },
1309 /* 0xe3 */ { NULL, NULL, 0 },
1310 /* 0xe4 */ { NULL, NULL, 0 },
1311 /* 0xe5 */ { NULL, NULL, 0 },
1312 /* 0xe6 */ { NULL, NULL, 0 },
1313 /* 0xe7 */ { NULL, NULL, 0 },
1314 /* 0xe8 */ { NULL, NULL, 0 },
1315 /* 0xe9 */ { NULL, NULL, 0 },
1316 /* 0xea */ { NULL, NULL, 0 },
1317 /* 0xeb */ { NULL, NULL, 0 },
1318 /* 0xec */ { NULL, NULL, 0 },
1319 /* 0xed */ { NULL, NULL, 0 },
1320 /* 0xee */ { NULL, NULL, 0 },
1321 /* 0xef */ { NULL, NULL, 0 },
1322 /* 0xf0 */ { NULL, NULL, 0 },
1323 /* 0xf1 */ { NULL, NULL, 0 },
1324 /* 0xf2 */ { NULL, NULL, 0 },
1325 /* 0xf3 */ { NULL, NULL, 0 },
1326 /* 0xf4 */ { NULL, NULL, 0 },
1327 /* 0xf5 */ { NULL, NULL, 0 },
1328 /* 0xf6 */ { NULL, NULL, 0 },
1329 /* 0xf7 */ { NULL, NULL, 0 },
1330 /* 0xf8 */ { NULL, NULL, 0 },
1331 /* 0xf9 */ { NULL, NULL, 0 },
1332 /* 0xfa */ { NULL, NULL, 0 },
1333 /* 0xfb */ { NULL, NULL, 0 },
1334 /* 0xfc */ { NULL, NULL, 0 },
1335 /* 0xfd */ { NULL, NULL, 0 },
1336 /* 0xfe */ { NULL, NULL, 0 },
1337 /* 0xff */ { NULL, NULL, 0 }
1341 /*******************************************************************
1342 allocate and initialize a reply packet
1343 ********************************************************************/
1345 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1346 const uint8_t *inbuf, char **outbuf,
1347 uint8_t num_words, uint32_t num_bytes)
1349 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1352 * Protect against integer wrap.
1353 * The SMB layer reply can be up to 0xFFFFFF bytes.
1355 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1357 if (asprintf(&msg, "num_bytes too large: %u",
1358 (unsigned)num_bytes) == -1) {
1359 msg = discard_const_p(char, "num_bytes too large");
1365 * Here we include the NBT header for now.
1367 *outbuf = talloc_array(mem_ctx, char,
1368 NBT_HDR_SIZE + smb_len);
1369 if (*outbuf == NULL) {
1373 construct_reply_common(req->cmd, inbuf, *outbuf);
1374 srv_set_message(*outbuf, num_words, num_bytes, false);
1376 * Zero out the word area, the caller has to take care of the bcc area
1379 if (num_words != 0) {
1380 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1386 void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1389 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1391 smb_panic("could not allocate output buffer\n");
1393 req->outbuf = (uint8_t *)outbuf;
1397 /*******************************************************************
1398 Dump a packet to a file.
1399 ********************************************************************/
1401 static void smb_dump(const char *name, int type, const char *data)
1406 if (DEBUGLEVEL < 50) {
1410 len = smb_len_tcp(data)+4;
1411 for (i=1;i<100;i++) {
1412 fname = talloc_asprintf(talloc_tos(),
1416 type ? "req" : "resp");
1417 if (fname == NULL) {
1420 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1421 if (fd != -1 || errno != EEXIST) break;
1425 ssize_t ret = write(fd, data, len);
1427 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1429 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1434 /****************************************************************************
1435 Prepare everything for calling the actual request function, and potentially
1436 call the request function via the "new" interface.
1438 Return False if the "legacy" function needs to be called, everything is
1441 Return True if we're done.
1443 I know this API sucks, but it is the one with the least code change I could
1445 ****************************************************************************/
1447 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1450 uint64_t session_tag;
1451 connection_struct *conn = NULL;
1452 struct smbXsrv_connection *xconn = req->xconn;
1453 NTTIME now = timeval_to_nttime(&req->request_time);
1454 struct smbXsrv_session *session = NULL;
1459 if (!xconn->smb1.negprot.done) {
1462 * Without a negprot the request must
1463 * either be a negprot, or one of the
1464 * evil old SMB mailslot messaging types.
1472 exit_server_cleanly("The first request "
1473 "should be a negprot");
1477 if (smb_messages[type].fn == NULL) {
1478 DEBUG(0,("Unknown message type %d!\n",type));
1479 smb_dump("Unknown", 1, (const char *)req->inbuf);
1480 reply_unknown_new(req, type);
1484 flags = smb_messages[type].flags;
1486 /* In share mode security we must ignore the vuid. */
1487 session_tag = req->vuid;
1490 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1491 (int)getpid(), (unsigned long)conn));
1493 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1495 /* Ensure this value is replaced in the incoming packet. */
1496 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1499 * Ensure the correct username is in current_user_info. This is a
1500 * really ugly bugfix for problems with multiple session_setup_and_X's
1501 * being done and allowing %U and %G substitutions to work correctly.
1502 * There is a reason this code is done here, don't move it unless you
1503 * know what you're doing... :-).
1508 * lookup an existing session
1510 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1511 * here, the main check is still in change_to_user()
1513 status = smb1srv_session_lookup(xconn,
1517 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1520 status = NT_STATUS_OK;
1523 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1524 (unsigned long long)session_tag,
1525 (unsigned long long)req->mid));
1526 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1531 if (session_tag != xconn->client->last_session_id) {
1532 struct user_struct *vuser = NULL;
1534 xconn->client->last_session_id = session_tag;
1536 vuser = session->compat;
1539 set_current_user_info(
1540 vuser->session_info->unix_info->sanitized_username,
1541 vuser->session_info->unix_info->unix_name,
1542 vuser->session_info->info->domain_name);
1546 /* Does this call need to be run as the connected user? */
1547 if (flags & AS_USER) {
1549 /* Does this call need a valid tree connection? */
1552 * Amazingly, the error code depends on the command
1555 if (type == SMBntcreateX) {
1556 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1558 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1563 if (!change_to_user(conn,session_tag)) {
1564 DEBUG(0, ("Error: Could not change to user. Removing "
1565 "deferred open, mid=%llu.\n",
1566 (unsigned long long)req->mid));
1567 reply_force_doserror(req, ERRSRV, ERRbaduid);
1571 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1573 /* Does it need write permission? */
1574 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1575 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1579 /* IPC services are limited */
1580 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1581 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1585 /* This call needs to be run as root */
1586 change_to_root_user();
1589 /* load service specific parameters */
1591 if (req->encrypted) {
1592 conn->encrypted_tid = true;
1593 /* encrypted required from now on. */
1594 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1595 } else if (ENCRYPTION_REQUIRED(conn)) {
1596 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1597 DEBUG(1,("service[%s] requires encryption"
1598 "%s ACCESS_DENIED. mid=%llu\n",
1599 lp_servicename(talloc_tos(), SNUM(conn)),
1601 (unsigned long long)req->mid));
1602 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1607 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1608 (flags & (AS_USER|DO_CHDIR)
1610 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1613 conn->num_smb_operations++;
1617 * Does this protocol need to be run as guest? (Only archane
1618 * messenger service requests have this...)
1620 if (flags & AS_GUEST) {
1624 if (!change_to_guest()) {
1625 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1629 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1631 if (raddr == NULL) {
1632 reply_nterror(req, NT_STATUS_NO_MEMORY);
1637 * Haven't we checked this in smbd_process already???
1640 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1641 xconn->remote_hostname, raddr);
1645 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1650 smb_messages[type].fn(req);
1654 /****************************************************************************
1655 Construct a reply to the incoming packet.
1656 ****************************************************************************/
1658 static void construct_reply(struct smbXsrv_connection *xconn,
1659 char *inbuf, int size, size_t unread_bytes,
1660 uint32_t seqnum, bool encrypted,
1661 struct smb_perfcount_data *deferred_pcd)
1663 struct smbd_server_connection *sconn = xconn->client->sconn;
1664 struct smb_request *req;
1666 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1667 smb_panic("could not allocate smb_request");
1670 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1671 encrypted, seqnum)) {
1672 exit_server_cleanly("Invalid SMB request");
1675 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1677 /* we popped this message off the queue - keep original perf data */
1679 req->pcd = *deferred_pcd;
1681 SMB_PERFCOUNT_START(&req->pcd);
1682 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1683 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1686 req->conn = switch_message(req->cmd, req);
1688 if (req->outbuf == NULL) {
1690 * Request has suspended itself, will come
1695 if (CVAL(req->outbuf,0) == 0) {
1696 show_msg((char *)req->outbuf);
1698 smb_request_done(req);
1701 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1702 char *inbuf, int size, uint32_t seqnum,
1704 struct smb_perfcount_data *deferred_pcd)
1706 struct smb_request **reqs = NULL;
1707 struct smb_request *req;
1711 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, xconn, encrypted,
1712 seqnum, &reqs, &num_reqs);
1714 char errbuf[smb_size];
1715 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1716 __LINE__, __FILE__);
1717 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1719 exit_server_cleanly("construct_reply_chain: "
1720 "srv_send_smb failed.");
1726 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1728 req->conn = switch_message(req->cmd, req);
1730 if (req->outbuf == NULL) {
1732 * Request has suspended itself, will come
1737 smb_request_done(req);
1741 * To be called from an async SMB handler that is potentially chained
1742 * when it is finished for shipping.
1745 void smb_request_done(struct smb_request *req)
1747 struct smb_request **reqs = NULL;
1748 struct smb_request *first_req;
1749 size_t i, num_reqs, next_index;
1752 if (req->chain == NULL) {
1758 num_reqs = talloc_array_length(reqs);
1760 for (i=0; i<num_reqs; i++) {
1761 if (reqs[i] == req) {
1765 if (i == num_reqs) {
1767 * Invalid chain, should not happen
1769 status = NT_STATUS_INTERNAL_ERROR;
1774 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1775 struct smb_request *next = reqs[next_index];
1776 struct smbXsrv_tcon *tcon;
1777 NTTIME now = timeval_to_nttime(&req->request_time);
1779 next->vuid = SVAL(req->outbuf, smb_uid);
1780 next->tid = SVAL(req->outbuf, smb_tid);
1781 status = smb1srv_tcon_lookup(req->xconn, req->tid,
1783 if (NT_STATUS_IS_OK(status)) {
1784 req->conn = tcon->compat;
1788 next->chain_fsp = req->chain_fsp;
1789 next->inbuf = req->inbuf;
1792 req->conn = switch_message(req->cmd, req);
1794 if (req->outbuf == NULL) {
1796 * Request has suspended itself, will come
1804 first_req = reqs[0];
1806 for (i=1; i<next_index; i++) {
1809 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1811 status = NT_STATUS_INTERNAL_ERROR;
1816 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1817 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1820 * This scary statement intends to set the
1821 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1822 * to the value last_req->outbuf carries
1824 SSVAL(first_req->outbuf, smb_flg2,
1825 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1826 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1829 * Transfer the error codes from the subrequest to the main one
1831 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1832 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1835 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1838 if (!srv_send_smb(first_req->xconn,
1839 (char *)first_req->outbuf,
1840 true, first_req->seqnum+1,
1841 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1843 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1846 TALLOC_FREE(req); /* non-chained case */
1847 TALLOC_FREE(reqs); /* chained case */
1852 char errbuf[smb_size];
1853 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1854 if (!srv_send_smb(req->xconn, errbuf, true,
1855 req->seqnum+1, req->encrypted,
1857 exit_server_cleanly("construct_reply_chain: "
1858 "srv_send_smb failed.");
1861 TALLOC_FREE(req); /* non-chained case */
1862 TALLOC_FREE(reqs); /* chained case */
1865 /****************************************************************************
1866 Process an smb from the client
1867 ****************************************************************************/
1868 static void process_smb(struct smbXsrv_connection *xconn,
1869 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1870 uint32_t seqnum, bool encrypted,
1871 struct smb_perfcount_data *deferred_pcd)
1873 struct smbd_server_connection *sconn = xconn->client->sconn;
1874 int msg_type = CVAL(inbuf,0);
1876 DO_PROFILE_INC(request);
1878 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1880 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1881 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1883 if (msg_type != NBSSmessage) {
1885 * NetBIOS session request, keepalive, etc.
1887 reply_special(xconn, (char *)inbuf, nread);
1891 if (sconn->using_smb2) {
1892 /* At this point we're not really using smb2,
1893 * we make the decision here.. */
1894 if (smbd_is_smb2_header(inbuf, nread)) {
1895 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1896 size_t pdulen = nread - NBT_HDR_SIZE;
1897 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1899 } else if (nread >= smb_size && valid_smb_header(inbuf)
1900 && CVAL(inbuf, smb_com) != 0x72) {
1901 /* This is a non-negprot SMB1 packet.
1902 Disable SMB2 from now on. */
1903 sconn->using_smb2 = false;
1907 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1908 * so subtract 4 from it. */
1909 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1910 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1913 /* special magic for immediate exit */
1915 (IVAL(inbuf, 4) == 0x74697865) &&
1916 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1917 uint8_t exitcode = CVAL(inbuf, 8);
1918 DEBUG(1, ("Exiting immediately with code %d\n",
1923 exit_server_cleanly("Non-SMB packet");
1926 show_msg((char *)inbuf);
1928 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1929 construct_reply_chain(xconn, (char *)inbuf, nread,
1930 seqnum, encrypted, deferred_pcd);
1932 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
1933 seqnum, encrypted, deferred_pcd);
1939 sconn->num_requests++;
1941 /* The timeout_processing function isn't run nearly
1942 often enough to implement 'max log size' without
1943 overrunning the size of the file by many megabytes.
1944 This is especially true if we are running at debug
1945 level 10. Checking every 50 SMBs is a nice
1946 tradeoff of performance vs log file size overrun. */
1948 if ((sconn->num_requests % 50) == 0 &&
1949 need_to_check_log_size()) {
1950 change_to_root_user();
1955 /****************************************************************************
1956 Return a string containing the function name of a SMB command.
1957 ****************************************************************************/
1959 const char *smb_fn_name(int type)
1961 const char *unknown_name = "SMBunknown";
1963 if (smb_messages[type].name == NULL)
1964 return(unknown_name);
1966 return(smb_messages[type].name);
1969 /****************************************************************************
1970 Helper functions for contruct_reply.
1971 ****************************************************************************/
1973 void add_to_common_flags2(uint32_t v)
1978 void remove_from_common_flags2(uint32_t v)
1980 common_flags2 &= ~v;
1983 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
1986 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1987 uint16_t out_flags2 = common_flags2;
1989 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1990 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1991 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1993 srv_set_message(outbuf,0,0,false);
1995 SCVAL(outbuf, smb_com, cmd);
1996 SIVAL(outbuf,smb_rcls,0);
1997 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1998 SSVAL(outbuf,smb_flg2, out_flags2);
1999 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
2000 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2002 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2003 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2004 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2005 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2008 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2010 construct_reply_common(req->cmd, req->inbuf, outbuf);
2014 * @brief Find the smb_cmd offset of the last command pushed
2015 * @param[in] buf The buffer we're building up
2016 * @retval Where can we put our next andx cmd?
2018 * While chaining requests, the "next" request we're looking at needs to put
2019 * its SMB_Command before the data the previous request already built up added
2020 * to the chain. Find the offset to the place where we have to put our cmd.
2023 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2028 cmd = CVAL(buf, smb_com);
2030 if (!is_andx_req(cmd)) {
2036 while (CVAL(buf, ofs) != 0xff) {
2038 if (!is_andx_req(CVAL(buf, ofs))) {
2043 * ofs is from start of smb header, so add the 4 length
2044 * bytes. The next cmd is right after the wct field.
2046 ofs = SVAL(buf, ofs+2) + 4 + 1;
2048 if (ofs+4 >= talloc_get_size(buf)) {
2058 * @brief Do the smb chaining at a buffer level
2059 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2060 * @param[in] andx_buf Buffer to be appended
2063 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2065 uint8_t smb_command = CVAL(andx_buf, smb_com);
2066 uint8_t wct = CVAL(andx_buf, smb_wct);
2067 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2068 uint32_t num_bytes = smb_buflen(andx_buf);
2069 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2072 size_t old_size, new_size;
2074 size_t chain_padding = 0;
2075 size_t andx_cmd_ofs;
2078 old_size = talloc_get_size(*poutbuf);
2080 if ((old_size % 4) != 0) {
2082 * Align the wct field of subsequent requests to a 4-byte
2085 chain_padding = 4 - (old_size % 4);
2089 * After the old request comes the new wct field (1 byte), the vwv's
2090 * and the num_bytes field.
2093 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2094 new_size += num_bytes;
2096 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2097 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2098 (unsigned)new_size));
2102 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2103 if (outbuf == NULL) {
2104 DEBUG(0, ("talloc failed\n"));
2109 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2110 DEBUG(1, ("invalid command chain\n"));
2111 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2115 if (chain_padding != 0) {
2116 memset(outbuf + old_size, 0, chain_padding);
2117 old_size += chain_padding;
2120 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2121 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2126 * Push the chained request:
2131 SCVAL(outbuf, ofs, wct);
2138 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2143 * Read&X has an offset into its data buffer at
2144 * vwv[6]. reply_read_andx has no idea anymore that it's
2145 * running from within a chain, so we have to fix up the
2148 * Although it looks disgusting at this place, I want to keep
2149 * it here. The alternative would be to push knowledge about
2150 * the andx chain down into read&x again.
2153 if (smb_command == SMBreadX) {
2154 uint8_t *bytes_addr;
2158 * Invalid read&x response
2163 bytes_addr = outbuf + ofs /* vwv start */
2164 + sizeof(uint16_t) * wct /* vwv array */
2165 + sizeof(uint16_t) /* bcc */
2166 + 1; /* padding byte */
2168 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2169 bytes_addr - outbuf - 4);
2172 ofs += sizeof(uint16_t) * wct;
2178 SSVAL(outbuf, ofs, num_bytes);
2179 ofs += sizeof(uint16_t);
2185 memcpy(outbuf + ofs, bytes, num_bytes);
2190 bool smb1_is_chain(const uint8_t *buf)
2192 uint8_t cmd, wct, andx_cmd;
2194 cmd = CVAL(buf, smb_com);
2195 if (!is_andx_req(cmd)) {
2198 wct = CVAL(buf, smb_wct);
2202 andx_cmd = CVAL(buf, smb_vwv);
2203 return (andx_cmd != 0xFF);
2206 bool smb1_walk_chain(const uint8_t *buf,
2207 bool (*fn)(uint8_t cmd,
2208 uint8_t wct, const uint16_t *vwv,
2209 uint16_t num_bytes, const uint8_t *bytes,
2210 void *private_data),
2213 size_t smblen = smb_len(buf);
2214 const char *smb_buf = smb_base(buf);
2215 uint8_t cmd, chain_cmd;
2217 const uint16_t *vwv;
2219 const uint8_t *bytes;
2221 cmd = CVAL(buf, smb_com);
2222 wct = CVAL(buf, smb_wct);
2223 vwv = (const uint16_t *)(buf + smb_vwv);
2224 num_bytes = smb_buflen(buf);
2225 bytes = (const uint8_t *)smb_buf_const(buf);
2227 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2231 if (!is_andx_req(cmd)) {
2238 chain_cmd = CVAL(vwv, 0);
2240 while (chain_cmd != 0xff) {
2241 uint32_t chain_offset; /* uint32_t to avoid overflow */
2242 size_t length_needed;
2243 ptrdiff_t vwv_offset;
2245 chain_offset = SVAL(vwv+1, 0);
2248 * Check if the client tries to fool us. The chain
2249 * offset needs to point beyond the current request in
2250 * the chain, it needs to strictly grow. Otherwise we
2251 * might be tricked into an endless loop always
2252 * processing the same request over and over again. We
2253 * used to assume that vwv and the byte buffer array
2254 * in a chain are always attached, but OS/2 the
2255 * Write&X/Read&X chain puts the Read&X vwv array
2256 * right behind the Write&X vwv chain. The Write&X bcc
2257 * array is put behind the Read&X vwv array. So now we
2258 * check whether the chain offset points strictly
2259 * behind the previous vwv array. req->buf points
2260 * right after the vwv array of the previous
2262 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2266 vwv_offset = ((const char *)vwv - smb_buf);
2267 if (chain_offset <= vwv_offset) {
2272 * Next check: Make sure the chain offset does not
2273 * point beyond the overall smb request length.
2276 length_needed = chain_offset+1; /* wct */
2277 if (length_needed > smblen) {
2282 * Now comes the pointer magic. Goal here is to set up
2283 * vwv and buf correctly again. The chain offset (the
2284 * former vwv[1]) points at the new wct field.
2287 wct = CVAL(smb_buf, chain_offset);
2289 if (is_andx_req(chain_cmd) && (wct < 2)) {
2294 * Next consistency check: Make the new vwv array fits
2295 * in the overall smb request.
2298 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2299 if (length_needed > smblen) {
2302 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2305 * Now grab the new byte buffer....
2308 num_bytes = SVAL(vwv+wct, 0);
2311 * .. and check that it fits.
2314 length_needed += num_bytes;
2315 if (length_needed > smblen) {
2318 bytes = (const uint8_t *)(vwv+wct+1);
2320 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2324 if (!is_andx_req(chain_cmd)) {
2327 chain_cmd = CVAL(vwv, 0);
2332 static bool smb1_chain_length_cb(uint8_t cmd,
2333 uint8_t wct, const uint16_t *vwv,
2334 uint16_t num_bytes, const uint8_t *bytes,
2337 unsigned *count = (unsigned *)private_data;
2342 unsigned smb1_chain_length(const uint8_t *buf)
2346 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2352 struct smb1_parse_chain_state {
2353 TALLOC_CTX *mem_ctx;
2355 struct smbd_server_connection *sconn;
2356 struct smbXsrv_connection *xconn;
2360 struct smb_request **reqs;
2364 static bool smb1_parse_chain_cb(uint8_t cmd,
2365 uint8_t wct, const uint16_t *vwv,
2366 uint16_t num_bytes, const uint8_t *bytes,
2369 struct smb1_parse_chain_state *state =
2370 (struct smb1_parse_chain_state *)private_data;
2371 struct smb_request **reqs;
2372 struct smb_request *req;
2375 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2376 struct smb_request *, state->num_reqs+1);
2382 req = talloc(reqs, struct smb_request);
2387 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2388 state->encrypted, state->seqnum);
2395 req->buflen = num_bytes;
2398 reqs[state->num_reqs] = req;
2399 state->num_reqs += 1;
2403 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2404 struct smbXsrv_connection *xconn,
2405 bool encrypted, uint32_t seqnum,
2406 struct smb_request ***reqs, unsigned *num_reqs)
2408 struct smbd_server_connection *sconn = NULL;
2409 struct smb1_parse_chain_state state;
2412 if (xconn != NULL) {
2413 sconn = xconn->client->sconn;
2416 state.mem_ctx = mem_ctx;
2418 state.sconn = sconn;
2419 state.xconn = xconn;
2420 state.encrypted = encrypted;
2421 state.seqnum = seqnum;
2425 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2426 TALLOC_FREE(state.reqs);
2429 for (i=0; i<state.num_reqs; i++) {
2430 state.reqs[i]->chain = state.reqs;
2433 *num_reqs = state.num_reqs;
2437 /****************************************************************************
2438 Check if services need reloading.
2439 ****************************************************************************/
2441 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2444 if (last_smb_conf_reload_time == 0) {
2445 last_smb_conf_reload_time = t;
2448 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2449 reload_services(sconn, conn_snum_used, true);
2450 last_smb_conf_reload_time = t;
2454 static bool fd_is_readable(int fd)
2458 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2460 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2464 static void smbd_server_connection_write_handler(
2465 struct smbXsrv_connection *xconn)
2467 /* TODO: make write nonblocking */
2470 static void smbd_server_connection_read_handler(
2471 struct smbXsrv_connection *xconn, int fd)
2473 uint8_t *inbuf = NULL;
2474 size_t inbuf_len = 0;
2475 size_t unread_bytes = 0;
2476 bool encrypted = false;
2477 TALLOC_CTX *mem_ctx = talloc_tos();
2481 bool async_echo = lp_async_smb_echo_handler();
2482 bool from_client = false;
2485 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2487 * This is the super-ugly hack to prefer the packets
2488 * forwarded by the echo handler over the ones by the
2491 fd = xconn->smb1.echo_handler.trusted_fd;
2495 from_client = (xconn->transport.sock == fd);
2497 if (async_echo && from_client) {
2498 smbd_lock_socket(xconn);
2500 if (!fd_is_readable(fd)) {
2501 DEBUG(10,("the echo listener was faster\n"));
2502 smbd_unlock_socket(xconn);
2507 /* TODO: make this completely nonblocking */
2508 status = receive_smb_talloc(mem_ctx, xconn, fd,
2509 (char **)(void *)&inbuf,
2513 &inbuf_len, &seqnum,
2514 !from_client /* trusted channel */);
2516 if (async_echo && from_client) {
2517 smbd_unlock_socket(xconn);
2520 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2523 if (NT_STATUS_IS_ERR(status)) {
2524 exit_server_cleanly("failed to receive smb request");
2526 if (!NT_STATUS_IS_OK(status)) {
2531 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2532 seqnum, encrypted, NULL);
2535 static void smbd_server_connection_handler(struct tevent_context *ev,
2536 struct tevent_fd *fde,
2540 struct smbXsrv_connection *xconn =
2541 talloc_get_type_abort(private_data,
2542 struct smbXsrv_connection);
2544 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2546 * we're not supposed to do any io
2548 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2549 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2553 if (flags & TEVENT_FD_WRITE) {
2554 smbd_server_connection_write_handler(xconn);
2557 if (flags & TEVENT_FD_READ) {
2558 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2563 static void smbd_server_echo_handler(struct tevent_context *ev,
2564 struct tevent_fd *fde,
2568 struct smbXsrv_connection *xconn =
2569 talloc_get_type_abort(private_data,
2570 struct smbXsrv_connection);
2572 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2574 * we're not supposed to do any io
2576 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2577 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2581 if (flags & TEVENT_FD_WRITE) {
2582 smbd_server_connection_write_handler(xconn);
2585 if (flags & TEVENT_FD_READ) {
2586 smbd_server_connection_read_handler(
2587 xconn, xconn->smb1.echo_handler.trusted_fd);
2592 struct smbd_release_ip_state {
2593 struct smbXsrv_connection *xconn;
2594 struct tevent_immediate *im;
2595 char addr[INET6_ADDRSTRLEN];
2598 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2599 struct tevent_immediate *im,
2602 struct smbd_release_ip_state *state =
2603 talloc_get_type_abort(private_data,
2604 struct smbd_release_ip_state);
2605 struct smbXsrv_connection *xconn = state->xconn;
2607 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2609 * smbd_server_connection_terminate() already triggered ?
2614 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2617 /****************************************************************************
2618 received when we should release a specific IP
2619 ****************************************************************************/
2620 static int release_ip(uint32_t src_vnn, uint32_t dst_vnn,
2622 const uint8_t *msg, size_t msglen,
2625 struct smbd_release_ip_state *state =
2626 talloc_get_type_abort(private_data,
2627 struct smbd_release_ip_state);
2628 struct smbXsrv_connection *xconn = state->xconn;
2630 const char *addr = state->addr;
2631 const char *p = addr;
2636 if (msg[msglen-1] != '\0') {
2640 ip = (const char *)msg;
2642 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2643 /* avoid recursion */
2647 if (strncmp("::ffff:", addr, 7) == 0) {
2651 DEBUG(10, ("Got release IP message for %s, "
2652 "our address is %s\n", ip, p));
2654 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2655 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2658 * With SMB2 we should do a clean disconnect,
2659 * the previous_session_id in the session setup
2660 * will cleanup the old session, tcons and opens.
2662 * A clean disconnect is needed in order to support
2665 * Note: typically this is never triggered
2666 * as we got a TCP RST (triggered by ctdb event scripts)
2667 * before we get CTDB_SRVID_RELEASE_IP.
2669 * We used to call _exit(1) here, but as this was mostly never
2670 * triggered and has implication on our process model,
2671 * we can just use smbd_server_connection_terminate()
2674 * We don't call smbd_server_connection_terminate() directly
2675 * as we might be called from within ctdbd_migrate(),
2676 * we need to defer our action to the next event loop
2678 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2679 smbd_release_ip_immediate, state);
2682 * Make sure we don't get any io on the connection.
2684 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2685 return EADDRNOTAVAIL;
2691 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2692 struct sockaddr_storage *srv,
2693 struct sockaddr_storage *clnt)
2695 struct smbd_release_ip_state *state;
2696 struct ctdbd_connection *cconn;
2699 cconn = messaging_ctdbd_connection();
2700 if (cconn == NULL) {
2701 return NT_STATUS_NO_MEMORY;
2704 state = talloc_zero(xconn, struct smbd_release_ip_state);
2705 if (state == NULL) {
2706 return NT_STATUS_NO_MEMORY;
2708 state->xconn = xconn;
2709 state->im = tevent_create_immediate(state);
2710 if (state->im == NULL) {
2711 return NT_STATUS_NO_MEMORY;
2713 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2714 return NT_STATUS_NO_MEMORY;
2717 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2719 return map_nt_error_from_unix(ret);
2721 return NT_STATUS_OK;
2724 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2725 void *private_data, uint32_t msg_type,
2726 struct server_id server_id, DATA_BLOB *data)
2728 struct smbd_server_connection *sconn = talloc_get_type_abort(
2729 private_data, struct smbd_server_connection);
2730 const char *ip = (char *) data->data;
2733 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2735 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2737 if (client_ip == NULL) {
2741 if (strequal(ip, client_ip)) {
2742 DBG_WARNING("Got kill client message for %s - "
2743 "exiting immediately\n", ip);
2744 exit_server_cleanly("Forced disconnect for client");
2747 TALLOC_FREE(client_ip);
2751 * Send keepalive packets to our client
2753 static bool keepalive_fn(const struct timeval *now, void *private_data)
2755 struct smbd_server_connection *sconn = talloc_get_type_abort(
2756 private_data, struct smbd_server_connection);
2757 struct smbXsrv_connection *xconn = NULL;
2760 if (sconn->using_smb2) {
2761 /* Don't do keepalives on an SMB2 connection. */
2766 * With SMB1 we only have 1 connection
2768 xconn = sconn->client->connections;
2769 smbd_lock_socket(xconn);
2770 ret = send_keepalive(xconn->transport.sock);
2771 smbd_unlock_socket(xconn);
2774 int saved_errno = errno;
2776 * Try and give an error message saying what
2779 DEBUG(0, ("send_keepalive failed for client %s. "
2780 "Error %s - exiting\n",
2781 smbXsrv_connection_dbg(xconn),
2782 strerror(saved_errno)));
2783 errno = saved_errno;
2790 * Do the recurring check if we're idle
2792 static bool deadtime_fn(const struct timeval *now, void *private_data)
2794 struct smbd_server_connection *sconn =
2795 (struct smbd_server_connection *)private_data;
2797 if ((conn_num_open(sconn) == 0)
2798 || (conn_idle_all(sconn, now->tv_sec))) {
2799 DEBUG( 2, ( "Closing idle connection\n" ) );
2800 messaging_send(sconn->msg_ctx,
2801 messaging_server_id(sconn->msg_ctx),
2802 MSG_SHUTDOWN, &data_blob_null);
2810 * Do the recurring log file and smb.conf reload checks.
2813 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2815 struct smbd_server_connection *sconn = talloc_get_type_abort(
2816 private_data, struct smbd_server_connection);
2818 DEBUG(5, ("housekeeping\n"));
2820 change_to_root_user();
2822 /* update printer queue caches if necessary */
2823 update_monitored_printq_cache(sconn->msg_ctx);
2825 /* check if we need to reload services */
2826 check_reload(sconn, time_mono(NULL));
2829 * Force a log file check.
2831 force_check_log_size();
2837 * Read an smb packet in the echo handler child, giving the parent
2838 * smbd one second to react once the socket becomes readable.
2841 struct smbd_echo_read_state {
2842 struct tevent_context *ev;
2843 struct smbXsrv_connection *xconn;
2850 static void smbd_echo_read_readable(struct tevent_req *subreq);
2851 static void smbd_echo_read_waited(struct tevent_req *subreq);
2853 static struct tevent_req *smbd_echo_read_send(
2854 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2855 struct smbXsrv_connection *xconn)
2857 struct tevent_req *req, *subreq;
2858 struct smbd_echo_read_state *state;
2860 req = tevent_req_create(mem_ctx, &state,
2861 struct smbd_echo_read_state);
2866 state->xconn = xconn;
2868 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2869 if (tevent_req_nomem(subreq, req)) {
2870 return tevent_req_post(req, ev);
2872 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2876 static void smbd_echo_read_readable(struct tevent_req *subreq)
2878 struct tevent_req *req = tevent_req_callback_data(
2879 subreq, struct tevent_req);
2880 struct smbd_echo_read_state *state = tevent_req_data(
2881 req, struct smbd_echo_read_state);
2885 ok = wait_for_read_recv(subreq, &err);
2886 TALLOC_FREE(subreq);
2888 tevent_req_nterror(req, map_nt_error_from_unix(err));
2893 * Give the parent smbd one second to step in
2896 subreq = tevent_wakeup_send(
2897 state, state->ev, timeval_current_ofs(1, 0));
2898 if (tevent_req_nomem(subreq, req)) {
2901 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2904 static void smbd_echo_read_waited(struct tevent_req *subreq)
2906 struct tevent_req *req = tevent_req_callback_data(
2907 subreq, struct tevent_req);
2908 struct smbd_echo_read_state *state = tevent_req_data(
2909 req, struct smbd_echo_read_state);
2910 struct smbXsrv_connection *xconn = state->xconn;
2916 ok = tevent_wakeup_recv(subreq);
2917 TALLOC_FREE(subreq);
2919 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2923 ok = smbd_lock_socket_internal(xconn);
2925 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2926 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2930 if (!fd_is_readable(xconn->transport.sock)) {
2931 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2934 ok = smbd_unlock_socket_internal(xconn);
2936 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2937 DEBUG(1, ("%s: failed to unlock socket\n",
2942 subreq = wait_for_read_send(state, state->ev,
2943 xconn->transport.sock, false);
2944 if (tevent_req_nomem(subreq, req)) {
2947 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2951 status = receive_smb_talloc(state, xconn,
2952 xconn->transport.sock,
2959 false /* trusted_channel*/);
2961 if (tevent_req_nterror(req, status)) {
2962 tevent_req_nterror(req, status);
2963 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2964 (int)getpid(), nt_errstr(status)));
2968 ok = smbd_unlock_socket_internal(xconn);
2970 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2971 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2974 tevent_req_done(req);
2977 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2978 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2980 struct smbd_echo_read_state *state = tevent_req_data(
2981 req, struct smbd_echo_read_state);
2984 if (tevent_req_is_nterror(req, &status)) {
2987 *pbuf = talloc_move(mem_ctx, &state->buf);
2988 *pbuflen = state->buflen;
2989 *pseqnum = state->seqnum;
2990 return NT_STATUS_OK;
2993 struct smbd_echo_state {
2994 struct tevent_context *ev;
2995 struct iovec *pending;
2996 struct smbd_server_connection *sconn;
2997 struct smbXsrv_connection *xconn;
3000 struct tevent_fd *parent_fde;
3002 struct tevent_req *write_req;
3005 static void smbd_echo_writer_done(struct tevent_req *req);
3007 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3011 if (state->write_req != NULL) {
3015 num_pending = talloc_array_length(state->pending);
3016 if (num_pending == 0) {
3020 state->write_req = writev_send(state, state->ev, NULL,
3021 state->parent_pipe, false,
3022 state->pending, num_pending);
3023 if (state->write_req == NULL) {
3024 DEBUG(1, ("writev_send failed\n"));
3028 talloc_steal(state->write_req, state->pending);
3029 state->pending = NULL;
3031 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3035 static void smbd_echo_writer_done(struct tevent_req *req)
3037 struct smbd_echo_state *state = tevent_req_callback_data(
3038 req, struct smbd_echo_state);
3042 written = writev_recv(req, &err);
3044 state->write_req = NULL;
3045 if (written == -1) {
3046 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3049 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3050 smbd_echo_activate_writer(state);
3053 static bool smbd_echo_reply(struct smbd_echo_state *state,
3054 uint8_t *inbuf, size_t inbuf_len,
3057 struct smb_request req;
3058 uint16_t num_replies;
3062 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3063 DEBUG(10, ("Got netbios keepalive\n"));
3070 if (inbuf_len < smb_size) {
3071 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3074 if (!valid_smb_header(inbuf)) {
3075 DEBUG(10, ("Got invalid SMB header\n"));
3079 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3085 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3086 smb_messages[req.cmd].name
3087 ? smb_messages[req.cmd].name : "unknown"));
3089 if (req.cmd != SMBecho) {
3096 num_replies = SVAL(req.vwv+0, 0);
3097 if (num_replies != 1) {
3098 /* Not a Windows "Hey, you're still there?" request */
3102 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3104 DEBUG(10, ("create_outbuf failed\n"));
3107 req.outbuf = (uint8_t *)outbuf;
3109 SSVAL(req.outbuf, smb_vwv0, num_replies);
3111 if (req.buflen > 0) {
3112 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3115 ok = srv_send_smb(req.xconn,
3119 TALLOC_FREE(outbuf);
3127 static void smbd_echo_exit(struct tevent_context *ev,
3128 struct tevent_fd *fde, uint16_t flags,
3131 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3135 static void smbd_echo_got_packet(struct tevent_req *req);
3137 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3140 struct smbd_echo_state *state;
3141 struct tevent_req *read_req;
3143 state = talloc_zero(xconn, struct smbd_echo_state);
3144 if (state == NULL) {
3145 DEBUG(1, ("talloc failed\n"));
3148 state->xconn = xconn;
3149 state->parent_pipe = parent_pipe;
3150 state->ev = s3_tevent_context_init(state);
3151 if (state->ev == NULL) {
3152 DEBUG(1, ("tevent_context_init failed\n"));
3156 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3157 TEVENT_FD_READ, smbd_echo_exit,
3159 if (state->parent_fde == NULL) {
3160 DEBUG(1, ("tevent_add_fd failed\n"));
3165 read_req = smbd_echo_read_send(state, state->ev, xconn);
3166 if (read_req == NULL) {
3167 DEBUG(1, ("smbd_echo_read_send failed\n"));
3171 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3174 if (tevent_loop_once(state->ev) == -1) {
3175 DEBUG(1, ("tevent_loop_once failed: %s\n",
3183 static void smbd_echo_got_packet(struct tevent_req *req)
3185 struct smbd_echo_state *state = tevent_req_callback_data(
3186 req, struct smbd_echo_state);
3190 uint32_t seqnum = 0;
3193 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3195 if (!NT_STATUS_IS_OK(status)) {
3196 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3197 nt_errstr(status)));
3201 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3207 num_pending = talloc_array_length(state->pending);
3208 tmp = talloc_realloc(state, state->pending, struct iovec,
3211 DEBUG(1, ("talloc_realloc failed\n"));
3214 state->pending = tmp;
3216 if (buflen >= smb_size) {
3218 * place the seqnum in the packet so that the main process
3219 * can reply with signing
3221 SIVAL(buf, smb_ss_field, seqnum);
3222 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3225 iov = &state->pending[num_pending];
3226 iov->iov_base = talloc_move(state->pending, &buf);
3227 iov->iov_len = buflen;
3229 DEBUG(10,("echo_handler[%d]: forward to main\n",
3231 smbd_echo_activate_writer(state);
3234 req = smbd_echo_read_send(state, state->ev, state->xconn);
3236 DEBUG(1, ("smbd_echo_read_send failed\n"));
3239 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3244 * Handle SMBecho requests in a forked child process
3246 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3248 int listener_pipe[2];
3251 bool use_mutex = false;
3253 res = pipe(listener_pipe);
3255 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3259 #ifdef HAVE_ROBUST_MUTEXES
3260 use_mutex = tdb_runtime_check_for_robust_mutexes();
3263 pthread_mutexattr_t a;
3265 xconn->smb1.echo_handler.socket_mutex =
3266 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3267 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3268 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3273 res = pthread_mutexattr_init(&a);
3275 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3279 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3281 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3283 pthread_mutexattr_destroy(&a);
3286 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3288 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3290 pthread_mutexattr_destroy(&a);
3293 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3295 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3296 "%s\n", strerror(res)));
3297 pthread_mutexattr_destroy(&a);
3300 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3302 pthread_mutexattr_destroy(&a);
3304 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3312 xconn->smb1.echo_handler.socket_lock_fd =
3313 create_unlink_tmp(lp_lock_directory());
3314 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3315 DEBUG(1, ("Could not create lock fd: %s\n",
3325 close(listener_pipe[0]);
3326 set_blocking(listener_pipe[1], false);
3328 status = smbd_reinit_after_fork(xconn->msg_ctx, xconn->ev_ctx,
3330 if (!NT_STATUS_IS_OK(status)) {
3331 DEBUG(1, ("reinit_after_fork failed: %s\n",
3332 nt_errstr(status)));
3335 smbd_echo_loop(xconn, listener_pipe[1]);
3338 close(listener_pipe[1]);
3339 listener_pipe[1] = -1;
3340 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3342 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3345 * Without smb signing this is the same as the normal smbd
3346 * listener. This needs to change once signing comes in.
3348 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3350 xconn->smb1.echo_handler.trusted_fd,
3352 smbd_server_echo_handler,
3354 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3355 DEBUG(1, ("event_add_fd failed\n"));
3362 if (listener_pipe[0] != -1) {
3363 close(listener_pipe[0]);
3365 if (listener_pipe[1] != -1) {
3366 close(listener_pipe[1]);
3368 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3369 close(xconn->smb1.echo_handler.socket_lock_fd);
3371 #ifdef HAVE_ROBUST_MUTEXES
3372 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3373 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3374 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3377 smbd_echo_init(xconn);
3382 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3385 if (user->session_info &&
3386 (user->session_info->unix_token->uid == uid)) {
3394 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3397 if (user->session_info != NULL) {
3399 struct security_unix_token *utok;
3401 utok = user->session_info->unix_token;
3402 if (utok->gid == gid) {
3405 for(i=0; i<utok->ngroups; i++) {
3406 if (utok->groups[i] == gid) {
3416 static bool sid_in_use(const struct user_struct *user,
3417 const struct dom_sid *psid)
3420 struct security_token *tok;
3422 if (user->session_info == NULL) {
3425 tok = user->session_info->security_token;
3428 * Not sure session_info->security_token can
3429 * ever be NULL. This check might be not
3434 if (security_token_has_sid(tok, psid)) {
3442 static bool id_in_use(const struct user_struct *user,
3443 const struct id_cache_ref *id)
3447 return uid_in_use(user, id->id.uid);
3449 return gid_in_use(user, id->id.gid);
3451 return sid_in_use(user, &id->id.sid);
3458 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3461 struct server_id server_id,
3464 const char *msg = (data && data->data)
3465 ? (const char *)data->data : "<NULL>";
3466 struct id_cache_ref id;
3467 struct smbd_server_connection *sconn =
3468 talloc_get_type_abort(private_data,
3469 struct smbd_server_connection);
3471 if (!id_cache_ref_parse(msg, &id)) {
3472 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3476 if (id_in_use(sconn->users, &id)) {
3477 exit_server_cleanly(msg);
3479 id_cache_delete_from_cache(&id);
3482 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3483 enum protocol_types protocol)
3487 conn->protocol = protocol;
3489 if (protocol >= PROTOCOL_SMB2_02) {
3490 status = smb2srv_session_table_init(conn);
3491 if (!NT_STATUS_IS_OK(status)) {
3492 conn->protocol = PROTOCOL_NONE;
3496 status = smb2srv_open_table_init(conn);
3497 if (!NT_STATUS_IS_OK(status)) {
3498 conn->protocol = PROTOCOL_NONE;
3502 status = smb1srv_session_table_init(conn);
3503 if (!NT_STATUS_IS_OK(status)) {
3504 conn->protocol = PROTOCOL_NONE;
3508 status = smb1srv_tcon_table_init(conn);
3509 if (!NT_STATUS_IS_OK(status)) {
3510 conn->protocol = PROTOCOL_NONE;
3514 status = smb1srv_open_table_init(conn);
3515 if (!NT_STATUS_IS_OK(status)) {
3516 conn->protocol = PROTOCOL_NONE;
3521 set_Protocol(protocol);
3522 return NT_STATUS_OK;
3525 struct smbd_tevent_trace_state {
3526 struct tevent_context *ev;
3528 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3531 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3534 struct smbd_tevent_trace_state *state =
3535 (struct smbd_tevent_trace_state *)private_data;
3538 case TEVENT_TRACE_BEFORE_WAIT:
3539 if (!smbprofile_dump_pending()) {
3541 * If there's no dump pending
3542 * we don't want to schedule a new 1 sec timer.
3544 * Instead we want to sleep as long as nothing happens.
3546 smbprofile_dump_setup(NULL);
3548 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3550 case TEVENT_TRACE_AFTER_WAIT:
3551 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3552 if (!smbprofile_dump_pending()) {
3554 * We need to flush our state after sleeping
3555 * (hopefully a long time).
3559 * future profiling events should trigger timers
3560 * on our main event context.
3562 smbprofile_dump_setup(state->ev);
3565 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3566 TALLOC_FREE(state->frame);
3567 state->frame = talloc_stackframe_pool(8192);
3569 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3570 TALLOC_FREE(state->frame);
3578 * Create a debug string for the connection
3580 * This is allocated to talloc_tos() or a string constant
3581 * in certain corner cases. The returned string should
3582 * hence not be free'd directly but only via the talloc stack.
3584 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3589 * TODO: this can be improved later
3590 * maybe including the client guid or more
3592 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3594 return "<tsocket_address_string() failed>";
3600 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3601 struct smbXsrv_connection **_xconn)
3603 TALLOC_CTX *frame = talloc_stackframe();
3604 struct smbXsrv_connection *xconn;
3605 struct sockaddr_storage ss_srv;
3606 void *sp_srv = (void *)&ss_srv;
3607 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3608 struct sockaddr_storage ss_clnt;
3609 void *sp_clnt = (void *)&ss_clnt;
3610 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3611 socklen_t sa_socklen;
3612 struct tsocket_address *local_address = NULL;
3613 struct tsocket_address *remote_address = NULL;
3614 const char *remaddr = NULL;
3616 const char *rhost = NULL;
3622 DO_PROFILE_INC(connect);
3624 xconn = talloc_zero(client, struct smbXsrv_connection);
3625 if (xconn == NULL) {
3626 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3628 return NT_STATUS_NO_MEMORY;
3630 talloc_steal(frame, xconn);
3632 xconn->ev_ctx = client->ev_ctx;
3633 xconn->msg_ctx = client->msg_ctx;
3634 xconn->transport.sock = sock_fd;
3635 smbd_echo_init(xconn);
3636 xconn->protocol = PROTOCOL_NONE;
3638 /* Ensure child is set to blocking mode */
3639 set_blocking(sock_fd,True);
3641 set_socket_options(sock_fd, "SO_KEEPALIVE");
3642 set_socket_options(sock_fd, lp_socket_options());
3644 sa_socklen = sizeof(ss_clnt);
3645 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3647 int saved_errno = errno;
3648 int level = (errno == ENOTCONN)?2:0;
3649 DEBUG(level,("getpeername() failed - %s\n",
3650 strerror(saved_errno)));
3652 return map_nt_error_from_unix_common(saved_errno);
3654 ret = tsocket_address_bsd_from_sockaddr(xconn,
3655 sa_clnt, sa_socklen,
3658 int saved_errno = errno;
3659 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3660 __location__, strerror(saved_errno)));
3662 return map_nt_error_from_unix_common(saved_errno);
3665 sa_socklen = sizeof(ss_srv);
3666 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3668 int saved_errno = errno;
3669 int level = (errno == ENOTCONN)?2:0;
3670 DEBUG(level,("getsockname() failed - %s\n",
3671 strerror(saved_errno)));
3673 return map_nt_error_from_unix_common(saved_errno);
3675 ret = tsocket_address_bsd_from_sockaddr(xconn,
3679 int saved_errno = errno;
3680 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3681 __location__, strerror(saved_errno)));
3683 return map_nt_error_from_unix_common(saved_errno);
3686 if (tsocket_address_is_inet(remote_address, "ip")) {
3687 remaddr = tsocket_address_inet_addr_string(remote_address,
3689 if (remaddr == NULL) {
3690 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3691 __location__, strerror(errno)));
3693 return NT_STATUS_NO_MEMORY;
3696 remaddr = "0.0.0.0";
3700 * Before the first packet, check the global hosts allow/ hosts deny
3701 * parameters before doing any parsing of packets passed to us by the
3702 * client. This prevents attacks on our parsing code from hosts not in
3703 * the hosts allow list.
3706 ret = get_remote_hostname(remote_address,
3709 int saved_errno = errno;
3710 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3711 __location__, strerror(saved_errno)));
3713 return map_nt_error_from_unix_common(saved_errno);
3716 if (strequal(rhost, "UNKNOWN")) {
3720 xconn->local_address = local_address;
3721 xconn->remote_address = remote_address;
3722 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3723 if (xconn->remote_hostname == NULL) {
3724 return NT_STATUS_NO_MEMORY;
3727 if (!srv_init_signing(xconn)) {
3728 DEBUG(0, ("Failed to init smb_signing\n"));
3730 return NT_STATUS_INTERNAL_ERROR;
3733 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3734 xconn->remote_hostname,
3736 DEBUG( 1, ("Connection denied from %s to %s\n",
3737 tsocket_address_string(remote_address, talloc_tos()),
3738 tsocket_address_string(local_address, talloc_tos())));
3741 * We return a valid xconn
3742 * so that the caller can return an error message
3745 client->connections = xconn;
3746 xconn->client = client;
3747 talloc_steal(client, xconn);
3751 return NT_STATUS_NETWORK_ACCESS_DENIED;
3754 DEBUG(10, ("Connection allowed from %s to %s\n",
3755 tsocket_address_string(remote_address, talloc_tos()),
3756 tsocket_address_string(local_address, talloc_tos())));
3758 if (lp_clustering()) {
3760 * We need to tell ctdb about our client's TCP
3761 * connection, so that for failover ctdbd can send
3762 * tickle acks, triggering a reconnection by the
3767 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3768 if (!NT_STATUS_IS_OK(status)) {
3769 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3770 nt_errstr(status)));
3774 tmp = lp_max_xmit();
3775 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3776 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3778 xconn->smb1.negprot.max_recv = tmp;
3780 xconn->smb1.sessions.done_sesssetup = false;
3781 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3783 xconn->transport.fde = tevent_add_fd(client->ev_ctx,
3787 smbd_server_connection_handler,
3789 if (!xconn->transport.fde) {
3791 return NT_STATUS_NO_MEMORY;
3794 /* for now we only have one connection */
3795 DLIST_ADD_END(client->connections, xconn, NULL);
3796 xconn->client = client;
3797 talloc_steal(client, xconn);
3801 return NT_STATUS_OK;
3804 /****************************************************************************
3805 Process commands from the client
3806 ****************************************************************************/
3808 void smbd_process(struct tevent_context *ev_ctx,
3809 struct messaging_context *msg_ctx,
3813 struct smbd_tevent_trace_state trace_state = {
3815 .frame = talloc_stackframe(),
3817 struct smbXsrv_client *client = NULL;
3818 struct smbd_server_connection *sconn = NULL;
3819 struct smbXsrv_connection *xconn = NULL;
3820 const char *locaddr = NULL;
3821 const char *remaddr = NULL;
3825 client = talloc_zero(ev_ctx, struct smbXsrv_client);
3826 if (client == NULL) {
3827 DEBUG(0,("talloc_zero(struct smbXsrv_client)\n"));
3828 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3832 * TODO: remove this...:-)
3834 global_smbXsrv_client = client;
3836 client->ev_ctx = ev_ctx;
3837 client->msg_ctx = msg_ctx;
3839 sconn = talloc_zero(client, struct smbd_server_connection);
3840 if (sconn == NULL) {
3841 exit_server("failed to create smbd_server_connection");
3844 client->sconn = sconn;
3845 sconn->client = client;
3847 sconn->ev_ctx = ev_ctx;
3848 sconn->msg_ctx = msg_ctx;
3850 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3852 * We're not making the decision here,
3853 * we're just allowing the client
3854 * to decide between SMB1 and SMB2
3855 * with the first negprot
3858 sconn->using_smb2 = true;
3862 smbd_setup_sig_term_handler(sconn);
3863 smbd_setup_sig_hup_handler(sconn);
3865 if (!serverid_register(messaging_server_id(msg_ctx),
3866 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3868 |FLAG_MSG_PRINT_GENERAL)) {
3869 exit_server_cleanly("Could not register myself in "
3874 status = smbd_add_connection(client, sock_fd, &xconn);
3875 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3877 * send a negative session response "not listening on calling
3880 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3881 (void)srv_send_smb(xconn,(char *)buf, false,
3883 exit_server_cleanly("connection denied");
3884 } else if (!NT_STATUS_IS_OK(status)) {
3885 exit_server_cleanly(nt_errstr(status));
3888 sconn->local_address =
3889 tsocket_address_copy(xconn->local_address, sconn);
3890 if (sconn->local_address == NULL) {
3891 exit_server_cleanly("tsocket_address_copy() failed");
3893 sconn->remote_address =
3894 tsocket_address_copy(xconn->remote_address, sconn);
3895 if (sconn->remote_address == NULL) {
3896 exit_server_cleanly("tsocket_address_copy() failed");
3898 sconn->remote_hostname =
3899 talloc_strdup(sconn, xconn->remote_hostname);
3900 if (sconn->remote_hostname == NULL) {
3901 exit_server_cleanly("tsocket_strdup() failed");
3904 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3905 locaddr = tsocket_address_inet_addr_string(
3906 sconn->local_address,
3908 if (locaddr == NULL) {
3909 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3910 __location__, strerror(errno)));
3911 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3914 locaddr = "0.0.0.0";
3917 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
3918 remaddr = tsocket_address_inet_addr_string(
3919 sconn->remote_address,
3921 if (remaddr == NULL) {
3922 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3923 __location__, strerror(errno)));
3924 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3927 remaddr = "0.0.0.0";
3930 /* this is needed so that we get decent entries
3931 in smbstatus for port 445 connects */
3932 set_remote_machine_name(remaddr, false);
3933 reload_services(sconn, conn_snum_used, true);
3934 sub_set_socket_ids(remaddr,
3935 sconn->remote_hostname,
3938 if (lp_preload_modules()) {
3939 smb_load_modules(lp_preload_modules());
3942 smb_perfcount_init();
3944 if (!init_account_policy()) {
3945 exit_server("Could not open account policy tdb.\n");
3948 if (*lp_root_directory(talloc_tos())) {
3949 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3950 DEBUG(0,("Failed to change root to %s\n",
3951 lp_root_directory(talloc_tos())));
3952 exit_server("Failed to chroot()");
3954 if (chdir("/") == -1) {
3955 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3956 exit_server("Failed to chroot()");
3958 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3961 if (!file_init(sconn)) {
3962 exit_server("file_init() failed");
3966 if (!init_oplocks(sconn))
3967 exit_server("Failed to init oplocks");
3969 /* register our message handlers */
3970 messaging_register(sconn->msg_ctx, sconn,
3971 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3972 messaging_register(sconn->msg_ctx, sconn,
3973 MSG_SMB_CLOSE_FILE, msg_close_file);
3974 messaging_register(sconn->msg_ctx, sconn,
3975 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3977 id_cache_register_msgs(sconn->msg_ctx);
3978 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3979 messaging_register(sconn->msg_ctx, sconn,
3980 ID_CACHE_KILL, smbd_id_cache_kill);
3982 messaging_deregister(sconn->msg_ctx,
3983 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3984 messaging_register(sconn->msg_ctx, sconn,
3985 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3987 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3989 messaging_register(sconn->msg_ctx, sconn,
3990 MSG_SMB_KILL_CLIENT_IP,
3991 msg_kill_client_ip);
3993 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3996 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3997 * MSGs to all child processes
3999 messaging_deregister(sconn->msg_ctx,
4001 messaging_register(sconn->msg_ctx, NULL,
4002 MSG_DEBUG, debug_message);
4004 if ((lp_keepalive() != 0)
4005 && !(event_add_idle(ev_ctx, NULL,
4006 timeval_set(lp_keepalive(), 0),
4007 "keepalive", keepalive_fn,
4009 DEBUG(0, ("Could not add keepalive event\n"));
4013 if (!(event_add_idle(ev_ctx, NULL,
4014 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4015 "deadtime", deadtime_fn, sconn))) {
4016 DEBUG(0, ("Could not add deadtime event\n"));
4020 if (!(event_add_idle(ev_ctx, NULL,
4021 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4022 "housekeeping", housekeeping_fn, sconn))) {
4023 DEBUG(0, ("Could not add housekeeping event\n"));
4027 smbprofile_dump_setup(ev_ctx);
4029 if (!init_dptrs(sconn)) {
4030 exit_server("init_dptrs() failed");
4033 TALLOC_FREE(trace_state.frame);
4035 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4038 ret = tevent_loop_wait(ev_ctx);
4040 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4041 " exiting\n", ret, strerror(errno)));
4044 TALLOC_FREE(trace_state.frame);
4046 exit_server_cleanly(NULL);
4049 bool req_is_in_chain(const struct smb_request *req)
4051 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4053 * We're right now handling a subsequent request, so we must
4059 if (!is_andx_req(req->cmd)) {
4065 * Okay, an illegal request, but definitely not chained :-)
4070 return (CVAL(req->vwv+0, 0) != 0xFF);