2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
43 #include "system/threads.h"
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list {
47 struct pending_message_list *next, *prev;
48 struct timeval request_time; /* When was this first issued? */
49 struct smbd_server_connection *sconn;
50 struct tevent_timer *te;
51 struct smb_perfcount_data pcd;
56 struct deferred_open_record *open_rec;
59 static void construct_reply_common(struct smb_request *req, const char *inbuf,
61 static struct pending_message_list *get_deferred_open_message_smb(
62 struct smbd_server_connection *sconn, uint64_t mid);
63 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
65 static void smbd_echo_init(struct smbXsrv_connection *xconn)
67 xconn->smb1.echo_handler.trusted_fd = -1;
68 xconn->smb1.echo_handler.socket_lock_fd = -1;
69 #ifdef HAVE_ROBUST_MUTEXES
70 xconn->smb1.echo_handler.socket_mutex = NULL;
74 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
76 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
80 #ifdef HAVE_ROBUST_MUTEXES
81 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
89 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
91 struct smbXsrv_connection *xconn = sconn->conn;
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 smbd_server_connection *sconn)
146 if (!smbd_lock_socket_internal(sconn)) {
147 exit_server_cleanly("failed to lock socket");
151 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
153 struct smbXsrv_connection *xconn = sconn->conn;
155 if (!smbd_echo_active(xconn)) {
159 xconn->smb1.echo_handler.ref_count--;
161 if (xconn->smb1.echo_handler.ref_count > 0) {
165 #ifdef HAVE_ROBUST_MUTEXES
166 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
169 while (ret == EINTR) {
170 ret = pthread_mutex_unlock(
171 xconn->smb1.echo_handler.socket_mutex);
177 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
184 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
189 xconn->smb1.echo_handler.socket_lock_fd,
190 F_SETLKW, 0, 0, F_UNLCK);
191 } while (!ok && (errno == EINTR));
194 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
199 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
204 void smbd_unlock_socket(struct smbd_server_connection *sconn)
206 if (!smbd_unlock_socket_internal(sconn)) {
207 exit_server_cleanly("failed to unlock socket");
211 /* Accessor function for smb_read_error for smbd functions. */
213 /****************************************************************************
215 ****************************************************************************/
217 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
218 bool do_signing, uint32_t seqnum,
220 struct smb_perfcount_data *pcd)
222 struct smbXsrv_connection *xconn = sconn->conn;
225 char *buf_out = buffer;
227 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
229 * we're not supposed to do any io
234 smbd_lock_socket(sconn);
237 /* Sign the outgoing packet if required. */
238 srv_calculate_sign_mac(xconn, buf_out, seqnum);
242 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
243 if (!NT_STATUS_IS_OK(status)) {
244 DEBUG(0, ("send_smb: SMB encryption failed "
245 "on outgoing packet! Error %s\n",
246 nt_errstr(status) ));
252 len = smb_len_large(buf_out) + 4;
254 ret = write_data(xconn->transport.sock, buf_out, len);
256 int saved_errno = errno;
258 * Try and give an error message saying what
261 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
262 (int)getpid(), (int)len,
263 smbXsrv_connection_dbg(xconn),
264 (int)ret, strerror(saved_errno)));
267 srv_free_enc_buffer(sconn, buf_out);
271 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
272 srv_free_enc_buffer(sconn, buf_out);
274 SMB_PERFCOUNT_END(pcd);
276 smbd_unlock_socket(sconn);
280 /*******************************************************************
281 Setup the word count and byte count for a smb message.
282 ********************************************************************/
284 int srv_set_message(char *buf,
289 if (zero && (num_words || num_bytes)) {
290 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
292 SCVAL(buf,smb_wct,num_words);
293 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
294 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
295 return (smb_size + num_words*2 + num_bytes);
298 static bool valid_smb_header(struct smbd_server_connection *sconn,
299 const uint8_t *inbuf)
301 if (is_encrypted_packet(sconn, inbuf)) {
305 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
306 * but it just looks weird to call strncmp for this one.
308 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
311 /* Socket functions for smbd packet processing. */
313 static bool valid_packet_size(size_t len)
316 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
317 * of header. Don't print the error if this fits.... JRA.
320 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
321 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
322 (unsigned long)len));
328 static NTSTATUS read_packet_remainder(int fd, char *buffer,
329 unsigned int timeout, ssize_t len)
337 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
338 if (!NT_STATUS_IS_OK(status)) {
339 char addr[INET6_ADDRSTRLEN];
340 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
342 get_peer_addr(fd, addr, sizeof(addr)),
348 /****************************************************************************
349 Attempt a zerocopy writeX read. We know here that len > smb_size-4
350 ****************************************************************************/
353 * Unfortunately, earlier versions of smbclient/libsmbclient
354 * don't send this "standard" writeX header. I've fixed this
355 * for 3.2 but we'll use the old method with earlier versions.
356 * Windows and CIFSFS at least use this standard size. Not
360 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
361 (2*14) + /* word count (including bcc) */ \
364 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
365 const char lenbuf[4],
366 struct smbd_server_connection *sconn,
369 unsigned int timeout,
373 /* Size of a WRITEX call (+4 byte len). */
374 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
375 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
379 memcpy(writeX_header, lenbuf, 4);
381 status = read_fd_with_timeout(
382 sock, writeX_header + 4,
383 STANDARD_WRITE_AND_X_HEADER_SIZE,
384 STANDARD_WRITE_AND_X_HEADER_SIZE,
387 if (!NT_STATUS_IS_OK(status)) {
388 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
390 tsocket_address_string(sconn->remote_address,
397 * Ok - now try and see if this is a possible
401 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
403 * If the data offset is beyond what
404 * we've read, drain the extra bytes.
406 uint16_t doff = SVAL(writeX_header,smb_vwv11);
409 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
410 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
411 if (drain_socket(sock, drain) != drain) {
412 smb_panic("receive_smb_raw_talloc_partial_read:"
413 " failed to drain pending bytes");
416 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
419 /* Spoof down the length and null out the bcc. */
420 set_message_bcc(writeX_header, 0);
421 newlen = smb_len(writeX_header);
423 /* Copy the header we've written. */
425 *buffer = (char *)talloc_memdup(mem_ctx,
427 sizeof(writeX_header));
429 if (*buffer == NULL) {
430 DEBUG(0, ("Could not allocate inbuf of length %d\n",
431 (int)sizeof(writeX_header)));
432 return NT_STATUS_NO_MEMORY;
435 /* Work out the remaining bytes. */
436 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
437 *len_ret = newlen + 4;
441 if (!valid_packet_size(len)) {
442 return NT_STATUS_INVALID_PARAMETER;
446 * Not a valid writeX call. Just do the standard
450 *buffer = talloc_array(mem_ctx, char, len+4);
452 if (*buffer == NULL) {
453 DEBUG(0, ("Could not allocate inbuf of length %d\n",
455 return NT_STATUS_NO_MEMORY;
458 /* Copy in what we already read. */
461 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
462 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
465 status = read_packet_remainder(
467 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
470 if (!NT_STATUS_IS_OK(status)) {
471 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
481 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
482 struct smbd_server_connection *sconn,
484 char **buffer, unsigned int timeout,
485 size_t *p_unread, size_t *plen)
487 struct smbXsrv_connection *xconn = sconn->conn;
490 int min_recv_size = lp_min_receive_file_size();
495 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
497 if (!NT_STATUS_IS_OK(status)) {
501 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
502 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
503 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
504 !srv_is_signing_active(xconn) &&
505 xconn->smb1.echo_handler.trusted_fde == NULL) {
507 return receive_smb_raw_talloc_partial_read(
508 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
512 if (!valid_packet_size(len)) {
513 return NT_STATUS_INVALID_PARAMETER;
517 * The +4 here can't wrap, we've checked the length above already.
520 *buffer = talloc_array(mem_ctx, char, len+4);
522 if (*buffer == NULL) {
523 DEBUG(0, ("Could not allocate inbuf of length %d\n",
525 return NT_STATUS_NO_MEMORY;
528 memcpy(*buffer, lenbuf, sizeof(lenbuf));
530 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
531 if (!NT_STATUS_IS_OK(status)) {
539 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
540 struct smbd_server_connection *sconn,
542 char **buffer, unsigned int timeout,
543 size_t *p_unread, bool *p_encrypted,
546 bool trusted_channel)
548 struct smbXsrv_connection *xconn = sconn->conn;
552 *p_encrypted = false;
554 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
556 if (!NT_STATUS_IS_OK(status)) {
557 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
558 ("receive_smb_raw_talloc failed for client %s "
559 "read error = %s.\n",
560 tsocket_address_string(sconn->remote_address,
562 nt_errstr(status)) );
566 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
567 status = srv_decrypt_buffer(sconn, *buffer);
568 if (!NT_STATUS_IS_OK(status)) {
569 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
570 "incoming packet! Error %s\n",
571 nt_errstr(status) ));
577 /* Check the incoming SMB signature. */
578 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
579 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
580 "incoming packet!\n"));
581 return NT_STATUS_INVALID_NETWORK_RESPONSE;
589 * Initialize a struct smb_request from an inbuf
592 static bool init_smb_request(struct smb_request *req,
593 struct smbd_server_connection *sconn,
594 struct smbXsrv_connection *xconn,
596 size_t unread_bytes, bool encrypted,
599 struct smbXsrv_tcon *tcon;
602 size_t req_size = smb_len(inbuf) + 4;
604 /* Ensure we have at least smb_size bytes. */
605 if (req_size < smb_size) {
606 DEBUG(0,("init_smb_request: invalid request size %u\n",
607 (unsigned int)req_size ));
611 req->request_time = timeval_current();
612 now = timeval_to_nttime(&req->request_time);
614 req->cmd = CVAL(inbuf, smb_com);
615 req->flags2 = SVAL(inbuf, smb_flg2);
616 req->smbpid = SVAL(inbuf, smb_pid);
617 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
618 req->seqnum = seqnum;
619 req->vuid = SVAL(inbuf, smb_uid);
620 req->tid = SVAL(inbuf, smb_tid);
621 req->wct = CVAL(inbuf, smb_wct);
622 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
623 req->buflen = smb_buflen(inbuf);
624 req->buf = (const uint8_t *)smb_buf_const(inbuf);
625 req->unread_bytes = unread_bytes;
626 req->encrypted = encrypted;
629 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
630 if (NT_STATUS_IS_OK(status)) {
631 req->conn = tcon->compat;
635 req->chain_fsp = NULL;
637 req->priv_paths = NULL;
639 smb_init_perfcount_data(&req->pcd);
641 /* Ensure we have at least wct words and 2 bytes of bcc. */
642 if (smb_size + req->wct*2 > req_size) {
643 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
644 (unsigned int)req->wct,
645 (unsigned int)req_size));
648 /* Ensure bcc is correct. */
649 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
650 DEBUG(0,("init_smb_request: invalid bcc number %u "
651 "(wct = %u, size %u)\n",
652 (unsigned int)req->buflen,
653 (unsigned int)req->wct,
654 (unsigned int)req_size));
662 static void process_smb(struct smbd_server_connection *conn,
663 uint8_t *inbuf, size_t nread, size_t unread_bytes,
664 uint32_t seqnum, bool encrypted,
665 struct smb_perfcount_data *deferred_pcd);
667 static void smbd_deferred_open_timer(struct tevent_context *ev,
668 struct tevent_timer *te,
669 struct timeval _tval,
672 struct pending_message_list *msg = talloc_get_type(private_data,
673 struct pending_message_list);
674 struct smbd_server_connection *sconn = msg->sconn;
675 TALLOC_CTX *mem_ctx = talloc_tos();
676 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
679 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
682 exit_server("smbd_deferred_open_timer: talloc failed\n");
686 /* We leave this message on the queue so the open code can
687 know this is a retry. */
688 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
689 (unsigned long long)mid ));
691 /* Mark the message as processed so this is not
692 * re-processed in error. */
693 msg->processed = true;
695 process_smb(sconn, inbuf,
697 msg->seqnum, msg->encrypted, &msg->pcd);
699 /* If it's still there and was processed, remove it. */
700 msg = get_deferred_open_message_smb(sconn, mid);
701 if (msg && msg->processed) {
702 remove_deferred_open_message_smb(sconn, mid);
706 /****************************************************************************
707 Function to push a message onto the tail of a linked list of smb messages ready
709 ****************************************************************************/
711 static bool push_queued_message(struct smb_request *req,
712 struct timeval request_time,
713 struct timeval end_time,
714 struct deferred_open_record *open_rec)
716 int msg_len = smb_len(req->inbuf) + 4;
717 struct pending_message_list *msg;
719 msg = talloc_zero(NULL, struct pending_message_list);
722 DEBUG(0,("push_message: malloc fail (1)\n"));
725 msg->sconn = req->sconn;
727 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
728 if(msg->buf.data == NULL) {
729 DEBUG(0,("push_message: malloc fail (2)\n"));
734 msg->request_time = request_time;
735 msg->seqnum = req->seqnum;
736 msg->encrypted = req->encrypted;
737 msg->processed = false;
738 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
741 msg->open_rec = talloc_move(msg, &open_rec);
745 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
748 smbd_deferred_open_timer,
751 DEBUG(0,("push_message: event_add_timed failed\n"));
757 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
758 struct pending_message_list *);
760 DEBUG(10,("push_message: pushed message length %u on "
761 "deferred_open_queue\n", (unsigned int)msg_len));
766 /****************************************************************************
767 Function to delete a sharing violation open message by mid.
768 ****************************************************************************/
770 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
773 struct pending_message_list *pml;
775 if (sconn->using_smb2) {
776 remove_deferred_open_message_smb2(sconn, mid);
780 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
781 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
782 DEBUG(10,("remove_deferred_open_message_smb: "
783 "deleting mid %llu len %u\n",
784 (unsigned long long)mid,
785 (unsigned int)pml->buf.length ));
786 DLIST_REMOVE(sconn->deferred_open_queue, pml);
793 /****************************************************************************
794 Move a sharing violation open retry message to the front of the list and
795 schedule it for immediate processing.
796 ****************************************************************************/
798 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
801 struct pending_message_list *pml;
804 if (sconn->using_smb2) {
805 return schedule_deferred_open_message_smb2(sconn, mid);
808 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
809 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
811 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
814 (unsigned long long)msg_mid ));
816 if (mid == msg_mid) {
817 struct tevent_timer *te;
819 if (pml->processed) {
820 /* A processed message should not be
822 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
823 "message mid %llu was already processed\n",
824 (unsigned long long)msg_mid ));
828 DEBUG(10,("schedule_deferred_open_message_smb: "
829 "scheduling mid %llu\n",
830 (unsigned long long)mid ));
832 te = tevent_add_timer(pml->sconn->ev_ctx,
835 smbd_deferred_open_timer,
838 DEBUG(10,("schedule_deferred_open_message_smb: "
839 "event_add_timed() failed, "
840 "skipping mid %llu\n",
841 (unsigned long long)msg_mid ));
844 TALLOC_FREE(pml->te);
846 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
851 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
852 "find message mid %llu\n",
853 (unsigned long long)mid ));
858 /****************************************************************************
859 Return true if this mid is on the deferred queue and was not yet processed.
860 ****************************************************************************/
862 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
864 struct pending_message_list *pml;
866 if (sconn->using_smb2) {
867 return open_was_deferred_smb2(sconn, mid);
870 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
871 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
878 /****************************************************************************
879 Return the message queued by this mid.
880 ****************************************************************************/
882 static struct pending_message_list *get_deferred_open_message_smb(
883 struct smbd_server_connection *sconn, uint64_t mid)
885 struct pending_message_list *pml;
887 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
888 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
895 /****************************************************************************
896 Get the state data queued by this mid.
897 ****************************************************************************/
899 bool get_deferred_open_message_state(struct smb_request *smbreq,
900 struct timeval *p_request_time,
901 struct deferred_open_record **open_rec)
903 struct pending_message_list *pml;
905 if (smbreq->sconn->using_smb2) {
906 return get_deferred_open_message_state_smb2(smbreq->smb2req,
911 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
915 if (p_request_time) {
916 *p_request_time = pml->request_time;
918 if (open_rec != NULL) {
919 *open_rec = pml->open_rec;
924 /****************************************************************************
925 Function to push a deferred open smb message onto a linked list of local smb
926 messages ready for processing.
927 ****************************************************************************/
929 bool push_deferred_open_message_smb(struct smb_request *req,
930 struct timeval request_time,
931 struct timeval timeout,
933 struct deferred_open_record *open_rec)
935 struct timeval end_time;
938 return push_deferred_open_message_smb2(req->smb2req,
945 if (req->unread_bytes) {
946 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
947 "unread_bytes = %u\n",
948 (unsigned int)req->unread_bytes ));
949 smb_panic("push_deferred_open_message_smb: "
950 "logic error unread_bytes != 0" );
953 end_time = timeval_sum(&request_time, &timeout);
955 DEBUG(10,("push_deferred_open_message_smb: pushing message "
956 "len %u mid %llu timeout time [%u.%06u]\n",
957 (unsigned int) smb_len(req->inbuf)+4,
958 (unsigned long long)req->mid,
959 (unsigned int)end_time.tv_sec,
960 (unsigned int)end_time.tv_usec));
962 return push_queued_message(req, request_time, end_time, open_rec);
965 static void smbd_sig_term_handler(struct tevent_context *ev,
966 struct tevent_signal *se,
972 exit_server_cleanly("termination signal");
975 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
977 struct tevent_signal *se;
979 se = tevent_add_signal(sconn->ev_ctx,
982 smbd_sig_term_handler,
985 exit_server("failed to setup SIGTERM handler");
989 static void smbd_sig_hup_handler(struct tevent_context *ev,
990 struct tevent_signal *se,
996 struct smbd_server_connection *sconn =
997 talloc_get_type_abort(private_data,
998 struct smbd_server_connection);
1000 change_to_root_user();
1001 DEBUG(1,("Reloading services after SIGHUP\n"));
1002 reload_services(sconn, conn_snum_used, false);
1005 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1007 struct tevent_signal *se;
1009 se = tevent_add_signal(sconn->ev_ctx,
1012 smbd_sig_hup_handler,
1015 exit_server("failed to setup SIGHUP handler");
1019 static void smbd_conf_updated(struct messaging_context *msg,
1022 struct server_id server_id,
1025 struct smbd_server_connection *sconn =
1026 talloc_get_type_abort(private_data,
1027 struct smbd_server_connection);
1029 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1030 "updated. Reloading.\n"));
1031 change_to_root_user();
1032 reload_services(sconn, conn_snum_used, false);
1036 * Only allow 5 outstanding trans requests. We're allocating memory, so
1040 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1043 for (; list != NULL; list = list->next) {
1045 if (list->mid == mid) {
1046 return NT_STATUS_INVALID_PARAMETER;
1052 return NT_STATUS_INSUFFICIENT_RESOURCES;
1055 return NT_STATUS_OK;
1059 These flags determine some of the permissions required to do an operation
1061 Note that I don't set NEED_WRITE on some write operations because they
1062 are used by some brain-dead clients when printing, and I don't want to
1063 force write permissions on print services.
1065 #define AS_USER (1<<0)
1066 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1067 #define TIME_INIT (1<<2)
1068 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1069 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1070 #define DO_CHDIR (1<<6)
1073 define a list of possible SMB messages and their corresponding
1074 functions. Any message that has a NULL function is unimplemented -
1075 please feel free to contribute implementations!
1077 static const struct smb_message_struct {
1079 void (*fn)(struct smb_request *req);
1081 } smb_messages[256] = {
1083 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1084 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1085 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1086 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1087 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1088 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1089 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1090 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1091 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1092 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1093 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1094 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1095 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1096 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1097 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1098 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1099 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1100 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1101 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1102 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1103 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1104 /* 0x15 */ { NULL, NULL, 0 },
1105 /* 0x16 */ { NULL, NULL, 0 },
1106 /* 0x17 */ { NULL, NULL, 0 },
1107 /* 0x18 */ { NULL, NULL, 0 },
1108 /* 0x19 */ { NULL, NULL, 0 },
1109 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1110 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1111 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1112 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1113 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1114 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1115 /* 0x20 */ { "SMBwritec", NULL,0},
1116 /* 0x21 */ { NULL, NULL, 0 },
1117 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1118 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1119 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1120 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1121 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1122 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1123 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1124 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1125 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1126 /* 0x2b */ { "SMBecho",reply_echo,0},
1127 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1128 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1129 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1130 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1131 /* 0x30 */ { NULL, NULL, 0 },
1132 /* 0x31 */ { NULL, NULL, 0 },
1133 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1134 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1135 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1136 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1137 /* 0x36 */ { NULL, NULL, 0 },
1138 /* 0x37 */ { NULL, NULL, 0 },
1139 /* 0x38 */ { NULL, NULL, 0 },
1140 /* 0x39 */ { NULL, NULL, 0 },
1141 /* 0x3a */ { NULL, NULL, 0 },
1142 /* 0x3b */ { NULL, NULL, 0 },
1143 /* 0x3c */ { NULL, NULL, 0 },
1144 /* 0x3d */ { NULL, NULL, 0 },
1145 /* 0x3e */ { NULL, NULL, 0 },
1146 /* 0x3f */ { NULL, NULL, 0 },
1147 /* 0x40 */ { NULL, NULL, 0 },
1148 /* 0x41 */ { NULL, NULL, 0 },
1149 /* 0x42 */ { NULL, NULL, 0 },
1150 /* 0x43 */ { NULL, NULL, 0 },
1151 /* 0x44 */ { NULL, NULL, 0 },
1152 /* 0x45 */ { NULL, NULL, 0 },
1153 /* 0x46 */ { NULL, NULL, 0 },
1154 /* 0x47 */ { NULL, NULL, 0 },
1155 /* 0x48 */ { NULL, NULL, 0 },
1156 /* 0x49 */ { NULL, NULL, 0 },
1157 /* 0x4a */ { NULL, NULL, 0 },
1158 /* 0x4b */ { NULL, NULL, 0 },
1159 /* 0x4c */ { NULL, NULL, 0 },
1160 /* 0x4d */ { NULL, NULL, 0 },
1161 /* 0x4e */ { NULL, NULL, 0 },
1162 /* 0x4f */ { NULL, NULL, 0 },
1163 /* 0x50 */ { NULL, NULL, 0 },
1164 /* 0x51 */ { NULL, NULL, 0 },
1165 /* 0x52 */ { NULL, NULL, 0 },
1166 /* 0x53 */ { NULL, NULL, 0 },
1167 /* 0x54 */ { NULL, NULL, 0 },
1168 /* 0x55 */ { NULL, NULL, 0 },
1169 /* 0x56 */ { NULL, NULL, 0 },
1170 /* 0x57 */ { NULL, NULL, 0 },
1171 /* 0x58 */ { NULL, NULL, 0 },
1172 /* 0x59 */ { NULL, NULL, 0 },
1173 /* 0x5a */ { NULL, NULL, 0 },
1174 /* 0x5b */ { NULL, NULL, 0 },
1175 /* 0x5c */ { NULL, NULL, 0 },
1176 /* 0x5d */ { NULL, NULL, 0 },
1177 /* 0x5e */ { NULL, NULL, 0 },
1178 /* 0x5f */ { NULL, NULL, 0 },
1179 /* 0x60 */ { NULL, NULL, 0 },
1180 /* 0x61 */ { NULL, NULL, 0 },
1181 /* 0x62 */ { NULL, NULL, 0 },
1182 /* 0x63 */ { NULL, NULL, 0 },
1183 /* 0x64 */ { NULL, NULL, 0 },
1184 /* 0x65 */ { NULL, NULL, 0 },
1185 /* 0x66 */ { NULL, NULL, 0 },
1186 /* 0x67 */ { NULL, NULL, 0 },
1187 /* 0x68 */ { NULL, NULL, 0 },
1188 /* 0x69 */ { NULL, NULL, 0 },
1189 /* 0x6a */ { NULL, NULL, 0 },
1190 /* 0x6b */ { NULL, NULL, 0 },
1191 /* 0x6c */ { NULL, NULL, 0 },
1192 /* 0x6d */ { NULL, NULL, 0 },
1193 /* 0x6e */ { NULL, NULL, 0 },
1194 /* 0x6f */ { NULL, NULL, 0 },
1195 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1196 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1197 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1198 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1199 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1200 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1201 /* 0x76 */ { NULL, NULL, 0 },
1202 /* 0x77 */ { NULL, NULL, 0 },
1203 /* 0x78 */ { NULL, NULL, 0 },
1204 /* 0x79 */ { NULL, NULL, 0 },
1205 /* 0x7a */ { NULL, NULL, 0 },
1206 /* 0x7b */ { NULL, NULL, 0 },
1207 /* 0x7c */ { NULL, NULL, 0 },
1208 /* 0x7d */ { NULL, NULL, 0 },
1209 /* 0x7e */ { NULL, NULL, 0 },
1210 /* 0x7f */ { NULL, NULL, 0 },
1211 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1212 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1213 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1214 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1215 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1216 /* 0x85 */ { NULL, NULL, 0 },
1217 /* 0x86 */ { NULL, NULL, 0 },
1218 /* 0x87 */ { NULL, NULL, 0 },
1219 /* 0x88 */ { NULL, NULL, 0 },
1220 /* 0x89 */ { NULL, NULL, 0 },
1221 /* 0x8a */ { NULL, NULL, 0 },
1222 /* 0x8b */ { NULL, NULL, 0 },
1223 /* 0x8c */ { NULL, NULL, 0 },
1224 /* 0x8d */ { NULL, NULL, 0 },
1225 /* 0x8e */ { NULL, NULL, 0 },
1226 /* 0x8f */ { NULL, NULL, 0 },
1227 /* 0x90 */ { NULL, NULL, 0 },
1228 /* 0x91 */ { NULL, NULL, 0 },
1229 /* 0x92 */ { NULL, NULL, 0 },
1230 /* 0x93 */ { NULL, NULL, 0 },
1231 /* 0x94 */ { NULL, NULL, 0 },
1232 /* 0x95 */ { NULL, NULL, 0 },
1233 /* 0x96 */ { NULL, NULL, 0 },
1234 /* 0x97 */ { NULL, NULL, 0 },
1235 /* 0x98 */ { NULL, NULL, 0 },
1236 /* 0x99 */ { NULL, NULL, 0 },
1237 /* 0x9a */ { NULL, NULL, 0 },
1238 /* 0x9b */ { NULL, NULL, 0 },
1239 /* 0x9c */ { NULL, NULL, 0 },
1240 /* 0x9d */ { NULL, NULL, 0 },
1241 /* 0x9e */ { NULL, NULL, 0 },
1242 /* 0x9f */ { NULL, NULL, 0 },
1243 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1244 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1245 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1246 /* 0xa3 */ { NULL, NULL, 0 },
1247 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1248 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1249 /* 0xa6 */ { NULL, NULL, 0 },
1250 /* 0xa7 */ { NULL, NULL, 0 },
1251 /* 0xa8 */ { NULL, NULL, 0 },
1252 /* 0xa9 */ { NULL, NULL, 0 },
1253 /* 0xaa */ { NULL, NULL, 0 },
1254 /* 0xab */ { NULL, NULL, 0 },
1255 /* 0xac */ { NULL, NULL, 0 },
1256 /* 0xad */ { NULL, NULL, 0 },
1257 /* 0xae */ { NULL, NULL, 0 },
1258 /* 0xaf */ { NULL, NULL, 0 },
1259 /* 0xb0 */ { NULL, NULL, 0 },
1260 /* 0xb1 */ { NULL, NULL, 0 },
1261 /* 0xb2 */ { NULL, NULL, 0 },
1262 /* 0xb3 */ { NULL, NULL, 0 },
1263 /* 0xb4 */ { NULL, NULL, 0 },
1264 /* 0xb5 */ { NULL, NULL, 0 },
1265 /* 0xb6 */ { NULL, NULL, 0 },
1266 /* 0xb7 */ { NULL, NULL, 0 },
1267 /* 0xb8 */ { NULL, NULL, 0 },
1268 /* 0xb9 */ { NULL, NULL, 0 },
1269 /* 0xba */ { NULL, NULL, 0 },
1270 /* 0xbb */ { NULL, NULL, 0 },
1271 /* 0xbc */ { NULL, NULL, 0 },
1272 /* 0xbd */ { NULL, NULL, 0 },
1273 /* 0xbe */ { NULL, NULL, 0 },
1274 /* 0xbf */ { NULL, NULL, 0 },
1275 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1276 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1277 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1278 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1279 /* 0xc4 */ { NULL, NULL, 0 },
1280 /* 0xc5 */ { NULL, NULL, 0 },
1281 /* 0xc6 */ { NULL, NULL, 0 },
1282 /* 0xc7 */ { NULL, NULL, 0 },
1283 /* 0xc8 */ { NULL, NULL, 0 },
1284 /* 0xc9 */ { NULL, NULL, 0 },
1285 /* 0xca */ { NULL, NULL, 0 },
1286 /* 0xcb */ { NULL, NULL, 0 },
1287 /* 0xcc */ { NULL, NULL, 0 },
1288 /* 0xcd */ { NULL, NULL, 0 },
1289 /* 0xce */ { NULL, NULL, 0 },
1290 /* 0xcf */ { NULL, NULL, 0 },
1291 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1292 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1293 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1294 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1295 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1296 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1297 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1298 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1299 /* 0xd8 */ { NULL, NULL, 0 },
1300 /* 0xd9 */ { NULL, NULL, 0 },
1301 /* 0xda */ { NULL, NULL, 0 },
1302 /* 0xdb */ { NULL, NULL, 0 },
1303 /* 0xdc */ { NULL, NULL, 0 },
1304 /* 0xdd */ { NULL, NULL, 0 },
1305 /* 0xde */ { NULL, NULL, 0 },
1306 /* 0xdf */ { NULL, NULL, 0 },
1307 /* 0xe0 */ { NULL, NULL, 0 },
1308 /* 0xe1 */ { NULL, NULL, 0 },
1309 /* 0xe2 */ { NULL, NULL, 0 },
1310 /* 0xe3 */ { NULL, NULL, 0 },
1311 /* 0xe4 */ { NULL, NULL, 0 },
1312 /* 0xe5 */ { NULL, NULL, 0 },
1313 /* 0xe6 */ { NULL, NULL, 0 },
1314 /* 0xe7 */ { NULL, NULL, 0 },
1315 /* 0xe8 */ { NULL, NULL, 0 },
1316 /* 0xe9 */ { NULL, NULL, 0 },
1317 /* 0xea */ { NULL, NULL, 0 },
1318 /* 0xeb */ { NULL, NULL, 0 },
1319 /* 0xec */ { NULL, NULL, 0 },
1320 /* 0xed */ { NULL, NULL, 0 },
1321 /* 0xee */ { NULL, NULL, 0 },
1322 /* 0xef */ { NULL, NULL, 0 },
1323 /* 0xf0 */ { NULL, NULL, 0 },
1324 /* 0xf1 */ { NULL, NULL, 0 },
1325 /* 0xf2 */ { NULL, NULL, 0 },
1326 /* 0xf3 */ { NULL, NULL, 0 },
1327 /* 0xf4 */ { NULL, NULL, 0 },
1328 /* 0xf5 */ { NULL, NULL, 0 },
1329 /* 0xf6 */ { NULL, NULL, 0 },
1330 /* 0xf7 */ { NULL, NULL, 0 },
1331 /* 0xf8 */ { NULL, NULL, 0 },
1332 /* 0xf9 */ { NULL, NULL, 0 },
1333 /* 0xfa */ { NULL, NULL, 0 },
1334 /* 0xfb */ { NULL, NULL, 0 },
1335 /* 0xfc */ { NULL, NULL, 0 },
1336 /* 0xfd */ { NULL, NULL, 0 },
1337 /* 0xfe */ { NULL, NULL, 0 },
1338 /* 0xff */ { NULL, NULL, 0 }
1342 /*******************************************************************
1343 allocate and initialize a reply packet
1344 ********************************************************************/
1346 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1347 const char *inbuf, char **outbuf, uint8_t num_words,
1350 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1353 * Protect against integer wrap.
1354 * The SMB layer reply can be up to 0xFFFFFF bytes.
1356 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1358 if (asprintf(&msg, "num_bytes too large: %u",
1359 (unsigned)num_bytes) == -1) {
1360 msg = discard_const_p(char, "num_bytes too large");
1366 * Here we include the NBT header for now.
1368 *outbuf = talloc_array(mem_ctx, char,
1369 NBT_HDR_SIZE + smb_len);
1370 if (*outbuf == NULL) {
1374 construct_reply_common(req, inbuf, *outbuf);
1375 srv_set_message(*outbuf, num_words, num_bytes, false);
1377 * Zero out the word area, the caller has to take care of the bcc area
1380 if (num_words != 0) {
1381 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1387 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1390 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1392 smb_panic("could not allocate output buffer\n");
1394 req->outbuf = (uint8_t *)outbuf;
1398 /*******************************************************************
1399 Dump a packet to a file.
1400 ********************************************************************/
1402 static void smb_dump(const char *name, int type, const char *data)
1407 if (DEBUGLEVEL < 50) {
1411 len = smb_len_tcp(data)+4;
1412 for (i=1;i<100;i++) {
1413 fname = talloc_asprintf(talloc_tos(),
1417 type ? "req" : "resp");
1418 if (fname == NULL) {
1421 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1422 if (fd != -1 || errno != EEXIST) break;
1426 ssize_t ret = write(fd, data, len);
1428 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1430 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1435 /****************************************************************************
1436 Prepare everything for calling the actual request function, and potentially
1437 call the request function via the "new" interface.
1439 Return False if the "legacy" function needs to be called, everything is
1442 Return True if we're done.
1444 I know this API sucks, but it is the one with the least code change I could
1446 ****************************************************************************/
1448 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1451 uint64_t session_tag;
1452 connection_struct *conn = NULL;
1453 struct smbd_server_connection *sconn = req->sconn;
1454 NTTIME now = timeval_to_nttime(&req->request_time);
1455 struct smbXsrv_session *session = NULL;
1460 if (smb_messages[type].fn == NULL) {
1461 DEBUG(0,("Unknown message type %d!\n",type));
1462 smb_dump("Unknown", 1, (const char *)req->inbuf);
1463 reply_unknown_new(req, type);
1467 flags = smb_messages[type].flags;
1469 /* In share mode security we must ignore the vuid. */
1470 session_tag = req->vuid;
1473 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1474 (int)getpid(), (unsigned long)conn));
1476 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1478 /* Ensure this value is replaced in the incoming packet. */
1479 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1482 * Ensure the correct username is in current_user_info. This is a
1483 * really ugly bugfix for problems with multiple session_setup_and_X's
1484 * being done and allowing %U and %G substitutions to work correctly.
1485 * There is a reason this code is done here, don't move it unless you
1486 * know what you're doing... :-).
1491 * lookup an existing session
1493 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1494 * here, the main check is still in change_to_user()
1496 status = smb1srv_session_lookup(sconn->conn,
1500 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1503 status = NT_STATUS_OK;
1506 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1507 (unsigned long long)session_tag,
1508 (unsigned long long)req->mid));
1509 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1514 if (session_tag != sconn->conn->last_session_id) {
1515 struct user_struct *vuser = NULL;
1517 sconn->conn->last_session_id = session_tag;
1519 vuser = session->compat;
1522 set_current_user_info(
1523 vuser->session_info->unix_info->sanitized_username,
1524 vuser->session_info->unix_info->unix_name,
1525 vuser->session_info->info->domain_name);
1529 /* Does this call need to be run as the connected user? */
1530 if (flags & AS_USER) {
1532 /* Does this call need a valid tree connection? */
1535 * Amazingly, the error code depends on the command
1538 if (type == SMBntcreateX) {
1539 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1541 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1546 if (!change_to_user(conn,session_tag)) {
1547 DEBUG(0, ("Error: Could not change to user. Removing "
1548 "deferred open, mid=%llu.\n",
1549 (unsigned long long)req->mid));
1550 reply_force_doserror(req, ERRSRV, ERRbaduid);
1554 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1556 /* Does it need write permission? */
1557 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1558 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1562 /* IPC services are limited */
1563 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1564 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1568 /* This call needs to be run as root */
1569 change_to_root_user();
1572 /* load service specific parameters */
1574 if (req->encrypted) {
1575 conn->encrypted_tid = true;
1576 /* encrypted required from now on. */
1577 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1578 } else if (ENCRYPTION_REQUIRED(conn)) {
1579 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1580 DEBUG(1,("service[%s] requires encryption"
1581 "%s ACCESS_DENIED. mid=%llu\n",
1582 lp_servicename(talloc_tos(), SNUM(conn)),
1584 (unsigned long long)req->mid));
1585 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1590 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1591 (flags & (AS_USER|DO_CHDIR)
1593 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1596 conn->num_smb_operations++;
1600 * Does this protocol need to be run as guest? (Only archane
1601 * messenger service requests have this...)
1603 if (flags & AS_GUEST) {
1607 if (!change_to_guest()) {
1608 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1612 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1614 if (raddr == NULL) {
1615 reply_nterror(req, NT_STATUS_NO_MEMORY);
1620 * Haven't we checked this in smbd_process already???
1623 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1624 sconn->remote_hostname, raddr);
1628 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1633 smb_messages[type].fn(req);
1637 /****************************************************************************
1638 Construct a reply to the incoming packet.
1639 ****************************************************************************/
1641 static void construct_reply(struct smbd_server_connection *sconn,
1642 char *inbuf, int size, size_t unread_bytes,
1643 uint32_t seqnum, bool encrypted,
1644 struct smb_perfcount_data *deferred_pcd)
1646 struct smbXsrv_connection *xconn = sconn->conn;
1647 connection_struct *conn;
1648 struct smb_request *req;
1650 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1651 smb_panic("could not allocate smb_request");
1654 if (!init_smb_request(req, sconn, xconn, (uint8 *)inbuf, unread_bytes,
1655 encrypted, seqnum)) {
1656 exit_server_cleanly("Invalid SMB request");
1659 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1661 /* we popped this message off the queue - keep original perf data */
1663 req->pcd = *deferred_pcd;
1665 SMB_PERFCOUNT_START(&req->pcd);
1666 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1667 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1670 conn = switch_message(req->cmd, req);
1672 if (req->outbuf == NULL) {
1676 if (CVAL(req->outbuf,0) == 0) {
1677 show_msg((char *)req->outbuf);
1680 if (!srv_send_smb(req->sconn,
1681 (char *)req->outbuf,
1682 true, req->seqnum+1,
1683 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1685 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1693 static void construct_reply_chain(struct smbd_server_connection *sconn,
1694 char *inbuf, int size, uint32_t seqnum,
1696 struct smb_perfcount_data *deferred_pcd)
1698 struct smb_request **reqs = NULL;
1699 struct smb_request *req;
1703 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1704 seqnum, &reqs, &num_reqs);
1706 char errbuf[smb_size];
1707 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1708 __LINE__, __FILE__);
1709 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1711 exit_server_cleanly("construct_reply_chain: "
1712 "srv_send_smb failed.");
1718 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1720 req->conn = switch_message(req->cmd, req);
1722 if (req->outbuf == NULL) {
1724 * Request has suspended itself, will come
1729 smb_request_done(req);
1733 * To be called from an async SMB handler that is potentially chained
1734 * when it is finished for shipping.
1737 void smb_request_done(struct smb_request *req)
1739 struct smb_request **reqs = NULL;
1740 struct smb_request *first_req;
1741 size_t i, num_reqs, next_index;
1744 if (req->chain == NULL) {
1750 num_reqs = talloc_array_length(reqs);
1752 for (i=0; i<num_reqs; i++) {
1753 if (reqs[i] == req) {
1757 if (i == num_reqs) {
1759 * Invalid chain, should not happen
1761 status = NT_STATUS_INTERNAL_ERROR;
1766 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1767 struct smb_request *next = reqs[next_index];
1768 struct smbXsrv_tcon *tcon;
1769 NTTIME now = timeval_to_nttime(&req->request_time);
1771 next->vuid = SVAL(req->outbuf, smb_uid);
1772 next->tid = SVAL(req->outbuf, smb_tid);
1773 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1775 if (NT_STATUS_IS_OK(status)) {
1776 req->conn = tcon->compat;
1780 next->chain_fsp = req->chain_fsp;
1781 next->inbuf = req->inbuf;
1784 req->conn = switch_message(req->cmd, req);
1786 if (req->outbuf == NULL) {
1788 * Request has suspended itself, will come
1796 first_req = reqs[0];
1798 for (i=1; i<next_index; i++) {
1801 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1803 status = NT_STATUS_INTERNAL_ERROR;
1808 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1809 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1812 * This scary statement intends to set the
1813 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1814 * to the value last_req->outbuf carries
1816 SSVAL(first_req->outbuf, smb_flg2,
1817 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1818 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1821 * Transfer the error codes from the subrequest to the main one
1823 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1824 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1827 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1830 if (!srv_send_smb(first_req->sconn,
1831 (char *)first_req->outbuf,
1832 true, first_req->seqnum+1,
1833 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1835 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1838 TALLOC_FREE(req); /* non-chained case */
1839 TALLOC_FREE(reqs); /* chained case */
1844 char errbuf[smb_size];
1845 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1846 if (!srv_send_smb(req->sconn, errbuf, true,
1847 req->seqnum+1, req->encrypted,
1849 exit_server_cleanly("construct_reply_chain: "
1850 "srv_send_smb failed.");
1853 TALLOC_FREE(req); /* non-chained case */
1854 TALLOC_FREE(reqs); /* chained case */
1857 /****************************************************************************
1858 Process an smb from the client
1859 ****************************************************************************/
1860 static void process_smb(struct smbd_server_connection *sconn,
1861 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1862 uint32_t seqnum, bool encrypted,
1863 struct smb_perfcount_data *deferred_pcd)
1865 int msg_type = CVAL(inbuf,0);
1867 DO_PROFILE_INC(smb_count);
1869 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1871 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1872 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1874 if (msg_type != NBSSmessage) {
1876 * NetBIOS session request, keepalive, etc.
1878 reply_special(sconn, (char *)inbuf, nread);
1882 if (sconn->using_smb2) {
1883 /* At this point we're not really using smb2,
1884 * we make the decision here.. */
1885 if (smbd_is_smb2_header(inbuf, nread)) {
1886 smbd_smb2_first_negprot(sconn, inbuf, nread);
1888 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1889 && CVAL(inbuf, smb_com) != 0x72) {
1890 /* This is a non-negprot SMB1 packet.
1891 Disable SMB2 from now on. */
1892 sconn->using_smb2 = false;
1896 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1897 * so subtract 4 from it. */
1898 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1899 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1902 /* special magic for immediate exit */
1904 (IVAL(inbuf, 4) == 0x74697865) &&
1905 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1906 uint8_t exitcode = CVAL(inbuf, 8);
1907 DEBUG(1, ("Exiting immediately with code %d\n",
1912 exit_server_cleanly("Non-SMB packet");
1915 show_msg((char *)inbuf);
1917 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1918 construct_reply_chain(sconn, (char *)inbuf, nread,
1919 seqnum, encrypted, deferred_pcd);
1921 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1922 seqnum, encrypted, deferred_pcd);
1928 sconn->num_requests++;
1930 /* The timeout_processing function isn't run nearly
1931 often enough to implement 'max log size' without
1932 overrunning the size of the file by many megabytes.
1933 This is especially true if we are running at debug
1934 level 10. Checking every 50 SMBs is a nice
1935 tradeoff of performance vs log file size overrun. */
1937 if ((sconn->num_requests % 50) == 0 &&
1938 need_to_check_log_size()) {
1939 change_to_root_user();
1944 /****************************************************************************
1945 Return a string containing the function name of a SMB command.
1946 ****************************************************************************/
1948 const char *smb_fn_name(int type)
1950 const char *unknown_name = "SMBunknown";
1952 if (smb_messages[type].name == NULL)
1953 return(unknown_name);
1955 return(smb_messages[type].name);
1958 /****************************************************************************
1959 Helper functions for contruct_reply.
1960 ****************************************************************************/
1962 void add_to_common_flags2(uint32 v)
1967 void remove_from_common_flags2(uint32 v)
1969 common_flags2 &= ~v;
1972 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1975 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1976 uint16_t out_flags2 = common_flags2;
1978 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1979 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1980 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1982 srv_set_message(outbuf,0,0,false);
1984 SCVAL(outbuf, smb_com, req->cmd);
1985 SIVAL(outbuf,smb_rcls,0);
1986 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1987 SSVAL(outbuf,smb_flg2, out_flags2);
1988 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1989 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1991 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1992 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1993 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1994 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1997 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1999 construct_reply_common(req, (const char *)req->inbuf, outbuf);
2003 * @brief Find the smb_cmd offset of the last command pushed
2004 * @param[in] buf The buffer we're building up
2005 * @retval Where can we put our next andx cmd?
2007 * While chaining requests, the "next" request we're looking at needs to put
2008 * its SMB_Command before the data the previous request already built up added
2009 * to the chain. Find the offset to the place where we have to put our cmd.
2012 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2017 cmd = CVAL(buf, smb_com);
2019 if (!is_andx_req(cmd)) {
2025 while (CVAL(buf, ofs) != 0xff) {
2027 if (!is_andx_req(CVAL(buf, ofs))) {
2032 * ofs is from start of smb header, so add the 4 length
2033 * bytes. The next cmd is right after the wct field.
2035 ofs = SVAL(buf, ofs+2) + 4 + 1;
2037 if (ofs+4 >= talloc_get_size(buf)) {
2047 * @brief Do the smb chaining at a buffer level
2048 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2049 * @param[in] andx_buf Buffer to be appended
2052 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2054 uint8_t smb_command = CVAL(andx_buf, smb_com);
2055 uint8_t wct = CVAL(andx_buf, smb_wct);
2056 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2057 uint32_t num_bytes = smb_buflen(andx_buf);
2058 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2061 size_t old_size, new_size;
2063 size_t chain_padding = 0;
2064 size_t andx_cmd_ofs;
2067 old_size = talloc_get_size(*poutbuf);
2069 if ((old_size % 4) != 0) {
2071 * Align the wct field of subsequent requests to a 4-byte
2074 chain_padding = 4 - (old_size % 4);
2078 * After the old request comes the new wct field (1 byte), the vwv's
2079 * and the num_bytes field.
2082 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2083 new_size += num_bytes;
2085 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2086 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2087 (unsigned)new_size));
2091 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2092 if (outbuf == NULL) {
2093 DEBUG(0, ("talloc failed\n"));
2098 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2099 DEBUG(1, ("invalid command chain\n"));
2100 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2104 if (chain_padding != 0) {
2105 memset(outbuf + old_size, 0, chain_padding);
2106 old_size += chain_padding;
2109 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2110 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2115 * Push the chained request:
2120 SCVAL(outbuf, ofs, wct);
2127 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2132 * Read&X has an offset into its data buffer at
2133 * vwv[6]. reply_read_andx has no idea anymore that it's
2134 * running from within a chain, so we have to fix up the
2137 * Although it looks disgusting at this place, I want to keep
2138 * it here. The alternative would be to push knowledge about
2139 * the andx chain down into read&x again.
2142 if (smb_command == SMBreadX) {
2143 uint8_t *bytes_addr;
2147 * Invalid read&x response
2152 bytes_addr = outbuf + ofs /* vwv start */
2153 + sizeof(uint16_t) * wct /* vwv array */
2154 + sizeof(uint16_t); /* bcc */
2156 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2157 bytes_addr - outbuf - 4);
2160 ofs += sizeof(uint16_t) * wct;
2166 SSVAL(outbuf, ofs, num_bytes);
2167 ofs += sizeof(uint16_t);
2173 memcpy(outbuf + ofs, bytes, num_bytes);
2178 bool smb1_is_chain(const uint8_t *buf)
2180 uint8_t cmd, wct, andx_cmd;
2182 cmd = CVAL(buf, smb_com);
2183 if (!is_andx_req(cmd)) {
2186 wct = CVAL(buf, smb_wct);
2190 andx_cmd = CVAL(buf, smb_vwv);
2191 return (andx_cmd != 0xFF);
2194 bool smb1_walk_chain(const uint8_t *buf,
2195 bool (*fn)(uint8_t cmd,
2196 uint8_t wct, const uint16_t *vwv,
2197 uint16_t num_bytes, const uint8_t *bytes,
2198 void *private_data),
2201 size_t smblen = smb_len(buf);
2202 const char *smb_buf = smb_base(buf);
2203 uint8_t cmd, chain_cmd;
2205 const uint16_t *vwv;
2207 const uint8_t *bytes;
2209 cmd = CVAL(buf, smb_com);
2210 wct = CVAL(buf, smb_wct);
2211 vwv = (const uint16_t *)(buf + smb_vwv);
2212 num_bytes = smb_buflen(buf);
2213 bytes = (const uint8_t *)smb_buf_const(buf);
2215 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2219 if (!is_andx_req(cmd)) {
2226 chain_cmd = CVAL(vwv, 0);
2228 while (chain_cmd != 0xff) {
2229 uint32_t chain_offset; /* uint32_t to avoid overflow */
2230 size_t length_needed;
2231 ptrdiff_t vwv_offset;
2233 chain_offset = SVAL(vwv+1, 0);
2236 * Check if the client tries to fool us. The chain
2237 * offset needs to point beyond the current request in
2238 * the chain, it needs to strictly grow. Otherwise we
2239 * might be tricked into an endless loop always
2240 * processing the same request over and over again. We
2241 * used to assume that vwv and the byte buffer array
2242 * in a chain are always attached, but OS/2 the
2243 * Write&X/Read&X chain puts the Read&X vwv array
2244 * right behind the Write&X vwv chain. The Write&X bcc
2245 * array is put behind the Read&X vwv array. So now we
2246 * check whether the chain offset points strictly
2247 * behind the previous vwv array. req->buf points
2248 * right after the vwv array of the previous
2250 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2254 vwv_offset = ((const char *)vwv - smb_buf);
2255 if (chain_offset <= vwv_offset) {
2260 * Next check: Make sure the chain offset does not
2261 * point beyond the overall smb request length.
2264 length_needed = chain_offset+1; /* wct */
2265 if (length_needed > smblen) {
2270 * Now comes the pointer magic. Goal here is to set up
2271 * vwv and buf correctly again. The chain offset (the
2272 * former vwv[1]) points at the new wct field.
2275 wct = CVAL(smb_buf, chain_offset);
2277 if (is_andx_req(chain_cmd) && (wct < 2)) {
2282 * Next consistency check: Make the new vwv array fits
2283 * in the overall smb request.
2286 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2287 if (length_needed > smblen) {
2290 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2293 * Now grab the new byte buffer....
2296 num_bytes = SVAL(vwv+wct, 0);
2299 * .. and check that it fits.
2302 length_needed += num_bytes;
2303 if (length_needed > smblen) {
2306 bytes = (const uint8_t *)(vwv+wct+1);
2308 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2312 if (!is_andx_req(chain_cmd)) {
2315 chain_cmd = CVAL(vwv, 0);
2320 static bool smb1_chain_length_cb(uint8_t cmd,
2321 uint8_t wct, const uint16_t *vwv,
2322 uint16_t num_bytes, const uint8_t *bytes,
2325 unsigned *count = (unsigned *)private_data;
2330 unsigned smb1_chain_length(const uint8_t *buf)
2334 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2340 struct smb1_parse_chain_state {
2341 TALLOC_CTX *mem_ctx;
2343 struct smbd_server_connection *sconn;
2344 struct smbXsrv_connection *xconn;
2348 struct smb_request **reqs;
2352 static bool smb1_parse_chain_cb(uint8_t cmd,
2353 uint8_t wct, const uint16_t *vwv,
2354 uint16_t num_bytes, const uint8_t *bytes,
2357 struct smb1_parse_chain_state *state =
2358 (struct smb1_parse_chain_state *)private_data;
2359 struct smb_request **reqs;
2360 struct smb_request *req;
2363 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2364 struct smb_request *, state->num_reqs+1);
2370 req = talloc(reqs, struct smb_request);
2375 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2376 state->encrypted, state->seqnum);
2383 req->buflen = num_bytes;
2386 reqs[state->num_reqs] = req;
2387 state->num_reqs += 1;
2391 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2392 struct smbd_server_connection *sconn,
2393 bool encrypted, uint32_t seqnum,
2394 struct smb_request ***reqs, unsigned *num_reqs)
2396 struct smbXsrv_connection *xconn = sconn->conn;
2397 struct smb1_parse_chain_state state;
2400 state.mem_ctx = mem_ctx;
2402 state.sconn = sconn;
2403 state.xconn = xconn;
2404 state.encrypted = encrypted;
2405 state.seqnum = seqnum;
2409 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2410 TALLOC_FREE(state.reqs);
2413 for (i=0; i<state.num_reqs; i++) {
2414 state.reqs[i]->chain = state.reqs;
2417 *num_reqs = state.num_reqs;
2421 /****************************************************************************
2422 Check if services need reloading.
2423 ****************************************************************************/
2425 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2428 if (last_smb_conf_reload_time == 0) {
2429 last_smb_conf_reload_time = t;
2432 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2433 reload_services(sconn, conn_snum_used, true);
2434 last_smb_conf_reload_time = t;
2438 static bool fd_is_readable(int fd)
2442 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2444 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2448 static void smbd_server_connection_write_handler(
2449 struct smbd_server_connection *sconn)
2451 /* TODO: make write nonblocking */
2454 static void smbd_server_connection_read_handler(
2455 struct smbd_server_connection *sconn, int fd)
2457 struct smbXsrv_connection *xconn = sconn->conn;
2458 uint8_t *inbuf = NULL;
2459 size_t inbuf_len = 0;
2460 size_t unread_bytes = 0;
2461 bool encrypted = false;
2462 TALLOC_CTX *mem_ctx = talloc_tos();
2466 bool async_echo = lp_async_smb_echo_handler();
2467 bool from_client = false;
2470 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2472 * This is the super-ugly hack to prefer the packets
2473 * forwarded by the echo handler over the ones by the
2476 fd = xconn->smb1.echo_handler.trusted_fd;
2480 from_client = (xconn->transport.sock == fd);
2482 if (async_echo && from_client) {
2483 smbd_lock_socket(sconn);
2485 if (!fd_is_readable(fd)) {
2486 DEBUG(10,("the echo listener was faster\n"));
2487 smbd_unlock_socket(sconn);
2492 /* TODO: make this completely nonblocking */
2493 status = receive_smb_talloc(mem_ctx, sconn, fd,
2494 (char **)(void *)&inbuf,
2498 &inbuf_len, &seqnum,
2499 !from_client /* trusted channel */);
2501 if (async_echo && from_client) {
2502 smbd_unlock_socket(sconn);
2505 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2508 if (NT_STATUS_IS_ERR(status)) {
2509 exit_server_cleanly("failed to receive smb request");
2511 if (!NT_STATUS_IS_OK(status)) {
2516 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2517 seqnum, encrypted, NULL);
2520 static void smbd_server_connection_handler(struct tevent_context *ev,
2521 struct tevent_fd *fde,
2525 struct smbd_server_connection *conn = talloc_get_type(private_data,
2526 struct smbd_server_connection);
2527 struct smbXsrv_connection *xconn = conn->conn;
2529 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2531 * we're not supposed to do any io
2533 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2534 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2538 if (flags & TEVENT_FD_WRITE) {
2539 smbd_server_connection_write_handler(conn);
2542 if (flags & TEVENT_FD_READ) {
2543 smbd_server_connection_read_handler(conn, xconn->transport.sock);
2548 static void smbd_server_echo_handler(struct tevent_context *ev,
2549 struct tevent_fd *fde,
2553 struct smbd_server_connection *conn = talloc_get_type(private_data,
2554 struct smbd_server_connection);
2555 struct smbXsrv_connection *xconn = conn->conn;
2557 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2559 * we're not supposed to do any io
2561 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2562 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2566 if (flags & TEVENT_FD_WRITE) {
2567 smbd_server_connection_write_handler(conn);
2570 if (flags & TEVENT_FD_READ) {
2571 smbd_server_connection_read_handler(
2572 conn, xconn->smb1.echo_handler.trusted_fd);
2577 struct smbd_release_ip_state {
2578 struct smbd_server_connection *sconn;
2579 struct tevent_immediate *im;
2580 char addr[INET6_ADDRSTRLEN];
2583 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2584 struct tevent_immediate *im,
2587 struct smbd_release_ip_state *state =
2588 talloc_get_type_abort(private_data,
2589 struct smbd_release_ip_state);
2590 struct smbXsrv_connection *xconn = state->sconn->conn;
2592 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2594 * smbd_server_connection_terminate() already triggered ?
2599 smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
2602 /****************************************************************************
2603 received when we should release a specific IP
2604 ****************************************************************************/
2605 static bool release_ip(const char *ip, void *priv)
2607 struct smbd_release_ip_state *state =
2608 talloc_get_type_abort(priv,
2609 struct smbd_release_ip_state);
2610 struct smbXsrv_connection *xconn = state->sconn->conn;
2611 const char *addr = state->addr;
2612 const char *p = addr;
2614 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2615 /* avoid recursion */
2619 if (strncmp("::ffff:", addr, 7) == 0) {
2623 DEBUG(10, ("Got release IP message for %s, "
2624 "our address is %s\n", ip, p));
2626 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2627 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2630 * With SMB2 we should do a clean disconnect,
2631 * the previous_session_id in the session setup
2632 * will cleanup the old session, tcons and opens.
2634 * A clean disconnect is needed in order to support
2637 * Note: typically this is never triggered
2638 * as we got a TCP RST (triggered by ctdb event scripts)
2639 * before we get CTDB_SRVID_RELEASE_IP.
2641 * We used to call _exit(1) here, but as this was mostly never
2642 * triggered and has implication on our process model,
2643 * we can just use smbd_server_connection_terminate()
2646 * We don't call smbd_server_connection_terminate() directly
2647 * as we might be called from within ctdbd_migrate(),
2648 * we need to defer our action to the next event loop
2650 tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
2651 smbd_release_ip_immediate, state);
2654 * Make sure we don't get any io on the connection.
2656 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2663 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2664 struct sockaddr_storage *srv,
2665 struct sockaddr_storage *clnt)
2667 struct smbd_release_ip_state *state;
2668 struct ctdbd_connection *cconn;
2670 cconn = messaging_ctdbd_connection();
2671 if (cconn == NULL) {
2672 return NT_STATUS_NO_MEMORY;
2675 state = talloc_zero(sconn, struct smbd_release_ip_state);
2676 if (state == NULL) {
2677 return NT_STATUS_NO_MEMORY;
2679 state->sconn = sconn;
2680 state->im = tevent_create_immediate(state);
2681 if (state->im == NULL) {
2682 return NT_STATUS_NO_MEMORY;
2684 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2685 return NT_STATUS_NO_MEMORY;
2688 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2691 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2692 void *private_data, uint32_t msg_type,
2693 struct server_id server_id, DATA_BLOB *data)
2695 struct smbd_server_connection *sconn = talloc_get_type_abort(
2696 private_data, struct smbd_server_connection);
2697 const char *ip = (char *) data->data;
2700 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2702 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2704 if (client_ip == NULL) {
2708 if (strequal(ip, client_ip)) {
2709 DEBUG(1, ("Got kill client message for %s - "
2710 "exiting immediately\n", ip));
2711 exit_server_cleanly("Forced disconnect for client");
2714 TALLOC_FREE(client_ip);
2718 * Send keepalive packets to our client
2720 static bool keepalive_fn(const struct timeval *now, void *private_data)
2722 struct smbd_server_connection *sconn = talloc_get_type_abort(
2723 private_data, struct smbd_server_connection);
2724 struct smbXsrv_connection *xconn = sconn->conn;
2727 if (sconn->using_smb2) {
2728 /* Don't do keepalives on an SMB2 connection. */
2732 smbd_lock_socket(sconn);
2733 ret = send_keepalive(xconn->transport.sock);
2734 smbd_unlock_socket(sconn);
2737 int saved_errno = errno;
2739 * Try and give an error message saying what
2742 DEBUG(0, ("send_keepalive failed for client %s. "
2743 "Error %s - exiting\n",
2744 smbXsrv_connection_dbg(xconn),
2745 strerror(saved_errno)));
2746 errno = saved_errno;
2753 * Do the recurring check if we're idle
2755 static bool deadtime_fn(const struct timeval *now, void *private_data)
2757 struct smbd_server_connection *sconn =
2758 (struct smbd_server_connection *)private_data;
2760 if ((conn_num_open(sconn) == 0)
2761 || (conn_idle_all(sconn, now->tv_sec))) {
2762 DEBUG( 2, ( "Closing idle connection\n" ) );
2763 messaging_send(sconn->msg_ctx,
2764 messaging_server_id(sconn->msg_ctx),
2765 MSG_SHUTDOWN, &data_blob_null);
2773 * Do the recurring log file and smb.conf reload checks.
2776 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2778 struct smbd_server_connection *sconn = talloc_get_type_abort(
2779 private_data, struct smbd_server_connection);
2781 DEBUG(5, ("housekeeping\n"));
2783 change_to_root_user();
2785 /* update printer queue caches if necessary */
2786 update_monitored_printq_cache(sconn->msg_ctx);
2788 /* check if we need to reload services */
2789 check_reload(sconn, time_mono(NULL));
2792 * Force a log file check.
2794 force_check_log_size();
2800 * Read an smb packet in the echo handler child, giving the parent
2801 * smbd one second to react once the socket becomes readable.
2804 struct smbd_echo_read_state {
2805 struct tevent_context *ev;
2806 struct smbd_server_connection *sconn;
2813 static void smbd_echo_read_readable(struct tevent_req *subreq);
2814 static void smbd_echo_read_waited(struct tevent_req *subreq);
2816 static struct tevent_req *smbd_echo_read_send(
2817 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2818 struct smbd_server_connection *sconn)
2820 struct tevent_req *req, *subreq;
2821 struct smbd_echo_read_state *state;
2822 struct smbXsrv_connection *xconn = sconn->conn;
2824 req = tevent_req_create(mem_ctx, &state,
2825 struct smbd_echo_read_state);
2830 state->sconn = sconn;
2832 subreq = wait_for_read_send(state, ev, xconn->transport.sock);
2833 if (tevent_req_nomem(subreq, req)) {
2834 return tevent_req_post(req, ev);
2836 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2840 static void smbd_echo_read_readable(struct tevent_req *subreq)
2842 struct tevent_req *req = tevent_req_callback_data(
2843 subreq, struct tevent_req);
2844 struct smbd_echo_read_state *state = tevent_req_data(
2845 req, struct smbd_echo_read_state);
2849 ok = wait_for_read_recv(subreq, &err);
2850 TALLOC_FREE(subreq);
2852 tevent_req_nterror(req, map_nt_error_from_unix(err));
2857 * Give the parent smbd one second to step in
2860 subreq = tevent_wakeup_send(
2861 state, state->ev, timeval_current_ofs(1, 0));
2862 if (tevent_req_nomem(subreq, req)) {
2865 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2868 static void smbd_echo_read_waited(struct tevent_req *subreq)
2870 struct tevent_req *req = tevent_req_callback_data(
2871 subreq, struct tevent_req);
2872 struct smbd_echo_read_state *state = tevent_req_data(
2873 req, struct smbd_echo_read_state);
2874 struct smbd_server_connection *sconn = state->sconn;
2875 struct smbXsrv_connection *xconn = sconn->conn;
2881 ok = tevent_wakeup_recv(subreq);
2882 TALLOC_FREE(subreq);
2884 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2888 ok = smbd_lock_socket_internal(sconn);
2890 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2891 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2895 if (!fd_is_readable(xconn->transport.sock)) {
2896 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2899 ok = smbd_unlock_socket_internal(sconn);
2901 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2902 DEBUG(1, ("%s: failed to unlock socket\n",
2907 subreq = wait_for_read_send(state, state->ev,
2908 xconn->transport.sock);
2909 if (tevent_req_nomem(subreq, req)) {
2912 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2916 status = receive_smb_talloc(state, sconn,
2917 xconn->transport.sock,
2924 false /* trusted_channel*/);
2926 if (tevent_req_nterror(req, status)) {
2927 tevent_req_nterror(req, status);
2928 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2929 (int)getpid(), nt_errstr(status)));
2933 ok = smbd_unlock_socket_internal(sconn);
2935 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2936 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2939 tevent_req_done(req);
2942 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2943 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2945 struct smbd_echo_read_state *state = tevent_req_data(
2946 req, struct smbd_echo_read_state);
2949 if (tevent_req_is_nterror(req, &status)) {
2952 *pbuf = talloc_move(mem_ctx, &state->buf);
2953 *pbuflen = state->buflen;
2954 *pseqnum = state->seqnum;
2955 return NT_STATUS_OK;
2958 struct smbd_echo_state {
2959 struct tevent_context *ev;
2960 struct iovec *pending;
2961 struct smbd_server_connection *sconn;
2962 struct smbXsrv_connection *xconn;
2965 struct tevent_fd *parent_fde;
2967 struct tevent_req *write_req;
2970 static void smbd_echo_writer_done(struct tevent_req *req);
2972 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2976 if (state->write_req != NULL) {
2980 num_pending = talloc_array_length(state->pending);
2981 if (num_pending == 0) {
2985 state->write_req = writev_send(state, state->ev, NULL,
2986 state->parent_pipe, false,
2987 state->pending, num_pending);
2988 if (state->write_req == NULL) {
2989 DEBUG(1, ("writev_send failed\n"));
2993 talloc_steal(state->write_req, state->pending);
2994 state->pending = NULL;
2996 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3000 static void smbd_echo_writer_done(struct tevent_req *req)
3002 struct smbd_echo_state *state = tevent_req_callback_data(
3003 req, struct smbd_echo_state);
3007 written = writev_recv(req, &err);
3009 state->write_req = NULL;
3010 if (written == -1) {
3011 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3014 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3015 smbd_echo_activate_writer(state);
3018 static bool smbd_echo_reply(struct smbd_echo_state *state,
3019 uint8_t *inbuf, size_t inbuf_len,
3022 struct smb_request req;
3023 uint16_t num_replies;
3027 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3028 DEBUG(10, ("Got netbios keepalive\n"));
3035 if (inbuf_len < smb_size) {
3036 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3039 if (!valid_smb_header(state->sconn, inbuf)) {
3040 DEBUG(10, ("Got invalid SMB header\n"));
3044 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3050 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3051 smb_messages[req.cmd].name
3052 ? smb_messages[req.cmd].name : "unknown"));
3054 if (req.cmd != SMBecho) {
3061 num_replies = SVAL(req.vwv+0, 0);
3062 if (num_replies != 1) {
3063 /* Not a Windows "Hey, you're still there?" request */
3067 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3069 DEBUG(10, ("create_outbuf failed\n"));
3072 req.outbuf = (uint8_t *)outbuf;
3074 SSVAL(req.outbuf, smb_vwv0, num_replies);
3076 if (req.buflen > 0) {
3077 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3080 ok = srv_send_smb(req.sconn,
3084 TALLOC_FREE(outbuf);
3092 static void smbd_echo_exit(struct tevent_context *ev,
3093 struct tevent_fd *fde, uint16_t flags,
3096 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3100 static void smbd_echo_got_packet(struct tevent_req *req);
3102 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3105 struct smbXsrv_connection *xconn = sconn->conn;
3106 struct smbd_echo_state *state;
3107 struct tevent_req *read_req;
3109 state = talloc_zero(sconn, struct smbd_echo_state);
3110 if (state == NULL) {
3111 DEBUG(1, ("talloc failed\n"));
3114 state->sconn = sconn;
3115 state->xconn = xconn;
3116 state->parent_pipe = parent_pipe;
3117 state->ev = s3_tevent_context_init(state);
3118 if (state->ev == NULL) {
3119 DEBUG(1, ("tevent_context_init failed\n"));
3123 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3124 TEVENT_FD_READ, smbd_echo_exit,
3126 if (state->parent_fde == NULL) {
3127 DEBUG(1, ("tevent_add_fd failed\n"));
3132 read_req = smbd_echo_read_send(state, state->ev, sconn);
3133 if (read_req == NULL) {
3134 DEBUG(1, ("smbd_echo_read_send failed\n"));
3138 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3141 if (tevent_loop_once(state->ev) == -1) {
3142 DEBUG(1, ("tevent_loop_once failed: %s\n",
3150 static void smbd_echo_got_packet(struct tevent_req *req)
3152 struct smbd_echo_state *state = tevent_req_callback_data(
3153 req, struct smbd_echo_state);
3157 uint32_t seqnum = 0;
3160 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3162 if (!NT_STATUS_IS_OK(status)) {
3163 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3164 nt_errstr(status)));
3168 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3174 num_pending = talloc_array_length(state->pending);
3175 tmp = talloc_realloc(state, state->pending, struct iovec,
3178 DEBUG(1, ("talloc_realloc failed\n"));
3181 state->pending = tmp;
3183 if (buflen >= smb_size) {
3185 * place the seqnum in the packet so that the main process
3186 * can reply with signing
3188 SIVAL(buf, smb_ss_field, seqnum);
3189 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3192 iov = &state->pending[num_pending];
3193 iov->iov_base = talloc_move(state->pending, &buf);
3194 iov->iov_len = buflen;
3196 DEBUG(10,("echo_handler[%d]: forward to main\n",
3198 smbd_echo_activate_writer(state);
3201 req = smbd_echo_read_send(state, state->ev, state->sconn);
3203 DEBUG(1, ("smbd_echo_read_send failed\n"));
3206 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3211 * Handle SMBecho requests in a forked child process
3213 bool fork_echo_handler(struct smbd_server_connection *sconn)
3215 struct smbXsrv_connection *xconn = sconn->conn;
3216 int listener_pipe[2];
3219 bool use_mutex = false;
3221 res = pipe(listener_pipe);
3223 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3227 #ifdef HAVE_ROBUST_MUTEXES
3228 use_mutex = tdb_runtime_check_for_robust_mutexes();
3231 pthread_mutexattr_t a;
3233 xconn->smb1.echo_handler.socket_mutex =
3234 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3235 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3236 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3241 res = pthread_mutexattr_init(&a);
3243 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3247 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3249 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3251 pthread_mutexattr_destroy(&a);
3254 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3256 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3258 pthread_mutexattr_destroy(&a);
3261 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3263 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3264 "%s\n", strerror(res)));
3265 pthread_mutexattr_destroy(&a);
3268 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3270 pthread_mutexattr_destroy(&a);
3272 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3280 xconn->smb1.echo_handler.socket_lock_fd =
3281 create_unlink_tmp(lp_lock_directory());
3282 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3283 DEBUG(1, ("Could not create lock fd: %s\n",
3293 close(listener_pipe[0]);
3294 set_blocking(listener_pipe[1], false);
3296 status = reinit_after_fork(sconn->msg_ctx,
3299 if (!NT_STATUS_IS_OK(status)) {
3300 DEBUG(1, ("reinit_after_fork failed: %s\n",
3301 nt_errstr(status)));
3304 smbd_echo_loop(sconn, listener_pipe[1]);
3307 close(listener_pipe[1]);
3308 listener_pipe[1] = -1;
3309 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3311 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3314 * Without smb signing this is the same as the normal smbd
3315 * listener. This needs to change once signing comes in.
3317 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3319 xconn->smb1.echo_handler.trusted_fd,
3321 smbd_server_echo_handler,
3323 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3324 DEBUG(1, ("event_add_fd failed\n"));
3331 if (listener_pipe[0] != -1) {
3332 close(listener_pipe[0]);
3334 if (listener_pipe[1] != -1) {
3335 close(listener_pipe[1]);
3337 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3338 close(xconn->smb1.echo_handler.socket_lock_fd);
3340 #ifdef HAVE_ROBUST_MUTEXES
3341 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3342 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3343 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3346 smbd_echo_init(xconn);
3351 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3354 if (user->session_info &&
3355 (user->session_info->unix_token->uid == uid)) {
3363 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3366 if (user->session_info != NULL) {
3368 struct security_unix_token *utok;
3370 utok = user->session_info->unix_token;
3371 if (utok->gid == gid) {
3374 for(i=0; i<utok->ngroups; i++) {
3375 if (utok->groups[i] == gid) {
3385 static bool sid_in_use(const struct user_struct *user,
3386 const struct dom_sid *psid)
3389 struct security_token *tok;
3391 if (user->session_info == NULL) {
3394 tok = user->session_info->security_token;
3397 * Not sure session_info->security_token can
3398 * ever be NULL. This check might be not
3403 if (security_token_has_sid(tok, psid)) {
3411 static bool id_in_use(const struct user_struct *user,
3412 const struct id_cache_ref *id)
3416 return uid_in_use(user, id->id.uid);
3418 return gid_in_use(user, id->id.gid);
3420 return sid_in_use(user, &id->id.sid);
3427 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3430 struct server_id server_id,
3433 const char *msg = (data && data->data)
3434 ? (const char *)data->data : "<NULL>";
3435 struct id_cache_ref id;
3436 struct smbd_server_connection *sconn =
3437 talloc_get_type_abort(private_data,
3438 struct smbd_server_connection);
3440 if (!id_cache_ref_parse(msg, &id)) {
3441 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3445 if (id_in_use(sconn->users, &id)) {
3446 exit_server_cleanly(msg);
3448 id_cache_delete_from_cache(&id);
3451 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3452 enum protocol_types protocol)
3456 set_Protocol(protocol);
3457 conn->protocol = protocol;
3459 if (protocol >= PROTOCOL_SMB2_02) {
3460 status = smb2srv_session_table_init(conn);
3461 if (!NT_STATUS_IS_OK(status)) {
3465 status = smb2srv_open_table_init(conn);
3466 if (!NT_STATUS_IS_OK(status)) {
3470 status = smb1srv_session_table_init(conn);
3471 if (!NT_STATUS_IS_OK(status)) {
3475 status = smb1srv_tcon_table_init(conn);
3476 if (!NT_STATUS_IS_OK(status)) {
3480 status = smb1srv_open_table_init(conn);
3481 if (!NT_STATUS_IS_OK(status)) {
3486 return NT_STATUS_OK;
3489 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3492 struct smbXsrv_connection *conn =
3493 talloc_get_type_abort(private_data,
3494 struct smbXsrv_connection);
3497 case TEVENT_TRACE_BEFORE_WAIT:
3499 * This just removes compiler warning
3500 * without profile support
3502 conn->smbd_idle_profstamp = 0;
3503 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3505 case TEVENT_TRACE_AFTER_WAIT:
3506 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3508 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3509 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3510 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3517 * Create a debug string for the connection
3519 * This is allocated to talloc_tos() or a string constant
3520 * in certain corner cases. The returned string should
3521 * hence not be free'd directly but only via the talloc stack.
3523 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3528 * TODO: this can be improved later
3529 * maybe including the client guid or more
3531 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3533 return "<tsocket_address_string() failed>";
3539 /****************************************************************************
3540 Process commands from the client
3541 ****************************************************************************/
3543 void smbd_process(struct tevent_context *ev_ctx,
3544 struct messaging_context *msg_ctx,
3548 TALLOC_CTX *frame = talloc_stackframe();
3549 struct smbXsrv_connection *xconn;
3550 struct smbd_server_connection *sconn;
3551 struct sockaddr_storage ss_srv;
3552 void *sp_srv = (void *)&ss_srv;
3553 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3554 struct sockaddr_storage ss_clnt;
3555 void *sp_clnt = (void *)&ss_clnt;
3556 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3557 socklen_t sa_socklen;
3558 struct tsocket_address *local_address = NULL;
3559 struct tsocket_address *remote_address = NULL;
3560 const char *locaddr = NULL;
3561 const char *remaddr = NULL;
3566 xconn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3567 if (xconn == NULL) {
3568 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3569 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3572 xconn->ev_ctx = ev_ctx;
3573 xconn->msg_ctx = msg_ctx;
3574 xconn->transport.sock = sock_fd;
3575 smbd_echo_init(xconn);
3577 sconn = talloc_zero(xconn, struct smbd_server_connection);
3579 exit_server("failed to create smbd_server_connection");
3582 xconn->sconn = sconn;
3583 sconn->conn = xconn;
3586 * TODO: remove this...:-)
3588 global_smbXsrv_connection = xconn;
3590 sconn->ev_ctx = ev_ctx;
3591 sconn->msg_ctx = msg_ctx;
3594 smbd_setup_sig_term_handler(sconn);
3595 smbd_setup_sig_hup_handler(sconn);
3597 if (!serverid_register(messaging_server_id(msg_ctx),
3598 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3600 |FLAG_MSG_PRINT_GENERAL)) {
3601 exit_server_cleanly("Could not register myself in "
3606 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3608 * We're not making the decision here,
3609 * we're just allowing the client
3610 * to decide between SMB1 and SMB2
3611 * with the first negprot
3614 sconn->using_smb2 = true;
3617 /* Ensure child is set to blocking mode */
3618 set_blocking(sock_fd,True);
3620 set_socket_options(sock_fd, "SO_KEEPALIVE");
3621 set_socket_options(sock_fd, lp_socket_options());
3623 sa_socklen = sizeof(ss_clnt);
3624 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3626 int level = (errno == ENOTCONN)?2:0;
3627 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3628 exit_server_cleanly("getpeername() failed.\n");
3630 ret = tsocket_address_bsd_from_sockaddr(sconn,
3631 sa_clnt, sa_socklen,
3634 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3635 __location__, strerror(errno)));
3636 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3639 sa_socklen = sizeof(ss_srv);
3640 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3642 int level = (errno == ENOTCONN)?2:0;
3643 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3644 exit_server_cleanly("getsockname() failed.\n");
3646 ret = tsocket_address_bsd_from_sockaddr(sconn,
3650 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3651 __location__, strerror(errno)));
3652 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3655 sconn->local_address = local_address;
3656 sconn->remote_address = remote_address;
3658 if (tsocket_address_is_inet(local_address, "ip")) {
3659 locaddr = tsocket_address_inet_addr_string(
3660 sconn->local_address,
3662 if (locaddr == NULL) {
3663 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3664 __location__, strerror(errno)));
3665 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3668 locaddr = "0.0.0.0";
3671 if (tsocket_address_is_inet(remote_address, "ip")) {
3672 remaddr = tsocket_address_inet_addr_string(
3673 sconn->remote_address,
3675 if (remaddr == NULL) {
3676 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3677 __location__, strerror(errno)));
3678 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3681 remaddr = "0.0.0.0";
3684 /* this is needed so that we get decent entries
3685 in smbstatus for port 445 connects */
3686 set_remote_machine_name(remaddr, false);
3687 reload_services(sconn, conn_snum_used, true);
3690 * Before the first packet, check the global hosts allow/ hosts deny
3691 * parameters before doing any parsing of packets passed to us by the
3692 * client. This prevents attacks on our parsing code from hosts not in
3693 * the hosts allow list.
3696 ret = get_remote_hostname(remote_address,
3700 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3701 __location__, strerror(errno)));
3702 exit_server_cleanly("get_remote_hostname failed.\n");
3704 if (strequal(rhost, "UNKNOWN")) {
3705 rhost = talloc_strdup(talloc_tos(), remaddr);
3707 sconn->remote_hostname = talloc_move(sconn, &rhost);
3709 sub_set_socket_ids(remaddr,
3710 sconn->remote_hostname,
3713 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3714 sconn->remote_hostname,
3717 * send a negative session response "not listening on calling
3720 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3721 DEBUG( 1, ("Connection denied from %s to %s\n",
3722 tsocket_address_string(remote_address, talloc_tos()),
3723 tsocket_address_string(local_address, talloc_tos())));
3724 (void)srv_send_smb(sconn,(char *)buf, false,
3726 exit_server_cleanly("connection denied");
3729 DEBUG(10, ("Connection allowed from %s to %s\n",
3730 tsocket_address_string(remote_address, talloc_tos()),
3731 tsocket_address_string(local_address, talloc_tos())));
3733 if (lp_preload_modules()) {
3734 smb_load_modules(lp_preload_modules());
3737 smb_perfcount_init();
3739 if (!init_account_policy()) {
3740 exit_server("Could not open account policy tdb.\n");
3743 if (*lp_root_directory(talloc_tos())) {
3744 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3745 DEBUG(0,("Failed to change root to %s\n",
3746 lp_root_directory(talloc_tos())));
3747 exit_server("Failed to chroot()");
3749 if (chdir("/") == -1) {
3750 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3751 exit_server("Failed to chroot()");
3753 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3756 if (!srv_init_signing(xconn)) {
3757 exit_server("Failed to init smb_signing");
3760 if (!file_init(sconn)) {
3761 exit_server("file_init() failed");
3765 if (!init_oplocks(sconn))
3766 exit_server("Failed to init oplocks");
3768 /* register our message handlers */
3769 messaging_register(sconn->msg_ctx, sconn,
3770 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3771 messaging_register(sconn->msg_ctx, sconn,
3772 MSG_SMB_CLOSE_FILE, msg_close_file);
3773 messaging_register(sconn->msg_ctx, sconn,
3774 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3776 id_cache_register_msgs(sconn->msg_ctx);
3777 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3778 messaging_register(sconn->msg_ctx, sconn,
3779 ID_CACHE_KILL, smbd_id_cache_kill);
3781 messaging_deregister(sconn->msg_ctx,
3782 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3783 messaging_register(sconn->msg_ctx, sconn,
3784 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3786 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3788 messaging_register(sconn->msg_ctx, sconn,
3789 MSG_SMB_KILL_CLIENT_IP,
3790 msg_kill_client_ip);
3792 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3795 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3796 * MSGs to all child processes
3798 messaging_deregister(sconn->msg_ctx,
3800 messaging_register(sconn->msg_ctx, NULL,
3801 MSG_DEBUG, debug_message);
3803 if ((lp_keepalive() != 0)
3804 && !(event_add_idle(ev_ctx, NULL,
3805 timeval_set(lp_keepalive(), 0),
3806 "keepalive", keepalive_fn,
3808 DEBUG(0, ("Could not add keepalive event\n"));
3812 if (!(event_add_idle(ev_ctx, NULL,
3813 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3814 "deadtime", deadtime_fn, sconn))) {
3815 DEBUG(0, ("Could not add deadtime event\n"));
3819 if (!(event_add_idle(ev_ctx, NULL,
3820 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3821 "housekeeping", housekeeping_fn, sconn))) {
3822 DEBUG(0, ("Could not add housekeeping event\n"));
3826 if (lp_clustering()) {
3828 * We need to tell ctdb about our client's TCP
3829 * connection, so that for failover ctdbd can send
3830 * tickle acks, triggering a reconnection by the
3835 status = smbd_register_ips(sconn, &ss_srv, &ss_clnt);
3836 if (!NT_STATUS_IS_OK(status)) {
3837 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3838 nt_errstr(status)));
3842 tmp = lp_max_xmit();
3843 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3844 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3846 xconn->smb1.negprot.max_recv = tmp;
3848 xconn->smb1.sessions.done_sesssetup = false;
3849 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3851 if (!init_dptrs(sconn)) {
3852 exit_server("init_dptrs() failed");
3855 xconn->transport.fde = tevent_add_fd(ev_ctx,
3859 smbd_server_connection_handler,
3861 if (!xconn->transport.fde) {
3862 exit_server("failed to create smbd_server_connection fde");
3865 sconn->conn->local_address = sconn->local_address;
3866 sconn->conn->remote_address = sconn->remote_address;
3867 sconn->conn->remote_hostname = sconn->remote_hostname;
3868 sconn->conn->protocol = PROTOCOL_NONE;
3872 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, xconn);
3875 frame = talloc_stackframe_pool(8192);
3878 if (tevent_loop_once(ev_ctx) == -1) {
3879 if (errno != EINTR) {
3880 DEBUG(3, ("tevent_loop_once failed: %s,"
3881 " exiting\n", strerror(errno) ));
3889 exit_server_cleanly(NULL);
3892 bool req_is_in_chain(const struct smb_request *req)
3894 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3896 * We're right now handling a subsequent request, so we must
3902 if (!is_andx_req(req->cmd)) {
3908 * Okay, an illegal request, but definitely not chained :-)
3913 return (CVAL(req->vwv+0, 0) != 0xFF);