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"
32 extern bool global_machine_password_needs_changing;
34 static void construct_reply_common(struct smb_request *req, const char *inbuf,
36 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
38 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
42 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
46 sconn->smb1.echo_handler.ref_count++;
48 if (sconn->smb1.echo_handler.ref_count > 1) {
52 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
56 sconn->smb1.echo_handler.socket_lock_fd,
57 SMB_F_SETLKW, 0, 0, F_WRLCK);
58 } while (!ok && (errno == EINTR));
61 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
65 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
70 void smbd_lock_socket(struct smbd_server_connection *sconn)
72 if (!smbd_lock_socket_internal(sconn)) {
73 exit_server_cleanly("failed to lock socket");
77 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
81 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
85 sconn->smb1.echo_handler.ref_count--;
87 if (sconn->smb1.echo_handler.ref_count > 0) {
93 sconn->smb1.echo_handler.socket_lock_fd,
94 SMB_F_SETLKW, 0, 0, F_UNLCK);
95 } while (!ok && (errno == EINTR));
98 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
102 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
107 void smbd_unlock_socket(struct smbd_server_connection *sconn)
109 if (!smbd_unlock_socket_internal(sconn)) {
110 exit_server_cleanly("failed to unlock socket");
114 /* Accessor function for smb_read_error for smbd functions. */
116 /****************************************************************************
118 ****************************************************************************/
120 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
121 bool do_signing, uint32_t seqnum,
123 struct smb_perfcount_data *pcd)
128 char *buf_out = buffer;
130 smbd_lock_socket(sconn);
133 /* Sign the outgoing packet if required. */
134 srv_calculate_sign_mac(sconn, buf_out, seqnum);
138 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
139 if (!NT_STATUS_IS_OK(status)) {
140 DEBUG(0, ("send_smb: SMB encryption failed "
141 "on outgoing packet! Error %s\n",
142 nt_errstr(status) ));
147 len = smb_len(buf_out) + 4;
149 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
152 char addr[INET6_ADDRSTRLEN];
154 * Try and give an error message saying what
157 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
158 (int)sys_getpid(), (int)len,
159 get_peer_addr(sconn->sock, addr, sizeof(addr)),
160 (int)ret, strerror(errno) ));
162 srv_free_enc_buffer(buf_out);
166 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
167 srv_free_enc_buffer(buf_out);
169 SMB_PERFCOUNT_END(pcd);
171 smbd_unlock_socket(sconn);
175 /*******************************************************************
176 Setup the word count and byte count for a smb message.
177 ********************************************************************/
179 int srv_set_message(char *buf,
184 if (zero && (num_words || num_bytes)) {
185 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
187 SCVAL(buf,smb_wct,num_words);
188 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
189 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
190 return (smb_size + num_words*2 + num_bytes);
193 static bool valid_smb_header(const uint8_t *inbuf)
195 if (is_encrypted_packet(inbuf)) {
199 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
200 * but it just looks weird to call strncmp for this one.
202 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
205 /* Socket functions for smbd packet processing. */
207 static bool valid_packet_size(size_t len)
210 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
211 * of header. Don't print the error if this fits.... JRA.
214 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
215 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
216 (unsigned long)len));
222 static NTSTATUS read_packet_remainder(int fd, char *buffer,
223 unsigned int timeout, ssize_t len)
231 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
232 if (!NT_STATUS_IS_OK(status)) {
233 char addr[INET6_ADDRSTRLEN];
234 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
236 get_peer_addr(fd, addr, sizeof(addr)),
242 /****************************************************************************
243 Attempt a zerocopy writeX read. We know here that len > smb_size-4
244 ****************************************************************************/
247 * Unfortunately, earlier versions of smbclient/libsmbclient
248 * don't send this "standard" writeX header. I've fixed this
249 * for 3.2 but we'll use the old method with earlier versions.
250 * Windows and CIFSFS at least use this standard size. Not
254 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
255 (2*14) + /* word count (including bcc) */ \
258 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
259 const char lenbuf[4],
260 struct smbd_server_connection *sconn,
262 unsigned int timeout,
266 /* Size of a WRITEX call (+4 byte len). */
267 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
268 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
272 memcpy(writeX_header, lenbuf, 4);
274 status = read_fd_with_timeout(
275 sconn->sock, writeX_header + 4,
276 STANDARD_WRITE_AND_X_HEADER_SIZE,
277 STANDARD_WRITE_AND_X_HEADER_SIZE,
280 if (!NT_STATUS_IS_OK(status)) {
281 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
282 "error = %s.\n", sconn->client_id.addr,
288 * Ok - now try and see if this is a possible
292 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
294 * If the data offset is beyond what
295 * we've read, drain the extra bytes.
297 uint16_t doff = SVAL(writeX_header,smb_vwv11);
300 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
301 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
302 if (drain_socket(sconn->sock, drain) != drain) {
303 smb_panic("receive_smb_raw_talloc_partial_read:"
304 " failed to drain pending bytes");
307 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
310 /* Spoof down the length and null out the bcc. */
311 set_message_bcc(writeX_header, 0);
312 newlen = smb_len(writeX_header);
314 /* Copy the header we've written. */
316 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
318 sizeof(writeX_header));
320 if (*buffer == NULL) {
321 DEBUG(0, ("Could not allocate inbuf of length %d\n",
322 (int)sizeof(writeX_header)));
323 return NT_STATUS_NO_MEMORY;
326 /* Work out the remaining bytes. */
327 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
328 *len_ret = newlen + 4;
332 if (!valid_packet_size(len)) {
333 return NT_STATUS_INVALID_PARAMETER;
337 * Not a valid writeX call. Just do the standard
341 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
343 if (*buffer == NULL) {
344 DEBUG(0, ("Could not allocate inbuf of length %d\n",
346 return NT_STATUS_NO_MEMORY;
349 /* Copy in what we already read. */
352 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
353 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
356 status = read_packet_remainder(
358 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
361 if (!NT_STATUS_IS_OK(status)) {
362 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
372 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
373 struct smbd_server_connection *sconn,
374 char **buffer, unsigned int timeout,
375 size_t *p_unread, size_t *plen)
379 int min_recv_size = lp_min_receive_file_size();
384 status = read_smb_length_return_keepalive(sconn->sock, lenbuf, timeout,
386 if (!NT_STATUS_IS_OK(status)) {
390 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
391 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
392 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
393 !srv_is_signing_active(sconn) &&
394 sconn->smb1.echo_handler.trusted_fde == NULL) {
396 return receive_smb_raw_talloc_partial_read(
397 mem_ctx, lenbuf, sconn, buffer, timeout,
401 if (!valid_packet_size(len)) {
402 return NT_STATUS_INVALID_PARAMETER;
406 * The +4 here can't wrap, we've checked the length above already.
409 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
411 if (*buffer == NULL) {
412 DEBUG(0, ("Could not allocate inbuf of length %d\n",
414 return NT_STATUS_NO_MEMORY;
417 memcpy(*buffer, lenbuf, sizeof(lenbuf));
419 status = read_packet_remainder(sconn->sock, (*buffer)+4, timeout, len);
420 if (!NT_STATUS_IS_OK(status)) {
428 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
429 struct smbd_server_connection *sconn,
430 char **buffer, unsigned int timeout,
431 size_t *p_unread, bool *p_encrypted,
434 bool trusted_channel)
439 *p_encrypted = false;
441 status = receive_smb_raw_talloc(mem_ctx, sconn, buffer, timeout,
443 if (!NT_STATUS_IS_OK(status)) {
444 DEBUG(1, ("read_smb_length_return_keepalive failed for "
445 "client %s read error = %s.\n",
446 sconn->client_id.addr, nt_errstr(status)));
450 if (is_encrypted_packet((uint8_t *)*buffer)) {
451 status = srv_decrypt_buffer(*buffer);
452 if (!NT_STATUS_IS_OK(status)) {
453 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
454 "incoming packet! Error %s\n",
455 nt_errstr(status) ));
461 /* Check the incoming SMB signature. */
462 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
463 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
464 "incoming packet!\n"));
465 return NT_STATUS_INVALID_NETWORK_RESPONSE;
473 * Initialize a struct smb_request from an inbuf
476 static bool init_smb_request(struct smb_request *req,
477 struct smbd_server_connection *sconn,
479 size_t unread_bytes, bool encrypted,
482 size_t req_size = smb_len(inbuf) + 4;
483 /* Ensure we have at least smb_size bytes. */
484 if (req_size < smb_size) {
485 DEBUG(0,("init_smb_request: invalid request size %u\n",
486 (unsigned int)req_size ));
489 req->cmd = CVAL(inbuf, smb_com);
490 req->flags2 = SVAL(inbuf, smb_flg2);
491 req->smbpid = SVAL(inbuf, smb_pid);
492 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
493 req->seqnum = seqnum;
494 req->vuid = SVAL(inbuf, smb_uid);
495 req->tid = SVAL(inbuf, smb_tid);
496 req->wct = CVAL(inbuf, smb_wct);
497 req->vwv = (uint16_t *)(inbuf+smb_vwv);
498 req->buflen = smb_buflen(inbuf);
499 req->buf = (const uint8_t *)smb_buf(inbuf);
500 req->unread_bytes = unread_bytes;
501 req->encrypted = encrypted;
503 req->conn = conn_find(sconn,req->tid);
504 req->chain_fsp = NULL;
505 req->chain_outbuf = NULL;
508 smb_init_perfcount_data(&req->pcd);
510 /* Ensure we have at least wct words and 2 bytes of bcc. */
511 if (smb_size + req->wct*2 > req_size) {
512 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
513 (unsigned int)req->wct,
514 (unsigned int)req_size));
517 /* Ensure bcc is correct. */
518 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
519 DEBUG(0,("init_smb_request: invalid bcc number %u "
520 "(wct = %u, size %u)\n",
521 (unsigned int)req->buflen,
522 (unsigned int)req->wct,
523 (unsigned int)req_size));
531 static void process_smb(struct smbd_server_connection *conn,
532 uint8_t *inbuf, size_t nread, size_t unread_bytes,
533 uint32_t seqnum, bool encrypted,
534 struct smb_perfcount_data *deferred_pcd);
536 static void smbd_deferred_open_timer(struct event_context *ev,
537 struct timed_event *te,
538 struct timeval _tval,
541 struct pending_message_list *msg = talloc_get_type(private_data,
542 struct pending_message_list);
543 TALLOC_CTX *mem_ctx = talloc_tos();
544 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
547 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
550 exit_server("smbd_deferred_open_timer: talloc failed\n");
554 /* We leave this message on the queue so the open code can
555 know this is a retry. */
556 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
557 (unsigned long long)mid ));
559 /* Mark the message as processed so this is not
560 * re-processed in error. */
561 msg->processed = true;
563 process_smb(smbd_server_conn, inbuf,
565 msg->seqnum, msg->encrypted, &msg->pcd);
567 /* If it's still there and was processed, remove it. */
568 msg = get_deferred_open_message_smb(mid);
569 if (msg && msg->processed) {
570 remove_deferred_open_message_smb(mid);
574 /****************************************************************************
575 Function to push a message onto the tail of a linked list of smb messages ready
577 ****************************************************************************/
579 static bool push_queued_message(struct smb_request *req,
580 struct timeval request_time,
581 struct timeval end_time,
582 char *private_data, size_t private_len)
584 int msg_len = smb_len(req->inbuf) + 4;
585 struct pending_message_list *msg;
587 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
590 DEBUG(0,("push_message: malloc fail (1)\n"));
594 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
595 if(msg->buf.data == NULL) {
596 DEBUG(0,("push_message: malloc fail (2)\n"));
601 msg->request_time = request_time;
602 msg->seqnum = req->seqnum;
603 msg->encrypted = req->encrypted;
604 msg->processed = false;
605 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
608 msg->private_data = data_blob_talloc(msg, private_data,
610 if (msg->private_data.data == NULL) {
611 DEBUG(0,("push_message: malloc fail (3)\n"));
617 msg->te = event_add_timed(smbd_event_context(),
620 smbd_deferred_open_timer,
623 DEBUG(0,("push_message: event_add_timed failed\n"));
628 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
630 DEBUG(10,("push_message: pushed message length %u on "
631 "deferred_open_queue\n", (unsigned int)msg_len));
636 /****************************************************************************
637 Function to delete a sharing violation open message by mid.
638 ****************************************************************************/
640 void remove_deferred_open_message_smb(uint64_t mid)
642 struct pending_message_list *pml;
644 if (smbd_server_conn->using_smb2) {
645 remove_deferred_open_message_smb2(smbd_server_conn, mid);
649 for (pml = deferred_open_queue; pml; pml = pml->next) {
650 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
651 DEBUG(10,("remove_deferred_open_message_smb: "
652 "deleting mid %llu len %u\n",
653 (unsigned long long)mid,
654 (unsigned int)pml->buf.length ));
655 DLIST_REMOVE(deferred_open_queue, pml);
662 /****************************************************************************
663 Move a sharing violation open retry message to the front of the list and
664 schedule it for immediate processing.
665 ****************************************************************************/
667 void schedule_deferred_open_message_smb(uint64_t mid)
669 struct pending_message_list *pml;
672 if (smbd_server_conn->using_smb2) {
673 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
677 for (pml = deferred_open_queue; pml; pml = pml->next) {
678 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
680 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
683 (unsigned long long)msg_mid ));
685 if (mid == msg_mid) {
686 struct timed_event *te;
688 if (pml->processed) {
689 /* A processed message should not be
691 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
692 "message mid %llu was already processed\n",
693 (unsigned long long)msg_mid ));
697 DEBUG(10,("schedule_deferred_open_message_smb: "
698 "scheduling mid %llu\n",
699 (unsigned long long)mid ));
701 te = event_add_timed(smbd_event_context(),
704 smbd_deferred_open_timer,
707 DEBUG(10,("schedule_deferred_open_message_smb: "
708 "event_add_timed() failed, "
709 "skipping mid %llu\n",
710 (unsigned long long)msg_mid ));
713 TALLOC_FREE(pml->te);
715 DLIST_PROMOTE(deferred_open_queue, pml);
720 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
721 "find message mid %llu\n",
722 (unsigned long long)mid ));
725 /****************************************************************************
726 Return true if this mid is on the deferred queue and was not yet processed.
727 ****************************************************************************/
729 bool open_was_deferred(uint64_t mid)
731 struct pending_message_list *pml;
733 if (smbd_server_conn->using_smb2) {
734 return open_was_deferred_smb2(smbd_server_conn, mid);
737 for (pml = deferred_open_queue; pml; pml = pml->next) {
738 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
745 /****************************************************************************
746 Return the message queued by this mid.
747 ****************************************************************************/
749 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
751 struct pending_message_list *pml;
753 for (pml = deferred_open_queue; pml; pml = pml->next) {
754 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
761 /****************************************************************************
762 Get the state data queued by this mid.
763 ****************************************************************************/
765 bool get_deferred_open_message_state(struct smb_request *smbreq,
766 struct timeval *p_request_time,
769 struct pending_message_list *pml;
771 if (smbd_server_conn->using_smb2) {
772 return get_deferred_open_message_state_smb2(smbreq->smb2req,
777 pml = get_deferred_open_message_smb(smbreq->mid);
781 if (p_request_time) {
782 *p_request_time = pml->request_time;
785 *pp_state = (void *)pml->private_data.data;
790 /****************************************************************************
791 Function to push a deferred open smb message onto a linked list of local smb
792 messages ready for processing.
793 ****************************************************************************/
795 bool push_deferred_open_message_smb(struct smb_request *req,
796 struct timeval request_time,
797 struct timeval timeout,
799 char *private_data, size_t priv_len)
801 struct timeval end_time;
804 return push_deferred_open_message_smb2(req->smb2req,
812 if (req->unread_bytes) {
813 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
814 "unread_bytes = %u\n",
815 (unsigned int)req->unread_bytes ));
816 smb_panic("push_deferred_open_message_smb: "
817 "logic error unread_bytes != 0" );
820 end_time = timeval_sum(&request_time, &timeout);
822 DEBUG(10,("push_deferred_open_message_smb: pushing message "
823 "len %u mid %llu timeout time [%u.%06u]\n",
824 (unsigned int) smb_len(req->inbuf)+4,
825 (unsigned long long)req->mid,
826 (unsigned int)end_time.tv_sec,
827 (unsigned int)end_time.tv_usec));
829 return push_queued_message(req, request_time, end_time,
830 private_data, priv_len);
834 struct timed_event *te;
835 struct timeval interval;
837 bool (*handler)(const struct timeval *now, void *private_data);
841 static void smbd_idle_event_handler(struct event_context *ctx,
842 struct timed_event *te,
846 struct idle_event *event =
847 talloc_get_type_abort(private_data, struct idle_event);
849 TALLOC_FREE(event->te);
851 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
852 event->name, event->te));
854 if (!event->handler(&now, event->private_data)) {
855 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
856 event->name, event->te));
857 /* Don't repeat, delete ourselves */
862 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
863 event->name, event->te));
865 event->te = event_add_timed(ctx, event,
866 timeval_sum(&now, &event->interval),
867 smbd_idle_event_handler, event);
869 /* We can't do much but fail here. */
870 SMB_ASSERT(event->te != NULL);
873 struct idle_event *event_add_idle(struct event_context *event_ctx,
875 struct timeval interval,
877 bool (*handler)(const struct timeval *now,
881 struct idle_event *result;
882 struct timeval now = timeval_current();
884 result = TALLOC_P(mem_ctx, struct idle_event);
885 if (result == NULL) {
886 DEBUG(0, ("talloc failed\n"));
890 result->interval = interval;
891 result->handler = handler;
892 result->private_data = private_data;
894 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
895 DEBUG(0, ("talloc failed\n"));
900 result->te = event_add_timed(event_ctx, result,
901 timeval_sum(&now, &interval),
902 smbd_idle_event_handler, result);
903 if (result->te == NULL) {
904 DEBUG(0, ("event_add_timed failed\n"));
909 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
913 static void smbd_sig_term_handler(struct tevent_context *ev,
914 struct tevent_signal *se,
920 exit_server_cleanly("termination signal");
923 void smbd_setup_sig_term_handler(void)
925 struct tevent_signal *se;
927 se = tevent_add_signal(smbd_event_context(),
928 smbd_event_context(),
930 smbd_sig_term_handler,
933 exit_server("failed to setup SIGTERM handler");
937 static void smbd_sig_hup_handler(struct tevent_context *ev,
938 struct tevent_signal *se,
944 struct messaging_context *msg_ctx = talloc_get_type_abort(
945 private_data, struct messaging_context);
946 change_to_root_user();
947 DEBUG(1,("Reloading services after SIGHUP\n"));
948 reload_services(msg_ctx, smbd_server_conn->sock, False);
950 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
954 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
955 struct messaging_context *msg_ctx)
957 struct tevent_signal *se;
959 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
962 exit_server("failed to setup SIGHUP handler");
966 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
973 timeout = SMBD_SELECT_TIMEOUT * 1000;
976 * Are there any timed events waiting ? If so, ensure we don't
977 * select for longer than it would take to wait for them.
980 event_add_to_poll_args(smbd_event_context(), conn,
981 &conn->pfds, &num_pfds, &timeout);
983 /* Process a signal and timed events now... */
984 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
985 return NT_STATUS_RETRY;
990 START_PROFILE(smbd_idle);
992 ret = sys_poll(conn->pfds, num_pfds, timeout);
995 END_PROFILE(smbd_idle);
999 if (ret == -1 && errno != EINTR) {
1000 return map_nt_error_from_unix(errno);
1003 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1006 return NT_STATUS_RETRY;
1009 /* Did we timeout ? */
1011 return NT_STATUS_RETRY;
1014 /* should not be reached */
1015 return NT_STATUS_INTERNAL_ERROR;
1019 * Only allow 5 outstanding trans requests. We're allocating memory, so
1023 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1026 for (; list != NULL; list = list->next) {
1028 if (list->mid == mid) {
1029 return NT_STATUS_INVALID_PARAMETER;
1035 return NT_STATUS_INSUFFICIENT_RESOURCES;
1038 return NT_STATUS_OK;
1042 These flags determine some of the permissions required to do an operation
1044 Note that I don't set NEED_WRITE on some write operations because they
1045 are used by some brain-dead clients when printing, and I don't want to
1046 force write permissions on print services.
1048 #define AS_USER (1<<0)
1049 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1050 #define TIME_INIT (1<<2)
1051 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1052 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1053 #define DO_CHDIR (1<<6)
1056 define a list of possible SMB messages and their corresponding
1057 functions. Any message that has a NULL function is unimplemented -
1058 please feel free to contribute implementations!
1060 static const struct smb_message_struct {
1062 void (*fn)(struct smb_request *req);
1064 } smb_messages[256] = {
1066 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1067 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1068 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1069 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1070 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1071 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1072 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1073 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1074 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1075 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1076 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1077 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1078 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1079 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1080 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1081 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1082 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1083 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1084 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1085 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1086 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1087 /* 0x15 */ { NULL, NULL, 0 },
1088 /* 0x16 */ { NULL, NULL, 0 },
1089 /* 0x17 */ { NULL, NULL, 0 },
1090 /* 0x18 */ { NULL, NULL, 0 },
1091 /* 0x19 */ { NULL, NULL, 0 },
1092 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1093 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1094 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1095 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1096 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1097 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1098 /* 0x20 */ { "SMBwritec", NULL,0},
1099 /* 0x21 */ { NULL, NULL, 0 },
1100 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1101 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1102 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1103 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1104 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1105 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1106 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1107 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1108 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1109 /* 0x2b */ { "SMBecho",reply_echo,0},
1110 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1111 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1112 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1113 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1114 /* 0x30 */ { NULL, NULL, 0 },
1115 /* 0x31 */ { NULL, NULL, 0 },
1116 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1117 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1118 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1119 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1120 /* 0x36 */ { NULL, NULL, 0 },
1121 /* 0x37 */ { NULL, NULL, 0 },
1122 /* 0x38 */ { NULL, NULL, 0 },
1123 /* 0x39 */ { NULL, NULL, 0 },
1124 /* 0x3a */ { NULL, NULL, 0 },
1125 /* 0x3b */ { NULL, NULL, 0 },
1126 /* 0x3c */ { NULL, NULL, 0 },
1127 /* 0x3d */ { NULL, NULL, 0 },
1128 /* 0x3e */ { NULL, NULL, 0 },
1129 /* 0x3f */ { NULL, NULL, 0 },
1130 /* 0x40 */ { NULL, NULL, 0 },
1131 /* 0x41 */ { NULL, NULL, 0 },
1132 /* 0x42 */ { NULL, NULL, 0 },
1133 /* 0x43 */ { NULL, NULL, 0 },
1134 /* 0x44 */ { NULL, NULL, 0 },
1135 /* 0x45 */ { NULL, NULL, 0 },
1136 /* 0x46 */ { NULL, NULL, 0 },
1137 /* 0x47 */ { NULL, NULL, 0 },
1138 /* 0x48 */ { NULL, NULL, 0 },
1139 /* 0x49 */ { NULL, NULL, 0 },
1140 /* 0x4a */ { NULL, NULL, 0 },
1141 /* 0x4b */ { NULL, NULL, 0 },
1142 /* 0x4c */ { NULL, NULL, 0 },
1143 /* 0x4d */ { NULL, NULL, 0 },
1144 /* 0x4e */ { NULL, NULL, 0 },
1145 /* 0x4f */ { NULL, NULL, 0 },
1146 /* 0x50 */ { NULL, NULL, 0 },
1147 /* 0x51 */ { NULL, NULL, 0 },
1148 /* 0x52 */ { NULL, NULL, 0 },
1149 /* 0x53 */ { NULL, NULL, 0 },
1150 /* 0x54 */ { NULL, NULL, 0 },
1151 /* 0x55 */ { NULL, NULL, 0 },
1152 /* 0x56 */ { NULL, NULL, 0 },
1153 /* 0x57 */ { NULL, NULL, 0 },
1154 /* 0x58 */ { NULL, NULL, 0 },
1155 /* 0x59 */ { NULL, NULL, 0 },
1156 /* 0x5a */ { NULL, NULL, 0 },
1157 /* 0x5b */ { NULL, NULL, 0 },
1158 /* 0x5c */ { NULL, NULL, 0 },
1159 /* 0x5d */ { NULL, NULL, 0 },
1160 /* 0x5e */ { NULL, NULL, 0 },
1161 /* 0x5f */ { NULL, NULL, 0 },
1162 /* 0x60 */ { NULL, NULL, 0 },
1163 /* 0x61 */ { NULL, NULL, 0 },
1164 /* 0x62 */ { NULL, NULL, 0 },
1165 /* 0x63 */ { NULL, NULL, 0 },
1166 /* 0x64 */ { NULL, NULL, 0 },
1167 /* 0x65 */ { NULL, NULL, 0 },
1168 /* 0x66 */ { NULL, NULL, 0 },
1169 /* 0x67 */ { NULL, NULL, 0 },
1170 /* 0x68 */ { NULL, NULL, 0 },
1171 /* 0x69 */ { NULL, NULL, 0 },
1172 /* 0x6a */ { NULL, NULL, 0 },
1173 /* 0x6b */ { NULL, NULL, 0 },
1174 /* 0x6c */ { NULL, NULL, 0 },
1175 /* 0x6d */ { NULL, NULL, 0 },
1176 /* 0x6e */ { NULL, NULL, 0 },
1177 /* 0x6f */ { NULL, NULL, 0 },
1178 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1179 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1180 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1181 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1182 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1183 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1184 /* 0x76 */ { NULL, NULL, 0 },
1185 /* 0x77 */ { NULL, NULL, 0 },
1186 /* 0x78 */ { NULL, NULL, 0 },
1187 /* 0x79 */ { NULL, NULL, 0 },
1188 /* 0x7a */ { NULL, NULL, 0 },
1189 /* 0x7b */ { NULL, NULL, 0 },
1190 /* 0x7c */ { NULL, NULL, 0 },
1191 /* 0x7d */ { NULL, NULL, 0 },
1192 /* 0x7e */ { NULL, NULL, 0 },
1193 /* 0x7f */ { NULL, NULL, 0 },
1194 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1195 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1196 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1197 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1198 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1199 /* 0x85 */ { NULL, NULL, 0 },
1200 /* 0x86 */ { NULL, NULL, 0 },
1201 /* 0x87 */ { NULL, NULL, 0 },
1202 /* 0x88 */ { NULL, NULL, 0 },
1203 /* 0x89 */ { NULL, NULL, 0 },
1204 /* 0x8a */ { NULL, NULL, 0 },
1205 /* 0x8b */ { NULL, NULL, 0 },
1206 /* 0x8c */ { NULL, NULL, 0 },
1207 /* 0x8d */ { NULL, NULL, 0 },
1208 /* 0x8e */ { NULL, NULL, 0 },
1209 /* 0x8f */ { NULL, NULL, 0 },
1210 /* 0x90 */ { NULL, NULL, 0 },
1211 /* 0x91 */ { NULL, NULL, 0 },
1212 /* 0x92 */ { NULL, NULL, 0 },
1213 /* 0x93 */ { NULL, NULL, 0 },
1214 /* 0x94 */ { NULL, NULL, 0 },
1215 /* 0x95 */ { NULL, NULL, 0 },
1216 /* 0x96 */ { NULL, NULL, 0 },
1217 /* 0x97 */ { NULL, NULL, 0 },
1218 /* 0x98 */ { NULL, NULL, 0 },
1219 /* 0x99 */ { NULL, NULL, 0 },
1220 /* 0x9a */ { NULL, NULL, 0 },
1221 /* 0x9b */ { NULL, NULL, 0 },
1222 /* 0x9c */ { NULL, NULL, 0 },
1223 /* 0x9d */ { NULL, NULL, 0 },
1224 /* 0x9e */ { NULL, NULL, 0 },
1225 /* 0x9f */ { NULL, NULL, 0 },
1226 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1227 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1228 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1229 /* 0xa3 */ { NULL, NULL, 0 },
1230 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1231 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1232 /* 0xa6 */ { NULL, NULL, 0 },
1233 /* 0xa7 */ { NULL, NULL, 0 },
1234 /* 0xa8 */ { NULL, NULL, 0 },
1235 /* 0xa9 */ { NULL, NULL, 0 },
1236 /* 0xaa */ { NULL, NULL, 0 },
1237 /* 0xab */ { NULL, NULL, 0 },
1238 /* 0xac */ { NULL, NULL, 0 },
1239 /* 0xad */ { NULL, NULL, 0 },
1240 /* 0xae */ { NULL, NULL, 0 },
1241 /* 0xaf */ { NULL, NULL, 0 },
1242 /* 0xb0 */ { NULL, NULL, 0 },
1243 /* 0xb1 */ { NULL, NULL, 0 },
1244 /* 0xb2 */ { NULL, NULL, 0 },
1245 /* 0xb3 */ { NULL, NULL, 0 },
1246 /* 0xb4 */ { NULL, NULL, 0 },
1247 /* 0xb5 */ { NULL, NULL, 0 },
1248 /* 0xb6 */ { NULL, NULL, 0 },
1249 /* 0xb7 */ { NULL, NULL, 0 },
1250 /* 0xb8 */ { NULL, NULL, 0 },
1251 /* 0xb9 */ { NULL, NULL, 0 },
1252 /* 0xba */ { NULL, NULL, 0 },
1253 /* 0xbb */ { NULL, NULL, 0 },
1254 /* 0xbc */ { NULL, NULL, 0 },
1255 /* 0xbd */ { NULL, NULL, 0 },
1256 /* 0xbe */ { NULL, NULL, 0 },
1257 /* 0xbf */ { NULL, NULL, 0 },
1258 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1259 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1260 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1261 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1262 /* 0xc4 */ { NULL, NULL, 0 },
1263 /* 0xc5 */ { NULL, NULL, 0 },
1264 /* 0xc6 */ { NULL, NULL, 0 },
1265 /* 0xc7 */ { NULL, NULL, 0 },
1266 /* 0xc8 */ { NULL, NULL, 0 },
1267 /* 0xc9 */ { NULL, NULL, 0 },
1268 /* 0xca */ { NULL, NULL, 0 },
1269 /* 0xcb */ { NULL, NULL, 0 },
1270 /* 0xcc */ { NULL, NULL, 0 },
1271 /* 0xcd */ { NULL, NULL, 0 },
1272 /* 0xce */ { NULL, NULL, 0 },
1273 /* 0xcf */ { NULL, NULL, 0 },
1274 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1275 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1276 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1277 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1278 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1279 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1280 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1281 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1282 /* 0xd8 */ { NULL, NULL, 0 },
1283 /* 0xd9 */ { NULL, NULL, 0 },
1284 /* 0xda */ { NULL, NULL, 0 },
1285 /* 0xdb */ { NULL, NULL, 0 },
1286 /* 0xdc */ { NULL, NULL, 0 },
1287 /* 0xdd */ { NULL, NULL, 0 },
1288 /* 0xde */ { NULL, NULL, 0 },
1289 /* 0xdf */ { NULL, NULL, 0 },
1290 /* 0xe0 */ { NULL, NULL, 0 },
1291 /* 0xe1 */ { NULL, NULL, 0 },
1292 /* 0xe2 */ { NULL, NULL, 0 },
1293 /* 0xe3 */ { NULL, NULL, 0 },
1294 /* 0xe4 */ { NULL, NULL, 0 },
1295 /* 0xe5 */ { NULL, NULL, 0 },
1296 /* 0xe6 */ { NULL, NULL, 0 },
1297 /* 0xe7 */ { NULL, NULL, 0 },
1298 /* 0xe8 */ { NULL, NULL, 0 },
1299 /* 0xe9 */ { NULL, NULL, 0 },
1300 /* 0xea */ { NULL, NULL, 0 },
1301 /* 0xeb */ { NULL, NULL, 0 },
1302 /* 0xec */ { NULL, NULL, 0 },
1303 /* 0xed */ { NULL, NULL, 0 },
1304 /* 0xee */ { NULL, NULL, 0 },
1305 /* 0xef */ { NULL, NULL, 0 },
1306 /* 0xf0 */ { NULL, NULL, 0 },
1307 /* 0xf1 */ { NULL, NULL, 0 },
1308 /* 0xf2 */ { NULL, NULL, 0 },
1309 /* 0xf3 */ { NULL, NULL, 0 },
1310 /* 0xf4 */ { NULL, NULL, 0 },
1311 /* 0xf5 */ { NULL, NULL, 0 },
1312 /* 0xf6 */ { NULL, NULL, 0 },
1313 /* 0xf7 */ { NULL, NULL, 0 },
1314 /* 0xf8 */ { NULL, NULL, 0 },
1315 /* 0xf9 */ { NULL, NULL, 0 },
1316 /* 0xfa */ { NULL, NULL, 0 },
1317 /* 0xfb */ { NULL, NULL, 0 },
1318 /* 0xfc */ { NULL, NULL, 0 },
1319 /* 0xfd */ { NULL, NULL, 0 },
1320 /* 0xfe */ { NULL, NULL, 0 },
1321 /* 0xff */ { NULL, NULL, 0 }
1325 /*******************************************************************
1326 allocate and initialize a reply packet
1327 ********************************************************************/
1329 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1330 const char *inbuf, char **outbuf, uint8_t num_words,
1334 * Protect against integer wrap
1336 if ((num_bytes > 0xffffff)
1337 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1339 if (asprintf(&msg, "num_bytes too large: %u",
1340 (unsigned)num_bytes) == -1) {
1341 msg = CONST_DISCARD(char *, "num_bytes too large");
1346 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1347 smb_size + num_words*2 + num_bytes);
1348 if (*outbuf == NULL) {
1352 construct_reply_common(req, inbuf, *outbuf);
1353 srv_set_message(*outbuf, num_words, num_bytes, false);
1355 * Zero out the word area, the caller has to take care of the bcc area
1358 if (num_words != 0) {
1359 memset(*outbuf + smb_vwv0, 0, num_words*2);
1365 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1368 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1370 smb_panic("could not allocate output buffer\n");
1372 req->outbuf = (uint8_t *)outbuf;
1376 /*******************************************************************
1377 Dump a packet to a file.
1378 ********************************************************************/
1380 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1384 if (DEBUGLEVEL < 50) {
1388 if (len < 4) len = smb_len(data)+4;
1389 for (i=1;i<100;i++) {
1390 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1391 type ? "req" : "resp") == -1) {
1394 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1395 if (fd != -1 || errno != EEXIST) break;
1398 ssize_t ret = write(fd, data, len);
1400 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1402 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1407 /****************************************************************************
1408 Prepare everything for calling the actual request function, and potentially
1409 call the request function via the "new" interface.
1411 Return False if the "legacy" function needs to be called, everything is
1414 Return True if we're done.
1416 I know this API sucks, but it is the one with the least code change I could
1418 ****************************************************************************/
1420 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1424 connection_struct *conn = NULL;
1425 struct smbd_server_connection *sconn = req->sconn;
1429 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1430 * so subtract 4 from it. */
1431 if (!valid_smb_header(req->inbuf)
1432 || (size < (smb_size - 4))) {
1433 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1434 smb_len(req->inbuf)));
1435 exit_server_cleanly("Non-SMB packet");
1438 if (smb_messages[type].fn == NULL) {
1439 DEBUG(0,("Unknown message type %d!\n",type));
1440 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1441 reply_unknown_new(req, type);
1445 flags = smb_messages[type].flags;
1447 /* In share mode security we must ignore the vuid. */
1448 session_tag = (lp_security() == SEC_SHARE)
1449 ? UID_FIELD_INVALID : req->vuid;
1452 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1453 (int)sys_getpid(), (unsigned long)conn));
1455 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1457 /* Ensure this value is replaced in the incoming packet. */
1458 SSVAL(req->inbuf,smb_uid,session_tag);
1461 * Ensure the correct username is in current_user_info. This is a
1462 * really ugly bugfix for problems with multiple session_setup_and_X's
1463 * being done and allowing %U and %G substitutions to work correctly.
1464 * There is a reason this code is done here, don't move it unless you
1465 * know what you're doing... :-).
1469 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1470 user_struct *vuser = NULL;
1472 sconn->smb1.sessions.last_session_tag = session_tag;
1473 if(session_tag != UID_FIELD_INVALID) {
1474 vuser = get_valid_user_struct(sconn, session_tag);
1476 set_current_user_info(
1477 vuser->session_info->sanitized_username,
1478 vuser->session_info->unix_name,
1479 vuser->session_info->info3->base.domain.string);
1484 /* Does this call need to be run as the connected user? */
1485 if (flags & AS_USER) {
1487 /* Does this call need a valid tree connection? */
1490 * Amazingly, the error code depends on the command
1493 if (type == SMBntcreateX) {
1494 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1496 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1501 if (!change_to_user(conn,session_tag)) {
1502 DEBUG(0, ("Error: Could not change to user. Removing "
1503 "deferred open, mid=%llu.\n",
1504 (unsigned long long)req->mid));
1505 reply_force_doserror(req, ERRSRV, ERRbaduid);
1509 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1511 /* Does it need write permission? */
1512 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1513 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1517 /* IPC services are limited */
1518 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1519 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1523 /* This call needs to be run as root */
1524 change_to_root_user();
1527 /* load service specific parameters */
1529 if (req->encrypted) {
1530 conn->encrypted_tid = true;
1531 /* encrypted required from now on. */
1532 conn->encrypt_level = Required;
1533 } else if (ENCRYPTION_REQUIRED(conn)) {
1534 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1535 exit_server_cleanly("encryption required "
1541 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1542 (flags & (AS_USER|DO_CHDIR)
1544 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1547 conn->num_smb_operations++;
1550 /* does this protocol need to be run as guest? */
1551 if ((flags & AS_GUEST)
1552 && (!change_to_guest() ||
1553 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1554 sconn->client_id.name,
1555 sconn->client_id.addr))) {
1556 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1560 smb_messages[type].fn(req);
1564 /****************************************************************************
1565 Construct a reply to the incoming packet.
1566 ****************************************************************************/
1568 static void construct_reply(struct smbd_server_connection *sconn,
1569 char *inbuf, int size, size_t unread_bytes,
1570 uint32_t seqnum, bool encrypted,
1571 struct smb_perfcount_data *deferred_pcd)
1573 connection_struct *conn;
1574 struct smb_request *req;
1576 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1577 smb_panic("could not allocate smb_request");
1580 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1581 encrypted, seqnum)) {
1582 exit_server_cleanly("Invalid SMB request");
1585 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1587 /* we popped this message off the queue - keep original perf data */
1589 req->pcd = *deferred_pcd;
1591 SMB_PERFCOUNT_START(&req->pcd);
1592 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1593 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1596 conn = switch_message(req->cmd, req, size);
1598 if (req->unread_bytes) {
1599 /* writeX failed. drain socket. */
1600 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1601 req->unread_bytes) {
1602 smb_panic("failed to drain pending bytes");
1604 req->unread_bytes = 0;
1612 if (req->outbuf == NULL) {
1616 if (CVAL(req->outbuf,0) == 0) {
1617 show_msg((char *)req->outbuf);
1620 if (!srv_send_smb(req->sconn,
1621 (char *)req->outbuf,
1622 true, req->seqnum+1,
1623 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1625 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1633 /****************************************************************************
1634 Process an smb from the client
1635 ****************************************************************************/
1636 static void process_smb(struct smbd_server_connection *sconn,
1637 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1638 uint32_t seqnum, bool encrypted,
1639 struct smb_perfcount_data *deferred_pcd)
1641 int msg_type = CVAL(inbuf,0);
1643 DO_PROFILE_INC(smb_count);
1645 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1647 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1648 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1650 if (msg_type != 0) {
1652 * NetBIOS session request, keepalive, etc.
1654 reply_special(sconn, (char *)inbuf, nread);
1658 if (sconn->using_smb2) {
1659 /* At this point we're not really using smb2,
1660 * we make the decision here.. */
1661 if (smbd_is_smb2_header(inbuf, nread)) {
1662 smbd_smb2_first_negprot(sconn, inbuf, nread);
1664 } else if (nread >= smb_size && valid_smb_header(inbuf)
1665 && CVAL(inbuf, smb_com) != 0x72) {
1666 /* This is a non-negprot SMB1 packet.
1667 Disable SMB2 from now on. */
1668 sconn->using_smb2 = false;
1672 show_msg((char *)inbuf);
1674 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1675 encrypted, deferred_pcd);
1679 sconn->smb1.num_requests++;
1681 /* The timeout_processing function isn't run nearly
1682 often enough to implement 'max log size' without
1683 overrunning the size of the file by many megabytes.
1684 This is especially true if we are running at debug
1685 level 10. Checking every 50 SMBs is a nice
1686 tradeoff of performance vs log file size overrun. */
1688 if ((sconn->smb1.num_requests % 50) == 0 &&
1689 need_to_check_log_size()) {
1690 change_to_root_user();
1695 /****************************************************************************
1696 Return a string containing the function name of a SMB command.
1697 ****************************************************************************/
1699 const char *smb_fn_name(int type)
1701 const char *unknown_name = "SMBunknown";
1703 if (smb_messages[type].name == NULL)
1704 return(unknown_name);
1706 return(smb_messages[type].name);
1709 /****************************************************************************
1710 Helper functions for contruct_reply.
1711 ****************************************************************************/
1713 void add_to_common_flags2(uint32 v)
1718 void remove_from_common_flags2(uint32 v)
1720 common_flags2 &= ~v;
1723 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1726 srv_set_message(outbuf,0,0,false);
1728 SCVAL(outbuf, smb_com, req->cmd);
1729 SIVAL(outbuf,smb_rcls,0);
1730 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1731 SSVAL(outbuf,smb_flg2,
1732 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1734 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1736 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1737 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1738 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1739 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1742 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1744 construct_reply_common(req, (char *)req->inbuf, outbuf);
1748 * How many bytes have we already accumulated up to the current wct field
1752 size_t req_wct_ofs(struct smb_request *req)
1756 if (req->chain_outbuf == NULL) {
1759 buf_size = talloc_get_size(req->chain_outbuf);
1760 if ((buf_size % 4) != 0) {
1761 buf_size += (4 - (buf_size % 4));
1763 return buf_size - 4;
1767 * Hack around reply_nterror & friends not being aware of chained requests,
1768 * generating illegal (i.e. wct==0) chain replies.
1771 static void fixup_chain_error_packet(struct smb_request *req)
1773 uint8_t *outbuf = req->outbuf;
1775 reply_outbuf(req, 2, 0);
1776 memcpy(req->outbuf, outbuf, smb_wct);
1777 TALLOC_FREE(outbuf);
1778 SCVAL(req->outbuf, smb_vwv0, 0xff);
1782 * @brief Find the smb_cmd offset of the last command pushed
1783 * @param[in] buf The buffer we're building up
1784 * @retval Where can we put our next andx cmd?
1786 * While chaining requests, the "next" request we're looking at needs to put
1787 * its SMB_Command before the data the previous request already built up added
1788 * to the chain. Find the offset to the place where we have to put our cmd.
1791 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1796 cmd = CVAL(buf, smb_com);
1798 SMB_ASSERT(is_andx_req(cmd));
1802 while (CVAL(buf, ofs) != 0xff) {
1804 if (!is_andx_req(CVAL(buf, ofs))) {
1809 * ofs is from start of smb header, so add the 4 length
1810 * bytes. The next cmd is right after the wct field.
1812 ofs = SVAL(buf, ofs+2) + 4 + 1;
1814 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1822 * @brief Do the smb chaining at a buffer level
1823 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1824 * @param[in] smb_command The command that we want to issue
1825 * @param[in] wct How many words?
1826 * @param[in] vwv The words, already in network order
1827 * @param[in] bytes_alignment How shall we align "bytes"?
1828 * @param[in] num_bytes How many bytes?
1829 * @param[in] bytes The data the request ships
1831 * smb_splice_chain() adds the vwv and bytes to the request already present in
1835 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1836 uint8_t wct, const uint16_t *vwv,
1837 size_t bytes_alignment,
1838 uint32_t num_bytes, const uint8_t *bytes)
1841 size_t old_size, new_size;
1843 size_t chain_padding = 0;
1844 size_t bytes_padding = 0;
1847 old_size = talloc_get_size(*poutbuf);
1850 * old_size == smb_wct means we're pushing the first request in for
1854 first_request = (old_size == smb_wct);
1856 if (!first_request && ((old_size % 4) != 0)) {
1858 * Align the wct field of subsequent requests to a 4-byte
1861 chain_padding = 4 - (old_size % 4);
1865 * After the old request comes the new wct field (1 byte), the vwv's
1866 * and the num_bytes field. After at we might need to align the bytes
1867 * given to us to "bytes_alignment", increasing the num_bytes value.
1870 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1872 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1873 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1876 new_size += bytes_padding + num_bytes;
1878 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1879 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1880 (unsigned)new_size));
1884 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1885 if (outbuf == NULL) {
1886 DEBUG(0, ("talloc failed\n"));
1891 if (first_request) {
1892 SCVAL(outbuf, smb_com, smb_command);
1894 size_t andx_cmd_ofs;
1896 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1897 DEBUG(1, ("invalid command chain\n"));
1898 *poutbuf = TALLOC_REALLOC_ARRAY(
1899 NULL, *poutbuf, uint8_t, old_size);
1903 if (chain_padding != 0) {
1904 memset(outbuf + old_size, 0, chain_padding);
1905 old_size += chain_padding;
1908 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1909 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1915 * Push the chained request:
1920 SCVAL(outbuf, ofs, wct);
1927 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1928 ofs += sizeof(uint16_t) * wct;
1934 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1935 ofs += sizeof(uint16_t);
1941 if (bytes_padding != 0) {
1942 memset(outbuf + ofs, 0, bytes_padding);
1943 ofs += bytes_padding;
1950 memcpy(outbuf + ofs, bytes, num_bytes);
1955 /****************************************************************************
1956 Construct a chained reply and add it to the already made reply
1957 ****************************************************************************/
1959 void chain_reply(struct smb_request *req)
1961 size_t smblen = smb_len(req->inbuf);
1962 size_t already_used, length_needed;
1964 uint32_t chain_offset; /* uint32_t to avoid overflow */
1971 if (IVAL(req->outbuf, smb_rcls) != 0) {
1972 fixup_chain_error_packet(req);
1976 * Any of the AndX requests and replies have at least a wct of
1977 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1978 * beginning of the SMB header to the next wct field.
1980 * None of the AndX requests put anything valuable in vwv[0] and [1],
1981 * so we can overwrite it here to form the chain.
1984 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1985 if (req->chain_outbuf == NULL) {
1986 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1987 req, req->outbuf, uint8_t,
1988 smb_len(req->outbuf) + 4);
1989 if (req->chain_outbuf == NULL) {
1990 smb_panic("talloc failed");
1998 * Here we assume that this is the end of the chain. For that we need
1999 * to set "next command" to 0xff and the offset to 0. If we later find
2000 * more commands in the chain, this will be overwritten again.
2003 SCVAL(req->outbuf, smb_vwv0, 0xff);
2004 SCVAL(req->outbuf, smb_vwv0+1, 0);
2005 SSVAL(req->outbuf, smb_vwv1, 0);
2007 if (req->chain_outbuf == NULL) {
2009 * In req->chain_outbuf we collect all the replies. Start the
2010 * chain by copying in the first reply.
2012 * We do the realloc because later on we depend on
2013 * talloc_get_size to determine the length of
2014 * chain_outbuf. The reply_xxx routines might have
2015 * over-allocated (reply_pipe_read_and_X used to be such an
2018 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2019 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2020 if (req->chain_outbuf == NULL) {
2021 smb_panic("talloc failed");
2026 * Update smb headers where subsequent chained commands
2027 * may have updated them.
2029 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2030 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2032 if (!smb_splice_chain(&req->chain_outbuf,
2033 CVAL(req->outbuf, smb_com),
2034 CVAL(req->outbuf, smb_wct),
2035 (uint16_t *)(req->outbuf + smb_vwv),
2036 0, smb_buflen(req->outbuf),
2037 (uint8_t *)smb_buf(req->outbuf))) {
2040 TALLOC_FREE(req->outbuf);
2044 * We use the old request's vwv field to grab the next chained command
2045 * and offset into the chained fields.
2048 chain_cmd = CVAL(req->vwv+0, 0);
2049 chain_offset = SVAL(req->vwv+1, 0);
2051 if (chain_cmd == 0xff) {
2053 * End of chain, no more requests from the client. So ship the
2056 smb_setlen((char *)(req->chain_outbuf),
2057 talloc_get_size(req->chain_outbuf) - 4);
2059 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2060 true, req->seqnum+1,
2061 IS_CONN_ENCRYPTED(req->conn)
2064 exit_server_cleanly("chain_reply: srv_send_smb "
2067 TALLOC_FREE(req->chain_outbuf);
2072 /* add a new perfcounter for this element of chain */
2073 SMB_PERFCOUNT_ADD(&req->pcd);
2074 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2075 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2078 * Check if the client tries to fool us. The request so far uses the
2079 * space to the end of the byte buffer in the request just
2080 * processed. The chain_offset can't point into that area. If that was
2081 * the case, we could end up with an endless processing of the chain,
2082 * we would always handle the same request.
2085 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2086 if (chain_offset < already_used) {
2091 * Next check: Make sure the chain offset does not point beyond the
2092 * overall smb request length.
2095 length_needed = chain_offset+1; /* wct */
2096 if (length_needed > smblen) {
2101 * Now comes the pointer magic. Goal here is to set up req->vwv and
2102 * req->buf correctly again to be able to call the subsequent
2103 * switch_message(). The chain offset (the former vwv[1]) points at
2104 * the new wct field.
2107 wct = CVAL(smb_base(req->inbuf), chain_offset);
2110 * Next consistency check: Make the new vwv array fits in the overall
2114 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2115 if (length_needed > smblen) {
2118 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2121 * Now grab the new byte buffer....
2124 buflen = SVAL(vwv+wct, 0);
2127 * .. and check that it fits.
2130 length_needed += buflen;
2131 if (length_needed > smblen) {
2134 buf = (uint8_t *)(vwv+wct+1);
2136 req->cmd = chain_cmd;
2139 req->buflen = buflen;
2142 switch_message(chain_cmd, req, smblen);
2144 if (req->outbuf == NULL) {
2146 * This happens if the chained command has suspended itself or
2147 * if it has called srv_send_smb() itself.
2153 * We end up here if the chained command was not itself chained or
2154 * suspended, but for example a close() command. We now need to splice
2155 * the chained commands' outbuf into the already built up chain_outbuf
2156 * and ship the result.
2162 * We end up here if there's any error in the chain syntax. Report a
2163 * DOS error, just like Windows does.
2165 reply_force_doserror(req, ERRSRV, ERRerror);
2166 fixup_chain_error_packet(req);
2170 * This scary statement intends to set the
2171 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2172 * to the value req->outbuf carries
2174 SSVAL(req->chain_outbuf, smb_flg2,
2175 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2176 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2179 * Transfer the error codes from the subrequest to the main one
2181 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2182 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2184 if (!smb_splice_chain(&req->chain_outbuf,
2185 CVAL(req->outbuf, smb_com),
2186 CVAL(req->outbuf, smb_wct),
2187 (uint16_t *)(req->outbuf + smb_vwv),
2188 0, smb_buflen(req->outbuf),
2189 (uint8_t *)smb_buf(req->outbuf))) {
2190 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2192 TALLOC_FREE(req->outbuf);
2194 smb_setlen((char *)(req->chain_outbuf),
2195 talloc_get_size(req->chain_outbuf) - 4);
2197 show_msg((char *)(req->chain_outbuf));
2199 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2200 true, req->seqnum+1,
2201 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2203 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2205 TALLOC_FREE(req->chain_outbuf);
2209 /****************************************************************************
2210 Check if services need reloading.
2211 ****************************************************************************/
2213 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2216 if (last_smb_conf_reload_time == 0) {
2217 last_smb_conf_reload_time = t;
2220 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2221 reload_services(sconn->msg_ctx, sconn->sock, True);
2222 last_smb_conf_reload_time = t;
2226 static bool fd_is_readable(int fd)
2230 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2232 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2236 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2238 /* TODO: make write nonblocking */
2241 static void smbd_server_connection_read_handler(
2242 struct smbd_server_connection *conn, int fd)
2244 uint8_t *inbuf = NULL;
2245 size_t inbuf_len = 0;
2246 size_t unread_bytes = 0;
2247 bool encrypted = false;
2248 TALLOC_CTX *mem_ctx = talloc_tos();
2252 bool from_client = (conn->sock == fd);
2255 smbd_lock_socket(conn);
2257 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2258 DEBUG(10,("the echo listener was faster\n"));
2259 smbd_unlock_socket(conn);
2263 /* TODO: make this completely nonblocking */
2264 status = receive_smb_talloc(mem_ctx, conn,
2265 (char **)(void *)&inbuf,
2269 &inbuf_len, &seqnum,
2270 false /* trusted channel */);
2271 smbd_unlock_socket(conn);
2273 /* TODO: make this completely nonblocking */
2274 status = receive_smb_talloc(mem_ctx, conn,
2275 (char **)(void *)&inbuf,
2279 &inbuf_len, &seqnum,
2280 true /* trusted channel */);
2283 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2286 if (NT_STATUS_IS_ERR(status)) {
2287 exit_server_cleanly("failed to receive smb request");
2289 if (!NT_STATUS_IS_OK(status)) {
2294 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2295 seqnum, encrypted, NULL);
2298 static void smbd_server_connection_handler(struct event_context *ev,
2299 struct fd_event *fde,
2303 struct smbd_server_connection *conn = talloc_get_type(private_data,
2304 struct smbd_server_connection);
2306 if (flags & EVENT_FD_WRITE) {
2307 smbd_server_connection_write_handler(conn);
2310 if (flags & EVENT_FD_READ) {
2311 smbd_server_connection_read_handler(conn, conn->sock);
2316 static void smbd_server_echo_handler(struct event_context *ev,
2317 struct fd_event *fde,
2321 struct smbd_server_connection *conn = talloc_get_type(private_data,
2322 struct smbd_server_connection);
2324 if (flags & EVENT_FD_WRITE) {
2325 smbd_server_connection_write_handler(conn);
2328 if (flags & EVENT_FD_READ) {
2329 smbd_server_connection_read_handler(
2330 conn, conn->smb1.echo_handler.trusted_fd);
2335 /****************************************************************************
2336 received when we should release a specific IP
2337 ****************************************************************************/
2338 static void release_ip(const char *ip, void *priv)
2340 const char *addr = (const char *)priv;
2341 const char *p = addr;
2343 if (strncmp("::ffff:", addr, 7) == 0) {
2347 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2348 /* we can't afford to do a clean exit - that involves
2349 database writes, which would potentially mean we
2350 are still running after the failover has finished -
2351 we have to get rid of this process ID straight
2353 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2355 /* note we must exit with non-zero status so the unclean handler gets
2356 called in the parent, so that the brl database is tickled */
2361 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2362 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2364 struct smbd_server_connection *sconn = talloc_get_type_abort(
2365 private_data, struct smbd_server_connection);
2367 release_ip((char *)data->data, sconn->client_id.addr);
2370 #ifdef CLUSTER_SUPPORT
2371 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2372 struct sockaddr_storage *client)
2375 length = sizeof(*server);
2376 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2379 length = sizeof(*client);
2380 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2388 * Send keepalive packets to our client
2390 static bool keepalive_fn(const struct timeval *now, void *private_data)
2392 struct smbd_server_connection *sconn = smbd_server_conn;
2395 if (sconn->using_smb2) {
2396 /* Don't do keepalives on an SMB2 connection. */
2400 smbd_lock_socket(smbd_server_conn);
2401 ret = send_keepalive(sconn->sock);
2402 smbd_unlock_socket(smbd_server_conn);
2405 char addr[INET6_ADDRSTRLEN];
2407 * Try and give an error message saying what
2410 DEBUG(0, ("send_keepalive failed for client %s. "
2411 "Error %s - exiting\n",
2412 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2420 * Do the recurring check if we're idle
2422 static bool deadtime_fn(const struct timeval *now, void *private_data)
2424 struct smbd_server_connection *sconn =
2425 (struct smbd_server_connection *)private_data;
2427 if ((conn_num_open(sconn) == 0)
2428 || (conn_idle_all(sconn, now->tv_sec))) {
2429 DEBUG( 2, ( "Closing idle connection\n" ) );
2430 messaging_send(sconn->msg_ctx,
2431 messaging_server_id(sconn->msg_ctx),
2432 MSG_SHUTDOWN, &data_blob_null);
2440 * Do the recurring log file and smb.conf reload checks.
2443 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2445 struct smbd_server_connection *sconn = talloc_get_type_abort(
2446 private_data, struct smbd_server_connection);
2448 DEBUG(5, ("housekeeping\n"));
2450 change_to_root_user();
2452 /* update printer queue caches if necessary */
2453 update_monitored_printq_cache(sconn->msg_ctx);
2455 /* check if we need to reload services */
2456 check_reload(sconn, time_mono(NULL));
2458 /* Change machine password if neccessary. */
2459 attempt_machine_password_change();
2462 * Force a log file check.
2464 force_check_log_size();
2469 static int create_unlink_tmp(const char *dir)
2474 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2475 if (fname == NULL) {
2479 fd = mkstemp(fname);
2484 if (unlink(fname) == -1) {
2485 int sys_errno = errno;
2495 struct smbd_echo_state {
2496 struct tevent_context *ev;
2497 struct iovec *pending;
2498 struct smbd_server_connection *sconn;
2501 struct tevent_fd *parent_fde;
2503 struct tevent_fd *read_fde;
2504 struct tevent_req *write_req;
2507 static void smbd_echo_writer_done(struct tevent_req *req);
2509 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2513 if (state->write_req != NULL) {
2517 num_pending = talloc_array_length(state->pending);
2518 if (num_pending == 0) {
2522 state->write_req = writev_send(state, state->ev, NULL,
2523 state->parent_pipe, false,
2524 state->pending, num_pending);
2525 if (state->write_req == NULL) {
2526 DEBUG(1, ("writev_send failed\n"));
2530 talloc_steal(state->write_req, state->pending);
2531 state->pending = NULL;
2533 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2537 static void smbd_echo_writer_done(struct tevent_req *req)
2539 struct smbd_echo_state *state = tevent_req_callback_data(
2540 req, struct smbd_echo_state);
2544 written = writev_recv(req, &err);
2546 state->write_req = NULL;
2547 if (written == -1) {
2548 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2551 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2552 smbd_echo_activate_writer(state);
2555 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2558 struct smb_request req;
2559 uint16_t num_replies;
2564 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2565 DEBUG(10, ("Got netbios keepalive\n"));
2572 if (inbuf_len < smb_size) {
2573 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2576 if (!valid_smb_header(inbuf)) {
2577 DEBUG(10, ("Got invalid SMB header\n"));
2581 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2587 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2588 smb_messages[req.cmd].name
2589 ? smb_messages[req.cmd].name : "unknown"));
2591 if (req.cmd != SMBecho) {
2598 num_replies = SVAL(req.vwv+0, 0);
2599 if (num_replies != 1) {
2600 /* Not a Windows "Hey, you're still there?" request */
2604 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2606 DEBUG(10, ("create_outbuf failed\n"));
2609 req.outbuf = (uint8_t *)outbuf;
2611 SSVAL(req.outbuf, smb_vwv0, num_replies);
2613 if (req.buflen > 0) {
2614 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2617 out_len = smb_len(req.outbuf) + 4;
2619 ok = srv_send_smb(req.sconn,
2623 TALLOC_FREE(outbuf);
2631 static void smbd_echo_exit(struct tevent_context *ev,
2632 struct tevent_fd *fde, uint16_t flags,
2635 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2639 static void smbd_echo_reader(struct tevent_context *ev,
2640 struct tevent_fd *fde, uint16_t flags,
2643 struct smbd_echo_state *state = talloc_get_type_abort(
2644 private_data, struct smbd_echo_state);
2645 struct smbd_server_connection *sconn = state->sconn;
2646 size_t unread, num_pending;
2650 uint32_t seqnum = 0;
2653 bool encrypted = false;
2657 ok = smbd_lock_socket_internal(sconn);
2659 DEBUG(0, ("%s: failed to lock socket\n",
2664 if (!fd_is_readable(sconn->sock)) {
2665 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2666 (int)sys_getpid()));
2667 ok = smbd_unlock_socket_internal(sconn);
2669 DEBUG(1, ("%s: failed to unlock socket in\n",
2676 num_pending = talloc_array_length(state->pending);
2677 tmp = talloc_realloc(state, state->pending, struct iovec,
2680 DEBUG(1, ("talloc_realloc failed\n"));
2683 state->pending = tmp;
2685 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2687 status = receive_smb_talloc(state->pending, sconn,
2688 (char **)(void *)&state->pending[num_pending].iov_base,
2694 false /* trusted_channel*/);
2695 if (!NT_STATUS_IS_OK(status)) {
2696 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2697 (int)sys_getpid(), nt_errstr(status)));
2700 state->pending[num_pending].iov_len = iov_len;
2702 ok = smbd_unlock_socket_internal(sconn);
2704 DEBUG(1, ("%s: failed to unlock socket in\n",
2709 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2710 state->pending[num_pending].iov_len,
2713 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2714 /* no check, shrinking by some bytes does not fail */
2715 state->pending = talloc_realloc(state, state->pending,
2721 if (state->pending[num_pending].iov_len >= smb_size) {
2723 * place the seqnum in the packet so that the main process
2724 * can reply with signing
2726 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2727 smb_ss_field, seqnum);
2728 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2729 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2732 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2733 smbd_echo_activate_writer(state);
2736 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2739 struct smbd_echo_state *state;
2741 state = talloc_zero(sconn, struct smbd_echo_state);
2742 if (state == NULL) {
2743 DEBUG(1, ("talloc failed\n"));
2746 state->sconn = sconn;
2747 state->parent_pipe = parent_pipe;
2748 state->ev = s3_tevent_context_init(state);
2749 if (state->ev == NULL) {
2750 DEBUG(1, ("tevent_context_init failed\n"));
2754 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2755 TEVENT_FD_READ, smbd_echo_exit,
2757 if (state->parent_fde == NULL) {
2758 DEBUG(1, ("tevent_add_fd failed\n"));
2762 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2763 TEVENT_FD_READ, smbd_echo_reader,
2765 if (state->read_fde == NULL) {
2766 DEBUG(1, ("tevent_add_fd failed\n"));
2772 if (tevent_loop_once(state->ev) == -1) {
2773 DEBUG(1, ("tevent_loop_once failed: %s\n",
2782 * Handle SMBecho requests in a forked child process
2784 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2786 int listener_pipe[2];
2790 res = pipe(listener_pipe);
2792 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2795 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2796 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2797 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2805 close(listener_pipe[0]);
2806 set_blocking(listener_pipe[1], false);
2808 status = reinit_after_fork(sconn->msg_ctx,
2809 smbd_event_context(),
2810 procid_self(), false);
2811 if (!NT_STATUS_IS_OK(status)) {
2812 DEBUG(1, ("reinit_after_fork failed: %s\n",
2813 nt_errstr(status)));
2816 smbd_echo_loop(sconn, listener_pipe[1]);
2819 close(listener_pipe[1]);
2820 listener_pipe[1] = -1;
2821 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2823 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2826 * Without smb signing this is the same as the normal smbd
2827 * listener. This needs to change once signing comes in.
2829 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2831 sconn->smb1.echo_handler.trusted_fd,
2833 smbd_server_echo_handler,
2835 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2836 DEBUG(1, ("event_add_fd failed\n"));
2843 if (listener_pipe[0] != -1) {
2844 close(listener_pipe[0]);
2846 if (listener_pipe[1] != -1) {
2847 close(listener_pipe[1]);
2849 sconn->smb1.echo_handler.trusted_fd = -1;
2850 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2851 close(sconn->smb1.echo_handler.socket_lock_fd);
2853 sconn->smb1.echo_handler.trusted_fd = -1;
2854 sconn->smb1.echo_handler.socket_lock_fd = -1;
2860 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2861 struct sockaddr_storage *srv,
2862 struct sockaddr_storage *clnt)
2864 struct ctdbd_connection *cconn;
2865 char tmp_addr[INET6_ADDRSTRLEN];
2868 cconn = messaging_ctdbd_connection();
2869 if (cconn == NULL) {
2870 return NT_STATUS_NO_MEMORY;
2873 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2874 addr = talloc_strdup(cconn, tmp_addr);
2876 return NT_STATUS_NO_MEMORY;
2878 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2883 /****************************************************************************
2884 Process commands from the client
2885 ****************************************************************************/
2887 void smbd_process(struct smbd_server_connection *sconn)
2889 TALLOC_CTX *frame = talloc_stackframe();
2890 struct sockaddr_storage ss;
2891 struct sockaddr *sa = NULL;
2892 socklen_t sa_socklen;
2893 struct tsocket_address *local_address = NULL;
2894 struct tsocket_address *remote_address = NULL;
2895 const char *remaddr = NULL;
2898 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2899 !lp_async_smb_echo_handler()) {
2901 * We're not making the desion here,
2902 * we're just allowing the client
2903 * to decide between SMB1 and SMB2
2904 * with the first negprot
2907 sconn->using_smb2 = true;
2910 /* Ensure child is set to blocking mode */
2911 set_blocking(sconn->sock,True);
2913 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2914 set_socket_options(sconn->sock, lp_socket_options());
2916 sa = (struct sockaddr *)(void *)&ss;
2917 sa_socklen = sizeof(ss);
2918 ret = getpeername(sconn->sock, sa, &sa_socklen);
2920 int level = (errno == ENOTCONN)?2:0;
2921 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2922 exit_server_cleanly("getpeername() failed.\n");
2924 ret = tsocket_address_bsd_from_sockaddr(sconn,
2928 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2929 __location__, strerror(errno)));
2930 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2933 sa = (struct sockaddr *)(void *)&ss;
2934 sa_socklen = sizeof(ss);
2935 ret = getsockname(sconn->sock, sa, &sa_socklen);
2937 int level = (errno == ENOTCONN)?2:0;
2938 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2939 exit_server_cleanly("getsockname() failed.\n");
2941 ret = tsocket_address_bsd_from_sockaddr(sconn,
2945 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2946 __location__, strerror(errno)));
2947 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2950 sconn->local_address = local_address;
2951 sconn->remote_address = remote_address;
2953 if (tsocket_address_is_inet(remote_address, "ip")) {
2954 remaddr = tsocket_address_inet_addr_string(
2955 sconn->remote_address,
2957 if (remaddr == NULL) {
2961 remaddr = "0.0.0.0";
2964 /* this is needed so that we get decent entries
2965 in smbstatus for port 445 connects */
2966 set_remote_machine_name(remaddr, false);
2967 reload_services(sconn->msg_ctx, sconn->sock, true);
2970 * Before the first packet, check the global hosts allow/ hosts deny
2971 * parameters before doing any parsing of packets passed to us by the
2972 * client. This prevents attacks on our parsing code from hosts not in
2973 * the hosts allow list.
2976 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2977 sconn->client_id.name,
2978 sconn->client_id.addr)) {
2980 * send a negative session response "not listening on calling
2983 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2984 DEBUG( 1, ("Connection denied from %s to %s\n",
2985 tsocket_address_string(remote_address, talloc_tos()),
2986 tsocket_address_string(local_address, talloc_tos())));
2987 (void)srv_send_smb(sconn,(char *)buf, false,
2989 exit_server_cleanly("connection denied");
2992 DEBUG(10, ("Connection allowed from %s to %s\n",
2993 tsocket_address_string(remote_address, talloc_tos()),
2994 tsocket_address_string(local_address, talloc_tos())));
2998 smb_perfcount_init();
3000 if (!init_account_policy()) {
3001 exit_server("Could not open account policy tdb.\n");
3004 if (*lp_rootdir()) {
3005 if (chroot(lp_rootdir()) != 0) {
3006 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3007 exit_server("Failed to chroot()");
3009 if (chdir("/") == -1) {
3010 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3011 exit_server("Failed to chroot()");
3013 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3016 if (!srv_init_signing(sconn)) {
3017 exit_server("Failed to init smb_signing");
3020 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3021 exit_server("Failed to fork echo handler");
3025 if (!init_oplocks(sconn->msg_ctx))
3026 exit_server("Failed to init oplocks");
3028 /* register our message handlers */
3029 messaging_register(sconn->msg_ctx, NULL,
3030 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3031 messaging_register(sconn->msg_ctx, sconn,
3032 MSG_SMB_RELEASE_IP, msg_release_ip);
3033 messaging_register(sconn->msg_ctx, NULL,
3034 MSG_SMB_CLOSE_FILE, msg_close_file);
3037 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3038 * MSGs to all child processes
3040 messaging_deregister(sconn->msg_ctx,
3042 messaging_register(sconn->msg_ctx, NULL,
3043 MSG_DEBUG, debug_message);
3045 if ((lp_keepalive() != 0)
3046 && !(event_add_idle(smbd_event_context(), NULL,
3047 timeval_set(lp_keepalive(), 0),
3048 "keepalive", keepalive_fn,
3050 DEBUG(0, ("Could not add keepalive event\n"));
3054 if (!(event_add_idle(smbd_event_context(), NULL,
3055 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3056 "deadtime", deadtime_fn, sconn))) {
3057 DEBUG(0, ("Could not add deadtime event\n"));
3061 if (!(event_add_idle(smbd_event_context(), NULL,
3062 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3063 "housekeeping", housekeeping_fn, sconn))) {
3064 DEBUG(0, ("Could not add housekeeping event\n"));
3068 #ifdef CLUSTER_SUPPORT
3070 if (lp_clustering()) {
3072 * We need to tell ctdb about our client's TCP
3073 * connection, so that for failover ctdbd can send
3074 * tickle acks, triggering a reconnection by the
3078 struct sockaddr_storage srv, clnt;
3080 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3082 status = smbd_register_ips(sconn, &srv, &clnt);
3083 if (!NT_STATUS_IS_OK(status)) {
3084 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3085 nt_errstr(status)));
3089 DEBUG(0,("Unable to get tcp info for "
3090 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3097 sconn->nbt.got_session = false;
3099 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3101 sconn->smb1.sessions.done_sesssetup = false;
3102 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3103 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3104 /* users from session setup */
3105 sconn->smb1.sessions.session_userlist = NULL;
3106 /* workgroup from session setup. */
3107 sconn->smb1.sessions.session_workgroup = NULL;
3108 /* this holds info on user ids that are already validated for this VC */
3109 sconn->smb1.sessions.validated_users = NULL;
3110 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3111 sconn->smb1.sessions.num_validated_vuids = 0;
3114 if (!init_dptrs(sconn)) {
3115 exit_server("init_dptrs() failed");
3118 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3122 smbd_server_connection_handler,
3124 if (!sconn->smb1.fde) {
3125 exit_server("failed to create smbd_server_connection fde");
3133 frame = talloc_stackframe_pool(8192);
3137 status = smbd_server_connection_loop_once(sconn);
3138 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3139 !NT_STATUS_IS_OK(status)) {
3140 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3141 " exiting\n", nt_errstr(status)));
3148 exit_server_cleanly(NULL);
3151 bool req_is_in_chain(struct smb_request *req)
3153 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3155 * We're right now handling a subsequent request, so we must
3161 if (!is_andx_req(req->cmd)) {
3167 * Okay, an illegal request, but definitely not chained :-)
3172 return (CVAL(req->vwv+0, 0) != 0xFF);