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 = event_add_timed(server_event_context(),
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 = event_add_timed(server_event_context(),
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(void)
883 struct tevent_signal *se;
885 se = tevent_add_signal(server_event_context(),
886 server_event_context(),
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 messaging_context *msg_ctx = talloc_get_type_abort(
903 private_data, struct messaging_context);
904 change_to_root_user();
905 DEBUG(1,("Reloading services after SIGHUP\n"));
906 reload_services(msg_ctx, smbd_server_conn->sock, False);
908 printing_subsystem_update(ev, msg_ctx, true);
912 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
913 struct messaging_context *msg_ctx)
915 struct tevent_signal *se;
917 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
920 exit_server("failed to setup SIGHUP handler");
924 static NTSTATUS smbd_server_connection_loop_once(struct tevent_context *ev_ctx,
925 struct smbd_server_connection *conn)
932 timeout = SMBD_SELECT_TIMEOUT * 1000;
935 * Are there any timed events waiting ? If so, ensure we don't
936 * select for longer than it would take to wait for them.
939 event_add_to_poll_args(ev_ctx, conn, &conn->pfds, &num_pfds, &timeout);
941 /* Process a signal and timed events now... */
942 if (run_events_poll(ev_ctx, 0, NULL, 0)) {
943 return NT_STATUS_RETRY;
948 START_PROFILE(smbd_idle);
950 ret = sys_poll(conn->pfds, num_pfds, timeout);
953 END_PROFILE(smbd_idle);
958 if (errno == EINTR) {
959 return NT_STATUS_RETRY;
961 return map_nt_error_from_unix(errno);
964 retry = run_events_poll(ev_ctx, ret, conn->pfds, num_pfds);
966 return NT_STATUS_RETRY;
969 /* Did we timeout ? */
971 return NT_STATUS_RETRY;
974 /* should not be reached */
975 return NT_STATUS_INTERNAL_ERROR;
979 * Only allow 5 outstanding trans requests. We're allocating memory, so
983 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
986 for (; list != NULL; list = list->next) {
988 if (list->mid == mid) {
989 return NT_STATUS_INVALID_PARAMETER;
995 return NT_STATUS_INSUFFICIENT_RESOURCES;
1002 These flags determine some of the permissions required to do an operation
1004 Note that I don't set NEED_WRITE on some write operations because they
1005 are used by some brain-dead clients when printing, and I don't want to
1006 force write permissions on print services.
1008 #define AS_USER (1<<0)
1009 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1010 #define TIME_INIT (1<<2)
1011 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1012 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1013 #define DO_CHDIR (1<<6)
1016 define a list of possible SMB messages and their corresponding
1017 functions. Any message that has a NULL function is unimplemented -
1018 please feel free to contribute implementations!
1020 static const struct smb_message_struct {
1022 void (*fn)(struct smb_request *req);
1024 } smb_messages[256] = {
1026 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1027 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1028 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1029 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1030 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1031 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1032 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1033 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1034 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1035 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1036 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1037 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1038 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1039 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1040 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1041 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1042 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1043 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1044 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1045 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1046 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1047 /* 0x15 */ { NULL, NULL, 0 },
1048 /* 0x16 */ { NULL, NULL, 0 },
1049 /* 0x17 */ { NULL, NULL, 0 },
1050 /* 0x18 */ { NULL, NULL, 0 },
1051 /* 0x19 */ { NULL, NULL, 0 },
1052 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1053 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1054 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1055 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1056 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1057 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1058 /* 0x20 */ { "SMBwritec", NULL,0},
1059 /* 0x21 */ { NULL, NULL, 0 },
1060 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1061 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1062 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1063 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1064 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1065 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1066 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1067 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1068 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1069 /* 0x2b */ { "SMBecho",reply_echo,0},
1070 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1071 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1072 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1073 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1074 /* 0x30 */ { NULL, NULL, 0 },
1075 /* 0x31 */ { NULL, NULL, 0 },
1076 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1077 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1078 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1079 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1080 /* 0x36 */ { NULL, NULL, 0 },
1081 /* 0x37 */ { NULL, NULL, 0 },
1082 /* 0x38 */ { NULL, NULL, 0 },
1083 /* 0x39 */ { NULL, NULL, 0 },
1084 /* 0x3a */ { NULL, NULL, 0 },
1085 /* 0x3b */ { NULL, NULL, 0 },
1086 /* 0x3c */ { NULL, NULL, 0 },
1087 /* 0x3d */ { NULL, NULL, 0 },
1088 /* 0x3e */ { NULL, NULL, 0 },
1089 /* 0x3f */ { NULL, NULL, 0 },
1090 /* 0x40 */ { NULL, NULL, 0 },
1091 /* 0x41 */ { NULL, NULL, 0 },
1092 /* 0x42 */ { NULL, NULL, 0 },
1093 /* 0x43 */ { NULL, NULL, 0 },
1094 /* 0x44 */ { NULL, NULL, 0 },
1095 /* 0x45 */ { NULL, NULL, 0 },
1096 /* 0x46 */ { NULL, NULL, 0 },
1097 /* 0x47 */ { NULL, NULL, 0 },
1098 /* 0x48 */ { NULL, NULL, 0 },
1099 /* 0x49 */ { NULL, NULL, 0 },
1100 /* 0x4a */ { NULL, NULL, 0 },
1101 /* 0x4b */ { NULL, NULL, 0 },
1102 /* 0x4c */ { NULL, NULL, 0 },
1103 /* 0x4d */ { NULL, NULL, 0 },
1104 /* 0x4e */ { NULL, NULL, 0 },
1105 /* 0x4f */ { NULL, NULL, 0 },
1106 /* 0x50 */ { NULL, NULL, 0 },
1107 /* 0x51 */ { NULL, NULL, 0 },
1108 /* 0x52 */ { NULL, NULL, 0 },
1109 /* 0x53 */ { NULL, NULL, 0 },
1110 /* 0x54 */ { NULL, NULL, 0 },
1111 /* 0x55 */ { NULL, NULL, 0 },
1112 /* 0x56 */ { NULL, NULL, 0 },
1113 /* 0x57 */ { NULL, NULL, 0 },
1114 /* 0x58 */ { NULL, NULL, 0 },
1115 /* 0x59 */ { NULL, NULL, 0 },
1116 /* 0x5a */ { NULL, NULL, 0 },
1117 /* 0x5b */ { NULL, NULL, 0 },
1118 /* 0x5c */ { NULL, NULL, 0 },
1119 /* 0x5d */ { NULL, NULL, 0 },
1120 /* 0x5e */ { NULL, NULL, 0 },
1121 /* 0x5f */ { NULL, NULL, 0 },
1122 /* 0x60 */ { NULL, NULL, 0 },
1123 /* 0x61 */ { NULL, NULL, 0 },
1124 /* 0x62 */ { NULL, NULL, 0 },
1125 /* 0x63 */ { NULL, NULL, 0 },
1126 /* 0x64 */ { NULL, NULL, 0 },
1127 /* 0x65 */ { NULL, NULL, 0 },
1128 /* 0x66 */ { NULL, NULL, 0 },
1129 /* 0x67 */ { NULL, NULL, 0 },
1130 /* 0x68 */ { NULL, NULL, 0 },
1131 /* 0x69 */ { NULL, NULL, 0 },
1132 /* 0x6a */ { NULL, NULL, 0 },
1133 /* 0x6b */ { NULL, NULL, 0 },
1134 /* 0x6c */ { NULL, NULL, 0 },
1135 /* 0x6d */ { NULL, NULL, 0 },
1136 /* 0x6e */ { NULL, NULL, 0 },
1137 /* 0x6f */ { NULL, NULL, 0 },
1138 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1139 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1140 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1141 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1142 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1143 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1144 /* 0x76 */ { NULL, NULL, 0 },
1145 /* 0x77 */ { NULL, NULL, 0 },
1146 /* 0x78 */ { NULL, NULL, 0 },
1147 /* 0x79 */ { NULL, NULL, 0 },
1148 /* 0x7a */ { NULL, NULL, 0 },
1149 /* 0x7b */ { NULL, NULL, 0 },
1150 /* 0x7c */ { NULL, NULL, 0 },
1151 /* 0x7d */ { NULL, NULL, 0 },
1152 /* 0x7e */ { NULL, NULL, 0 },
1153 /* 0x7f */ { NULL, NULL, 0 },
1154 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1155 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1156 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1157 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1158 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1159 /* 0x85 */ { NULL, NULL, 0 },
1160 /* 0x86 */ { NULL, NULL, 0 },
1161 /* 0x87 */ { NULL, NULL, 0 },
1162 /* 0x88 */ { NULL, NULL, 0 },
1163 /* 0x89 */ { NULL, NULL, 0 },
1164 /* 0x8a */ { NULL, NULL, 0 },
1165 /* 0x8b */ { NULL, NULL, 0 },
1166 /* 0x8c */ { NULL, NULL, 0 },
1167 /* 0x8d */ { NULL, NULL, 0 },
1168 /* 0x8e */ { NULL, NULL, 0 },
1169 /* 0x8f */ { NULL, NULL, 0 },
1170 /* 0x90 */ { NULL, NULL, 0 },
1171 /* 0x91 */ { NULL, NULL, 0 },
1172 /* 0x92 */ { NULL, NULL, 0 },
1173 /* 0x93 */ { NULL, NULL, 0 },
1174 /* 0x94 */ { NULL, NULL, 0 },
1175 /* 0x95 */ { NULL, NULL, 0 },
1176 /* 0x96 */ { NULL, NULL, 0 },
1177 /* 0x97 */ { NULL, NULL, 0 },
1178 /* 0x98 */ { NULL, NULL, 0 },
1179 /* 0x99 */ { NULL, NULL, 0 },
1180 /* 0x9a */ { NULL, NULL, 0 },
1181 /* 0x9b */ { NULL, NULL, 0 },
1182 /* 0x9c */ { NULL, NULL, 0 },
1183 /* 0x9d */ { NULL, NULL, 0 },
1184 /* 0x9e */ { NULL, NULL, 0 },
1185 /* 0x9f */ { NULL, NULL, 0 },
1186 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1187 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1188 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1189 /* 0xa3 */ { NULL, NULL, 0 },
1190 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1191 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1192 /* 0xa6 */ { NULL, NULL, 0 },
1193 /* 0xa7 */ { NULL, NULL, 0 },
1194 /* 0xa8 */ { NULL, NULL, 0 },
1195 /* 0xa9 */ { NULL, NULL, 0 },
1196 /* 0xaa */ { NULL, NULL, 0 },
1197 /* 0xab */ { NULL, NULL, 0 },
1198 /* 0xac */ { NULL, NULL, 0 },
1199 /* 0xad */ { NULL, NULL, 0 },
1200 /* 0xae */ { NULL, NULL, 0 },
1201 /* 0xaf */ { NULL, NULL, 0 },
1202 /* 0xb0 */ { NULL, NULL, 0 },
1203 /* 0xb1 */ { NULL, NULL, 0 },
1204 /* 0xb2 */ { NULL, NULL, 0 },
1205 /* 0xb3 */ { NULL, NULL, 0 },
1206 /* 0xb4 */ { NULL, NULL, 0 },
1207 /* 0xb5 */ { NULL, NULL, 0 },
1208 /* 0xb6 */ { NULL, NULL, 0 },
1209 /* 0xb7 */ { NULL, NULL, 0 },
1210 /* 0xb8 */ { NULL, NULL, 0 },
1211 /* 0xb9 */ { NULL, NULL, 0 },
1212 /* 0xba */ { NULL, NULL, 0 },
1213 /* 0xbb */ { NULL, NULL, 0 },
1214 /* 0xbc */ { NULL, NULL, 0 },
1215 /* 0xbd */ { NULL, NULL, 0 },
1216 /* 0xbe */ { NULL, NULL, 0 },
1217 /* 0xbf */ { NULL, NULL, 0 },
1218 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1219 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1220 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1221 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1222 /* 0xc4 */ { NULL, NULL, 0 },
1223 /* 0xc5 */ { NULL, NULL, 0 },
1224 /* 0xc6 */ { NULL, NULL, 0 },
1225 /* 0xc7 */ { NULL, NULL, 0 },
1226 /* 0xc8 */ { NULL, NULL, 0 },
1227 /* 0xc9 */ { NULL, NULL, 0 },
1228 /* 0xca */ { NULL, NULL, 0 },
1229 /* 0xcb */ { NULL, NULL, 0 },
1230 /* 0xcc */ { NULL, NULL, 0 },
1231 /* 0xcd */ { NULL, NULL, 0 },
1232 /* 0xce */ { NULL, NULL, 0 },
1233 /* 0xcf */ { NULL, NULL, 0 },
1234 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1235 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1236 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1237 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1238 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1239 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1240 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1241 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1242 /* 0xd8 */ { NULL, NULL, 0 },
1243 /* 0xd9 */ { NULL, NULL, 0 },
1244 /* 0xda */ { NULL, NULL, 0 },
1245 /* 0xdb */ { NULL, NULL, 0 },
1246 /* 0xdc */ { NULL, NULL, 0 },
1247 /* 0xdd */ { NULL, NULL, 0 },
1248 /* 0xde */ { NULL, NULL, 0 },
1249 /* 0xdf */ { NULL, NULL, 0 },
1250 /* 0xe0 */ { NULL, NULL, 0 },
1251 /* 0xe1 */ { NULL, NULL, 0 },
1252 /* 0xe2 */ { NULL, NULL, 0 },
1253 /* 0xe3 */ { NULL, NULL, 0 },
1254 /* 0xe4 */ { NULL, NULL, 0 },
1255 /* 0xe5 */ { NULL, NULL, 0 },
1256 /* 0xe6 */ { NULL, NULL, 0 },
1257 /* 0xe7 */ { NULL, NULL, 0 },
1258 /* 0xe8 */ { NULL, NULL, 0 },
1259 /* 0xe9 */ { NULL, NULL, 0 },
1260 /* 0xea */ { NULL, NULL, 0 },
1261 /* 0xeb */ { NULL, NULL, 0 },
1262 /* 0xec */ { NULL, NULL, 0 },
1263 /* 0xed */ { NULL, NULL, 0 },
1264 /* 0xee */ { NULL, NULL, 0 },
1265 /* 0xef */ { NULL, NULL, 0 },
1266 /* 0xf0 */ { NULL, NULL, 0 },
1267 /* 0xf1 */ { NULL, NULL, 0 },
1268 /* 0xf2 */ { NULL, NULL, 0 },
1269 /* 0xf3 */ { NULL, NULL, 0 },
1270 /* 0xf4 */ { NULL, NULL, 0 },
1271 /* 0xf5 */ { NULL, NULL, 0 },
1272 /* 0xf6 */ { NULL, NULL, 0 },
1273 /* 0xf7 */ { NULL, NULL, 0 },
1274 /* 0xf8 */ { NULL, NULL, 0 },
1275 /* 0xf9 */ { NULL, NULL, 0 },
1276 /* 0xfa */ { NULL, NULL, 0 },
1277 /* 0xfb */ { NULL, NULL, 0 },
1278 /* 0xfc */ { NULL, NULL, 0 },
1279 /* 0xfd */ { NULL, NULL, 0 },
1280 /* 0xfe */ { NULL, NULL, 0 },
1281 /* 0xff */ { NULL, NULL, 0 }
1285 /*******************************************************************
1286 allocate and initialize a reply packet
1287 ********************************************************************/
1289 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1290 const char *inbuf, char **outbuf, uint8_t num_words,
1294 * Protect against integer wrap
1296 if ((num_bytes > 0xffffff)
1297 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1299 if (asprintf(&msg, "num_bytes too large: %u",
1300 (unsigned)num_bytes) == -1) {
1301 msg = discard_const_p(char, "num_bytes too large");
1306 *outbuf = talloc_array(mem_ctx, char,
1307 smb_size + num_words*2 + num_bytes);
1308 if (*outbuf == NULL) {
1312 construct_reply_common(req, inbuf, *outbuf);
1313 srv_set_message(*outbuf, num_words, num_bytes, false);
1315 * Zero out the word area, the caller has to take care of the bcc area
1318 if (num_words != 0) {
1319 memset(*outbuf + smb_vwv0, 0, num_words*2);
1325 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1328 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1330 smb_panic("could not allocate output buffer\n");
1332 req->outbuf = (uint8_t *)outbuf;
1336 /*******************************************************************
1337 Dump a packet to a file.
1338 ********************************************************************/
1340 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1344 if (DEBUGLEVEL < 50) {
1348 if (len < 4) len = smb_len(data)+4;
1349 for (i=1;i<100;i++) {
1350 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1351 type ? "req" : "resp") == -1) {
1354 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1355 if (fd != -1 || errno != EEXIST) break;
1358 ssize_t ret = write(fd, data, len);
1360 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1362 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1367 /****************************************************************************
1368 Prepare everything for calling the actual request function, and potentially
1369 call the request function via the "new" interface.
1371 Return False if the "legacy" function needs to be called, everything is
1374 Return True if we're done.
1376 I know this API sucks, but it is the one with the least code change I could
1378 ****************************************************************************/
1380 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1384 connection_struct *conn = NULL;
1385 struct smbd_server_connection *sconn = req->sconn;
1390 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1391 * so subtract 4 from it. */
1392 if (!valid_smb_header(sconn, req->inbuf)
1393 || (size < (smb_size - 4))) {
1394 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1395 smb_len(req->inbuf)));
1396 exit_server_cleanly("Non-SMB packet");
1399 if (smb_messages[type].fn == NULL) {
1400 DEBUG(0,("Unknown message type %d!\n",type));
1401 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1402 reply_unknown_new(req, type);
1406 flags = smb_messages[type].flags;
1408 /* In share mode security we must ignore the vuid. */
1409 session_tag = (lp_security() == SEC_SHARE)
1410 ? UID_FIELD_INVALID : req->vuid;
1413 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1414 (int)sys_getpid(), (unsigned long)conn));
1416 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1418 /* Ensure this value is replaced in the incoming packet. */
1419 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1422 * Ensure the correct username is in current_user_info. This is a
1423 * really ugly bugfix for problems with multiple session_setup_and_X's
1424 * being done and allowing %U and %G substitutions to work correctly.
1425 * There is a reason this code is done here, don't move it unless you
1426 * know what you're doing... :-).
1430 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1431 user_struct *vuser = NULL;
1433 sconn->smb1.sessions.last_session_tag = session_tag;
1434 if(session_tag != UID_FIELD_INVALID) {
1435 vuser = get_valid_user_struct(sconn, session_tag);
1437 set_current_user_info(
1438 vuser->session_info->unix_info->sanitized_username,
1439 vuser->session_info->unix_info->unix_name,
1440 vuser->session_info->info->domain_name);
1445 /* Does this call need to be run as the connected user? */
1446 if (flags & AS_USER) {
1448 /* Does this call need a valid tree connection? */
1451 * Amazingly, the error code depends on the command
1454 if (type == SMBntcreateX) {
1455 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1457 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1462 if (!change_to_user(conn,session_tag)) {
1463 DEBUG(0, ("Error: Could not change to user. Removing "
1464 "deferred open, mid=%llu.\n",
1465 (unsigned long long)req->mid));
1466 reply_force_doserror(req, ERRSRV, ERRbaduid);
1470 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1472 /* Does it need write permission? */
1473 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1474 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1478 /* IPC services are limited */
1479 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1480 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1484 /* This call needs to be run as root */
1485 change_to_root_user();
1488 /* load service specific parameters */
1490 if (req->encrypted) {
1491 conn->encrypted_tid = true;
1492 /* encrypted required from now on. */
1493 conn->encrypt_level = Required;
1494 } else if (ENCRYPTION_REQUIRED(conn)) {
1495 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1496 exit_server_cleanly("encryption required "
1502 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1503 (flags & (AS_USER|DO_CHDIR)
1505 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1508 conn->num_smb_operations++;
1511 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1513 if (raddr == NULL) {
1514 reply_nterror(req, NT_STATUS_NO_MEMORY);
1518 /* does this protocol need to be run as guest? */
1519 if ((flags & AS_GUEST)
1520 && (!change_to_guest() ||
1521 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1522 sconn->remote_hostname,
1524 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1528 smb_messages[type].fn(req);
1532 /****************************************************************************
1533 Construct a reply to the incoming packet.
1534 ****************************************************************************/
1536 static void construct_reply(struct smbd_server_connection *sconn,
1537 char *inbuf, int size, size_t unread_bytes,
1538 uint32_t seqnum, bool encrypted,
1539 struct smb_perfcount_data *deferred_pcd)
1541 connection_struct *conn;
1542 struct smb_request *req;
1544 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1545 smb_panic("could not allocate smb_request");
1548 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1549 encrypted, seqnum)) {
1550 exit_server_cleanly("Invalid SMB request");
1553 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1555 /* we popped this message off the queue - keep original perf data */
1557 req->pcd = *deferred_pcd;
1559 SMB_PERFCOUNT_START(&req->pcd);
1560 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1561 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1564 conn = switch_message(req->cmd, req, size);
1566 if (req->unread_bytes) {
1567 /* writeX failed. drain socket. */
1568 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1569 req->unread_bytes) {
1570 smb_panic("failed to drain pending bytes");
1572 req->unread_bytes = 0;
1580 if (req->outbuf == NULL) {
1584 if (CVAL(req->outbuf,0) == 0) {
1585 show_msg((char *)req->outbuf);
1588 if (!srv_send_smb(req->sconn,
1589 (char *)req->outbuf,
1590 true, req->seqnum+1,
1591 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1593 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1601 /****************************************************************************
1602 Process an smb from the client
1603 ****************************************************************************/
1604 static void process_smb(struct smbd_server_connection *sconn,
1605 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1606 uint32_t seqnum, bool encrypted,
1607 struct smb_perfcount_data *deferred_pcd)
1609 int msg_type = CVAL(inbuf,0);
1611 DO_PROFILE_INC(smb_count);
1613 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1615 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1616 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1618 if (msg_type != NBSSmessage) {
1620 * NetBIOS session request, keepalive, etc.
1622 reply_special(sconn, (char *)inbuf, nread);
1626 if (sconn->using_smb2) {
1627 /* At this point we're not really using smb2,
1628 * we make the decision here.. */
1629 if (smbd_is_smb2_header(inbuf, nread)) {
1630 smbd_smb2_first_negprot(sconn, inbuf, nread);
1632 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1633 && CVAL(inbuf, smb_com) != 0x72) {
1634 /* This is a non-negprot SMB1 packet.
1635 Disable SMB2 from now on. */
1636 sconn->using_smb2 = false;
1640 show_msg((char *)inbuf);
1642 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1643 encrypted, deferred_pcd);
1647 sconn->num_requests++;
1649 /* The timeout_processing function isn't run nearly
1650 often enough to implement 'max log size' without
1651 overrunning the size of the file by many megabytes.
1652 This is especially true if we are running at debug
1653 level 10. Checking every 50 SMBs is a nice
1654 tradeoff of performance vs log file size overrun. */
1656 if ((sconn->num_requests % 50) == 0 &&
1657 need_to_check_log_size()) {
1658 change_to_root_user();
1663 /****************************************************************************
1664 Return a string containing the function name of a SMB command.
1665 ****************************************************************************/
1667 const char *smb_fn_name(int type)
1669 const char *unknown_name = "SMBunknown";
1671 if (smb_messages[type].name == NULL)
1672 return(unknown_name);
1674 return(smb_messages[type].name);
1677 /****************************************************************************
1678 Helper functions for contruct_reply.
1679 ****************************************************************************/
1681 void add_to_common_flags2(uint32 v)
1686 void remove_from_common_flags2(uint32 v)
1688 common_flags2 &= ~v;
1691 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1694 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1695 uint16_t out_flags2 = common_flags2;
1697 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1698 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1699 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1701 srv_set_message(outbuf,0,0,false);
1703 SCVAL(outbuf, smb_com, req->cmd);
1704 SIVAL(outbuf,smb_rcls,0);
1705 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1706 SSVAL(outbuf,smb_flg2, out_flags2);
1707 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1708 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1710 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1711 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1712 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1713 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1716 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1718 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1722 * How many bytes have we already accumulated up to the current wct field
1726 size_t req_wct_ofs(struct smb_request *req)
1730 if (req->chain_outbuf == NULL) {
1733 buf_size = talloc_get_size(req->chain_outbuf);
1734 if ((buf_size % 4) != 0) {
1735 buf_size += (4 - (buf_size % 4));
1737 return buf_size - 4;
1741 * Hack around reply_nterror & friends not being aware of chained requests,
1742 * generating illegal (i.e. wct==0) chain replies.
1745 static void fixup_chain_error_packet(struct smb_request *req)
1747 uint8_t *outbuf = req->outbuf;
1749 reply_outbuf(req, 2, 0);
1750 memcpy(req->outbuf, outbuf, smb_wct);
1751 TALLOC_FREE(outbuf);
1752 SCVAL(req->outbuf, smb_vwv0, 0xff);
1756 * @brief Find the smb_cmd offset of the last command pushed
1757 * @param[in] buf The buffer we're building up
1758 * @retval Where can we put our next andx cmd?
1760 * While chaining requests, the "next" request we're looking at needs to put
1761 * its SMB_Command before the data the previous request already built up added
1762 * to the chain. Find the offset to the place where we have to put our cmd.
1765 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1770 cmd = CVAL(buf, smb_com);
1772 SMB_ASSERT(is_andx_req(cmd));
1776 while (CVAL(buf, ofs) != 0xff) {
1778 if (!is_andx_req(CVAL(buf, ofs))) {
1783 * ofs is from start of smb header, so add the 4 length
1784 * bytes. The next cmd is right after the wct field.
1786 ofs = SVAL(buf, ofs+2) + 4 + 1;
1788 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1796 * @brief Do the smb chaining at a buffer level
1797 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1798 * @param[in] smb_command The command that we want to issue
1799 * @param[in] wct How many words?
1800 * @param[in] vwv The words, already in network order
1801 * @param[in] bytes_alignment How shall we align "bytes"?
1802 * @param[in] num_bytes How many bytes?
1803 * @param[in] bytes The data the request ships
1805 * smb_splice_chain() adds the vwv and bytes to the request already present in
1809 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1810 uint8_t wct, const uint16_t *vwv,
1811 size_t bytes_alignment,
1812 uint32_t num_bytes, const uint8_t *bytes)
1815 size_t old_size, new_size;
1817 size_t chain_padding = 0;
1818 size_t bytes_padding = 0;
1821 old_size = talloc_get_size(*poutbuf);
1824 * old_size == smb_wct means we're pushing the first request in for
1828 first_request = (old_size == smb_wct);
1830 if (!first_request && ((old_size % 4) != 0)) {
1832 * Align the wct field of subsequent requests to a 4-byte
1835 chain_padding = 4 - (old_size % 4);
1839 * After the old request comes the new wct field (1 byte), the vwv's
1840 * and the num_bytes field. After at we might need to align the bytes
1841 * given to us to "bytes_alignment", increasing the num_bytes value.
1844 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1846 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1847 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1850 new_size += bytes_padding + num_bytes;
1852 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1853 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1854 (unsigned)new_size));
1858 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1859 if (outbuf == NULL) {
1860 DEBUG(0, ("talloc failed\n"));
1865 if (first_request) {
1866 SCVAL(outbuf, smb_com, smb_command);
1868 size_t andx_cmd_ofs;
1870 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1871 DEBUG(1, ("invalid command chain\n"));
1872 *poutbuf = talloc_realloc(
1873 NULL, *poutbuf, uint8_t, old_size);
1877 if (chain_padding != 0) {
1878 memset(outbuf + old_size, 0, chain_padding);
1879 old_size += chain_padding;
1882 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1883 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1889 * Push the chained request:
1894 SCVAL(outbuf, ofs, wct);
1901 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1902 ofs += sizeof(uint16_t) * wct;
1908 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1909 ofs += sizeof(uint16_t);
1915 if (bytes_padding != 0) {
1916 memset(outbuf + ofs, 0, bytes_padding);
1917 ofs += bytes_padding;
1924 memcpy(outbuf + ofs, bytes, num_bytes);
1929 /****************************************************************************
1930 Construct a chained reply and add it to the already made reply
1931 ****************************************************************************/
1933 void chain_reply(struct smb_request *req)
1935 size_t smblen = smb_len(req->inbuf);
1936 size_t already_used, length_needed;
1938 uint32_t chain_offset; /* uint32_t to avoid overflow */
1941 const uint16_t *vwv;
1945 if (IVAL(req->outbuf, smb_rcls) != 0) {
1946 fixup_chain_error_packet(req);
1950 * Any of the AndX requests and replies have at least a wct of
1951 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1952 * beginning of the SMB header to the next wct field.
1954 * None of the AndX requests put anything valuable in vwv[0] and [1],
1955 * so we can overwrite it here to form the chain.
1958 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1959 if (req->chain_outbuf == NULL) {
1960 req->chain_outbuf = talloc_realloc(
1961 req, req->outbuf, uint8_t,
1962 smb_len(req->outbuf) + 4);
1963 if (req->chain_outbuf == NULL) {
1964 smb_panic("talloc failed");
1972 * Here we assume that this is the end of the chain. For that we need
1973 * to set "next command" to 0xff and the offset to 0. If we later find
1974 * more commands in the chain, this will be overwritten again.
1977 SCVAL(req->outbuf, smb_vwv0, 0xff);
1978 SCVAL(req->outbuf, smb_vwv0+1, 0);
1979 SSVAL(req->outbuf, smb_vwv1, 0);
1981 if (req->chain_outbuf == NULL) {
1983 * In req->chain_outbuf we collect all the replies. Start the
1984 * chain by copying in the first reply.
1986 * We do the realloc because later on we depend on
1987 * talloc_get_size to determine the length of
1988 * chain_outbuf. The reply_xxx routines might have
1989 * over-allocated (reply_pipe_read_and_X used to be such an
1992 req->chain_outbuf = talloc_realloc(
1993 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1994 if (req->chain_outbuf == NULL) {
1995 smb_panic("talloc failed");
2000 * Update smb headers where subsequent chained commands
2001 * may have updated them.
2003 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2004 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2006 if (!smb_splice_chain(&req->chain_outbuf,
2007 CVAL(req->outbuf, smb_com),
2008 CVAL(req->outbuf, smb_wct),
2009 (uint16_t *)(req->outbuf + smb_vwv),
2010 0, smb_buflen(req->outbuf),
2011 (uint8_t *)smb_buf(req->outbuf))) {
2014 TALLOC_FREE(req->outbuf);
2018 * We use the old request's vwv field to grab the next chained command
2019 * and offset into the chained fields.
2022 chain_cmd = CVAL(req->vwv+0, 0);
2023 chain_offset = SVAL(req->vwv+1, 0);
2025 if (chain_cmd == 0xff) {
2027 * End of chain, no more requests from the client. So ship the
2030 smb_setlen((char *)(req->chain_outbuf),
2031 talloc_get_size(req->chain_outbuf) - 4);
2033 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2034 true, req->seqnum+1,
2035 IS_CONN_ENCRYPTED(req->conn)
2038 exit_server_cleanly("chain_reply: srv_send_smb "
2041 TALLOC_FREE(req->chain_outbuf);
2046 /* add a new perfcounter for this element of chain */
2047 SMB_PERFCOUNT_ADD(&req->pcd);
2048 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2049 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2052 * Check if the client tries to fool us. The chain offset
2053 * needs to point beyond the current request in the chain, it
2054 * needs to strictly grow. Otherwise we might be tricked into
2055 * an endless loop always processing the same request over and
2056 * over again. We used to assume that vwv and the byte buffer
2057 * array in a chain are always attached, but OS/2 the
2058 * Write&X/Read&X chain puts the Read&X vwv array right behind
2059 * the Write&X vwv chain. The Write&X bcc array is put behind
2060 * the Read&X vwv array. So now we check whether the chain
2061 * offset points strictly behind the previous vwv
2062 * array. req->buf points right after the vwv array of the
2063 * previous request. See
2064 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2068 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2069 if (chain_offset <= already_used) {
2074 * Next check: Make sure the chain offset does not point beyond the
2075 * overall smb request length.
2078 length_needed = chain_offset+1; /* wct */
2079 if (length_needed > smblen) {
2084 * Now comes the pointer magic. Goal here is to set up req->vwv and
2085 * req->buf correctly again to be able to call the subsequent
2086 * switch_message(). The chain offset (the former vwv[1]) points at
2087 * the new wct field.
2090 wct = CVAL(smb_base(req->inbuf), chain_offset);
2093 * Next consistency check: Make the new vwv array fits in the overall
2097 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2098 if (length_needed > smblen) {
2101 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2104 * Now grab the new byte buffer....
2107 buflen = SVAL(vwv+wct, 0);
2110 * .. and check that it fits.
2113 length_needed += buflen;
2114 if (length_needed > smblen) {
2117 buf = (const uint8_t *)(vwv+wct+1);
2119 req->cmd = chain_cmd;
2121 req->vwv = discard_const_p(uint16_t, vwv);
2122 req->buflen = buflen;
2125 switch_message(chain_cmd, req, smblen);
2127 if (req->outbuf == NULL) {
2129 * This happens if the chained command has suspended itself or
2130 * if it has called srv_send_smb() itself.
2136 * We end up here if the chained command was not itself chained or
2137 * suspended, but for example a close() command. We now need to splice
2138 * the chained commands' outbuf into the already built up chain_outbuf
2139 * and ship the result.
2145 * We end up here if there's any error in the chain syntax. Report a
2146 * DOS error, just like Windows does.
2148 reply_force_doserror(req, ERRSRV, ERRerror);
2149 fixup_chain_error_packet(req);
2153 * This scary statement intends to set the
2154 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2155 * to the value req->outbuf carries
2157 SSVAL(req->chain_outbuf, smb_flg2,
2158 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2159 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2162 * Transfer the error codes from the subrequest to the main one
2164 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2165 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2167 if (!smb_splice_chain(&req->chain_outbuf,
2168 CVAL(req->outbuf, smb_com),
2169 CVAL(req->outbuf, smb_wct),
2170 (uint16_t *)(req->outbuf + smb_vwv),
2171 0, smb_buflen(req->outbuf),
2172 (uint8_t *)smb_buf(req->outbuf))) {
2173 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2175 TALLOC_FREE(req->outbuf);
2177 smb_setlen((char *)(req->chain_outbuf),
2178 talloc_get_size(req->chain_outbuf) - 4);
2180 show_msg((char *)(req->chain_outbuf));
2182 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2183 true, req->seqnum+1,
2184 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2186 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2188 TALLOC_FREE(req->chain_outbuf);
2192 /****************************************************************************
2193 Check if services need reloading.
2194 ****************************************************************************/
2196 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2199 if (last_smb_conf_reload_time == 0) {
2200 last_smb_conf_reload_time = t;
2203 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2204 reload_services(sconn->msg_ctx, sconn->sock, True);
2205 last_smb_conf_reload_time = t;
2209 static bool fd_is_readable(int fd)
2213 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2215 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2219 static void smbd_server_connection_write_handler(
2220 struct smbd_server_connection *sconn)
2222 /* TODO: make write nonblocking */
2225 static void smbd_server_connection_read_handler(
2226 struct smbd_server_connection *sconn, int fd)
2228 uint8_t *inbuf = NULL;
2229 size_t inbuf_len = 0;
2230 size_t unread_bytes = 0;
2231 bool encrypted = false;
2232 TALLOC_CTX *mem_ctx = talloc_tos();
2238 if (lp_async_smb_echo_handler()
2239 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2241 * This is the super-ugly hack to prefer the packets
2242 * forwarded by the echo handler over the ones by the
2245 fd = sconn->smb1.echo_handler.trusted_fd;
2248 from_client = (sconn->sock == fd);
2251 smbd_lock_socket(sconn);
2253 if (!fd_is_readable(fd)) {
2254 DEBUG(10,("the echo listener was faster\n"));
2255 smbd_unlock_socket(sconn);
2260 /* TODO: make this completely nonblocking */
2261 status = receive_smb_talloc(mem_ctx, sconn, fd,
2262 (char **)(void *)&inbuf,
2266 &inbuf_len, &seqnum,
2267 false /* trusted channel */);
2270 smbd_unlock_socket(sconn);
2273 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2276 if (NT_STATUS_IS_ERR(status)) {
2277 exit_server_cleanly("failed to receive smb request");
2279 if (!NT_STATUS_IS_OK(status)) {
2284 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2285 seqnum, encrypted, NULL);
2288 static void smbd_server_connection_handler(struct event_context *ev,
2289 struct fd_event *fde,
2293 struct smbd_server_connection *conn = talloc_get_type(private_data,
2294 struct smbd_server_connection);
2296 if (flags & EVENT_FD_WRITE) {
2297 smbd_server_connection_write_handler(conn);
2300 if (flags & EVENT_FD_READ) {
2301 smbd_server_connection_read_handler(conn, conn->sock);
2306 static void smbd_server_echo_handler(struct event_context *ev,
2307 struct fd_event *fde,
2311 struct smbd_server_connection *conn = talloc_get_type(private_data,
2312 struct smbd_server_connection);
2314 if (flags & EVENT_FD_WRITE) {
2315 smbd_server_connection_write_handler(conn);
2318 if (flags & EVENT_FD_READ) {
2319 smbd_server_connection_read_handler(
2320 conn, conn->smb1.echo_handler.trusted_fd);
2325 #ifdef CLUSTER_SUPPORT
2326 /****************************************************************************
2327 received when we should release a specific IP
2328 ****************************************************************************/
2329 static void release_ip(const char *ip, void *priv)
2331 const char *addr = (const char *)priv;
2332 const char *p = addr;
2334 if (strncmp("::ffff:", addr, 7) == 0) {
2338 DEBUG(10, ("Got release IP message for %s, "
2339 "our address is %s\n", ip, p));
2341 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2342 /* we can't afford to do a clean exit - that involves
2343 database writes, which would potentially mean we
2344 are still running after the failover has finished -
2345 we have to get rid of this process ID straight
2347 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2349 /* note we must exit with non-zero status so the unclean handler gets
2350 called in the parent, so that the brl database is tickled */
2355 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2356 struct sockaddr_storage *client)
2359 length = sizeof(*server);
2360 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2363 length = sizeof(*client);
2364 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2372 * Send keepalive packets to our client
2374 static bool keepalive_fn(const struct timeval *now, void *private_data)
2376 struct smbd_server_connection *sconn = talloc_get_type_abort(
2377 private_data, struct smbd_server_connection);
2380 if (sconn->using_smb2) {
2381 /* Don't do keepalives on an SMB2 connection. */
2385 smbd_lock_socket(sconn);
2386 ret = send_keepalive(sconn->sock);
2387 smbd_unlock_socket(sconn);
2390 char addr[INET6_ADDRSTRLEN];
2392 * Try and give an error message saying what
2395 DEBUG(0, ("send_keepalive failed for client %s. "
2396 "Error %s - exiting\n",
2397 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2405 * Do the recurring check if we're idle
2407 static bool deadtime_fn(const struct timeval *now, void *private_data)
2409 struct smbd_server_connection *sconn =
2410 (struct smbd_server_connection *)private_data;
2412 if ((conn_num_open(sconn) == 0)
2413 || (conn_idle_all(sconn, now->tv_sec))) {
2414 DEBUG( 2, ( "Closing idle connection\n" ) );
2415 messaging_send(sconn->msg_ctx,
2416 messaging_server_id(sconn->msg_ctx),
2417 MSG_SHUTDOWN, &data_blob_null);
2425 * Do the recurring log file and smb.conf reload checks.
2428 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2430 struct smbd_server_connection *sconn = talloc_get_type_abort(
2431 private_data, struct smbd_server_connection);
2433 DEBUG(5, ("housekeeping\n"));
2435 change_to_root_user();
2437 /* update printer queue caches if necessary */
2438 update_monitored_printq_cache(sconn->msg_ctx);
2440 /* check if we need to reload services */
2441 check_reload(sconn, time_mono(NULL));
2443 /* Change machine password if neccessary. */
2444 attempt_machine_password_change();
2447 * Force a log file check.
2449 force_check_log_size();
2455 * Read an smb packet in the echo handler child, giving the parent
2456 * smbd one second to react once the socket becomes readable.
2459 struct smbd_echo_read_state {
2460 struct tevent_context *ev;
2461 struct smbd_server_connection *sconn;
2468 static void smbd_echo_read_readable(struct tevent_req *subreq);
2469 static void smbd_echo_read_waited(struct tevent_req *subreq);
2471 static struct tevent_req *smbd_echo_read_send(
2472 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2473 struct smbd_server_connection *sconn)
2475 struct tevent_req *req, *subreq;
2476 struct smbd_echo_read_state *state;
2478 req = tevent_req_create(mem_ctx, &state,
2479 struct smbd_echo_read_state);
2484 state->sconn = sconn;
2486 subreq = wait_for_read_send(state, ev, sconn->sock);
2487 if (tevent_req_nomem(subreq, req)) {
2488 return tevent_req_post(req, ev);
2490 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2494 static void smbd_echo_read_readable(struct tevent_req *subreq)
2496 struct tevent_req *req = tevent_req_callback_data(
2497 subreq, struct tevent_req);
2498 struct smbd_echo_read_state *state = tevent_req_data(
2499 req, struct smbd_echo_read_state);
2503 ok = wait_for_read_recv(subreq, &err);
2504 TALLOC_FREE(subreq);
2506 tevent_req_nterror(req, map_nt_error_from_unix(err));
2511 * Give the parent smbd one second to step in
2514 subreq = tevent_wakeup_send(
2515 state, state->ev, timeval_current_ofs(1, 0));
2516 if (tevent_req_nomem(subreq, req)) {
2519 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2522 static void smbd_echo_read_waited(struct tevent_req *subreq)
2524 struct tevent_req *req = tevent_req_callback_data(
2525 subreq, struct tevent_req);
2526 struct smbd_echo_read_state *state = tevent_req_data(
2527 req, struct smbd_echo_read_state);
2528 struct smbd_server_connection *sconn = state->sconn;
2534 ok = tevent_wakeup_recv(subreq);
2535 TALLOC_FREE(subreq);
2537 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2541 ok = smbd_lock_socket_internal(sconn);
2543 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2544 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2548 if (!fd_is_readable(sconn->sock)) {
2549 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2550 (int)sys_getpid()));
2552 ok = smbd_unlock_socket_internal(sconn);
2554 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2555 DEBUG(1, ("%s: failed to unlock socket\n",
2560 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2561 if (tevent_req_nomem(subreq, req)) {
2564 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2568 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2574 false /* trusted_channel*/);
2576 if (tevent_req_nterror(req, status)) {
2577 tevent_req_nterror(req, status);
2578 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2579 (int)sys_getpid(), nt_errstr(status)));
2583 ok = smbd_unlock_socket_internal(sconn);
2585 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2586 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2589 tevent_req_done(req);
2592 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2593 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2595 struct smbd_echo_read_state *state = tevent_req_data(
2596 req, struct smbd_echo_read_state);
2599 if (tevent_req_is_nterror(req, &status)) {
2602 *pbuf = talloc_move(mem_ctx, &state->buf);
2603 *pbuflen = state->buflen;
2604 *pseqnum = state->seqnum;
2605 return NT_STATUS_OK;
2608 struct smbd_echo_state {
2609 struct tevent_context *ev;
2610 struct iovec *pending;
2611 struct smbd_server_connection *sconn;
2614 struct tevent_fd *parent_fde;
2616 struct tevent_req *write_req;
2619 static void smbd_echo_writer_done(struct tevent_req *req);
2621 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2625 if (state->write_req != NULL) {
2629 num_pending = talloc_array_length(state->pending);
2630 if (num_pending == 0) {
2634 state->write_req = writev_send(state, state->ev, NULL,
2635 state->parent_pipe, false,
2636 state->pending, num_pending);
2637 if (state->write_req == NULL) {
2638 DEBUG(1, ("writev_send failed\n"));
2642 talloc_steal(state->write_req, state->pending);
2643 state->pending = NULL;
2645 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2649 static void smbd_echo_writer_done(struct tevent_req *req)
2651 struct smbd_echo_state *state = tevent_req_callback_data(
2652 req, struct smbd_echo_state);
2656 written = writev_recv(req, &err);
2658 state->write_req = NULL;
2659 if (written == -1) {
2660 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2663 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2664 smbd_echo_activate_writer(state);
2667 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2670 struct smb_request req;
2671 uint16_t num_replies;
2676 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2677 DEBUG(10, ("Got netbios keepalive\n"));
2684 if (inbuf_len < smb_size) {
2685 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2688 if (!valid_smb_header(smbd_server_conn, inbuf)) {
2689 DEBUG(10, ("Got invalid SMB header\n"));
2693 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2699 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2700 smb_messages[req.cmd].name
2701 ? smb_messages[req.cmd].name : "unknown"));
2703 if (req.cmd != SMBecho) {
2710 num_replies = SVAL(req.vwv+0, 0);
2711 if (num_replies != 1) {
2712 /* Not a Windows "Hey, you're still there?" request */
2716 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2718 DEBUG(10, ("create_outbuf failed\n"));
2721 req.outbuf = (uint8_t *)outbuf;
2723 SSVAL(req.outbuf, smb_vwv0, num_replies);
2725 if (req.buflen > 0) {
2726 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2729 out_len = smb_len(req.outbuf) + 4;
2731 ok = srv_send_smb(req.sconn,
2735 TALLOC_FREE(outbuf);
2743 static void smbd_echo_exit(struct tevent_context *ev,
2744 struct tevent_fd *fde, uint16_t flags,
2747 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2751 static void smbd_echo_got_packet(struct tevent_req *req);
2753 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2756 struct smbd_echo_state *state;
2757 struct tevent_req *read_req;
2759 state = talloc_zero(sconn, struct smbd_echo_state);
2760 if (state == NULL) {
2761 DEBUG(1, ("talloc failed\n"));
2764 state->sconn = sconn;
2765 state->parent_pipe = parent_pipe;
2766 state->ev = s3_tevent_context_init(state);
2767 if (state->ev == NULL) {
2768 DEBUG(1, ("tevent_context_init failed\n"));
2772 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2773 TEVENT_FD_READ, smbd_echo_exit,
2775 if (state->parent_fde == NULL) {
2776 DEBUG(1, ("tevent_add_fd failed\n"));
2781 read_req = smbd_echo_read_send(state, state->ev, sconn);
2782 if (read_req == NULL) {
2783 DEBUG(1, ("smbd_echo_read_send failed\n"));
2787 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2790 if (tevent_loop_once(state->ev) == -1) {
2791 DEBUG(1, ("tevent_loop_once failed: %s\n",
2799 static void smbd_echo_got_packet(struct tevent_req *req)
2801 struct smbd_echo_state *state = tevent_req_callback_data(
2802 req, struct smbd_echo_state);
2806 uint32_t seqnum = 0;
2809 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2811 if (!NT_STATUS_IS_OK(status)) {
2812 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2813 nt_errstr(status)));
2817 reply = smbd_echo_reply((uint8_t *)buf, buflen, seqnum);
2823 num_pending = talloc_array_length(state->pending);
2824 tmp = talloc_realloc(state, state->pending, struct iovec,
2827 DEBUG(1, ("talloc_realloc failed\n"));
2830 state->pending = tmp;
2832 if (buflen >= smb_size) {
2834 * place the seqnum in the packet so that the main process
2835 * can reply with signing
2837 SIVAL(buf, smb_ss_field, seqnum);
2838 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2841 iov = &state->pending[num_pending];
2842 iov->iov_base = buf;
2843 iov->iov_len = buflen;
2845 DEBUG(10,("echo_handler[%d]: forward to main\n",
2846 (int)sys_getpid()));
2847 smbd_echo_activate_writer(state);
2850 req = smbd_echo_read_send(state, state->ev, state->sconn);
2852 DEBUG(1, ("smbd_echo_read_send failed\n"));
2855 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2860 * Handle SMBecho requests in a forked child process
2862 bool fork_echo_handler(struct smbd_server_connection *sconn)
2864 int listener_pipe[2];
2868 res = pipe(listener_pipe);
2870 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2873 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2874 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2875 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2883 close(listener_pipe[0]);
2884 set_blocking(listener_pipe[1], false);
2886 status = reinit_after_fork(sconn->msg_ctx,
2887 server_event_context(),
2888 procid_self(), false);
2889 if (!NT_STATUS_IS_OK(status)) {
2890 DEBUG(1, ("reinit_after_fork failed: %s\n",
2891 nt_errstr(status)));
2894 smbd_echo_loop(sconn, listener_pipe[1]);
2897 close(listener_pipe[1]);
2898 listener_pipe[1] = -1;
2899 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2901 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2904 * Without smb signing this is the same as the normal smbd
2905 * listener. This needs to change once signing comes in.
2907 sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
2909 sconn->smb1.echo_handler.trusted_fd,
2911 smbd_server_echo_handler,
2913 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2914 DEBUG(1, ("event_add_fd failed\n"));
2921 if (listener_pipe[0] != -1) {
2922 close(listener_pipe[0]);
2924 if (listener_pipe[1] != -1) {
2925 close(listener_pipe[1]);
2927 sconn->smb1.echo_handler.trusted_fd = -1;
2928 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2929 close(sconn->smb1.echo_handler.socket_lock_fd);
2931 sconn->smb1.echo_handler.trusted_fd = -1;
2932 sconn->smb1.echo_handler.socket_lock_fd = -1;
2938 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2939 struct sockaddr_storage *srv,
2940 struct sockaddr_storage *clnt)
2942 struct ctdbd_connection *cconn;
2943 char tmp_addr[INET6_ADDRSTRLEN];
2946 cconn = messaging_ctdbd_connection();
2947 if (cconn == NULL) {
2948 return NT_STATUS_NO_MEMORY;
2951 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2952 addr = talloc_strdup(cconn, tmp_addr);
2954 return NT_STATUS_NO_MEMORY;
2956 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2961 /****************************************************************************
2962 Process commands from the client
2963 ****************************************************************************/
2965 void smbd_process(struct tevent_context *ev_ctx,
2966 struct smbd_server_connection *sconn)
2968 TALLOC_CTX *frame = talloc_stackframe();
2969 struct sockaddr_storage ss;
2970 struct sockaddr *sa = NULL;
2971 socklen_t sa_socklen;
2972 struct tsocket_address *local_address = NULL;
2973 struct tsocket_address *remote_address = NULL;
2974 const char *locaddr = NULL;
2975 const char *remaddr = NULL;
2979 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
2981 * We're not making the decision here,
2982 * we're just allowing the client
2983 * to decide between SMB1 and SMB2
2984 * with the first negprot
2987 sconn->using_smb2 = true;
2990 /* Ensure child is set to blocking mode */
2991 set_blocking(sconn->sock,True);
2993 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2994 set_socket_options(sconn->sock, lp_socket_options());
2996 sa = (struct sockaddr *)(void *)&ss;
2997 sa_socklen = sizeof(ss);
2998 ret = getpeername(sconn->sock, sa, &sa_socklen);
3000 int level = (errno == ENOTCONN)?2:0;
3001 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3002 exit_server_cleanly("getpeername() failed.\n");
3004 ret = tsocket_address_bsd_from_sockaddr(sconn,
3008 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3009 __location__, strerror(errno)));
3010 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3013 sa = (struct sockaddr *)(void *)&ss;
3014 sa_socklen = sizeof(ss);
3015 ret = getsockname(sconn->sock, sa, &sa_socklen);
3017 int level = (errno == ENOTCONN)?2:0;
3018 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3019 exit_server_cleanly("getsockname() failed.\n");
3021 ret = tsocket_address_bsd_from_sockaddr(sconn,
3025 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3026 __location__, strerror(errno)));
3027 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3030 sconn->local_address = local_address;
3031 sconn->remote_address = remote_address;
3033 if (tsocket_address_is_inet(local_address, "ip")) {
3034 locaddr = tsocket_address_inet_addr_string(
3035 sconn->local_address,
3037 if (locaddr == NULL) {
3038 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3039 __location__, strerror(errno)));
3040 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3043 locaddr = "0.0.0.0";
3046 if (tsocket_address_is_inet(remote_address, "ip")) {
3047 remaddr = tsocket_address_inet_addr_string(
3048 sconn->remote_address,
3050 if (remaddr == NULL) {
3051 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3052 __location__, strerror(errno)));
3053 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3056 remaddr = "0.0.0.0";
3059 /* this is needed so that we get decent entries
3060 in smbstatus for port 445 connects */
3061 set_remote_machine_name(remaddr, false);
3062 reload_services(sconn->msg_ctx, sconn->sock, true);
3065 * Before the first packet, check the global hosts allow/ hosts deny
3066 * parameters before doing any parsing of packets passed to us by the
3067 * client. This prevents attacks on our parsing code from hosts not in
3068 * the hosts allow list.
3071 ret = get_remote_hostname(remote_address,
3075 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3076 __location__, strerror(errno)));
3077 exit_server_cleanly("get_remote_hostname failed.\n");
3079 if (strequal(rhost, "UNKNOWN")) {
3080 rhost = talloc_strdup(talloc_tos(), remaddr);
3082 sconn->remote_hostname = talloc_move(sconn, &rhost);
3084 sub_set_socket_ids(remaddr,
3085 sconn->remote_hostname,
3088 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3089 sconn->remote_hostname,
3092 * send a negative session response "not listening on calling
3095 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3096 DEBUG( 1, ("Connection denied from %s to %s\n",
3097 tsocket_address_string(remote_address, talloc_tos()),
3098 tsocket_address_string(local_address, talloc_tos())));
3099 (void)srv_send_smb(sconn,(char *)buf, false,
3101 exit_server_cleanly("connection denied");
3104 DEBUG(10, ("Connection allowed from %s to %s\n",
3105 tsocket_address_string(remote_address, talloc_tos()),
3106 tsocket_address_string(local_address, talloc_tos())));
3110 smb_perfcount_init();
3112 if (!init_account_policy()) {
3113 exit_server("Could not open account policy tdb.\n");
3116 if (*lp_rootdir()) {
3117 if (chroot(lp_rootdir()) != 0) {
3118 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3119 exit_server("Failed to chroot()");
3121 if (chdir("/") == -1) {
3122 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3123 exit_server("Failed to chroot()");
3125 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3128 if (!srv_init_signing(sconn)) {
3129 exit_server("Failed to init smb_signing");
3133 if (!init_oplocks(sconn->msg_ctx))
3134 exit_server("Failed to init oplocks");
3136 /* register our message handlers */
3137 messaging_register(sconn->msg_ctx, NULL,
3138 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3139 messaging_register(sconn->msg_ctx, NULL,
3140 MSG_SMB_CLOSE_FILE, msg_close_file);
3143 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3144 * MSGs to all child processes
3146 messaging_deregister(sconn->msg_ctx,
3148 messaging_register(sconn->msg_ctx, NULL,
3149 MSG_DEBUG, debug_message);
3151 if ((lp_keepalive() != 0)
3152 && !(event_add_idle(ev_ctx, NULL,
3153 timeval_set(lp_keepalive(), 0),
3154 "keepalive", keepalive_fn,
3156 DEBUG(0, ("Could not add keepalive event\n"));
3160 if (!(event_add_idle(ev_ctx, NULL,
3161 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3162 "deadtime", deadtime_fn, sconn))) {
3163 DEBUG(0, ("Could not add deadtime event\n"));
3167 if (!(event_add_idle(ev_ctx, NULL,
3168 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3169 "housekeeping", housekeeping_fn, sconn))) {
3170 DEBUG(0, ("Could not add housekeeping event\n"));
3174 #ifdef CLUSTER_SUPPORT
3176 if (lp_clustering()) {
3178 * We need to tell ctdb about our client's TCP
3179 * connection, so that for failover ctdbd can send
3180 * tickle acks, triggering a reconnection by the
3184 struct sockaddr_storage srv, clnt;
3186 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3188 status = smbd_register_ips(sconn, &srv, &clnt);
3189 if (!NT_STATUS_IS_OK(status)) {
3190 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3191 nt_errstr(status)));
3195 DEBUG(0,("Unable to get tcp info for "
3196 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3203 sconn->nbt.got_session = false;
3205 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3207 sconn->smb1.sessions.done_sesssetup = false;
3208 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3209 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3210 /* users from session setup */
3211 sconn->smb1.sessions.session_userlist = NULL;
3212 /* workgroup from session setup. */
3213 sconn->smb1.sessions.session_workgroup = NULL;
3214 /* this holds info on user ids that are already validated for this VC */
3215 sconn->smb1.sessions.validated_users = NULL;
3216 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3217 sconn->smb1.sessions.num_validated_vuids = 0;
3220 if (!init_dptrs(sconn)) {
3221 exit_server("init_dptrs() failed");
3224 sconn->smb1.fde = event_add_fd(ev_ctx,
3228 smbd_server_connection_handler,
3230 if (!sconn->smb1.fde) {
3231 exit_server("failed to create smbd_server_connection fde");
3239 frame = talloc_stackframe_pool(8192);
3243 status = smbd_server_connection_loop_once(ev_ctx, sconn);
3244 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3245 !NT_STATUS_IS_OK(status)) {
3246 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3247 " exiting\n", nt_errstr(status)));
3254 exit_server_cleanly(NULL);
3257 bool req_is_in_chain(struct smb_request *req)
3259 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3261 * We're right now handling a subsequent request, so we must
3267 if (!is_andx_req(req->cmd)) {
3273 * Okay, an illegal request, but definitely not chained :-)
3278 return (CVAL(req->vwv+0, 0) != 0xFF);