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"
40 extern bool global_machine_password_needs_changing;
42 /* Internal message queue for deferred opens. */
43 struct pending_message_list {
44 struct pending_message_list *next, *prev;
45 struct timeval request_time; /* When was this first issued? */
46 struct smbd_server_connection *sconn;
47 struct timed_event *te;
48 struct smb_perfcount_data pcd;
53 DATA_BLOB private_data;
56 static void construct_reply_common(struct smb_request *req, const char *inbuf,
58 static struct pending_message_list *get_deferred_open_message_smb(
59 struct smbd_server_connection *sconn, uint64_t mid);
61 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
65 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
69 sconn->smb1.echo_handler.ref_count++;
71 if (sconn->smb1.echo_handler.ref_count > 1) {
75 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
79 sconn->smb1.echo_handler.socket_lock_fd,
80 SMB_F_SETLKW, 0, 0, F_WRLCK);
81 } while (!ok && (errno == EINTR));
84 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
88 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
93 void smbd_lock_socket(struct smbd_server_connection *sconn)
95 if (!smbd_lock_socket_internal(sconn)) {
96 exit_server_cleanly("failed to lock socket");
100 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
104 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
108 sconn->smb1.echo_handler.ref_count--;
110 if (sconn->smb1.echo_handler.ref_count > 0) {
116 sconn->smb1.echo_handler.socket_lock_fd,
117 SMB_F_SETLKW, 0, 0, F_UNLCK);
118 } while (!ok && (errno == EINTR));
121 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
125 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
130 void smbd_unlock_socket(struct smbd_server_connection *sconn)
132 if (!smbd_unlock_socket_internal(sconn)) {
133 exit_server_cleanly("failed to unlock socket");
137 /* Accessor function for smb_read_error for smbd functions. */
139 /****************************************************************************
141 ****************************************************************************/
143 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
144 bool do_signing, uint32_t seqnum,
146 struct smb_perfcount_data *pcd)
151 char *buf_out = buffer;
153 smbd_lock_socket(sconn);
156 /* Sign the outgoing packet if required. */
157 srv_calculate_sign_mac(sconn, buf_out, seqnum);
161 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
162 if (!NT_STATUS_IS_OK(status)) {
163 DEBUG(0, ("send_smb: SMB encryption failed "
164 "on outgoing packet! Error %s\n",
165 nt_errstr(status) ));
170 len = smb_len(buf_out) + 4;
172 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
175 char addr[INET6_ADDRSTRLEN];
177 * Try and give an error message saying what
180 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
181 (int)sys_getpid(), (int)len,
182 get_peer_addr(sconn->sock, addr, sizeof(addr)),
183 (int)ret, strerror(errno) ));
185 srv_free_enc_buffer(sconn, buf_out);
189 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
190 srv_free_enc_buffer(sconn, buf_out);
192 SMB_PERFCOUNT_END(pcd);
194 smbd_unlock_socket(sconn);
198 /*******************************************************************
199 Setup the word count and byte count for a smb message.
200 ********************************************************************/
202 int srv_set_message(char *buf,
207 if (zero && (num_words || num_bytes)) {
208 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
210 SCVAL(buf,smb_wct,num_words);
211 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
212 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
213 return (smb_size + num_words*2 + num_bytes);
216 static bool valid_smb_header(struct smbd_server_connection *sconn,
217 const uint8_t *inbuf)
219 if (is_encrypted_packet(sconn, inbuf)) {
223 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
224 * but it just looks weird to call strncmp for this one.
226 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
229 /* Socket functions for smbd packet processing. */
231 static bool valid_packet_size(size_t len)
234 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
235 * of header. Don't print the error if this fits.... JRA.
238 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
239 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
240 (unsigned long)len));
246 static NTSTATUS read_packet_remainder(int fd, char *buffer,
247 unsigned int timeout, ssize_t len)
255 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
256 if (!NT_STATUS_IS_OK(status)) {
257 char addr[INET6_ADDRSTRLEN];
258 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
260 get_peer_addr(fd, addr, sizeof(addr)),
266 /****************************************************************************
267 Attempt a zerocopy writeX read. We know here that len > smb_size-4
268 ****************************************************************************/
271 * Unfortunately, earlier versions of smbclient/libsmbclient
272 * don't send this "standard" writeX header. I've fixed this
273 * for 3.2 but we'll use the old method with earlier versions.
274 * Windows and CIFSFS at least use this standard size. Not
278 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
279 (2*14) + /* word count (including bcc) */ \
282 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
283 const char lenbuf[4],
284 struct smbd_server_connection *sconn,
287 unsigned int timeout,
291 /* Size of a WRITEX call (+4 byte len). */
292 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
293 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
297 memcpy(writeX_header, lenbuf, 4);
299 status = read_fd_with_timeout(
300 sock, writeX_header + 4,
301 STANDARD_WRITE_AND_X_HEADER_SIZE,
302 STANDARD_WRITE_AND_X_HEADER_SIZE,
305 if (!NT_STATUS_IS_OK(status)) {
306 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
308 tsocket_address_string(sconn->remote_address,
315 * Ok - now try and see if this is a possible
319 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
321 * If the data offset is beyond what
322 * we've read, drain the extra bytes.
324 uint16_t doff = SVAL(writeX_header,smb_vwv11);
327 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
328 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
329 if (drain_socket(sock, drain) != drain) {
330 smb_panic("receive_smb_raw_talloc_partial_read:"
331 " failed to drain pending bytes");
334 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
337 /* Spoof down the length and null out the bcc. */
338 set_message_bcc(writeX_header, 0);
339 newlen = smb_len(writeX_header);
341 /* Copy the header we've written. */
343 *buffer = (char *)talloc_memdup(mem_ctx,
345 sizeof(writeX_header));
347 if (*buffer == NULL) {
348 DEBUG(0, ("Could not allocate inbuf of length %d\n",
349 (int)sizeof(writeX_header)));
350 return NT_STATUS_NO_MEMORY;
353 /* Work out the remaining bytes. */
354 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
355 *len_ret = newlen + 4;
359 if (!valid_packet_size(len)) {
360 return NT_STATUS_INVALID_PARAMETER;
364 * Not a valid writeX call. Just do the standard
368 *buffer = talloc_array(mem_ctx, char, len+4);
370 if (*buffer == NULL) {
371 DEBUG(0, ("Could not allocate inbuf of length %d\n",
373 return NT_STATUS_NO_MEMORY;
376 /* Copy in what we already read. */
379 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
380 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
383 status = read_packet_remainder(
385 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
388 if (!NT_STATUS_IS_OK(status)) {
389 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
399 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
400 struct smbd_server_connection *sconn,
402 char **buffer, unsigned int timeout,
403 size_t *p_unread, size_t *plen)
407 int min_recv_size = lp_min_receive_file_size();
412 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
414 if (!NT_STATUS_IS_OK(status)) {
418 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
419 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
420 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
421 !srv_is_signing_active(sconn) &&
422 sconn->smb1.echo_handler.trusted_fde == NULL) {
424 return receive_smb_raw_talloc_partial_read(
425 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
429 if (!valid_packet_size(len)) {
430 return NT_STATUS_INVALID_PARAMETER;
434 * The +4 here can't wrap, we've checked the length above already.
437 *buffer = talloc_array(mem_ctx, char, len+4);
439 if (*buffer == NULL) {
440 DEBUG(0, ("Could not allocate inbuf of length %d\n",
442 return NT_STATUS_NO_MEMORY;
445 memcpy(*buffer, lenbuf, sizeof(lenbuf));
447 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
448 if (!NT_STATUS_IS_OK(status)) {
456 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
457 struct smbd_server_connection *sconn,
459 char **buffer, unsigned int timeout,
460 size_t *p_unread, bool *p_encrypted,
463 bool trusted_channel)
468 *p_encrypted = false;
470 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
472 if (!NT_STATUS_IS_OK(status)) {
473 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
474 ("receive_smb_raw_talloc failed for client %s "
475 "read error = %s.\n",
476 tsocket_address_string(sconn->remote_address,
478 nt_errstr(status)) );
482 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
483 status = srv_decrypt_buffer(sconn, *buffer);
484 if (!NT_STATUS_IS_OK(status)) {
485 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
486 "incoming packet! Error %s\n",
487 nt_errstr(status) ));
493 /* Check the incoming SMB signature. */
494 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
495 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
496 "incoming packet!\n"));
497 return NT_STATUS_INVALID_NETWORK_RESPONSE;
505 * Initialize a struct smb_request from an inbuf
508 static bool init_smb_request(struct smb_request *req,
509 struct smbd_server_connection *sconn,
511 size_t unread_bytes, bool encrypted,
514 size_t req_size = smb_len(inbuf) + 4;
515 /* Ensure we have at least smb_size bytes. */
516 if (req_size < smb_size) {
517 DEBUG(0,("init_smb_request: invalid request size %u\n",
518 (unsigned int)req_size ));
521 req->cmd = CVAL(inbuf, smb_com);
522 req->flags2 = SVAL(inbuf, smb_flg2);
523 req->smbpid = SVAL(inbuf, smb_pid);
524 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
525 req->seqnum = seqnum;
526 req->vuid = SVAL(inbuf, smb_uid);
527 req->tid = SVAL(inbuf, smb_tid);
528 req->wct = CVAL(inbuf, smb_wct);
529 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
530 req->buflen = smb_buflen(inbuf);
531 req->buf = (const uint8_t *)smb_buf_const(inbuf);
532 req->unread_bytes = unread_bytes;
533 req->encrypted = encrypted;
535 req->conn = conn_find(sconn,req->tid);
536 req->chain_fsp = NULL;
537 req->chain_outbuf = NULL;
540 smb_init_perfcount_data(&req->pcd);
542 /* Ensure we have at least wct words and 2 bytes of bcc. */
543 if (smb_size + req->wct*2 > req_size) {
544 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
545 (unsigned int)req->wct,
546 (unsigned int)req_size));
549 /* Ensure bcc is correct. */
550 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
551 DEBUG(0,("init_smb_request: invalid bcc number %u "
552 "(wct = %u, size %u)\n",
553 (unsigned int)req->buflen,
554 (unsigned int)req->wct,
555 (unsigned int)req_size));
563 static void process_smb(struct smbd_server_connection *conn,
564 uint8_t *inbuf, size_t nread, size_t unread_bytes,
565 uint32_t seqnum, bool encrypted,
566 struct smb_perfcount_data *deferred_pcd);
568 static void smbd_deferred_open_timer(struct event_context *ev,
569 struct timed_event *te,
570 struct timeval _tval,
573 struct pending_message_list *msg = talloc_get_type(private_data,
574 struct pending_message_list);
575 struct smbd_server_connection *sconn = msg->sconn;
576 TALLOC_CTX *mem_ctx = talloc_tos();
577 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
580 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
583 exit_server("smbd_deferred_open_timer: talloc failed\n");
587 /* We leave this message on the queue so the open code can
588 know this is a retry. */
589 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
590 (unsigned long long)mid ));
592 /* Mark the message as processed so this is not
593 * re-processed in error. */
594 msg->processed = true;
596 process_smb(sconn, inbuf,
598 msg->seqnum, msg->encrypted, &msg->pcd);
600 /* If it's still there and was processed, remove it. */
601 msg = get_deferred_open_message_smb(sconn, mid);
602 if (msg && msg->processed) {
603 remove_deferred_open_message_smb(sconn, mid);
607 /****************************************************************************
608 Function to push a message onto the tail of a linked list of smb messages ready
610 ****************************************************************************/
612 static bool push_queued_message(struct smb_request *req,
613 struct timeval request_time,
614 struct timeval end_time,
615 char *private_data, size_t private_len)
617 int msg_len = smb_len(req->inbuf) + 4;
618 struct pending_message_list *msg;
620 msg = talloc_zero(NULL, struct pending_message_list);
623 DEBUG(0,("push_message: malloc fail (1)\n"));
626 msg->sconn = req->sconn;
628 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
629 if(msg->buf.data == NULL) {
630 DEBUG(0,("push_message: malloc fail (2)\n"));
635 msg->request_time = request_time;
636 msg->seqnum = req->seqnum;
637 msg->encrypted = req->encrypted;
638 msg->processed = false;
639 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
642 msg->private_data = data_blob_talloc(msg, private_data,
644 if (msg->private_data.data == NULL) {
645 DEBUG(0,("push_message: malloc fail (3)\n"));
651 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
654 smbd_deferred_open_timer,
657 DEBUG(0,("push_message: event_add_timed failed\n"));
662 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
663 struct pending_message_list *);
665 DEBUG(10,("push_message: pushed message length %u on "
666 "deferred_open_queue\n", (unsigned int)msg_len));
671 /****************************************************************************
672 Function to delete a sharing violation open message by mid.
673 ****************************************************************************/
675 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
678 struct pending_message_list *pml;
680 if (sconn->using_smb2) {
681 remove_deferred_open_message_smb2(sconn, mid);
685 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
686 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
687 DEBUG(10,("remove_deferred_open_message_smb: "
688 "deleting mid %llu len %u\n",
689 (unsigned long long)mid,
690 (unsigned int)pml->buf.length ));
691 DLIST_REMOVE(sconn->deferred_open_queue, pml);
698 /****************************************************************************
699 Move a sharing violation open retry message to the front of the list and
700 schedule it for immediate processing.
701 ****************************************************************************/
703 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
706 struct pending_message_list *pml;
709 if (sconn->using_smb2) {
710 schedule_deferred_open_message_smb2(sconn, mid);
714 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
715 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
717 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
720 (unsigned long long)msg_mid ));
722 if (mid == msg_mid) {
723 struct timed_event *te;
725 if (pml->processed) {
726 /* A processed message should not be
728 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
729 "message mid %llu was already processed\n",
730 (unsigned long long)msg_mid ));
734 DEBUG(10,("schedule_deferred_open_message_smb: "
735 "scheduling mid %llu\n",
736 (unsigned long long)mid ));
738 te = tevent_add_timer(pml->sconn->ev_ctx,
741 smbd_deferred_open_timer,
744 DEBUG(10,("schedule_deferred_open_message_smb: "
745 "event_add_timed() failed, "
746 "skipping mid %llu\n",
747 (unsigned long long)msg_mid ));
750 TALLOC_FREE(pml->te);
752 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
757 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
758 "find message mid %llu\n",
759 (unsigned long long)mid ));
762 /****************************************************************************
763 Return true if this mid is on the deferred queue and was not yet processed.
764 ****************************************************************************/
766 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
768 struct pending_message_list *pml;
770 if (sconn->using_smb2) {
771 return open_was_deferred_smb2(sconn, mid);
774 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
775 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
782 /****************************************************************************
783 Return the message queued by this mid.
784 ****************************************************************************/
786 static struct pending_message_list *get_deferred_open_message_smb(
787 struct smbd_server_connection *sconn, uint64_t mid)
789 struct pending_message_list *pml;
791 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
792 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
799 /****************************************************************************
800 Get the state data queued by this mid.
801 ****************************************************************************/
803 bool get_deferred_open_message_state(struct smb_request *smbreq,
804 struct timeval *p_request_time,
807 struct pending_message_list *pml;
809 if (smbreq->sconn->using_smb2) {
810 return get_deferred_open_message_state_smb2(smbreq->smb2req,
815 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
819 if (p_request_time) {
820 *p_request_time = pml->request_time;
823 *pp_state = (void *)pml->private_data.data;
828 /****************************************************************************
829 Function to push a deferred open smb message onto a linked list of local smb
830 messages ready for processing.
831 ****************************************************************************/
833 bool push_deferred_open_message_smb(struct smb_request *req,
834 struct timeval request_time,
835 struct timeval timeout,
837 char *private_data, size_t priv_len)
839 struct timeval end_time;
842 return push_deferred_open_message_smb2(req->smb2req,
850 if (req->unread_bytes) {
851 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
852 "unread_bytes = %u\n",
853 (unsigned int)req->unread_bytes ));
854 smb_panic("push_deferred_open_message_smb: "
855 "logic error unread_bytes != 0" );
858 end_time = timeval_sum(&request_time, &timeout);
860 DEBUG(10,("push_deferred_open_message_smb: pushing message "
861 "len %u mid %llu timeout time [%u.%06u]\n",
862 (unsigned int) smb_len(req->inbuf)+4,
863 (unsigned long long)req->mid,
864 (unsigned int)end_time.tv_sec,
865 (unsigned int)end_time.tv_usec));
867 return push_queued_message(req, request_time, end_time,
868 private_data, priv_len);
871 static void smbd_sig_term_handler(struct tevent_context *ev,
872 struct tevent_signal *se,
878 exit_server_cleanly("termination signal");
881 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
883 struct tevent_signal *se;
885 se = tevent_add_signal(sconn->ev_ctx,
888 smbd_sig_term_handler,
891 exit_server("failed to setup SIGTERM handler");
895 static void smbd_sig_hup_handler(struct tevent_context *ev,
896 struct tevent_signal *se,
902 struct smbd_server_connection *sconn =
903 talloc_get_type_abort(private_data,
904 struct smbd_server_connection);
906 change_to_root_user();
907 DEBUG(1,("Reloading services after SIGHUP\n"));
908 reload_services(sconn->msg_ctx, sconn->sock, false);
911 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
913 struct tevent_signal *se;
915 se = tevent_add_signal(sconn->ev_ctx,
918 smbd_sig_hup_handler,
921 exit_server("failed to setup SIGHUP handler");
925 static NTSTATUS smbd_server_connection_loop_once(struct tevent_context *ev_ctx,
926 struct smbd_server_connection *conn)
933 timeout = SMBD_SELECT_TIMEOUT * 1000;
936 * Are there any timed events waiting ? If so, ensure we don't
937 * select for longer than it would take to wait for them.
940 event_add_to_poll_args(ev_ctx, conn, &conn->pfds, &num_pfds, &timeout);
942 /* Process a signal and timed events now... */
943 if (run_events_poll(ev_ctx, 0, NULL, 0)) {
944 return NT_STATUS_RETRY;
949 START_PROFILE(smbd_idle);
951 ret = sys_poll(conn->pfds, num_pfds, timeout);
954 END_PROFILE(smbd_idle);
959 if (errno == EINTR) {
960 return NT_STATUS_RETRY;
962 return map_nt_error_from_unix(errno);
965 retry = run_events_poll(ev_ctx, ret, conn->pfds, num_pfds);
967 return NT_STATUS_RETRY;
970 /* Did we timeout ? */
972 return NT_STATUS_RETRY;
975 /* should not be reached */
976 return NT_STATUS_INTERNAL_ERROR;
980 * Only allow 5 outstanding trans requests. We're allocating memory, so
984 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
987 for (; list != NULL; list = list->next) {
989 if (list->mid == mid) {
990 return NT_STATUS_INVALID_PARAMETER;
996 return NT_STATUS_INSUFFICIENT_RESOURCES;
1003 These flags determine some of the permissions required to do an operation
1005 Note that I don't set NEED_WRITE on some write operations because they
1006 are used by some brain-dead clients when printing, and I don't want to
1007 force write permissions on print services.
1009 #define AS_USER (1<<0)
1010 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1011 #define TIME_INIT (1<<2)
1012 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1013 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1014 #define DO_CHDIR (1<<6)
1017 define a list of possible SMB messages and their corresponding
1018 functions. Any message that has a NULL function is unimplemented -
1019 please feel free to contribute implementations!
1021 static const struct smb_message_struct {
1023 void (*fn)(struct smb_request *req);
1025 } smb_messages[256] = {
1027 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1028 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1029 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1030 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1031 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1032 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1033 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1034 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1035 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1036 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1037 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1038 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1039 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1040 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1041 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1042 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1043 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1044 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1045 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1046 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1047 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1048 /* 0x15 */ { NULL, NULL, 0 },
1049 /* 0x16 */ { NULL, NULL, 0 },
1050 /* 0x17 */ { NULL, NULL, 0 },
1051 /* 0x18 */ { NULL, NULL, 0 },
1052 /* 0x19 */ { NULL, NULL, 0 },
1053 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1054 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1055 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1056 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1057 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1058 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1059 /* 0x20 */ { "SMBwritec", NULL,0},
1060 /* 0x21 */ { NULL, NULL, 0 },
1061 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1062 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1063 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1064 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1065 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1066 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1067 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1068 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1069 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1070 /* 0x2b */ { "SMBecho",reply_echo,0},
1071 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1072 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1073 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1074 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1075 /* 0x30 */ { NULL, NULL, 0 },
1076 /* 0x31 */ { NULL, NULL, 0 },
1077 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1078 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1079 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1080 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1081 /* 0x36 */ { NULL, NULL, 0 },
1082 /* 0x37 */ { NULL, NULL, 0 },
1083 /* 0x38 */ { NULL, NULL, 0 },
1084 /* 0x39 */ { NULL, NULL, 0 },
1085 /* 0x3a */ { NULL, NULL, 0 },
1086 /* 0x3b */ { NULL, NULL, 0 },
1087 /* 0x3c */ { NULL, NULL, 0 },
1088 /* 0x3d */ { NULL, NULL, 0 },
1089 /* 0x3e */ { NULL, NULL, 0 },
1090 /* 0x3f */ { NULL, NULL, 0 },
1091 /* 0x40 */ { NULL, NULL, 0 },
1092 /* 0x41 */ { NULL, NULL, 0 },
1093 /* 0x42 */ { NULL, NULL, 0 },
1094 /* 0x43 */ { NULL, NULL, 0 },
1095 /* 0x44 */ { NULL, NULL, 0 },
1096 /* 0x45 */ { NULL, NULL, 0 },
1097 /* 0x46 */ { NULL, NULL, 0 },
1098 /* 0x47 */ { NULL, NULL, 0 },
1099 /* 0x48 */ { NULL, NULL, 0 },
1100 /* 0x49 */ { NULL, NULL, 0 },
1101 /* 0x4a */ { NULL, NULL, 0 },
1102 /* 0x4b */ { NULL, NULL, 0 },
1103 /* 0x4c */ { NULL, NULL, 0 },
1104 /* 0x4d */ { NULL, NULL, 0 },
1105 /* 0x4e */ { NULL, NULL, 0 },
1106 /* 0x4f */ { NULL, NULL, 0 },
1107 /* 0x50 */ { NULL, NULL, 0 },
1108 /* 0x51 */ { NULL, NULL, 0 },
1109 /* 0x52 */ { NULL, NULL, 0 },
1110 /* 0x53 */ { NULL, NULL, 0 },
1111 /* 0x54 */ { NULL, NULL, 0 },
1112 /* 0x55 */ { NULL, NULL, 0 },
1113 /* 0x56 */ { NULL, NULL, 0 },
1114 /* 0x57 */ { NULL, NULL, 0 },
1115 /* 0x58 */ { NULL, NULL, 0 },
1116 /* 0x59 */ { NULL, NULL, 0 },
1117 /* 0x5a */ { NULL, NULL, 0 },
1118 /* 0x5b */ { NULL, NULL, 0 },
1119 /* 0x5c */ { NULL, NULL, 0 },
1120 /* 0x5d */ { NULL, NULL, 0 },
1121 /* 0x5e */ { NULL, NULL, 0 },
1122 /* 0x5f */ { NULL, NULL, 0 },
1123 /* 0x60 */ { NULL, NULL, 0 },
1124 /* 0x61 */ { NULL, NULL, 0 },
1125 /* 0x62 */ { NULL, NULL, 0 },
1126 /* 0x63 */ { NULL, NULL, 0 },
1127 /* 0x64 */ { NULL, NULL, 0 },
1128 /* 0x65 */ { NULL, NULL, 0 },
1129 /* 0x66 */ { NULL, NULL, 0 },
1130 /* 0x67 */ { NULL, NULL, 0 },
1131 /* 0x68 */ { NULL, NULL, 0 },
1132 /* 0x69 */ { NULL, NULL, 0 },
1133 /* 0x6a */ { NULL, NULL, 0 },
1134 /* 0x6b */ { NULL, NULL, 0 },
1135 /* 0x6c */ { NULL, NULL, 0 },
1136 /* 0x6d */ { NULL, NULL, 0 },
1137 /* 0x6e */ { NULL, NULL, 0 },
1138 /* 0x6f */ { NULL, NULL, 0 },
1139 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1140 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1141 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1142 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1143 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1144 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1145 /* 0x76 */ { NULL, NULL, 0 },
1146 /* 0x77 */ { NULL, NULL, 0 },
1147 /* 0x78 */ { NULL, NULL, 0 },
1148 /* 0x79 */ { NULL, NULL, 0 },
1149 /* 0x7a */ { NULL, NULL, 0 },
1150 /* 0x7b */ { NULL, NULL, 0 },
1151 /* 0x7c */ { NULL, NULL, 0 },
1152 /* 0x7d */ { NULL, NULL, 0 },
1153 /* 0x7e */ { NULL, NULL, 0 },
1154 /* 0x7f */ { NULL, NULL, 0 },
1155 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1156 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1157 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1158 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1159 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1160 /* 0x85 */ { NULL, NULL, 0 },
1161 /* 0x86 */ { NULL, NULL, 0 },
1162 /* 0x87 */ { NULL, NULL, 0 },
1163 /* 0x88 */ { NULL, NULL, 0 },
1164 /* 0x89 */ { NULL, NULL, 0 },
1165 /* 0x8a */ { NULL, NULL, 0 },
1166 /* 0x8b */ { NULL, NULL, 0 },
1167 /* 0x8c */ { NULL, NULL, 0 },
1168 /* 0x8d */ { NULL, NULL, 0 },
1169 /* 0x8e */ { NULL, NULL, 0 },
1170 /* 0x8f */ { NULL, NULL, 0 },
1171 /* 0x90 */ { NULL, NULL, 0 },
1172 /* 0x91 */ { NULL, NULL, 0 },
1173 /* 0x92 */ { NULL, NULL, 0 },
1174 /* 0x93 */ { NULL, NULL, 0 },
1175 /* 0x94 */ { NULL, NULL, 0 },
1176 /* 0x95 */ { NULL, NULL, 0 },
1177 /* 0x96 */ { NULL, NULL, 0 },
1178 /* 0x97 */ { NULL, NULL, 0 },
1179 /* 0x98 */ { NULL, NULL, 0 },
1180 /* 0x99 */ { NULL, NULL, 0 },
1181 /* 0x9a */ { NULL, NULL, 0 },
1182 /* 0x9b */ { NULL, NULL, 0 },
1183 /* 0x9c */ { NULL, NULL, 0 },
1184 /* 0x9d */ { NULL, NULL, 0 },
1185 /* 0x9e */ { NULL, NULL, 0 },
1186 /* 0x9f */ { NULL, NULL, 0 },
1187 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1188 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1189 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1190 /* 0xa3 */ { NULL, NULL, 0 },
1191 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1192 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1193 /* 0xa6 */ { NULL, NULL, 0 },
1194 /* 0xa7 */ { NULL, NULL, 0 },
1195 /* 0xa8 */ { NULL, NULL, 0 },
1196 /* 0xa9 */ { NULL, NULL, 0 },
1197 /* 0xaa */ { NULL, NULL, 0 },
1198 /* 0xab */ { NULL, NULL, 0 },
1199 /* 0xac */ { NULL, NULL, 0 },
1200 /* 0xad */ { NULL, NULL, 0 },
1201 /* 0xae */ { NULL, NULL, 0 },
1202 /* 0xaf */ { NULL, NULL, 0 },
1203 /* 0xb0 */ { NULL, NULL, 0 },
1204 /* 0xb1 */ { NULL, NULL, 0 },
1205 /* 0xb2 */ { NULL, NULL, 0 },
1206 /* 0xb3 */ { NULL, NULL, 0 },
1207 /* 0xb4 */ { NULL, NULL, 0 },
1208 /* 0xb5 */ { NULL, NULL, 0 },
1209 /* 0xb6 */ { NULL, NULL, 0 },
1210 /* 0xb7 */ { NULL, NULL, 0 },
1211 /* 0xb8 */ { NULL, NULL, 0 },
1212 /* 0xb9 */ { NULL, NULL, 0 },
1213 /* 0xba */ { NULL, NULL, 0 },
1214 /* 0xbb */ { NULL, NULL, 0 },
1215 /* 0xbc */ { NULL, NULL, 0 },
1216 /* 0xbd */ { NULL, NULL, 0 },
1217 /* 0xbe */ { NULL, NULL, 0 },
1218 /* 0xbf */ { NULL, NULL, 0 },
1219 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1220 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1221 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1222 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1223 /* 0xc4 */ { NULL, NULL, 0 },
1224 /* 0xc5 */ { NULL, NULL, 0 },
1225 /* 0xc6 */ { NULL, NULL, 0 },
1226 /* 0xc7 */ { NULL, NULL, 0 },
1227 /* 0xc8 */ { NULL, NULL, 0 },
1228 /* 0xc9 */ { NULL, NULL, 0 },
1229 /* 0xca */ { NULL, NULL, 0 },
1230 /* 0xcb */ { NULL, NULL, 0 },
1231 /* 0xcc */ { NULL, NULL, 0 },
1232 /* 0xcd */ { NULL, NULL, 0 },
1233 /* 0xce */ { NULL, NULL, 0 },
1234 /* 0xcf */ { NULL, NULL, 0 },
1235 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1236 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1237 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1238 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1239 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1240 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1241 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1242 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1243 /* 0xd8 */ { NULL, NULL, 0 },
1244 /* 0xd9 */ { NULL, NULL, 0 },
1245 /* 0xda */ { NULL, NULL, 0 },
1246 /* 0xdb */ { NULL, NULL, 0 },
1247 /* 0xdc */ { NULL, NULL, 0 },
1248 /* 0xdd */ { NULL, NULL, 0 },
1249 /* 0xde */ { NULL, NULL, 0 },
1250 /* 0xdf */ { NULL, NULL, 0 },
1251 /* 0xe0 */ { NULL, NULL, 0 },
1252 /* 0xe1 */ { NULL, NULL, 0 },
1253 /* 0xe2 */ { NULL, NULL, 0 },
1254 /* 0xe3 */ { NULL, NULL, 0 },
1255 /* 0xe4 */ { NULL, NULL, 0 },
1256 /* 0xe5 */ { NULL, NULL, 0 },
1257 /* 0xe6 */ { NULL, NULL, 0 },
1258 /* 0xe7 */ { NULL, NULL, 0 },
1259 /* 0xe8 */ { NULL, NULL, 0 },
1260 /* 0xe9 */ { NULL, NULL, 0 },
1261 /* 0xea */ { NULL, NULL, 0 },
1262 /* 0xeb */ { NULL, NULL, 0 },
1263 /* 0xec */ { NULL, NULL, 0 },
1264 /* 0xed */ { NULL, NULL, 0 },
1265 /* 0xee */ { NULL, NULL, 0 },
1266 /* 0xef */ { NULL, NULL, 0 },
1267 /* 0xf0 */ { NULL, NULL, 0 },
1268 /* 0xf1 */ { NULL, NULL, 0 },
1269 /* 0xf2 */ { NULL, NULL, 0 },
1270 /* 0xf3 */ { NULL, NULL, 0 },
1271 /* 0xf4 */ { NULL, NULL, 0 },
1272 /* 0xf5 */ { NULL, NULL, 0 },
1273 /* 0xf6 */ { NULL, NULL, 0 },
1274 /* 0xf7 */ { NULL, NULL, 0 },
1275 /* 0xf8 */ { NULL, NULL, 0 },
1276 /* 0xf9 */ { NULL, NULL, 0 },
1277 /* 0xfa */ { NULL, NULL, 0 },
1278 /* 0xfb */ { NULL, NULL, 0 },
1279 /* 0xfc */ { NULL, NULL, 0 },
1280 /* 0xfd */ { NULL, NULL, 0 },
1281 /* 0xfe */ { NULL, NULL, 0 },
1282 /* 0xff */ { NULL, NULL, 0 }
1286 /*******************************************************************
1287 allocate and initialize a reply packet
1288 ********************************************************************/
1290 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1291 const char *inbuf, char **outbuf, uint8_t num_words,
1295 * Protect against integer wrap
1297 if ((num_bytes > 0xffffff)
1298 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1300 if (asprintf(&msg, "num_bytes too large: %u",
1301 (unsigned)num_bytes) == -1) {
1302 msg = discard_const_p(char, "num_bytes too large");
1307 *outbuf = talloc_array(mem_ctx, char,
1308 smb_size + num_words*2 + num_bytes);
1309 if (*outbuf == NULL) {
1313 construct_reply_common(req, inbuf, *outbuf);
1314 srv_set_message(*outbuf, num_words, num_bytes, false);
1316 * Zero out the word area, the caller has to take care of the bcc area
1319 if (num_words != 0) {
1320 memset(*outbuf + smb_vwv0, 0, num_words*2);
1326 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1329 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1331 smb_panic("could not allocate output buffer\n");
1333 req->outbuf = (uint8_t *)outbuf;
1337 /*******************************************************************
1338 Dump a packet to a file.
1339 ********************************************************************/
1341 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1345 if (DEBUGLEVEL < 50) {
1349 if (len < 4) len = smb_len(data)+4;
1350 for (i=1;i<100;i++) {
1351 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1352 type ? "req" : "resp") == -1) {
1355 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1356 if (fd != -1 || errno != EEXIST) break;
1359 ssize_t ret = write(fd, data, len);
1361 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1363 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1368 /****************************************************************************
1369 Prepare everything for calling the actual request function, and potentially
1370 call the request function via the "new" interface.
1372 Return False if the "legacy" function needs to be called, everything is
1375 Return True if we're done.
1377 I know this API sucks, but it is the one with the least code change I could
1379 ****************************************************************************/
1381 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1385 connection_struct *conn = NULL;
1386 struct smbd_server_connection *sconn = req->sconn;
1391 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1392 * so subtract 4 from it. */
1393 if (!valid_smb_header(sconn, req->inbuf)
1394 || (size < (smb_size - 4))) {
1395 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1396 smb_len(req->inbuf)));
1397 exit_server_cleanly("Non-SMB packet");
1400 if (smb_messages[type].fn == NULL) {
1401 DEBUG(0,("Unknown message type %d!\n",type));
1402 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1403 reply_unknown_new(req, type);
1407 flags = smb_messages[type].flags;
1409 /* In share mode security we must ignore the vuid. */
1410 session_tag = (lp_security() == SEC_SHARE)
1411 ? UID_FIELD_INVALID : req->vuid;
1414 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1415 (int)sys_getpid(), (unsigned long)conn));
1417 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1419 /* Ensure this value is replaced in the incoming packet. */
1420 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1423 * Ensure the correct username is in current_user_info. This is a
1424 * really ugly bugfix for problems with multiple session_setup_and_X's
1425 * being done and allowing %U and %G substitutions to work correctly.
1426 * There is a reason this code is done here, don't move it unless you
1427 * know what you're doing... :-).
1431 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1432 user_struct *vuser = NULL;
1434 sconn->smb1.sessions.last_session_tag = session_tag;
1435 if(session_tag != UID_FIELD_INVALID) {
1436 vuser = get_valid_user_struct(sconn, session_tag);
1438 set_current_user_info(
1439 vuser->session_info->unix_info->sanitized_username,
1440 vuser->session_info->unix_info->unix_name,
1441 vuser->session_info->info->domain_name);
1446 /* Does this call need to be run as the connected user? */
1447 if (flags & AS_USER) {
1449 /* Does this call need a valid tree connection? */
1452 * Amazingly, the error code depends on the command
1455 if (type == SMBntcreateX) {
1456 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1458 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1463 if (!change_to_user(conn,session_tag)) {
1464 DEBUG(0, ("Error: Could not change to user. Removing "
1465 "deferred open, mid=%llu.\n",
1466 (unsigned long long)req->mid));
1467 reply_force_doserror(req, ERRSRV, ERRbaduid);
1471 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1473 /* Does it need write permission? */
1474 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1475 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1479 /* IPC services are limited */
1480 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1481 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1485 /* This call needs to be run as root */
1486 change_to_root_user();
1489 /* load service specific parameters */
1491 if (req->encrypted) {
1492 conn->encrypted_tid = true;
1493 /* encrypted required from now on. */
1494 conn->encrypt_level = Required;
1495 } else if (ENCRYPTION_REQUIRED(conn)) {
1496 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1497 exit_server_cleanly("encryption required "
1503 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1504 (flags & (AS_USER|DO_CHDIR)
1506 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1509 conn->num_smb_operations++;
1512 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1514 if (raddr == NULL) {
1515 reply_nterror(req, NT_STATUS_NO_MEMORY);
1519 /* does this protocol need to be run as guest? */
1520 if ((flags & AS_GUEST)
1521 && (!change_to_guest() ||
1522 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1523 sconn->remote_hostname,
1525 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1529 smb_messages[type].fn(req);
1533 /****************************************************************************
1534 Construct a reply to the incoming packet.
1535 ****************************************************************************/
1537 static void construct_reply(struct smbd_server_connection *sconn,
1538 char *inbuf, int size, size_t unread_bytes,
1539 uint32_t seqnum, bool encrypted,
1540 struct smb_perfcount_data *deferred_pcd)
1542 connection_struct *conn;
1543 struct smb_request *req;
1545 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1546 smb_panic("could not allocate smb_request");
1549 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1550 encrypted, seqnum)) {
1551 exit_server_cleanly("Invalid SMB request");
1554 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1556 /* we popped this message off the queue - keep original perf data */
1558 req->pcd = *deferred_pcd;
1560 SMB_PERFCOUNT_START(&req->pcd);
1561 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1562 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1565 conn = switch_message(req->cmd, req, size);
1567 if (req->unread_bytes) {
1568 /* writeX failed. drain socket. */
1569 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1570 req->unread_bytes) {
1571 smb_panic("failed to drain pending bytes");
1573 req->unread_bytes = 0;
1581 if (req->outbuf == NULL) {
1585 if (CVAL(req->outbuf,0) == 0) {
1586 show_msg((char *)req->outbuf);
1589 if (!srv_send_smb(req->sconn,
1590 (char *)req->outbuf,
1591 true, req->seqnum+1,
1592 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1594 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1602 /****************************************************************************
1603 Process an smb from the client
1604 ****************************************************************************/
1605 static void process_smb(struct smbd_server_connection *sconn,
1606 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1607 uint32_t seqnum, bool encrypted,
1608 struct smb_perfcount_data *deferred_pcd)
1610 int msg_type = CVAL(inbuf,0);
1612 DO_PROFILE_INC(smb_count);
1614 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1616 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1617 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1619 if (msg_type != NBSSmessage) {
1621 * NetBIOS session request, keepalive, etc.
1623 reply_special(sconn, (char *)inbuf, nread);
1627 if (sconn->using_smb2) {
1628 /* At this point we're not really using smb2,
1629 * we make the decision here.. */
1630 if (smbd_is_smb2_header(inbuf, nread)) {
1631 smbd_smb2_first_negprot(sconn, inbuf, nread);
1633 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1634 && CVAL(inbuf, smb_com) != 0x72) {
1635 /* This is a non-negprot SMB1 packet.
1636 Disable SMB2 from now on. */
1637 sconn->using_smb2 = false;
1641 show_msg((char *)inbuf);
1643 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1644 encrypted, deferred_pcd);
1648 sconn->num_requests++;
1650 /* The timeout_processing function isn't run nearly
1651 often enough to implement 'max log size' without
1652 overrunning the size of the file by many megabytes.
1653 This is especially true if we are running at debug
1654 level 10. Checking every 50 SMBs is a nice
1655 tradeoff of performance vs log file size overrun. */
1657 if ((sconn->num_requests % 50) == 0 &&
1658 need_to_check_log_size()) {
1659 change_to_root_user();
1664 /****************************************************************************
1665 Return a string containing the function name of a SMB command.
1666 ****************************************************************************/
1668 const char *smb_fn_name(int type)
1670 const char *unknown_name = "SMBunknown";
1672 if (smb_messages[type].name == NULL)
1673 return(unknown_name);
1675 return(smb_messages[type].name);
1678 /****************************************************************************
1679 Helper functions for contruct_reply.
1680 ****************************************************************************/
1682 void add_to_common_flags2(uint32 v)
1687 void remove_from_common_flags2(uint32 v)
1689 common_flags2 &= ~v;
1692 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1695 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1696 uint16_t out_flags2 = common_flags2;
1698 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1699 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1700 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1702 srv_set_message(outbuf,0,0,false);
1704 SCVAL(outbuf, smb_com, req->cmd);
1705 SIVAL(outbuf,smb_rcls,0);
1706 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1707 SSVAL(outbuf,smb_flg2, out_flags2);
1708 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1709 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1711 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1712 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1713 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1714 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1717 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1719 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1723 * How many bytes have we already accumulated up to the current wct field
1727 size_t req_wct_ofs(struct smb_request *req)
1731 if (req->chain_outbuf == NULL) {
1734 buf_size = talloc_get_size(req->chain_outbuf);
1735 if ((buf_size % 4) != 0) {
1736 buf_size += (4 - (buf_size % 4));
1738 return buf_size - 4;
1742 * Hack around reply_nterror & friends not being aware of chained requests,
1743 * generating illegal (i.e. wct==0) chain replies.
1746 static void fixup_chain_error_packet(struct smb_request *req)
1748 uint8_t *outbuf = req->outbuf;
1750 reply_outbuf(req, 2, 0);
1751 memcpy(req->outbuf, outbuf, smb_wct);
1752 TALLOC_FREE(outbuf);
1753 SCVAL(req->outbuf, smb_vwv0, 0xff);
1757 * @brief Find the smb_cmd offset of the last command pushed
1758 * @param[in] buf The buffer we're building up
1759 * @retval Where can we put our next andx cmd?
1761 * While chaining requests, the "next" request we're looking at needs to put
1762 * its SMB_Command before the data the previous request already built up added
1763 * to the chain. Find the offset to the place where we have to put our cmd.
1766 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1771 cmd = CVAL(buf, smb_com);
1773 SMB_ASSERT(is_andx_req(cmd));
1777 while (CVAL(buf, ofs) != 0xff) {
1779 if (!is_andx_req(CVAL(buf, ofs))) {
1784 * ofs is from start of smb header, so add the 4 length
1785 * bytes. The next cmd is right after the wct field.
1787 ofs = SVAL(buf, ofs+2) + 4 + 1;
1789 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1797 * @brief Do the smb chaining at a buffer level
1798 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1799 * @param[in] smb_command The command that we want to issue
1800 * @param[in] wct How many words?
1801 * @param[in] vwv The words, already in network order
1802 * @param[in] bytes_alignment How shall we align "bytes"?
1803 * @param[in] num_bytes How many bytes?
1804 * @param[in] bytes The data the request ships
1806 * smb_splice_chain() adds the vwv and bytes to the request already present in
1810 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1811 uint8_t wct, const uint16_t *vwv,
1812 size_t bytes_alignment,
1813 uint32_t num_bytes, const uint8_t *bytes)
1816 size_t old_size, new_size;
1818 size_t chain_padding = 0;
1819 size_t bytes_padding = 0;
1822 old_size = talloc_get_size(*poutbuf);
1825 * old_size == smb_wct means we're pushing the first request in for
1829 first_request = (old_size == smb_wct);
1831 if (!first_request && ((old_size % 4) != 0)) {
1833 * Align the wct field of subsequent requests to a 4-byte
1836 chain_padding = 4 - (old_size % 4);
1840 * After the old request comes the new wct field (1 byte), the vwv's
1841 * and the num_bytes field. After at we might need to align the bytes
1842 * given to us to "bytes_alignment", increasing the num_bytes value.
1845 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1847 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1848 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1851 new_size += bytes_padding + num_bytes;
1853 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1854 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1855 (unsigned)new_size));
1859 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1860 if (outbuf == NULL) {
1861 DEBUG(0, ("talloc failed\n"));
1866 if (first_request) {
1867 SCVAL(outbuf, smb_com, smb_command);
1869 size_t andx_cmd_ofs;
1871 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1872 DEBUG(1, ("invalid command chain\n"));
1873 *poutbuf = talloc_realloc(
1874 NULL, *poutbuf, uint8_t, old_size);
1878 if (chain_padding != 0) {
1879 memset(outbuf + old_size, 0, chain_padding);
1880 old_size += chain_padding;
1883 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1884 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1890 * Push the chained request:
1895 SCVAL(outbuf, ofs, wct);
1902 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1903 ofs += sizeof(uint16_t) * wct;
1909 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1910 ofs += sizeof(uint16_t);
1916 if (bytes_padding != 0) {
1917 memset(outbuf + ofs, 0, bytes_padding);
1918 ofs += bytes_padding;
1925 memcpy(outbuf + ofs, bytes, num_bytes);
1930 /****************************************************************************
1931 Construct a chained reply and add it to the already made reply
1932 ****************************************************************************/
1934 void chain_reply(struct smb_request *req)
1936 size_t smblen = smb_len(req->inbuf);
1937 size_t already_used, length_needed;
1939 uint32_t chain_offset; /* uint32_t to avoid overflow */
1942 const uint16_t *vwv;
1946 if (IVAL(req->outbuf, smb_rcls) != 0) {
1947 fixup_chain_error_packet(req);
1951 * Any of the AndX requests and replies have at least a wct of
1952 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1953 * beginning of the SMB header to the next wct field.
1955 * None of the AndX requests put anything valuable in vwv[0] and [1],
1956 * so we can overwrite it here to form the chain.
1959 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1960 if (req->chain_outbuf == NULL) {
1961 req->chain_outbuf = talloc_realloc(
1962 req, req->outbuf, uint8_t,
1963 smb_len(req->outbuf) + 4);
1964 if (req->chain_outbuf == NULL) {
1965 smb_panic("talloc failed");
1973 * Here we assume that this is the end of the chain. For that we need
1974 * to set "next command" to 0xff and the offset to 0. If we later find
1975 * more commands in the chain, this will be overwritten again.
1978 SCVAL(req->outbuf, smb_vwv0, 0xff);
1979 SCVAL(req->outbuf, smb_vwv0+1, 0);
1980 SSVAL(req->outbuf, smb_vwv1, 0);
1982 if (req->chain_outbuf == NULL) {
1984 * In req->chain_outbuf we collect all the replies. Start the
1985 * chain by copying in the first reply.
1987 * We do the realloc because later on we depend on
1988 * talloc_get_size to determine the length of
1989 * chain_outbuf. The reply_xxx routines might have
1990 * over-allocated (reply_pipe_read_and_X used to be such an
1993 req->chain_outbuf = talloc_realloc(
1994 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1995 if (req->chain_outbuf == NULL) {
1996 smb_panic("talloc failed");
2001 * Update smb headers where subsequent chained commands
2002 * may have updated them.
2004 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2005 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2007 if (!smb_splice_chain(&req->chain_outbuf,
2008 CVAL(req->outbuf, smb_com),
2009 CVAL(req->outbuf, smb_wct),
2010 (uint16_t *)(req->outbuf + smb_vwv),
2011 0, smb_buflen(req->outbuf),
2012 (uint8_t *)smb_buf(req->outbuf))) {
2015 TALLOC_FREE(req->outbuf);
2019 * We use the old request's vwv field to grab the next chained command
2020 * and offset into the chained fields.
2023 chain_cmd = CVAL(req->vwv+0, 0);
2024 chain_offset = SVAL(req->vwv+1, 0);
2026 if (chain_cmd == 0xff) {
2028 * End of chain, no more requests from the client. So ship the
2031 smb_setlen((char *)(req->chain_outbuf),
2032 talloc_get_size(req->chain_outbuf) - 4);
2034 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2035 true, req->seqnum+1,
2036 IS_CONN_ENCRYPTED(req->conn)
2039 exit_server_cleanly("chain_reply: srv_send_smb "
2042 TALLOC_FREE(req->chain_outbuf);
2047 /* add a new perfcounter for this element of chain */
2048 SMB_PERFCOUNT_ADD(&req->pcd);
2049 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2050 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2053 * Check if the client tries to fool us. The chain offset
2054 * needs to point beyond the current request in the chain, it
2055 * needs to strictly grow. Otherwise we might be tricked into
2056 * an endless loop always processing the same request over and
2057 * over again. We used to assume that vwv and the byte buffer
2058 * array in a chain are always attached, but OS/2 the
2059 * Write&X/Read&X chain puts the Read&X vwv array right behind
2060 * the Write&X vwv chain. The Write&X bcc array is put behind
2061 * the Read&X vwv array. So now we check whether the chain
2062 * offset points strictly behind the previous vwv
2063 * array. req->buf points right after the vwv array of the
2064 * previous request. See
2065 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2069 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2070 if (chain_offset <= already_used) {
2075 * Next check: Make sure the chain offset does not point beyond the
2076 * overall smb request length.
2079 length_needed = chain_offset+1; /* wct */
2080 if (length_needed > smblen) {
2085 * Now comes the pointer magic. Goal here is to set up req->vwv and
2086 * req->buf correctly again to be able to call the subsequent
2087 * switch_message(). The chain offset (the former vwv[1]) points at
2088 * the new wct field.
2091 wct = CVAL(smb_base(req->inbuf), chain_offset);
2094 * Next consistency check: Make the new vwv array fits in the overall
2098 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2099 if (length_needed > smblen) {
2102 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2105 * Now grab the new byte buffer....
2108 buflen = SVAL(vwv+wct, 0);
2111 * .. and check that it fits.
2114 length_needed += buflen;
2115 if (length_needed > smblen) {
2118 buf = (const uint8_t *)(vwv+wct+1);
2120 req->cmd = chain_cmd;
2122 req->vwv = discard_const_p(uint16_t, vwv);
2123 req->buflen = buflen;
2126 switch_message(chain_cmd, req, smblen);
2128 if (req->outbuf == NULL) {
2130 * This happens if the chained command has suspended itself or
2131 * if it has called srv_send_smb() itself.
2137 * We end up here if the chained command was not itself chained or
2138 * suspended, but for example a close() command. We now need to splice
2139 * the chained commands' outbuf into the already built up chain_outbuf
2140 * and ship the result.
2146 * We end up here if there's any error in the chain syntax. Report a
2147 * DOS error, just like Windows does.
2149 reply_force_doserror(req, ERRSRV, ERRerror);
2150 fixup_chain_error_packet(req);
2154 * This scary statement intends to set the
2155 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2156 * to the value req->outbuf carries
2158 SSVAL(req->chain_outbuf, smb_flg2,
2159 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2160 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2163 * Transfer the error codes from the subrequest to the main one
2165 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2166 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2168 if (!smb_splice_chain(&req->chain_outbuf,
2169 CVAL(req->outbuf, smb_com),
2170 CVAL(req->outbuf, smb_wct),
2171 (uint16_t *)(req->outbuf + smb_vwv),
2172 0, smb_buflen(req->outbuf),
2173 (uint8_t *)smb_buf(req->outbuf))) {
2174 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2176 TALLOC_FREE(req->outbuf);
2178 smb_setlen((char *)(req->chain_outbuf),
2179 talloc_get_size(req->chain_outbuf) - 4);
2181 show_msg((char *)(req->chain_outbuf));
2183 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2184 true, req->seqnum+1,
2185 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2187 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2189 TALLOC_FREE(req->chain_outbuf);
2193 /****************************************************************************
2194 Check if services need reloading.
2195 ****************************************************************************/
2197 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2200 if (last_smb_conf_reload_time == 0) {
2201 last_smb_conf_reload_time = t;
2204 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2205 reload_services(sconn->msg_ctx, sconn->sock, True);
2206 last_smb_conf_reload_time = t;
2210 static bool fd_is_readable(int fd)
2214 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2216 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2220 static void smbd_server_connection_write_handler(
2221 struct smbd_server_connection *sconn)
2223 /* TODO: make write nonblocking */
2226 static void smbd_server_connection_read_handler(
2227 struct smbd_server_connection *sconn, int fd)
2229 uint8_t *inbuf = NULL;
2230 size_t inbuf_len = 0;
2231 size_t unread_bytes = 0;
2232 bool encrypted = false;
2233 TALLOC_CTX *mem_ctx = talloc_tos();
2239 if (lp_async_smb_echo_handler()
2240 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2242 * This is the super-ugly hack to prefer the packets
2243 * forwarded by the echo handler over the ones by the
2246 fd = sconn->smb1.echo_handler.trusted_fd;
2249 from_client = (sconn->sock == fd);
2252 smbd_lock_socket(sconn);
2254 if (!fd_is_readable(fd)) {
2255 DEBUG(10,("the echo listener was faster\n"));
2256 smbd_unlock_socket(sconn);
2261 /* TODO: make this completely nonblocking */
2262 status = receive_smb_talloc(mem_ctx, sconn, fd,
2263 (char **)(void *)&inbuf,
2267 &inbuf_len, &seqnum,
2268 false /* trusted channel */);
2271 smbd_unlock_socket(sconn);
2274 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2277 if (NT_STATUS_IS_ERR(status)) {
2278 exit_server_cleanly("failed to receive smb request");
2280 if (!NT_STATUS_IS_OK(status)) {
2285 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2286 seqnum, encrypted, NULL);
2289 static void smbd_server_connection_handler(struct event_context *ev,
2290 struct fd_event *fde,
2294 struct smbd_server_connection *conn = talloc_get_type(private_data,
2295 struct smbd_server_connection);
2297 if (flags & EVENT_FD_WRITE) {
2298 smbd_server_connection_write_handler(conn);
2301 if (flags & EVENT_FD_READ) {
2302 smbd_server_connection_read_handler(conn, conn->sock);
2307 static void smbd_server_echo_handler(struct event_context *ev,
2308 struct fd_event *fde,
2312 struct smbd_server_connection *conn = talloc_get_type(private_data,
2313 struct smbd_server_connection);
2315 if (flags & EVENT_FD_WRITE) {
2316 smbd_server_connection_write_handler(conn);
2319 if (flags & EVENT_FD_READ) {
2320 smbd_server_connection_read_handler(
2321 conn, conn->smb1.echo_handler.trusted_fd);
2326 #ifdef CLUSTER_SUPPORT
2327 /****************************************************************************
2328 received when we should release a specific IP
2329 ****************************************************************************/
2330 static void release_ip(const char *ip, void *priv)
2332 const char *addr = (const char *)priv;
2333 const char *p = addr;
2335 if (strncmp("::ffff:", addr, 7) == 0) {
2339 DEBUG(10, ("Got release IP message for %s, "
2340 "our address is %s\n", ip, p));
2342 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2343 /* we can't afford to do a clean exit - that involves
2344 database writes, which would potentially mean we
2345 are still running after the failover has finished -
2346 we have to get rid of this process ID straight
2348 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2350 /* note we must exit with non-zero status so the unclean handler gets
2351 called in the parent, so that the brl database is tickled */
2356 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2357 struct sockaddr_storage *client)
2360 length = sizeof(*server);
2361 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2364 length = sizeof(*client);
2365 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2373 * Send keepalive packets to our client
2375 static bool keepalive_fn(const struct timeval *now, void *private_data)
2377 struct smbd_server_connection *sconn = talloc_get_type_abort(
2378 private_data, struct smbd_server_connection);
2381 if (sconn->using_smb2) {
2382 /* Don't do keepalives on an SMB2 connection. */
2386 smbd_lock_socket(sconn);
2387 ret = send_keepalive(sconn->sock);
2388 smbd_unlock_socket(sconn);
2391 char addr[INET6_ADDRSTRLEN];
2393 * Try and give an error message saying what
2396 DEBUG(0, ("send_keepalive failed for client %s. "
2397 "Error %s - exiting\n",
2398 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2406 * Do the recurring check if we're idle
2408 static bool deadtime_fn(const struct timeval *now, void *private_data)
2410 struct smbd_server_connection *sconn =
2411 (struct smbd_server_connection *)private_data;
2413 if ((conn_num_open(sconn) == 0)
2414 || (conn_idle_all(sconn, now->tv_sec))) {
2415 DEBUG( 2, ( "Closing idle connection\n" ) );
2416 messaging_send(sconn->msg_ctx,
2417 messaging_server_id(sconn->msg_ctx),
2418 MSG_SHUTDOWN, &data_blob_null);
2426 * Do the recurring log file and smb.conf reload checks.
2429 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2431 struct smbd_server_connection *sconn = talloc_get_type_abort(
2432 private_data, struct smbd_server_connection);
2434 DEBUG(5, ("housekeeping\n"));
2436 change_to_root_user();
2438 /* update printer queue caches if necessary */
2439 update_monitored_printq_cache(sconn->msg_ctx);
2441 /* check if we need to reload services */
2442 check_reload(sconn, time_mono(NULL));
2444 /* Change machine password if neccessary. */
2445 attempt_machine_password_change();
2448 * Force a log file check.
2450 force_check_log_size();
2456 * Read an smb packet in the echo handler child, giving the parent
2457 * smbd one second to react once the socket becomes readable.
2460 struct smbd_echo_read_state {
2461 struct tevent_context *ev;
2462 struct smbd_server_connection *sconn;
2469 static void smbd_echo_read_readable(struct tevent_req *subreq);
2470 static void smbd_echo_read_waited(struct tevent_req *subreq);
2472 static struct tevent_req *smbd_echo_read_send(
2473 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2474 struct smbd_server_connection *sconn)
2476 struct tevent_req *req, *subreq;
2477 struct smbd_echo_read_state *state;
2479 req = tevent_req_create(mem_ctx, &state,
2480 struct smbd_echo_read_state);
2485 state->sconn = sconn;
2487 subreq = wait_for_read_send(state, ev, sconn->sock);
2488 if (tevent_req_nomem(subreq, req)) {
2489 return tevent_req_post(req, ev);
2491 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2495 static void smbd_echo_read_readable(struct tevent_req *subreq)
2497 struct tevent_req *req = tevent_req_callback_data(
2498 subreq, struct tevent_req);
2499 struct smbd_echo_read_state *state = tevent_req_data(
2500 req, struct smbd_echo_read_state);
2504 ok = wait_for_read_recv(subreq, &err);
2505 TALLOC_FREE(subreq);
2507 tevent_req_nterror(req, map_nt_error_from_unix(err));
2512 * Give the parent smbd one second to step in
2515 subreq = tevent_wakeup_send(
2516 state, state->ev, timeval_current_ofs(1, 0));
2517 if (tevent_req_nomem(subreq, req)) {
2520 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2523 static void smbd_echo_read_waited(struct tevent_req *subreq)
2525 struct tevent_req *req = tevent_req_callback_data(
2526 subreq, struct tevent_req);
2527 struct smbd_echo_read_state *state = tevent_req_data(
2528 req, struct smbd_echo_read_state);
2529 struct smbd_server_connection *sconn = state->sconn;
2535 ok = tevent_wakeup_recv(subreq);
2536 TALLOC_FREE(subreq);
2538 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2542 ok = smbd_lock_socket_internal(sconn);
2544 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2545 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2549 if (!fd_is_readable(sconn->sock)) {
2550 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2551 (int)sys_getpid()));
2553 ok = smbd_unlock_socket_internal(sconn);
2555 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2556 DEBUG(1, ("%s: failed to unlock socket\n",
2561 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2562 if (tevent_req_nomem(subreq, req)) {
2565 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2569 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2575 false /* trusted_channel*/);
2577 if (tevent_req_nterror(req, status)) {
2578 tevent_req_nterror(req, status);
2579 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2580 (int)sys_getpid(), nt_errstr(status)));
2584 ok = smbd_unlock_socket_internal(sconn);
2586 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2587 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2590 tevent_req_done(req);
2593 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2594 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2596 struct smbd_echo_read_state *state = tevent_req_data(
2597 req, struct smbd_echo_read_state);
2600 if (tevent_req_is_nterror(req, &status)) {
2603 *pbuf = talloc_move(mem_ctx, &state->buf);
2604 *pbuflen = state->buflen;
2605 *pseqnum = state->seqnum;
2606 return NT_STATUS_OK;
2609 struct smbd_echo_state {
2610 struct tevent_context *ev;
2611 struct iovec *pending;
2612 struct smbd_server_connection *sconn;
2615 struct tevent_fd *parent_fde;
2617 struct tevent_req *write_req;
2620 static void smbd_echo_writer_done(struct tevent_req *req);
2622 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2626 if (state->write_req != NULL) {
2630 num_pending = talloc_array_length(state->pending);
2631 if (num_pending == 0) {
2635 state->write_req = writev_send(state, state->ev, NULL,
2636 state->parent_pipe, false,
2637 state->pending, num_pending);
2638 if (state->write_req == NULL) {
2639 DEBUG(1, ("writev_send failed\n"));
2643 talloc_steal(state->write_req, state->pending);
2644 state->pending = NULL;
2646 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2650 static void smbd_echo_writer_done(struct tevent_req *req)
2652 struct smbd_echo_state *state = tevent_req_callback_data(
2653 req, struct smbd_echo_state);
2657 written = writev_recv(req, &err);
2659 state->write_req = NULL;
2660 if (written == -1) {
2661 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2664 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2665 smbd_echo_activate_writer(state);
2668 static bool smbd_echo_reply(struct smbd_echo_state *state,
2669 uint8_t *inbuf, size_t inbuf_len,
2672 struct smb_request req;
2673 uint16_t num_replies;
2678 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2679 DEBUG(10, ("Got netbios keepalive\n"));
2686 if (inbuf_len < smb_size) {
2687 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2690 if (!valid_smb_header(state->sconn, inbuf)) {
2691 DEBUG(10, ("Got invalid SMB header\n"));
2695 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2701 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2702 smb_messages[req.cmd].name
2703 ? smb_messages[req.cmd].name : "unknown"));
2705 if (req.cmd != SMBecho) {
2712 num_replies = SVAL(req.vwv+0, 0);
2713 if (num_replies != 1) {
2714 /* Not a Windows "Hey, you're still there?" request */
2718 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2720 DEBUG(10, ("create_outbuf failed\n"));
2723 req.outbuf = (uint8_t *)outbuf;
2725 SSVAL(req.outbuf, smb_vwv0, num_replies);
2727 if (req.buflen > 0) {
2728 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2731 out_len = smb_len(req.outbuf) + 4;
2733 ok = srv_send_smb(req.sconn,
2737 TALLOC_FREE(outbuf);
2745 static void smbd_echo_exit(struct tevent_context *ev,
2746 struct tevent_fd *fde, uint16_t flags,
2749 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2753 static void smbd_echo_got_packet(struct tevent_req *req);
2755 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2758 struct smbd_echo_state *state;
2759 struct tevent_req *read_req;
2761 state = talloc_zero(sconn, struct smbd_echo_state);
2762 if (state == NULL) {
2763 DEBUG(1, ("talloc failed\n"));
2766 state->sconn = sconn;
2767 state->parent_pipe = parent_pipe;
2768 state->ev = s3_tevent_context_init(state);
2769 if (state->ev == NULL) {
2770 DEBUG(1, ("tevent_context_init failed\n"));
2774 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2775 TEVENT_FD_READ, smbd_echo_exit,
2777 if (state->parent_fde == NULL) {
2778 DEBUG(1, ("tevent_add_fd failed\n"));
2783 read_req = smbd_echo_read_send(state, state->ev, sconn);
2784 if (read_req == NULL) {
2785 DEBUG(1, ("smbd_echo_read_send failed\n"));
2789 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2792 if (tevent_loop_once(state->ev) == -1) {
2793 DEBUG(1, ("tevent_loop_once failed: %s\n",
2801 static void smbd_echo_got_packet(struct tevent_req *req)
2803 struct smbd_echo_state *state = tevent_req_callback_data(
2804 req, struct smbd_echo_state);
2808 uint32_t seqnum = 0;
2811 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2813 if (!NT_STATUS_IS_OK(status)) {
2814 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2815 nt_errstr(status)));
2819 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2825 num_pending = talloc_array_length(state->pending);
2826 tmp = talloc_realloc(state, state->pending, struct iovec,
2829 DEBUG(1, ("talloc_realloc failed\n"));
2832 state->pending = tmp;
2834 if (buflen >= smb_size) {
2836 * place the seqnum in the packet so that the main process
2837 * can reply with signing
2839 SIVAL(buf, smb_ss_field, seqnum);
2840 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2843 iov = &state->pending[num_pending];
2844 iov->iov_base = buf;
2845 iov->iov_len = buflen;
2847 DEBUG(10,("echo_handler[%d]: forward to main\n",
2848 (int)sys_getpid()));
2849 smbd_echo_activate_writer(state);
2852 req = smbd_echo_read_send(state, state->ev, state->sconn);
2854 DEBUG(1, ("smbd_echo_read_send failed\n"));
2857 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2862 * Handle SMBecho requests in a forked child process
2864 bool fork_echo_handler(struct smbd_server_connection *sconn)
2866 int listener_pipe[2];
2870 res = pipe(listener_pipe);
2872 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2875 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2876 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2877 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2885 close(listener_pipe[0]);
2886 set_blocking(listener_pipe[1], false);
2888 status = reinit_after_fork(sconn->msg_ctx,
2891 if (!NT_STATUS_IS_OK(status)) {
2892 DEBUG(1, ("reinit_after_fork failed: %s\n",
2893 nt_errstr(status)));
2896 smbd_echo_loop(sconn, listener_pipe[1]);
2899 close(listener_pipe[1]);
2900 listener_pipe[1] = -1;
2901 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2903 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2906 * Without smb signing this is the same as the normal smbd
2907 * listener. This needs to change once signing comes in.
2909 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
2911 sconn->smb1.echo_handler.trusted_fd,
2913 smbd_server_echo_handler,
2915 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2916 DEBUG(1, ("event_add_fd failed\n"));
2923 if (listener_pipe[0] != -1) {
2924 close(listener_pipe[0]);
2926 if (listener_pipe[1] != -1) {
2927 close(listener_pipe[1]);
2929 sconn->smb1.echo_handler.trusted_fd = -1;
2930 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2931 close(sconn->smb1.echo_handler.socket_lock_fd);
2933 sconn->smb1.echo_handler.trusted_fd = -1;
2934 sconn->smb1.echo_handler.socket_lock_fd = -1;
2940 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2941 struct sockaddr_storage *srv,
2942 struct sockaddr_storage *clnt)
2944 struct ctdbd_connection *cconn;
2945 char tmp_addr[INET6_ADDRSTRLEN];
2948 cconn = messaging_ctdbd_connection();
2949 if (cconn == NULL) {
2950 return NT_STATUS_NO_MEMORY;
2953 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2954 addr = talloc_strdup(cconn, tmp_addr);
2956 return NT_STATUS_NO_MEMORY;
2958 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2963 /****************************************************************************
2964 Process commands from the client
2965 ****************************************************************************/
2967 void smbd_process(struct tevent_context *ev_ctx,
2968 struct smbd_server_connection *sconn)
2970 TALLOC_CTX *frame = talloc_stackframe();
2971 struct sockaddr_storage ss;
2972 struct sockaddr *sa = NULL;
2973 socklen_t sa_socklen;
2974 struct tsocket_address *local_address = NULL;
2975 struct tsocket_address *remote_address = NULL;
2976 const char *locaddr = NULL;
2977 const char *remaddr = NULL;
2981 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
2983 * We're not making the decision here,
2984 * we're just allowing the client
2985 * to decide between SMB1 and SMB2
2986 * with the first negprot
2989 sconn->using_smb2 = true;
2992 /* Ensure child is set to blocking mode */
2993 set_blocking(sconn->sock,True);
2995 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2996 set_socket_options(sconn->sock, lp_socket_options());
2998 sa = (struct sockaddr *)(void *)&ss;
2999 sa_socklen = sizeof(ss);
3000 ret = getpeername(sconn->sock, sa, &sa_socklen);
3002 int level = (errno == ENOTCONN)?2:0;
3003 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3004 exit_server_cleanly("getpeername() failed.\n");
3006 ret = tsocket_address_bsd_from_sockaddr(sconn,
3010 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3011 __location__, strerror(errno)));
3012 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3015 sa = (struct sockaddr *)(void *)&ss;
3016 sa_socklen = sizeof(ss);
3017 ret = getsockname(sconn->sock, sa, &sa_socklen);
3019 int level = (errno == ENOTCONN)?2:0;
3020 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3021 exit_server_cleanly("getsockname() failed.\n");
3023 ret = tsocket_address_bsd_from_sockaddr(sconn,
3027 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3028 __location__, strerror(errno)));
3029 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3032 sconn->local_address = local_address;
3033 sconn->remote_address = remote_address;
3035 if (tsocket_address_is_inet(local_address, "ip")) {
3036 locaddr = tsocket_address_inet_addr_string(
3037 sconn->local_address,
3039 if (locaddr == NULL) {
3040 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3041 __location__, strerror(errno)));
3042 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3045 locaddr = "0.0.0.0";
3048 if (tsocket_address_is_inet(remote_address, "ip")) {
3049 remaddr = tsocket_address_inet_addr_string(
3050 sconn->remote_address,
3052 if (remaddr == NULL) {
3053 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3054 __location__, strerror(errno)));
3055 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3058 remaddr = "0.0.0.0";
3061 /* this is needed so that we get decent entries
3062 in smbstatus for port 445 connects */
3063 set_remote_machine_name(remaddr, false);
3064 reload_services(sconn->msg_ctx, sconn->sock, true);
3067 * Before the first packet, check the global hosts allow/ hosts deny
3068 * parameters before doing any parsing of packets passed to us by the
3069 * client. This prevents attacks on our parsing code from hosts not in
3070 * the hosts allow list.
3073 ret = get_remote_hostname(remote_address,
3077 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3078 __location__, strerror(errno)));
3079 exit_server_cleanly("get_remote_hostname failed.\n");
3081 if (strequal(rhost, "UNKNOWN")) {
3082 rhost = talloc_strdup(talloc_tos(), remaddr);
3084 sconn->remote_hostname = talloc_move(sconn, &rhost);
3086 sub_set_socket_ids(remaddr,
3087 sconn->remote_hostname,
3090 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3091 sconn->remote_hostname,
3094 * send a negative session response "not listening on calling
3097 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3098 DEBUG( 1, ("Connection denied from %s to %s\n",
3099 tsocket_address_string(remote_address, talloc_tos()),
3100 tsocket_address_string(local_address, talloc_tos())));
3101 (void)srv_send_smb(sconn,(char *)buf, false,
3103 exit_server_cleanly("connection denied");
3106 DEBUG(10, ("Connection allowed from %s to %s\n",
3107 tsocket_address_string(remote_address, talloc_tos()),
3108 tsocket_address_string(local_address, talloc_tos())));
3112 smb_perfcount_init();
3114 if (!init_account_policy()) {
3115 exit_server("Could not open account policy tdb.\n");
3118 if (*lp_rootdir()) {
3119 if (chroot(lp_rootdir()) != 0) {
3120 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3121 exit_server("Failed to chroot()");
3123 if (chdir("/") == -1) {
3124 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3125 exit_server("Failed to chroot()");
3127 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3130 if (!srv_init_signing(sconn)) {
3131 exit_server("Failed to init smb_signing");
3135 if (!init_oplocks(sconn))
3136 exit_server("Failed to init oplocks");
3138 /* register our message handlers */
3139 messaging_register(sconn->msg_ctx, sconn,
3140 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3141 messaging_register(sconn->msg_ctx, sconn,
3142 MSG_SMB_CLOSE_FILE, msg_close_file);
3143 messaging_register(sconn->msg_ctx, sconn,
3144 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3147 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3148 * MSGs to all child processes
3150 messaging_deregister(sconn->msg_ctx,
3152 messaging_register(sconn->msg_ctx, NULL,
3153 MSG_DEBUG, debug_message);
3155 if ((lp_keepalive() != 0)
3156 && !(event_add_idle(ev_ctx, NULL,
3157 timeval_set(lp_keepalive(), 0),
3158 "keepalive", keepalive_fn,
3160 DEBUG(0, ("Could not add keepalive event\n"));
3164 if (!(event_add_idle(ev_ctx, NULL,
3165 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3166 "deadtime", deadtime_fn, sconn))) {
3167 DEBUG(0, ("Could not add deadtime event\n"));
3171 if (!(event_add_idle(ev_ctx, NULL,
3172 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3173 "housekeeping", housekeeping_fn, sconn))) {
3174 DEBUG(0, ("Could not add housekeeping event\n"));
3178 #ifdef CLUSTER_SUPPORT
3180 if (lp_clustering()) {
3182 * We need to tell ctdb about our client's TCP
3183 * connection, so that for failover ctdbd can send
3184 * tickle acks, triggering a reconnection by the
3188 struct sockaddr_storage srv, clnt;
3190 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3192 status = smbd_register_ips(sconn, &srv, &clnt);
3193 if (!NT_STATUS_IS_OK(status)) {
3194 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3195 nt_errstr(status)));
3199 DEBUG(0,("Unable to get tcp info for "
3200 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3207 sconn->nbt.got_session = false;
3209 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3211 sconn->smb1.sessions.done_sesssetup = false;
3212 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3213 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3214 /* users from session setup */
3215 sconn->smb1.sessions.session_userlist = NULL;
3216 /* workgroup from session setup. */
3217 sconn->smb1.sessions.session_workgroup = NULL;
3218 /* this holds info on user ids that are already validated for this VC */
3219 sconn->smb1.sessions.validated_users = NULL;
3220 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3221 sconn->smb1.sessions.num_validated_vuids = 0;
3224 if (!init_dptrs(sconn)) {
3225 exit_server("init_dptrs() failed");
3228 sconn->smb1.fde = event_add_fd(ev_ctx,
3232 smbd_server_connection_handler,
3234 if (!sconn->smb1.fde) {
3235 exit_server("failed to create smbd_server_connection fde");
3243 frame = talloc_stackframe_pool(8192);
3247 status = smbd_server_connection_loop_once(ev_ctx, sconn);
3248 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3249 !NT_STATUS_IS_OK(status)) {
3250 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3251 " exiting\n", nt_errstr(status)));
3258 exit_server_cleanly(NULL);
3261 bool req_is_in_chain(struct smb_request *req)
3263 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3265 * We're right now handling a subsequent request, so we must
3271 if (!is_andx_req(req->cmd)) {
3277 * Okay, an illegal request, but definitely not chained :-)
3282 return (CVAL(req->vwv+0, 0) != 0xFF);