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 "system/filesys.h"
23 #include "smbd/globals.h"
24 #include "librpc/gen_ndr/netlogon.h"
25 #include "librpc/gen_ndr/messaging.h"
26 #include "../lib/async_req/async_sock.h"
27 #include "ctdbd_conn.h"
28 #include "../lib/util/select.h"
29 #include "printing/pcap.h"
30 #include "system/select.h"
33 extern bool global_machine_password_needs_changing;
35 static void construct_reply_common(struct smb_request *req, const char *inbuf,
37 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
39 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
43 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
47 sconn->smb1.echo_handler.ref_count++;
49 if (sconn->smb1.echo_handler.ref_count > 1) {
53 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
57 sconn->smb1.echo_handler.socket_lock_fd,
58 SMB_F_SETLKW, 0, 0, F_WRLCK);
59 } while (!ok && (errno == EINTR));
62 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
66 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
71 void smbd_lock_socket(struct smbd_server_connection *sconn)
73 if (!smbd_lock_socket_internal(sconn)) {
74 exit_server_cleanly("failed to lock socket");
78 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
82 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
86 sconn->smb1.echo_handler.ref_count--;
88 if (sconn->smb1.echo_handler.ref_count > 0) {
94 sconn->smb1.echo_handler.socket_lock_fd,
95 SMB_F_SETLKW, 0, 0, F_UNLCK);
96 } while (!ok && (errno == EINTR));
99 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
103 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
108 void smbd_unlock_socket(struct smbd_server_connection *sconn)
110 if (!smbd_unlock_socket_internal(sconn)) {
111 exit_server_cleanly("failed to unlock socket");
115 /* Accessor function for smb_read_error for smbd functions. */
117 /****************************************************************************
119 ****************************************************************************/
121 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
122 bool do_signing, uint32_t seqnum,
124 struct smb_perfcount_data *pcd)
129 char *buf_out = buffer;
131 smbd_lock_socket(sconn);
134 /* Sign the outgoing packet if required. */
135 srv_calculate_sign_mac(sconn, buf_out, seqnum);
139 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
140 if (!NT_STATUS_IS_OK(status)) {
141 DEBUG(0, ("send_smb: SMB encryption failed "
142 "on outgoing packet! Error %s\n",
143 nt_errstr(status) ));
148 len = smb_len(buf_out) + 4;
150 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
153 char addr[INET6_ADDRSTRLEN];
155 * Try and give an error message saying what
158 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
159 (int)sys_getpid(), (int)len,
160 get_peer_addr(sconn->sock, addr, sizeof(addr)),
161 (int)ret, strerror(errno) ));
163 srv_free_enc_buffer(buf_out);
167 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
168 srv_free_enc_buffer(buf_out);
170 SMB_PERFCOUNT_END(pcd);
172 smbd_unlock_socket(sconn);
176 /*******************************************************************
177 Setup the word count and byte count for a smb message.
178 ********************************************************************/
180 int srv_set_message(char *buf,
185 if (zero && (num_words || num_bytes)) {
186 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
188 SCVAL(buf,smb_wct,num_words);
189 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
190 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
191 return (smb_size + num_words*2 + num_bytes);
194 static bool valid_smb_header(const uint8_t *inbuf)
196 if (is_encrypted_packet(inbuf)) {
200 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
201 * but it just looks weird to call strncmp for this one.
203 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
206 /* Socket functions for smbd packet processing. */
208 static bool valid_packet_size(size_t len)
211 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
212 * of header. Don't print the error if this fits.... JRA.
215 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
216 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
217 (unsigned long)len));
223 static NTSTATUS read_packet_remainder(int fd, char *buffer,
224 unsigned int timeout, ssize_t len)
232 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
233 if (!NT_STATUS_IS_OK(status)) {
234 char addr[INET6_ADDRSTRLEN];
235 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
237 get_peer_addr(fd, addr, sizeof(addr)),
243 /****************************************************************************
244 Attempt a zerocopy writeX read. We know here that len > smb_size-4
245 ****************************************************************************/
248 * Unfortunately, earlier versions of smbclient/libsmbclient
249 * don't send this "standard" writeX header. I've fixed this
250 * for 3.2 but we'll use the old method with earlier versions.
251 * Windows and CIFSFS at least use this standard size. Not
255 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
256 (2*14) + /* word count (including bcc) */ \
259 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
260 const char lenbuf[4],
261 struct smbd_server_connection *sconn,
263 unsigned int timeout,
267 /* Size of a WRITEX call (+4 byte len). */
268 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
269 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
273 memcpy(writeX_header, lenbuf, 4);
275 status = read_fd_with_timeout(
276 sconn->sock, writeX_header + 4,
277 STANDARD_WRITE_AND_X_HEADER_SIZE,
278 STANDARD_WRITE_AND_X_HEADER_SIZE,
281 if (!NT_STATUS_IS_OK(status)) {
282 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
283 "error = %s.\n", sconn->client_id.addr,
289 * Ok - now try and see if this is a possible
293 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
295 * If the data offset is beyond what
296 * we've read, drain the extra bytes.
298 uint16_t doff = SVAL(writeX_header,smb_vwv11);
301 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
302 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
303 if (drain_socket(sconn->sock, drain) != drain) {
304 smb_panic("receive_smb_raw_talloc_partial_read:"
305 " failed to drain pending bytes");
308 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
311 /* Spoof down the length and null out the bcc. */
312 set_message_bcc(writeX_header, 0);
313 newlen = smb_len(writeX_header);
315 /* Copy the header we've written. */
317 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
319 sizeof(writeX_header));
321 if (*buffer == NULL) {
322 DEBUG(0, ("Could not allocate inbuf of length %d\n",
323 (int)sizeof(writeX_header)));
324 return NT_STATUS_NO_MEMORY;
327 /* Work out the remaining bytes. */
328 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
329 *len_ret = newlen + 4;
333 if (!valid_packet_size(len)) {
334 return NT_STATUS_INVALID_PARAMETER;
338 * Not a valid writeX call. Just do the standard
342 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
344 if (*buffer == NULL) {
345 DEBUG(0, ("Could not allocate inbuf of length %d\n",
347 return NT_STATUS_NO_MEMORY;
350 /* Copy in what we already read. */
353 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
354 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
357 status = read_packet_remainder(
359 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
362 if (!NT_STATUS_IS_OK(status)) {
363 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
373 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
374 struct smbd_server_connection *sconn,
375 char **buffer, unsigned int timeout,
376 size_t *p_unread, size_t *plen)
380 int min_recv_size = lp_min_receive_file_size();
385 status = read_smb_length_return_keepalive(sconn->sock, lenbuf, timeout,
387 if (!NT_STATUS_IS_OK(status)) {
391 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
392 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
393 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
394 !srv_is_signing_active(sconn) &&
395 sconn->smb1.echo_handler.trusted_fde == NULL) {
397 return receive_smb_raw_talloc_partial_read(
398 mem_ctx, lenbuf, sconn, buffer, timeout,
402 if (!valid_packet_size(len)) {
403 return NT_STATUS_INVALID_PARAMETER;
407 * The +4 here can't wrap, we've checked the length above already.
410 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
412 if (*buffer == NULL) {
413 DEBUG(0, ("Could not allocate inbuf of length %d\n",
415 return NT_STATUS_NO_MEMORY;
418 memcpy(*buffer, lenbuf, sizeof(lenbuf));
420 status = read_packet_remainder(sconn->sock, (*buffer)+4, timeout, len);
421 if (!NT_STATUS_IS_OK(status)) {
429 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
430 struct smbd_server_connection *sconn,
431 char **buffer, unsigned int timeout,
432 size_t *p_unread, bool *p_encrypted,
435 bool trusted_channel)
440 *p_encrypted = false;
442 status = receive_smb_raw_talloc(mem_ctx, sconn, buffer, timeout,
444 if (!NT_STATUS_IS_OK(status)) {
445 DEBUG(1, ("read_smb_length_return_keepalive failed for "
446 "client %s read error = %s.\n",
447 sconn->client_id.addr, nt_errstr(status)));
451 if (is_encrypted_packet((uint8_t *)*buffer)) {
452 status = srv_decrypt_buffer(*buffer);
453 if (!NT_STATUS_IS_OK(status)) {
454 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
455 "incoming packet! Error %s\n",
456 nt_errstr(status) ));
462 /* Check the incoming SMB signature. */
463 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
464 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
465 "incoming packet!\n"));
466 return NT_STATUS_INVALID_NETWORK_RESPONSE;
474 * Initialize a struct smb_request from an inbuf
477 static bool init_smb_request(struct smb_request *req,
478 struct smbd_server_connection *sconn,
480 size_t unread_bytes, bool encrypted,
483 size_t req_size = smb_len(inbuf) + 4;
484 /* Ensure we have at least smb_size bytes. */
485 if (req_size < smb_size) {
486 DEBUG(0,("init_smb_request: invalid request size %u\n",
487 (unsigned int)req_size ));
490 req->cmd = CVAL(inbuf, smb_com);
491 req->flags2 = SVAL(inbuf, smb_flg2);
492 req->smbpid = SVAL(inbuf, smb_pid);
493 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
494 req->seqnum = seqnum;
495 req->vuid = SVAL(inbuf, smb_uid);
496 req->tid = SVAL(inbuf, smb_tid);
497 req->wct = CVAL(inbuf, smb_wct);
498 req->vwv = (uint16_t *)(inbuf+smb_vwv);
499 req->buflen = smb_buflen(inbuf);
500 req->buf = (const uint8_t *)smb_buf(inbuf);
501 req->unread_bytes = unread_bytes;
502 req->encrypted = encrypted;
504 req->conn = conn_find(sconn,req->tid);
505 req->chain_fsp = NULL;
506 req->chain_outbuf = NULL;
509 smb_init_perfcount_data(&req->pcd);
511 /* Ensure we have at least wct words and 2 bytes of bcc. */
512 if (smb_size + req->wct*2 > req_size) {
513 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
514 (unsigned int)req->wct,
515 (unsigned int)req_size));
518 /* Ensure bcc is correct. */
519 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
520 DEBUG(0,("init_smb_request: invalid bcc number %u "
521 "(wct = %u, size %u)\n",
522 (unsigned int)req->buflen,
523 (unsigned int)req->wct,
524 (unsigned int)req_size));
532 static void process_smb(struct smbd_server_connection *conn,
533 uint8_t *inbuf, size_t nread, size_t unread_bytes,
534 uint32_t seqnum, bool encrypted,
535 struct smb_perfcount_data *deferred_pcd);
537 static void smbd_deferred_open_timer(struct event_context *ev,
538 struct timed_event *te,
539 struct timeval _tval,
542 struct pending_message_list *msg = talloc_get_type(private_data,
543 struct pending_message_list);
544 TALLOC_CTX *mem_ctx = talloc_tos();
545 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
548 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
551 exit_server("smbd_deferred_open_timer: talloc failed\n");
555 /* We leave this message on the queue so the open code can
556 know this is a retry. */
557 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
558 (unsigned long long)mid ));
560 /* Mark the message as processed so this is not
561 * re-processed in error. */
562 msg->processed = true;
564 process_smb(smbd_server_conn, inbuf,
566 msg->seqnum, msg->encrypted, &msg->pcd);
568 /* If it's still there and was processed, remove it. */
569 msg = get_deferred_open_message_smb(mid);
570 if (msg && msg->processed) {
571 remove_deferred_open_message_smb(mid);
575 /****************************************************************************
576 Function to push a message onto the tail of a linked list of smb messages ready
578 ****************************************************************************/
580 static bool push_queued_message(struct smb_request *req,
581 struct timeval request_time,
582 struct timeval end_time,
583 char *private_data, size_t private_len)
585 int msg_len = smb_len(req->inbuf) + 4;
586 struct pending_message_list *msg;
588 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
591 DEBUG(0,("push_message: malloc fail (1)\n"));
595 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
596 if(msg->buf.data == NULL) {
597 DEBUG(0,("push_message: malloc fail (2)\n"));
602 msg->request_time = request_time;
603 msg->seqnum = req->seqnum;
604 msg->encrypted = req->encrypted;
605 msg->processed = false;
606 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
609 msg->private_data = data_blob_talloc(msg, private_data,
611 if (msg->private_data.data == NULL) {
612 DEBUG(0,("push_message: malloc fail (3)\n"));
618 msg->te = event_add_timed(smbd_event_context(),
621 smbd_deferred_open_timer,
624 DEBUG(0,("push_message: event_add_timed failed\n"));
629 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
631 DEBUG(10,("push_message: pushed message length %u on "
632 "deferred_open_queue\n", (unsigned int)msg_len));
637 /****************************************************************************
638 Function to delete a sharing violation open message by mid.
639 ****************************************************************************/
641 void remove_deferred_open_message_smb(uint64_t mid)
643 struct pending_message_list *pml;
645 if (smbd_server_conn->using_smb2) {
646 remove_deferred_open_message_smb2(smbd_server_conn, mid);
650 for (pml = deferred_open_queue; pml; pml = pml->next) {
651 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
652 DEBUG(10,("remove_deferred_open_message_smb: "
653 "deleting mid %llu len %u\n",
654 (unsigned long long)mid,
655 (unsigned int)pml->buf.length ));
656 DLIST_REMOVE(deferred_open_queue, pml);
663 /****************************************************************************
664 Move a sharing violation open retry message to the front of the list and
665 schedule it for immediate processing.
666 ****************************************************************************/
668 void schedule_deferred_open_message_smb(uint64_t mid)
670 struct pending_message_list *pml;
673 if (smbd_server_conn->using_smb2) {
674 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
678 for (pml = deferred_open_queue; pml; pml = pml->next) {
679 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
681 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
684 (unsigned long long)msg_mid ));
686 if (mid == msg_mid) {
687 struct timed_event *te;
689 if (pml->processed) {
690 /* A processed message should not be
692 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
693 "message mid %llu was already processed\n",
694 (unsigned long long)msg_mid ));
698 DEBUG(10,("schedule_deferred_open_message_smb: "
699 "scheduling mid %llu\n",
700 (unsigned long long)mid ));
702 te = event_add_timed(smbd_event_context(),
705 smbd_deferred_open_timer,
708 DEBUG(10,("schedule_deferred_open_message_smb: "
709 "event_add_timed() failed, "
710 "skipping mid %llu\n",
711 (unsigned long long)msg_mid ));
714 TALLOC_FREE(pml->te);
716 DLIST_PROMOTE(deferred_open_queue, pml);
721 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
722 "find message mid %llu\n",
723 (unsigned long long)mid ));
726 /****************************************************************************
727 Return true if this mid is on the deferred queue and was not yet processed.
728 ****************************************************************************/
730 bool open_was_deferred(uint64_t mid)
732 struct pending_message_list *pml;
734 if (smbd_server_conn->using_smb2) {
735 return open_was_deferred_smb2(smbd_server_conn, mid);
738 for (pml = deferred_open_queue; pml; pml = pml->next) {
739 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
746 /****************************************************************************
747 Return the message queued by this mid.
748 ****************************************************************************/
750 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
752 struct pending_message_list *pml;
754 for (pml = deferred_open_queue; pml; pml = pml->next) {
755 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
762 /****************************************************************************
763 Get the state data queued by this mid.
764 ****************************************************************************/
766 bool get_deferred_open_message_state(struct smb_request *smbreq,
767 struct timeval *p_request_time,
770 struct pending_message_list *pml;
772 if (smbd_server_conn->using_smb2) {
773 return get_deferred_open_message_state_smb2(smbreq->smb2req,
778 pml = get_deferred_open_message_smb(smbreq->mid);
782 if (p_request_time) {
783 *p_request_time = pml->request_time;
786 *pp_state = (void *)pml->private_data.data;
791 /****************************************************************************
792 Function to push a deferred open smb message onto a linked list of local smb
793 messages ready for processing.
794 ****************************************************************************/
796 bool push_deferred_open_message_smb(struct smb_request *req,
797 struct timeval request_time,
798 struct timeval timeout,
800 char *private_data, size_t priv_len)
802 struct timeval end_time;
805 return push_deferred_open_message_smb2(req->smb2req,
813 if (req->unread_bytes) {
814 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
815 "unread_bytes = %u\n",
816 (unsigned int)req->unread_bytes ));
817 smb_panic("push_deferred_open_message_smb: "
818 "logic error unread_bytes != 0" );
821 end_time = timeval_sum(&request_time, &timeout);
823 DEBUG(10,("push_deferred_open_message_smb: pushing message "
824 "len %u mid %llu timeout time [%u.%06u]\n",
825 (unsigned int) smb_len(req->inbuf)+4,
826 (unsigned long long)req->mid,
827 (unsigned int)end_time.tv_sec,
828 (unsigned int)end_time.tv_usec));
830 return push_queued_message(req, request_time, end_time,
831 private_data, priv_len);
835 struct timed_event *te;
836 struct timeval interval;
838 bool (*handler)(const struct timeval *now, void *private_data);
842 static void smbd_idle_event_handler(struct event_context *ctx,
843 struct timed_event *te,
847 struct idle_event *event =
848 talloc_get_type_abort(private_data, struct idle_event);
850 TALLOC_FREE(event->te);
852 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
853 event->name, event->te));
855 if (!event->handler(&now, event->private_data)) {
856 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
857 event->name, event->te));
858 /* Don't repeat, delete ourselves */
863 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
864 event->name, event->te));
866 event->te = event_add_timed(ctx, event,
867 timeval_sum(&now, &event->interval),
868 smbd_idle_event_handler, event);
870 /* We can't do much but fail here. */
871 SMB_ASSERT(event->te != NULL);
874 struct idle_event *event_add_idle(struct event_context *event_ctx,
876 struct timeval interval,
878 bool (*handler)(const struct timeval *now,
882 struct idle_event *result;
883 struct timeval now = timeval_current();
885 result = TALLOC_P(mem_ctx, struct idle_event);
886 if (result == NULL) {
887 DEBUG(0, ("talloc failed\n"));
891 result->interval = interval;
892 result->handler = handler;
893 result->private_data = private_data;
895 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
896 DEBUG(0, ("talloc failed\n"));
901 result->te = event_add_timed(event_ctx, result,
902 timeval_sum(&now, &interval),
903 smbd_idle_event_handler, result);
904 if (result->te == NULL) {
905 DEBUG(0, ("event_add_timed failed\n"));
910 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
914 static void smbd_sig_term_handler(struct tevent_context *ev,
915 struct tevent_signal *se,
921 exit_server_cleanly("termination signal");
924 void smbd_setup_sig_term_handler(void)
926 struct tevent_signal *se;
928 se = tevent_add_signal(smbd_event_context(),
929 smbd_event_context(),
931 smbd_sig_term_handler,
934 exit_server("failed to setup SIGTERM handler");
938 static void smbd_sig_hup_handler(struct tevent_context *ev,
939 struct tevent_signal *se,
945 struct messaging_context *msg_ctx = talloc_get_type_abort(
946 private_data, struct messaging_context);
947 change_to_root_user();
948 DEBUG(1,("Reloading services after SIGHUP\n"));
949 reload_services(msg_ctx, smbd_server_conn->sock, False);
951 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
955 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
956 struct messaging_context *msg_ctx)
958 struct tevent_signal *se;
960 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
963 exit_server("failed to setup SIGHUP handler");
967 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
974 timeout = SMBD_SELECT_TIMEOUT * 1000;
977 * Are there any timed events waiting ? If so, ensure we don't
978 * select for longer than it would take to wait for them.
981 event_add_to_poll_args(smbd_event_context(), conn,
982 &conn->pfds, &num_pfds, &timeout);
984 /* Process a signal and timed events now... */
985 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
986 return NT_STATUS_RETRY;
991 START_PROFILE(smbd_idle);
993 ret = sys_poll(conn->pfds, num_pfds, timeout);
996 END_PROFILE(smbd_idle);
1000 if (ret == -1 && errno != EINTR) {
1001 return map_nt_error_from_unix(errno);
1004 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1007 return NT_STATUS_RETRY;
1010 /* Did we timeout ? */
1012 return NT_STATUS_RETRY;
1015 /* should not be reached */
1016 return NT_STATUS_INTERNAL_ERROR;
1020 * Only allow 5 outstanding trans requests. We're allocating memory, so
1024 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1027 for (; list != NULL; list = list->next) {
1029 if (list->mid == mid) {
1030 return NT_STATUS_INVALID_PARAMETER;
1036 return NT_STATUS_INSUFFICIENT_RESOURCES;
1039 return NT_STATUS_OK;
1043 These flags determine some of the permissions required to do an operation
1045 Note that I don't set NEED_WRITE on some write operations because they
1046 are used by some brain-dead clients when printing, and I don't want to
1047 force write permissions on print services.
1049 #define AS_USER (1<<0)
1050 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1051 #define TIME_INIT (1<<2)
1052 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1053 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1054 #define DO_CHDIR (1<<6)
1057 define a list of possible SMB messages and their corresponding
1058 functions. Any message that has a NULL function is unimplemented -
1059 please feel free to contribute implementations!
1061 static const struct smb_message_struct {
1063 void (*fn)(struct smb_request *req);
1065 } smb_messages[256] = {
1067 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1068 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1069 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1070 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1071 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1072 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1073 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1074 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1075 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1076 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1077 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1078 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1079 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1080 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1081 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1082 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1083 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1084 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1085 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1086 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1087 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1088 /* 0x15 */ { NULL, NULL, 0 },
1089 /* 0x16 */ { NULL, NULL, 0 },
1090 /* 0x17 */ { NULL, NULL, 0 },
1091 /* 0x18 */ { NULL, NULL, 0 },
1092 /* 0x19 */ { NULL, NULL, 0 },
1093 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1094 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1095 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1096 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1097 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1098 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1099 /* 0x20 */ { "SMBwritec", NULL,0},
1100 /* 0x21 */ { NULL, NULL, 0 },
1101 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1102 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1103 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1104 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1105 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1106 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1107 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1108 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1109 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1110 /* 0x2b */ { "SMBecho",reply_echo,0},
1111 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1112 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1113 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1114 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1115 /* 0x30 */ { NULL, NULL, 0 },
1116 /* 0x31 */ { NULL, NULL, 0 },
1117 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1118 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1119 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1120 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1121 /* 0x36 */ { NULL, NULL, 0 },
1122 /* 0x37 */ { NULL, NULL, 0 },
1123 /* 0x38 */ { NULL, NULL, 0 },
1124 /* 0x39 */ { NULL, NULL, 0 },
1125 /* 0x3a */ { NULL, NULL, 0 },
1126 /* 0x3b */ { NULL, NULL, 0 },
1127 /* 0x3c */ { NULL, NULL, 0 },
1128 /* 0x3d */ { NULL, NULL, 0 },
1129 /* 0x3e */ { NULL, NULL, 0 },
1130 /* 0x3f */ { NULL, NULL, 0 },
1131 /* 0x40 */ { NULL, NULL, 0 },
1132 /* 0x41 */ { NULL, NULL, 0 },
1133 /* 0x42 */ { NULL, NULL, 0 },
1134 /* 0x43 */ { NULL, NULL, 0 },
1135 /* 0x44 */ { NULL, NULL, 0 },
1136 /* 0x45 */ { NULL, NULL, 0 },
1137 /* 0x46 */ { NULL, NULL, 0 },
1138 /* 0x47 */ { NULL, NULL, 0 },
1139 /* 0x48 */ { NULL, NULL, 0 },
1140 /* 0x49 */ { NULL, NULL, 0 },
1141 /* 0x4a */ { NULL, NULL, 0 },
1142 /* 0x4b */ { NULL, NULL, 0 },
1143 /* 0x4c */ { NULL, NULL, 0 },
1144 /* 0x4d */ { NULL, NULL, 0 },
1145 /* 0x4e */ { NULL, NULL, 0 },
1146 /* 0x4f */ { NULL, NULL, 0 },
1147 /* 0x50 */ { NULL, NULL, 0 },
1148 /* 0x51 */ { NULL, NULL, 0 },
1149 /* 0x52 */ { NULL, NULL, 0 },
1150 /* 0x53 */ { NULL, NULL, 0 },
1151 /* 0x54 */ { NULL, NULL, 0 },
1152 /* 0x55 */ { NULL, NULL, 0 },
1153 /* 0x56 */ { NULL, NULL, 0 },
1154 /* 0x57 */ { NULL, NULL, 0 },
1155 /* 0x58 */ { NULL, NULL, 0 },
1156 /* 0x59 */ { NULL, NULL, 0 },
1157 /* 0x5a */ { NULL, NULL, 0 },
1158 /* 0x5b */ { NULL, NULL, 0 },
1159 /* 0x5c */ { NULL, NULL, 0 },
1160 /* 0x5d */ { NULL, NULL, 0 },
1161 /* 0x5e */ { NULL, NULL, 0 },
1162 /* 0x5f */ { NULL, NULL, 0 },
1163 /* 0x60 */ { NULL, NULL, 0 },
1164 /* 0x61 */ { NULL, NULL, 0 },
1165 /* 0x62 */ { NULL, NULL, 0 },
1166 /* 0x63 */ { NULL, NULL, 0 },
1167 /* 0x64 */ { NULL, NULL, 0 },
1168 /* 0x65 */ { NULL, NULL, 0 },
1169 /* 0x66 */ { NULL, NULL, 0 },
1170 /* 0x67 */ { NULL, NULL, 0 },
1171 /* 0x68 */ { NULL, NULL, 0 },
1172 /* 0x69 */ { NULL, NULL, 0 },
1173 /* 0x6a */ { NULL, NULL, 0 },
1174 /* 0x6b */ { NULL, NULL, 0 },
1175 /* 0x6c */ { NULL, NULL, 0 },
1176 /* 0x6d */ { NULL, NULL, 0 },
1177 /* 0x6e */ { NULL, NULL, 0 },
1178 /* 0x6f */ { NULL, NULL, 0 },
1179 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1180 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1181 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1182 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1183 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1184 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1185 /* 0x76 */ { NULL, NULL, 0 },
1186 /* 0x77 */ { NULL, NULL, 0 },
1187 /* 0x78 */ { NULL, NULL, 0 },
1188 /* 0x79 */ { NULL, NULL, 0 },
1189 /* 0x7a */ { NULL, NULL, 0 },
1190 /* 0x7b */ { NULL, NULL, 0 },
1191 /* 0x7c */ { NULL, NULL, 0 },
1192 /* 0x7d */ { NULL, NULL, 0 },
1193 /* 0x7e */ { NULL, NULL, 0 },
1194 /* 0x7f */ { NULL, NULL, 0 },
1195 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1196 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1197 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1198 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1199 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1200 /* 0x85 */ { NULL, NULL, 0 },
1201 /* 0x86 */ { NULL, NULL, 0 },
1202 /* 0x87 */ { NULL, NULL, 0 },
1203 /* 0x88 */ { NULL, NULL, 0 },
1204 /* 0x89 */ { NULL, NULL, 0 },
1205 /* 0x8a */ { NULL, NULL, 0 },
1206 /* 0x8b */ { NULL, NULL, 0 },
1207 /* 0x8c */ { NULL, NULL, 0 },
1208 /* 0x8d */ { NULL, NULL, 0 },
1209 /* 0x8e */ { NULL, NULL, 0 },
1210 /* 0x8f */ { NULL, NULL, 0 },
1211 /* 0x90 */ { NULL, NULL, 0 },
1212 /* 0x91 */ { NULL, NULL, 0 },
1213 /* 0x92 */ { NULL, NULL, 0 },
1214 /* 0x93 */ { NULL, NULL, 0 },
1215 /* 0x94 */ { NULL, NULL, 0 },
1216 /* 0x95 */ { NULL, NULL, 0 },
1217 /* 0x96 */ { NULL, NULL, 0 },
1218 /* 0x97 */ { NULL, NULL, 0 },
1219 /* 0x98 */ { NULL, NULL, 0 },
1220 /* 0x99 */ { NULL, NULL, 0 },
1221 /* 0x9a */ { NULL, NULL, 0 },
1222 /* 0x9b */ { NULL, NULL, 0 },
1223 /* 0x9c */ { NULL, NULL, 0 },
1224 /* 0x9d */ { NULL, NULL, 0 },
1225 /* 0x9e */ { NULL, NULL, 0 },
1226 /* 0x9f */ { NULL, NULL, 0 },
1227 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1228 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1229 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1230 /* 0xa3 */ { NULL, NULL, 0 },
1231 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1232 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1233 /* 0xa6 */ { NULL, NULL, 0 },
1234 /* 0xa7 */ { NULL, NULL, 0 },
1235 /* 0xa8 */ { NULL, NULL, 0 },
1236 /* 0xa9 */ { NULL, NULL, 0 },
1237 /* 0xaa */ { NULL, NULL, 0 },
1238 /* 0xab */ { NULL, NULL, 0 },
1239 /* 0xac */ { NULL, NULL, 0 },
1240 /* 0xad */ { NULL, NULL, 0 },
1241 /* 0xae */ { NULL, NULL, 0 },
1242 /* 0xaf */ { NULL, NULL, 0 },
1243 /* 0xb0 */ { NULL, NULL, 0 },
1244 /* 0xb1 */ { NULL, NULL, 0 },
1245 /* 0xb2 */ { NULL, NULL, 0 },
1246 /* 0xb3 */ { NULL, NULL, 0 },
1247 /* 0xb4 */ { NULL, NULL, 0 },
1248 /* 0xb5 */ { NULL, NULL, 0 },
1249 /* 0xb6 */ { NULL, NULL, 0 },
1250 /* 0xb7 */ { NULL, NULL, 0 },
1251 /* 0xb8 */ { NULL, NULL, 0 },
1252 /* 0xb9 */ { NULL, NULL, 0 },
1253 /* 0xba */ { NULL, NULL, 0 },
1254 /* 0xbb */ { NULL, NULL, 0 },
1255 /* 0xbc */ { NULL, NULL, 0 },
1256 /* 0xbd */ { NULL, NULL, 0 },
1257 /* 0xbe */ { NULL, NULL, 0 },
1258 /* 0xbf */ { NULL, NULL, 0 },
1259 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1260 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1261 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1262 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1263 /* 0xc4 */ { NULL, NULL, 0 },
1264 /* 0xc5 */ { NULL, NULL, 0 },
1265 /* 0xc6 */ { NULL, NULL, 0 },
1266 /* 0xc7 */ { NULL, NULL, 0 },
1267 /* 0xc8 */ { NULL, NULL, 0 },
1268 /* 0xc9 */ { NULL, NULL, 0 },
1269 /* 0xca */ { NULL, NULL, 0 },
1270 /* 0xcb */ { NULL, NULL, 0 },
1271 /* 0xcc */ { NULL, NULL, 0 },
1272 /* 0xcd */ { NULL, NULL, 0 },
1273 /* 0xce */ { NULL, NULL, 0 },
1274 /* 0xcf */ { NULL, NULL, 0 },
1275 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1276 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1277 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1278 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1279 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1280 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1281 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1282 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1283 /* 0xd8 */ { NULL, NULL, 0 },
1284 /* 0xd9 */ { NULL, NULL, 0 },
1285 /* 0xda */ { NULL, NULL, 0 },
1286 /* 0xdb */ { NULL, NULL, 0 },
1287 /* 0xdc */ { NULL, NULL, 0 },
1288 /* 0xdd */ { NULL, NULL, 0 },
1289 /* 0xde */ { NULL, NULL, 0 },
1290 /* 0xdf */ { NULL, NULL, 0 },
1291 /* 0xe0 */ { NULL, NULL, 0 },
1292 /* 0xe1 */ { NULL, NULL, 0 },
1293 /* 0xe2 */ { NULL, NULL, 0 },
1294 /* 0xe3 */ { NULL, NULL, 0 },
1295 /* 0xe4 */ { NULL, NULL, 0 },
1296 /* 0xe5 */ { NULL, NULL, 0 },
1297 /* 0xe6 */ { NULL, NULL, 0 },
1298 /* 0xe7 */ { NULL, NULL, 0 },
1299 /* 0xe8 */ { NULL, NULL, 0 },
1300 /* 0xe9 */ { NULL, NULL, 0 },
1301 /* 0xea */ { NULL, NULL, 0 },
1302 /* 0xeb */ { NULL, NULL, 0 },
1303 /* 0xec */ { NULL, NULL, 0 },
1304 /* 0xed */ { NULL, NULL, 0 },
1305 /* 0xee */ { NULL, NULL, 0 },
1306 /* 0xef */ { NULL, NULL, 0 },
1307 /* 0xf0 */ { NULL, NULL, 0 },
1308 /* 0xf1 */ { NULL, NULL, 0 },
1309 /* 0xf2 */ { NULL, NULL, 0 },
1310 /* 0xf3 */ { NULL, NULL, 0 },
1311 /* 0xf4 */ { NULL, NULL, 0 },
1312 /* 0xf5 */ { NULL, NULL, 0 },
1313 /* 0xf6 */ { NULL, NULL, 0 },
1314 /* 0xf7 */ { NULL, NULL, 0 },
1315 /* 0xf8 */ { NULL, NULL, 0 },
1316 /* 0xf9 */ { NULL, NULL, 0 },
1317 /* 0xfa */ { NULL, NULL, 0 },
1318 /* 0xfb */ { NULL, NULL, 0 },
1319 /* 0xfc */ { NULL, NULL, 0 },
1320 /* 0xfd */ { NULL, NULL, 0 },
1321 /* 0xfe */ { NULL, NULL, 0 },
1322 /* 0xff */ { NULL, NULL, 0 }
1326 /*******************************************************************
1327 allocate and initialize a reply packet
1328 ********************************************************************/
1330 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1331 const char *inbuf, char **outbuf, uint8_t num_words,
1335 * Protect against integer wrap
1337 if ((num_bytes > 0xffffff)
1338 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1340 if (asprintf(&msg, "num_bytes too large: %u",
1341 (unsigned)num_bytes) == -1) {
1342 msg = CONST_DISCARD(char *, "num_bytes too large");
1347 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1348 smb_size + num_words*2 + num_bytes);
1349 if (*outbuf == NULL) {
1353 construct_reply_common(req, inbuf, *outbuf);
1354 srv_set_message(*outbuf, num_words, num_bytes, false);
1356 * Zero out the word area, the caller has to take care of the bcc area
1359 if (num_words != 0) {
1360 memset(*outbuf + smb_vwv0, 0, num_words*2);
1366 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1369 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1371 smb_panic("could not allocate output buffer\n");
1373 req->outbuf = (uint8_t *)outbuf;
1377 /*******************************************************************
1378 Dump a packet to a file.
1379 ********************************************************************/
1381 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1385 if (DEBUGLEVEL < 50) {
1389 if (len < 4) len = smb_len(data)+4;
1390 for (i=1;i<100;i++) {
1391 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1392 type ? "req" : "resp") == -1) {
1395 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1396 if (fd != -1 || errno != EEXIST) break;
1399 ssize_t ret = write(fd, data, len);
1401 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1403 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1408 /****************************************************************************
1409 Prepare everything for calling the actual request function, and potentially
1410 call the request function via the "new" interface.
1412 Return False if the "legacy" function needs to be called, everything is
1415 Return True if we're done.
1417 I know this API sucks, but it is the one with the least code change I could
1419 ****************************************************************************/
1421 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1425 connection_struct *conn = NULL;
1426 struct smbd_server_connection *sconn = req->sconn;
1430 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1431 * so subtract 4 from it. */
1432 if (!valid_smb_header(req->inbuf)
1433 || (size < (smb_size - 4))) {
1434 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1435 smb_len(req->inbuf)));
1436 exit_server_cleanly("Non-SMB packet");
1439 if (smb_messages[type].fn == NULL) {
1440 DEBUG(0,("Unknown message type %d!\n",type));
1441 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1442 reply_unknown_new(req, type);
1446 flags = smb_messages[type].flags;
1448 /* In share mode security we must ignore the vuid. */
1449 session_tag = (lp_security() == SEC_SHARE)
1450 ? UID_FIELD_INVALID : req->vuid;
1453 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1454 (int)sys_getpid(), (unsigned long)conn));
1456 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1458 /* Ensure this value is replaced in the incoming packet. */
1459 SSVAL(req->inbuf,smb_uid,session_tag);
1462 * Ensure the correct username is in current_user_info. This is a
1463 * really ugly bugfix for problems with multiple session_setup_and_X's
1464 * being done and allowing %U and %G substitutions to work correctly.
1465 * There is a reason this code is done here, don't move it unless you
1466 * know what you're doing... :-).
1470 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1471 user_struct *vuser = NULL;
1473 sconn->smb1.sessions.last_session_tag = session_tag;
1474 if(session_tag != UID_FIELD_INVALID) {
1475 vuser = get_valid_user_struct(sconn, session_tag);
1477 set_current_user_info(
1478 vuser->session_info->sanitized_username,
1479 vuser->session_info->unix_name,
1480 vuser->session_info->info3->base.domain.string);
1485 /* Does this call need to be run as the connected user? */
1486 if (flags & AS_USER) {
1488 /* Does this call need a valid tree connection? */
1491 * Amazingly, the error code depends on the command
1494 if (type == SMBntcreateX) {
1495 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1497 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1502 if (!change_to_user(conn,session_tag)) {
1503 DEBUG(0, ("Error: Could not change to user. Removing "
1504 "deferred open, mid=%llu.\n",
1505 (unsigned long long)req->mid));
1506 reply_force_doserror(req, ERRSRV, ERRbaduid);
1510 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1512 /* Does it need write permission? */
1513 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1514 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1518 /* IPC services are limited */
1519 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1520 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1524 /* This call needs to be run as root */
1525 change_to_root_user();
1528 /* load service specific parameters */
1530 if (req->encrypted) {
1531 conn->encrypted_tid = true;
1532 /* encrypted required from now on. */
1533 conn->encrypt_level = Required;
1534 } else if (ENCRYPTION_REQUIRED(conn)) {
1535 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1536 exit_server_cleanly("encryption required "
1542 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1543 (flags & (AS_USER|DO_CHDIR)
1545 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1548 conn->num_smb_operations++;
1551 /* does this protocol need to be run as guest? */
1552 if ((flags & AS_GUEST)
1553 && (!change_to_guest() ||
1554 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1555 sconn->client_id.name,
1556 sconn->client_id.addr))) {
1557 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1561 smb_messages[type].fn(req);
1565 /****************************************************************************
1566 Construct a reply to the incoming packet.
1567 ****************************************************************************/
1569 static void construct_reply(struct smbd_server_connection *sconn,
1570 char *inbuf, int size, size_t unread_bytes,
1571 uint32_t seqnum, bool encrypted,
1572 struct smb_perfcount_data *deferred_pcd)
1574 connection_struct *conn;
1575 struct smb_request *req;
1577 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1578 smb_panic("could not allocate smb_request");
1581 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1582 encrypted, seqnum)) {
1583 exit_server_cleanly("Invalid SMB request");
1586 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1588 /* we popped this message off the queue - keep original perf data */
1590 req->pcd = *deferred_pcd;
1592 SMB_PERFCOUNT_START(&req->pcd);
1593 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1594 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1597 conn = switch_message(req->cmd, req, size);
1599 if (req->unread_bytes) {
1600 /* writeX failed. drain socket. */
1601 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1602 req->unread_bytes) {
1603 smb_panic("failed to drain pending bytes");
1605 req->unread_bytes = 0;
1613 if (req->outbuf == NULL) {
1617 if (CVAL(req->outbuf,0) == 0) {
1618 show_msg((char *)req->outbuf);
1621 if (!srv_send_smb(req->sconn,
1622 (char *)req->outbuf,
1623 true, req->seqnum+1,
1624 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1626 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1634 /****************************************************************************
1635 Process an smb from the client
1636 ****************************************************************************/
1637 static void process_smb(struct smbd_server_connection *sconn,
1638 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1639 uint32_t seqnum, bool encrypted,
1640 struct smb_perfcount_data *deferred_pcd)
1642 int msg_type = CVAL(inbuf,0);
1644 DO_PROFILE_INC(smb_count);
1646 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1648 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1649 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1651 if (msg_type != 0) {
1653 * NetBIOS session request, keepalive, etc.
1655 reply_special(sconn, (char *)inbuf, nread);
1659 if (sconn->using_smb2) {
1660 /* At this point we're not really using smb2,
1661 * we make the decision here.. */
1662 if (smbd_is_smb2_header(inbuf, nread)) {
1663 smbd_smb2_first_negprot(sconn, inbuf, nread);
1665 } else if (nread >= smb_size && valid_smb_header(inbuf)
1666 && CVAL(inbuf, smb_com) != 0x72) {
1667 /* This is a non-negprot SMB1 packet.
1668 Disable SMB2 from now on. */
1669 sconn->using_smb2 = false;
1673 show_msg((char *)inbuf);
1675 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1676 encrypted, deferred_pcd);
1680 sconn->smb1.num_requests++;
1682 /* The timeout_processing function isn't run nearly
1683 often enough to implement 'max log size' without
1684 overrunning the size of the file by many megabytes.
1685 This is especially true if we are running at debug
1686 level 10. Checking every 50 SMBs is a nice
1687 tradeoff of performance vs log file size overrun. */
1689 if ((sconn->smb1.num_requests % 50) == 0 &&
1690 need_to_check_log_size()) {
1691 change_to_root_user();
1696 /****************************************************************************
1697 Return a string containing the function name of a SMB command.
1698 ****************************************************************************/
1700 const char *smb_fn_name(int type)
1702 const char *unknown_name = "SMBunknown";
1704 if (smb_messages[type].name == NULL)
1705 return(unknown_name);
1707 return(smb_messages[type].name);
1710 /****************************************************************************
1711 Helper functions for contruct_reply.
1712 ****************************************************************************/
1714 void add_to_common_flags2(uint32 v)
1719 void remove_from_common_flags2(uint32 v)
1721 common_flags2 &= ~v;
1724 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1727 srv_set_message(outbuf,0,0,false);
1729 SCVAL(outbuf, smb_com, req->cmd);
1730 SIVAL(outbuf,smb_rcls,0);
1731 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1732 SSVAL(outbuf,smb_flg2,
1733 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1735 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1737 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1738 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1739 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1740 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1743 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1745 construct_reply_common(req, (char *)req->inbuf, outbuf);
1749 * How many bytes have we already accumulated up to the current wct field
1753 size_t req_wct_ofs(struct smb_request *req)
1757 if (req->chain_outbuf == NULL) {
1760 buf_size = talloc_get_size(req->chain_outbuf);
1761 if ((buf_size % 4) != 0) {
1762 buf_size += (4 - (buf_size % 4));
1764 return buf_size - 4;
1768 * Hack around reply_nterror & friends not being aware of chained requests,
1769 * generating illegal (i.e. wct==0) chain replies.
1772 static void fixup_chain_error_packet(struct smb_request *req)
1774 uint8_t *outbuf = req->outbuf;
1776 reply_outbuf(req, 2, 0);
1777 memcpy(req->outbuf, outbuf, smb_wct);
1778 TALLOC_FREE(outbuf);
1779 SCVAL(req->outbuf, smb_vwv0, 0xff);
1783 * @brief Find the smb_cmd offset of the last command pushed
1784 * @param[in] buf The buffer we're building up
1785 * @retval Where can we put our next andx cmd?
1787 * While chaining requests, the "next" request we're looking at needs to put
1788 * its SMB_Command before the data the previous request already built up added
1789 * to the chain. Find the offset to the place where we have to put our cmd.
1792 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1797 cmd = CVAL(buf, smb_com);
1799 SMB_ASSERT(is_andx_req(cmd));
1803 while (CVAL(buf, ofs) != 0xff) {
1805 if (!is_andx_req(CVAL(buf, ofs))) {
1810 * ofs is from start of smb header, so add the 4 length
1811 * bytes. The next cmd is right after the wct field.
1813 ofs = SVAL(buf, ofs+2) + 4 + 1;
1815 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1823 * @brief Do the smb chaining at a buffer level
1824 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1825 * @param[in] smb_command The command that we want to issue
1826 * @param[in] wct How many words?
1827 * @param[in] vwv The words, already in network order
1828 * @param[in] bytes_alignment How shall we align "bytes"?
1829 * @param[in] num_bytes How many bytes?
1830 * @param[in] bytes The data the request ships
1832 * smb_splice_chain() adds the vwv and bytes to the request already present in
1836 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1837 uint8_t wct, const uint16_t *vwv,
1838 size_t bytes_alignment,
1839 uint32_t num_bytes, const uint8_t *bytes)
1842 size_t old_size, new_size;
1844 size_t chain_padding = 0;
1845 size_t bytes_padding = 0;
1848 old_size = talloc_get_size(*poutbuf);
1851 * old_size == smb_wct means we're pushing the first request in for
1855 first_request = (old_size == smb_wct);
1857 if (!first_request && ((old_size % 4) != 0)) {
1859 * Align the wct field of subsequent requests to a 4-byte
1862 chain_padding = 4 - (old_size % 4);
1866 * After the old request comes the new wct field (1 byte), the vwv's
1867 * and the num_bytes field. After at we might need to align the bytes
1868 * given to us to "bytes_alignment", increasing the num_bytes value.
1871 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1873 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1874 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1877 new_size += bytes_padding + num_bytes;
1879 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1880 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1881 (unsigned)new_size));
1885 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1886 if (outbuf == NULL) {
1887 DEBUG(0, ("talloc failed\n"));
1892 if (first_request) {
1893 SCVAL(outbuf, smb_com, smb_command);
1895 size_t andx_cmd_ofs;
1897 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1898 DEBUG(1, ("invalid command chain\n"));
1899 *poutbuf = TALLOC_REALLOC_ARRAY(
1900 NULL, *poutbuf, uint8_t, old_size);
1904 if (chain_padding != 0) {
1905 memset(outbuf + old_size, 0, chain_padding);
1906 old_size += chain_padding;
1909 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1910 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1916 * Push the chained request:
1921 SCVAL(outbuf, ofs, wct);
1928 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1929 ofs += sizeof(uint16_t) * wct;
1935 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1936 ofs += sizeof(uint16_t);
1942 if (bytes_padding != 0) {
1943 memset(outbuf + ofs, 0, bytes_padding);
1944 ofs += bytes_padding;
1951 memcpy(outbuf + ofs, bytes, num_bytes);
1956 /****************************************************************************
1957 Construct a chained reply and add it to the already made reply
1958 ****************************************************************************/
1960 void chain_reply(struct smb_request *req)
1962 size_t smblen = smb_len(req->inbuf);
1963 size_t already_used, length_needed;
1965 uint32_t chain_offset; /* uint32_t to avoid overflow */
1972 if (IVAL(req->outbuf, smb_rcls) != 0) {
1973 fixup_chain_error_packet(req);
1977 * Any of the AndX requests and replies have at least a wct of
1978 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1979 * beginning of the SMB header to the next wct field.
1981 * None of the AndX requests put anything valuable in vwv[0] and [1],
1982 * so we can overwrite it here to form the chain.
1985 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1986 if (req->chain_outbuf == NULL) {
1987 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1988 req, req->outbuf, uint8_t,
1989 smb_len(req->outbuf) + 4);
1990 if (req->chain_outbuf == NULL) {
1991 smb_panic("talloc failed");
1999 * Here we assume that this is the end of the chain. For that we need
2000 * to set "next command" to 0xff and the offset to 0. If we later find
2001 * more commands in the chain, this will be overwritten again.
2004 SCVAL(req->outbuf, smb_vwv0, 0xff);
2005 SCVAL(req->outbuf, smb_vwv0+1, 0);
2006 SSVAL(req->outbuf, smb_vwv1, 0);
2008 if (req->chain_outbuf == NULL) {
2010 * In req->chain_outbuf we collect all the replies. Start the
2011 * chain by copying in the first reply.
2013 * We do the realloc because later on we depend on
2014 * talloc_get_size to determine the length of
2015 * chain_outbuf. The reply_xxx routines might have
2016 * over-allocated (reply_pipe_read_and_X used to be such an
2019 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2020 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2021 if (req->chain_outbuf == NULL) {
2022 smb_panic("talloc failed");
2027 * Update smb headers where subsequent chained commands
2028 * may have updated them.
2030 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2031 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2033 if (!smb_splice_chain(&req->chain_outbuf,
2034 CVAL(req->outbuf, smb_com),
2035 CVAL(req->outbuf, smb_wct),
2036 (uint16_t *)(req->outbuf + smb_vwv),
2037 0, smb_buflen(req->outbuf),
2038 (uint8_t *)smb_buf(req->outbuf))) {
2041 TALLOC_FREE(req->outbuf);
2045 * We use the old request's vwv field to grab the next chained command
2046 * and offset into the chained fields.
2049 chain_cmd = CVAL(req->vwv+0, 0);
2050 chain_offset = SVAL(req->vwv+1, 0);
2052 if (chain_cmd == 0xff) {
2054 * End of chain, no more requests from the client. So ship the
2057 smb_setlen((char *)(req->chain_outbuf),
2058 talloc_get_size(req->chain_outbuf) - 4);
2060 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2061 true, req->seqnum+1,
2062 IS_CONN_ENCRYPTED(req->conn)
2065 exit_server_cleanly("chain_reply: srv_send_smb "
2068 TALLOC_FREE(req->chain_outbuf);
2073 /* add a new perfcounter for this element of chain */
2074 SMB_PERFCOUNT_ADD(&req->pcd);
2075 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2076 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2079 * Check if the client tries to fool us. The request so far uses the
2080 * space to the end of the byte buffer in the request just
2081 * processed. The chain_offset can't point into that area. If that was
2082 * the case, we could end up with an endless processing of the chain,
2083 * we would always handle the same request.
2086 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2087 if (chain_offset < already_used) {
2092 * Next check: Make sure the chain offset does not point beyond the
2093 * overall smb request length.
2096 length_needed = chain_offset+1; /* wct */
2097 if (length_needed > smblen) {
2102 * Now comes the pointer magic. Goal here is to set up req->vwv and
2103 * req->buf correctly again to be able to call the subsequent
2104 * switch_message(). The chain offset (the former vwv[1]) points at
2105 * the new wct field.
2108 wct = CVAL(smb_base(req->inbuf), chain_offset);
2111 * Next consistency check: Make the new vwv array fits in the overall
2115 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2116 if (length_needed > smblen) {
2119 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2122 * Now grab the new byte buffer....
2125 buflen = SVAL(vwv+wct, 0);
2128 * .. and check that it fits.
2131 length_needed += buflen;
2132 if (length_needed > smblen) {
2135 buf = (uint8_t *)(vwv+wct+1);
2137 req->cmd = chain_cmd;
2140 req->buflen = buflen;
2143 switch_message(chain_cmd, req, smblen);
2145 if (req->outbuf == NULL) {
2147 * This happens if the chained command has suspended itself or
2148 * if it has called srv_send_smb() itself.
2154 * We end up here if the chained command was not itself chained or
2155 * suspended, but for example a close() command. We now need to splice
2156 * the chained commands' outbuf into the already built up chain_outbuf
2157 * and ship the result.
2163 * We end up here if there's any error in the chain syntax. Report a
2164 * DOS error, just like Windows does.
2166 reply_force_doserror(req, ERRSRV, ERRerror);
2167 fixup_chain_error_packet(req);
2171 * This scary statement intends to set the
2172 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2173 * to the value req->outbuf carries
2175 SSVAL(req->chain_outbuf, smb_flg2,
2176 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2177 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2180 * Transfer the error codes from the subrequest to the main one
2182 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2183 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2185 if (!smb_splice_chain(&req->chain_outbuf,
2186 CVAL(req->outbuf, smb_com),
2187 CVAL(req->outbuf, smb_wct),
2188 (uint16_t *)(req->outbuf + smb_vwv),
2189 0, smb_buflen(req->outbuf),
2190 (uint8_t *)smb_buf(req->outbuf))) {
2191 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2193 TALLOC_FREE(req->outbuf);
2195 smb_setlen((char *)(req->chain_outbuf),
2196 talloc_get_size(req->chain_outbuf) - 4);
2198 show_msg((char *)(req->chain_outbuf));
2200 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2201 true, req->seqnum+1,
2202 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2204 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2206 TALLOC_FREE(req->chain_outbuf);
2210 /****************************************************************************
2211 Check if services need reloading.
2212 ****************************************************************************/
2214 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2217 if (last_smb_conf_reload_time == 0) {
2218 last_smb_conf_reload_time = t;
2221 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2222 reload_services(sconn->msg_ctx, sconn->sock, True);
2223 last_smb_conf_reload_time = t;
2227 static bool fd_is_readable(int fd)
2231 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2233 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2237 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2239 /* TODO: make write nonblocking */
2242 static void smbd_server_connection_read_handler(
2243 struct smbd_server_connection *conn, int fd)
2245 uint8_t *inbuf = NULL;
2246 size_t inbuf_len = 0;
2247 size_t unread_bytes = 0;
2248 bool encrypted = false;
2249 TALLOC_CTX *mem_ctx = talloc_tos();
2253 bool from_client = (conn->sock == fd);
2256 smbd_lock_socket(conn);
2258 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2259 DEBUG(10,("the echo listener was faster\n"));
2260 smbd_unlock_socket(conn);
2264 /* TODO: make this completely nonblocking */
2265 status = receive_smb_talloc(mem_ctx, conn,
2266 (char **)(void *)&inbuf,
2270 &inbuf_len, &seqnum,
2271 false /* trusted channel */);
2272 smbd_unlock_socket(conn);
2274 /* TODO: make this completely nonblocking */
2275 status = receive_smb_talloc(mem_ctx, conn,
2276 (char **)(void *)&inbuf,
2280 &inbuf_len, &seqnum,
2281 true /* trusted channel */);
2284 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2287 if (NT_STATUS_IS_ERR(status)) {
2288 exit_server_cleanly("failed to receive smb request");
2290 if (!NT_STATUS_IS_OK(status)) {
2295 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2296 seqnum, encrypted, NULL);
2299 static void smbd_server_connection_handler(struct event_context *ev,
2300 struct fd_event *fde,
2304 struct smbd_server_connection *conn = talloc_get_type(private_data,
2305 struct smbd_server_connection);
2307 if (flags & EVENT_FD_WRITE) {
2308 smbd_server_connection_write_handler(conn);
2311 if (flags & EVENT_FD_READ) {
2312 smbd_server_connection_read_handler(conn, conn->sock);
2317 static void smbd_server_echo_handler(struct event_context *ev,
2318 struct fd_event *fde,
2322 struct smbd_server_connection *conn = talloc_get_type(private_data,
2323 struct smbd_server_connection);
2325 if (flags & EVENT_FD_WRITE) {
2326 smbd_server_connection_write_handler(conn);
2329 if (flags & EVENT_FD_READ) {
2330 smbd_server_connection_read_handler(
2331 conn, conn->smb1.echo_handler.trusted_fd);
2336 /****************************************************************************
2337 received when we should release a specific IP
2338 ****************************************************************************/
2339 static void release_ip(const char *ip, void *priv)
2341 const char *addr = (const char *)priv;
2342 const char *p = addr;
2344 if (strncmp("::ffff:", addr, 7) == 0) {
2348 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2349 /* we can't afford to do a clean exit - that involves
2350 database writes, which would potentially mean we
2351 are still running after the failover has finished -
2352 we have to get rid of this process ID straight
2354 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2356 /* note we must exit with non-zero status so the unclean handler gets
2357 called in the parent, so that the brl database is tickled */
2362 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2363 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2365 struct smbd_server_connection *sconn = talloc_get_type_abort(
2366 private_data, struct smbd_server_connection);
2368 release_ip((char *)data->data, sconn->client_id.addr);
2371 #ifdef CLUSTER_SUPPORT
2372 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2373 struct sockaddr_storage *client)
2376 length = sizeof(*server);
2377 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2380 length = sizeof(*client);
2381 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2389 * Send keepalive packets to our client
2391 static bool keepalive_fn(const struct timeval *now, void *private_data)
2393 struct smbd_server_connection *sconn = smbd_server_conn;
2396 if (sconn->using_smb2) {
2397 /* Don't do keepalives on an SMB2 connection. */
2401 smbd_lock_socket(smbd_server_conn);
2402 ret = send_keepalive(sconn->sock);
2403 smbd_unlock_socket(smbd_server_conn);
2406 char addr[INET6_ADDRSTRLEN];
2408 * Try and give an error message saying what
2411 DEBUG(0, ("send_keepalive failed for client %s. "
2412 "Error %s - exiting\n",
2413 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2421 * Do the recurring check if we're idle
2423 static bool deadtime_fn(const struct timeval *now, void *private_data)
2425 struct smbd_server_connection *sconn =
2426 (struct smbd_server_connection *)private_data;
2428 if ((conn_num_open(sconn) == 0)
2429 || (conn_idle_all(sconn, now->tv_sec))) {
2430 DEBUG( 2, ( "Closing idle connection\n" ) );
2431 messaging_send(sconn->msg_ctx,
2432 messaging_server_id(sconn->msg_ctx),
2433 MSG_SHUTDOWN, &data_blob_null);
2441 * Do the recurring log file and smb.conf reload checks.
2444 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2446 struct smbd_server_connection *sconn = talloc_get_type_abort(
2447 private_data, struct smbd_server_connection);
2449 DEBUG(5, ("housekeeping\n"));
2451 change_to_root_user();
2453 /* update printer queue caches if necessary */
2454 update_monitored_printq_cache(sconn->msg_ctx);
2456 /* check if we need to reload services */
2457 check_reload(sconn, time_mono(NULL));
2459 /* Change machine password if neccessary. */
2460 attempt_machine_password_change();
2463 * Force a log file check.
2465 force_check_log_size();
2470 static int create_unlink_tmp(const char *dir)
2475 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2476 if (fname == NULL) {
2480 fd = mkstemp(fname);
2485 if (unlink(fname) == -1) {
2486 int sys_errno = errno;
2496 struct smbd_echo_state {
2497 struct tevent_context *ev;
2498 struct iovec *pending;
2499 struct smbd_server_connection *sconn;
2502 struct tevent_fd *parent_fde;
2504 struct tevent_fd *read_fde;
2505 struct tevent_req *write_req;
2508 static void smbd_echo_writer_done(struct tevent_req *req);
2510 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2514 if (state->write_req != NULL) {
2518 num_pending = talloc_array_length(state->pending);
2519 if (num_pending == 0) {
2523 state->write_req = writev_send(state, state->ev, NULL,
2524 state->parent_pipe, false,
2525 state->pending, num_pending);
2526 if (state->write_req == NULL) {
2527 DEBUG(1, ("writev_send failed\n"));
2531 talloc_steal(state->write_req, state->pending);
2532 state->pending = NULL;
2534 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2538 static void smbd_echo_writer_done(struct tevent_req *req)
2540 struct smbd_echo_state *state = tevent_req_callback_data(
2541 req, struct smbd_echo_state);
2545 written = writev_recv(req, &err);
2547 state->write_req = NULL;
2548 if (written == -1) {
2549 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2552 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2553 smbd_echo_activate_writer(state);
2556 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2559 struct smb_request req;
2560 uint16_t num_replies;
2565 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2566 DEBUG(10, ("Got netbios keepalive\n"));
2573 if (inbuf_len < smb_size) {
2574 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2577 if (!valid_smb_header(inbuf)) {
2578 DEBUG(10, ("Got invalid SMB header\n"));
2582 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2588 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2589 smb_messages[req.cmd].name
2590 ? smb_messages[req.cmd].name : "unknown"));
2592 if (req.cmd != SMBecho) {
2599 num_replies = SVAL(req.vwv+0, 0);
2600 if (num_replies != 1) {
2601 /* Not a Windows "Hey, you're still there?" request */
2605 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2607 DEBUG(10, ("create_outbuf failed\n"));
2610 req.outbuf = (uint8_t *)outbuf;
2612 SSVAL(req.outbuf, smb_vwv0, num_replies);
2614 if (req.buflen > 0) {
2615 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2618 out_len = smb_len(req.outbuf) + 4;
2620 ok = srv_send_smb(req.sconn,
2624 TALLOC_FREE(outbuf);
2632 static void smbd_echo_exit(struct tevent_context *ev,
2633 struct tevent_fd *fde, uint16_t flags,
2636 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2640 static void smbd_echo_reader(struct tevent_context *ev,
2641 struct tevent_fd *fde, uint16_t flags,
2644 struct smbd_echo_state *state = talloc_get_type_abort(
2645 private_data, struct smbd_echo_state);
2646 struct smbd_server_connection *sconn = state->sconn;
2647 size_t unread, num_pending;
2651 uint32_t seqnum = 0;
2654 bool encrypted = false;
2658 ok = smbd_lock_socket_internal(sconn);
2660 DEBUG(0, ("%s: failed to lock socket\n",
2665 if (!fd_is_readable(sconn->sock)) {
2666 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2667 (int)sys_getpid()));
2668 ok = smbd_unlock_socket_internal(sconn);
2670 DEBUG(1, ("%s: failed to unlock socket in\n",
2677 num_pending = talloc_array_length(state->pending);
2678 tmp = talloc_realloc(state, state->pending, struct iovec,
2681 DEBUG(1, ("talloc_realloc failed\n"));
2684 state->pending = tmp;
2686 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2688 status = receive_smb_talloc(state->pending, sconn,
2689 (char **)(void *)&state->pending[num_pending].iov_base,
2695 false /* trusted_channel*/);
2696 if (!NT_STATUS_IS_OK(status)) {
2697 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2698 (int)sys_getpid(), nt_errstr(status)));
2701 state->pending[num_pending].iov_len = iov_len;
2703 ok = smbd_unlock_socket_internal(sconn);
2705 DEBUG(1, ("%s: failed to unlock socket in\n",
2710 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2711 state->pending[num_pending].iov_len,
2714 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2715 /* no check, shrinking by some bytes does not fail */
2716 state->pending = talloc_realloc(state, state->pending,
2722 if (state->pending[num_pending].iov_len >= smb_size) {
2724 * place the seqnum in the packet so that the main process
2725 * can reply with signing
2727 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2728 smb_ss_field, seqnum);
2729 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2730 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2733 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2734 smbd_echo_activate_writer(state);
2737 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2740 struct smbd_echo_state *state;
2742 state = talloc_zero(sconn, struct smbd_echo_state);
2743 if (state == NULL) {
2744 DEBUG(1, ("talloc failed\n"));
2747 state->sconn = sconn;
2748 state->parent_pipe = parent_pipe;
2749 state->ev = s3_tevent_context_init(state);
2750 if (state->ev == NULL) {
2751 DEBUG(1, ("tevent_context_init failed\n"));
2755 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2756 TEVENT_FD_READ, smbd_echo_exit,
2758 if (state->parent_fde == NULL) {
2759 DEBUG(1, ("tevent_add_fd failed\n"));
2763 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2764 TEVENT_FD_READ, smbd_echo_reader,
2766 if (state->read_fde == NULL) {
2767 DEBUG(1, ("tevent_add_fd failed\n"));
2773 if (tevent_loop_once(state->ev) == -1) {
2774 DEBUG(1, ("tevent_loop_once failed: %s\n",
2783 * Handle SMBecho requests in a forked child process
2785 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2787 int listener_pipe[2];
2791 res = pipe(listener_pipe);
2793 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2796 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2797 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2798 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2806 close(listener_pipe[0]);
2807 set_blocking(listener_pipe[1], false);
2809 status = reinit_after_fork(sconn->msg_ctx,
2810 smbd_event_context(),
2811 procid_self(), false);
2812 if (!NT_STATUS_IS_OK(status)) {
2813 DEBUG(1, ("reinit_after_fork failed: %s\n",
2814 nt_errstr(status)));
2817 smbd_echo_loop(sconn, listener_pipe[1]);
2820 close(listener_pipe[1]);
2821 listener_pipe[1] = -1;
2822 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2824 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2827 * Without smb signing this is the same as the normal smbd
2828 * listener. This needs to change once signing comes in.
2830 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2832 sconn->smb1.echo_handler.trusted_fd,
2834 smbd_server_echo_handler,
2836 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2837 DEBUG(1, ("event_add_fd failed\n"));
2844 if (listener_pipe[0] != -1) {
2845 close(listener_pipe[0]);
2847 if (listener_pipe[1] != -1) {
2848 close(listener_pipe[1]);
2850 sconn->smb1.echo_handler.trusted_fd = -1;
2851 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2852 close(sconn->smb1.echo_handler.socket_lock_fd);
2854 sconn->smb1.echo_handler.trusted_fd = -1;
2855 sconn->smb1.echo_handler.socket_lock_fd = -1;
2861 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2862 struct sockaddr_storage *srv,
2863 struct sockaddr_storage *clnt)
2865 struct ctdbd_connection *cconn;
2866 char tmp_addr[INET6_ADDRSTRLEN];
2869 cconn = messaging_ctdbd_connection();
2870 if (cconn == NULL) {
2871 return NT_STATUS_NO_MEMORY;
2874 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2875 addr = talloc_strdup(cconn, tmp_addr);
2877 return NT_STATUS_NO_MEMORY;
2879 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2884 /****************************************************************************
2885 Process commands from the client
2886 ****************************************************************************/
2888 void smbd_process(struct smbd_server_connection *sconn)
2890 TALLOC_CTX *frame = talloc_stackframe();
2891 struct sockaddr_storage ss;
2892 struct sockaddr *sa = NULL;
2893 socklen_t sa_socklen;
2894 struct tsocket_address *local_address = NULL;
2895 struct tsocket_address *remote_address = NULL;
2896 const char *remaddr = NULL;
2899 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2900 !lp_async_smb_echo_handler()) {
2902 * We're not making the desion here,
2903 * we're just allowing the client
2904 * to decide between SMB1 and SMB2
2905 * with the first negprot
2908 sconn->using_smb2 = true;
2911 /* Ensure child is set to blocking mode */
2912 set_blocking(sconn->sock,True);
2914 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2915 set_socket_options(sconn->sock, lp_socket_options());
2917 sa = (struct sockaddr *)(void *)&ss;
2918 sa_socklen = sizeof(ss);
2919 ret = getpeername(sconn->sock, sa, &sa_socklen);
2921 int level = (errno == ENOTCONN)?2:0;
2922 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2923 exit_server_cleanly("getpeername() failed.\n");
2925 ret = tsocket_address_bsd_from_sockaddr(sconn,
2929 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2930 __location__, strerror(errno)));
2931 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2934 sa = (struct sockaddr *)(void *)&ss;
2935 sa_socklen = sizeof(ss);
2936 ret = getsockname(sconn->sock, sa, &sa_socklen);
2938 int level = (errno == ENOTCONN)?2:0;
2939 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2940 exit_server_cleanly("getsockname() failed.\n");
2942 ret = tsocket_address_bsd_from_sockaddr(sconn,
2946 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2947 __location__, strerror(errno)));
2948 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2951 sconn->local_address = local_address;
2952 sconn->remote_address = remote_address;
2954 if (tsocket_address_is_inet(remote_address, "ip")) {
2955 remaddr = tsocket_address_inet_addr_string(
2956 sconn->remote_address,
2958 if (remaddr == NULL) {
2962 remaddr = "0.0.0.0";
2965 /* this is needed so that we get decent entries
2966 in smbstatus for port 445 connects */
2967 set_remote_machine_name(remaddr, false);
2968 reload_services(sconn->msg_ctx, sconn->sock, true);
2971 * Before the first packet, check the global hosts allow/ hosts deny
2972 * parameters before doing any parsing of packets passed to us by the
2973 * client. This prevents attacks on our parsing code from hosts not in
2974 * the hosts allow list.
2977 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2978 sconn->client_id.name,
2979 sconn->client_id.addr)) {
2981 * send a negative session response "not listening on calling
2984 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2985 DEBUG( 1, ("Connection denied from %s to %s\n",
2986 tsocket_address_string(remote_address, talloc_tos()),
2987 tsocket_address_string(local_address, talloc_tos())));
2988 (void)srv_send_smb(sconn,(char *)buf, false,
2990 exit_server_cleanly("connection denied");
2993 DEBUG(10, ("Connection allowed from %s to %s\n",
2994 tsocket_address_string(remote_address, talloc_tos()),
2995 tsocket_address_string(local_address, talloc_tos())));
2999 smb_perfcount_init();
3001 if (!init_account_policy()) {
3002 exit_server("Could not open account policy tdb.\n");
3005 if (*lp_rootdir()) {
3006 if (chroot(lp_rootdir()) != 0) {
3007 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3008 exit_server("Failed to chroot()");
3010 if (chdir("/") == -1) {
3011 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3012 exit_server("Failed to chroot()");
3014 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3017 if (!srv_init_signing(sconn)) {
3018 exit_server("Failed to init smb_signing");
3021 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3022 exit_server("Failed to fork echo handler");
3026 if (!init_oplocks(sconn->msg_ctx))
3027 exit_server("Failed to init oplocks");
3029 /* register our message handlers */
3030 messaging_register(sconn->msg_ctx, NULL,
3031 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3032 messaging_register(sconn->msg_ctx, sconn,
3033 MSG_SMB_RELEASE_IP, msg_release_ip);
3034 messaging_register(sconn->msg_ctx, NULL,
3035 MSG_SMB_CLOSE_FILE, msg_close_file);
3038 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3039 * MSGs to all child processes
3041 messaging_deregister(sconn->msg_ctx,
3043 messaging_register(sconn->msg_ctx, NULL,
3044 MSG_DEBUG, debug_message);
3046 if ((lp_keepalive() != 0)
3047 && !(event_add_idle(smbd_event_context(), NULL,
3048 timeval_set(lp_keepalive(), 0),
3049 "keepalive", keepalive_fn,
3051 DEBUG(0, ("Could not add keepalive event\n"));
3055 if (!(event_add_idle(smbd_event_context(), NULL,
3056 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3057 "deadtime", deadtime_fn, sconn))) {
3058 DEBUG(0, ("Could not add deadtime event\n"));
3062 if (!(event_add_idle(smbd_event_context(), NULL,
3063 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3064 "housekeeping", housekeeping_fn, sconn))) {
3065 DEBUG(0, ("Could not add housekeeping event\n"));
3069 #ifdef CLUSTER_SUPPORT
3071 if (lp_clustering()) {
3073 * We need to tell ctdb about our client's TCP
3074 * connection, so that for failover ctdbd can send
3075 * tickle acks, triggering a reconnection by the
3079 struct sockaddr_storage srv, clnt;
3081 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3083 status = smbd_register_ips(sconn, &srv, &clnt);
3084 if (!NT_STATUS_IS_OK(status)) {
3085 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3086 nt_errstr(status)));
3090 DEBUG(0,("Unable to get tcp info for "
3091 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3098 sconn->nbt.got_session = false;
3100 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3102 sconn->smb1.sessions.done_sesssetup = false;
3103 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3104 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3105 /* users from session setup */
3106 sconn->smb1.sessions.session_userlist = NULL;
3107 /* workgroup from session setup. */
3108 sconn->smb1.sessions.session_workgroup = NULL;
3109 /* this holds info on user ids that are already validated for this VC */
3110 sconn->smb1.sessions.validated_users = NULL;
3111 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3112 sconn->smb1.sessions.num_validated_vuids = 0;
3115 if (!init_dptrs(sconn)) {
3116 exit_server("init_dptrs() failed");
3119 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3123 smbd_server_connection_handler,
3125 if (!sconn->smb1.fde) {
3126 exit_server("failed to create smbd_server_connection fde");
3134 frame = talloc_stackframe_pool(8192);
3138 status = smbd_server_connection_loop_once(sconn);
3139 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3140 !NT_STATUS_IS_OK(status)) {
3141 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3142 " exiting\n", nt_errstr(status)));
3149 exit_server_cleanly(NULL);
3152 bool req_is_in_chain(struct smb_request *req)
3154 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3156 * We're right now handling a subsequent request, so we must
3162 if (!is_andx_req(req->cmd)) {
3168 * Okay, an illegal request, but definitely not chained :-)
3173 return (CVAL(req->vwv+0, 0) != 0xFF);