2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/pcap.h"
31 #include "system/select.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
38 extern bool global_machine_password_needs_changing;
40 static void construct_reply_common(struct smb_request *req, const char *inbuf,
42 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
44 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
48 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
52 sconn->smb1.echo_handler.ref_count++;
54 if (sconn->smb1.echo_handler.ref_count > 1) {
58 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
62 sconn->smb1.echo_handler.socket_lock_fd,
63 SMB_F_SETLKW, 0, 0, F_WRLCK);
64 } while (!ok && (errno == EINTR));
67 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
71 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
76 void smbd_lock_socket(struct smbd_server_connection *sconn)
78 if (!smbd_lock_socket_internal(sconn)) {
79 exit_server_cleanly("failed to lock socket");
83 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
87 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
91 sconn->smb1.echo_handler.ref_count--;
93 if (sconn->smb1.echo_handler.ref_count > 0) {
99 sconn->smb1.echo_handler.socket_lock_fd,
100 SMB_F_SETLKW, 0, 0, F_UNLCK);
101 } while (!ok && (errno == EINTR));
104 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
108 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
113 void smbd_unlock_socket(struct smbd_server_connection *sconn)
115 if (!smbd_unlock_socket_internal(sconn)) {
116 exit_server_cleanly("failed to unlock socket");
120 /* Accessor function for smb_read_error for smbd functions. */
122 /****************************************************************************
124 ****************************************************************************/
126 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
127 bool do_signing, uint32_t seqnum,
129 struct smb_perfcount_data *pcd)
134 char *buf_out = buffer;
136 smbd_lock_socket(sconn);
139 /* Sign the outgoing packet if required. */
140 srv_calculate_sign_mac(sconn, buf_out, seqnum);
144 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
145 if (!NT_STATUS_IS_OK(status)) {
146 DEBUG(0, ("send_smb: SMB encryption failed "
147 "on outgoing packet! Error %s\n",
148 nt_errstr(status) ));
153 len = smb_len(buf_out) + 4;
155 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
158 char addr[INET6_ADDRSTRLEN];
160 * Try and give an error message saying what
163 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
164 (int)sys_getpid(), (int)len,
165 get_peer_addr(sconn->sock, addr, sizeof(addr)),
166 (int)ret, strerror(errno) ));
168 srv_free_enc_buffer(buf_out);
172 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
173 srv_free_enc_buffer(buf_out);
175 SMB_PERFCOUNT_END(pcd);
177 smbd_unlock_socket(sconn);
181 /*******************************************************************
182 Setup the word count and byte count for a smb message.
183 ********************************************************************/
185 int srv_set_message(char *buf,
190 if (zero && (num_words || num_bytes)) {
191 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
193 SCVAL(buf,smb_wct,num_words);
194 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
195 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
196 return (smb_size + num_words*2 + num_bytes);
199 static bool valid_smb_header(const uint8_t *inbuf)
201 if (is_encrypted_packet(inbuf)) {
205 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
206 * but it just looks weird to call strncmp for this one.
208 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
211 /* Socket functions for smbd packet processing. */
213 static bool valid_packet_size(size_t len)
216 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
217 * of header. Don't print the error if this fits.... JRA.
220 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
221 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
222 (unsigned long)len));
228 static NTSTATUS read_packet_remainder(int fd, char *buffer,
229 unsigned int timeout, ssize_t len)
237 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
238 if (!NT_STATUS_IS_OK(status)) {
239 char addr[INET6_ADDRSTRLEN];
240 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
242 get_peer_addr(fd, addr, sizeof(addr)),
248 /****************************************************************************
249 Attempt a zerocopy writeX read. We know here that len > smb_size-4
250 ****************************************************************************/
253 * Unfortunately, earlier versions of smbclient/libsmbclient
254 * don't send this "standard" writeX header. I've fixed this
255 * for 3.2 but we'll use the old method with earlier versions.
256 * Windows and CIFSFS at least use this standard size. Not
260 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
261 (2*14) + /* word count (including bcc) */ \
264 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
265 const char lenbuf[4],
266 struct smbd_server_connection *sconn,
269 unsigned int timeout,
273 /* Size of a WRITEX call (+4 byte len). */
274 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
275 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
279 memcpy(writeX_header, lenbuf, 4);
281 status = read_fd_with_timeout(
282 sock, writeX_header + 4,
283 STANDARD_WRITE_AND_X_HEADER_SIZE,
284 STANDARD_WRITE_AND_X_HEADER_SIZE,
287 if (!NT_STATUS_IS_OK(status)) {
288 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
289 "error = %s.\n", sconn->client_id.addr,
295 * Ok - now try and see if this is a possible
299 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
301 * If the data offset is beyond what
302 * we've read, drain the extra bytes.
304 uint16_t doff = SVAL(writeX_header,smb_vwv11);
307 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
308 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
309 if (drain_socket(sock, drain) != drain) {
310 smb_panic("receive_smb_raw_talloc_partial_read:"
311 " failed to drain pending bytes");
314 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
317 /* Spoof down the length and null out the bcc. */
318 set_message_bcc(writeX_header, 0);
319 newlen = smb_len(writeX_header);
321 /* Copy the header we've written. */
323 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
325 sizeof(writeX_header));
327 if (*buffer == NULL) {
328 DEBUG(0, ("Could not allocate inbuf of length %d\n",
329 (int)sizeof(writeX_header)));
330 return NT_STATUS_NO_MEMORY;
333 /* Work out the remaining bytes. */
334 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
335 *len_ret = newlen + 4;
339 if (!valid_packet_size(len)) {
340 return NT_STATUS_INVALID_PARAMETER;
344 * Not a valid writeX call. Just do the standard
348 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
350 if (*buffer == NULL) {
351 DEBUG(0, ("Could not allocate inbuf of length %d\n",
353 return NT_STATUS_NO_MEMORY;
356 /* Copy in what we already read. */
359 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
360 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
363 status = read_packet_remainder(
365 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
368 if (!NT_STATUS_IS_OK(status)) {
369 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
379 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
380 struct smbd_server_connection *sconn,
382 char **buffer, unsigned int timeout,
383 size_t *p_unread, size_t *plen)
387 int min_recv_size = lp_min_receive_file_size();
392 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
394 if (!NT_STATUS_IS_OK(status)) {
398 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
399 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
400 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
401 !srv_is_signing_active(sconn) &&
402 sconn->smb1.echo_handler.trusted_fde == NULL) {
404 return receive_smb_raw_talloc_partial_read(
405 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
409 if (!valid_packet_size(len)) {
410 return NT_STATUS_INVALID_PARAMETER;
414 * The +4 here can't wrap, we've checked the length above already.
417 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
419 if (*buffer == NULL) {
420 DEBUG(0, ("Could not allocate inbuf of length %d\n",
422 return NT_STATUS_NO_MEMORY;
425 memcpy(*buffer, lenbuf, sizeof(lenbuf));
427 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
428 if (!NT_STATUS_IS_OK(status)) {
436 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
437 struct smbd_server_connection *sconn,
439 char **buffer, unsigned int timeout,
440 size_t *p_unread, bool *p_encrypted,
443 bool trusted_channel)
448 *p_encrypted = false;
450 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
452 if (!NT_STATUS_IS_OK(status)) {
453 DEBUG(1, ("read_smb_length_return_keepalive failed for "
454 "client %s read error = %s.\n",
455 sconn->client_id.addr, nt_errstr(status)));
459 if (is_encrypted_packet((uint8_t *)*buffer)) {
460 status = srv_decrypt_buffer(*buffer);
461 if (!NT_STATUS_IS_OK(status)) {
462 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
463 "incoming packet! Error %s\n",
464 nt_errstr(status) ));
470 /* Check the incoming SMB signature. */
471 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
472 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
473 "incoming packet!\n"));
474 return NT_STATUS_INVALID_NETWORK_RESPONSE;
482 * Initialize a struct smb_request from an inbuf
485 static bool init_smb_request(struct smb_request *req,
486 struct smbd_server_connection *sconn,
488 size_t unread_bytes, bool encrypted,
491 size_t req_size = smb_len(inbuf) + 4;
492 /* Ensure we have at least smb_size bytes. */
493 if (req_size < smb_size) {
494 DEBUG(0,("init_smb_request: invalid request size %u\n",
495 (unsigned int)req_size ));
498 req->cmd = CVAL(inbuf, smb_com);
499 req->flags2 = SVAL(inbuf, smb_flg2);
500 req->smbpid = SVAL(inbuf, smb_pid);
501 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
502 req->seqnum = seqnum;
503 req->vuid = SVAL(inbuf, smb_uid);
504 req->tid = SVAL(inbuf, smb_tid);
505 req->wct = CVAL(inbuf, smb_wct);
506 req->vwv = (uint16_t *)(inbuf+smb_vwv);
507 req->buflen = smb_buflen(inbuf);
508 req->buf = (const uint8_t *)smb_buf(inbuf);
509 req->unread_bytes = unread_bytes;
510 req->encrypted = encrypted;
512 req->conn = conn_find(sconn,req->tid);
513 req->chain_fsp = NULL;
514 req->chain_outbuf = NULL;
517 smb_init_perfcount_data(&req->pcd);
519 /* Ensure we have at least wct words and 2 bytes of bcc. */
520 if (smb_size + req->wct*2 > req_size) {
521 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
522 (unsigned int)req->wct,
523 (unsigned int)req_size));
526 /* Ensure bcc is correct. */
527 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
528 DEBUG(0,("init_smb_request: invalid bcc number %u "
529 "(wct = %u, size %u)\n",
530 (unsigned int)req->buflen,
531 (unsigned int)req->wct,
532 (unsigned int)req_size));
540 static void process_smb(struct smbd_server_connection *conn,
541 uint8_t *inbuf, size_t nread, size_t unread_bytes,
542 uint32_t seqnum, bool encrypted,
543 struct smb_perfcount_data *deferred_pcd);
545 static void smbd_deferred_open_timer(struct event_context *ev,
546 struct timed_event *te,
547 struct timeval _tval,
550 struct pending_message_list *msg = talloc_get_type(private_data,
551 struct pending_message_list);
552 TALLOC_CTX *mem_ctx = talloc_tos();
553 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
556 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
559 exit_server("smbd_deferred_open_timer: talloc failed\n");
563 /* We leave this message on the queue so the open code can
564 know this is a retry. */
565 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
566 (unsigned long long)mid ));
568 /* Mark the message as processed so this is not
569 * re-processed in error. */
570 msg->processed = true;
572 process_smb(smbd_server_conn, inbuf,
574 msg->seqnum, msg->encrypted, &msg->pcd);
576 /* If it's still there and was processed, remove it. */
577 msg = get_deferred_open_message_smb(mid);
578 if (msg && msg->processed) {
579 remove_deferred_open_message_smb(mid);
583 /****************************************************************************
584 Function to push a message onto the tail of a linked list of smb messages ready
586 ****************************************************************************/
588 static bool push_queued_message(struct smb_request *req,
589 struct timeval request_time,
590 struct timeval end_time,
591 char *private_data, size_t private_len)
593 int msg_len = smb_len(req->inbuf) + 4;
594 struct pending_message_list *msg;
596 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
599 DEBUG(0,("push_message: malloc fail (1)\n"));
603 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
604 if(msg->buf.data == NULL) {
605 DEBUG(0,("push_message: malloc fail (2)\n"));
610 msg->request_time = request_time;
611 msg->seqnum = req->seqnum;
612 msg->encrypted = req->encrypted;
613 msg->processed = false;
614 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
617 msg->private_data = data_blob_talloc(msg, private_data,
619 if (msg->private_data.data == NULL) {
620 DEBUG(0,("push_message: malloc fail (3)\n"));
626 msg->te = event_add_timed(smbd_event_context(),
629 smbd_deferred_open_timer,
632 DEBUG(0,("push_message: event_add_timed failed\n"));
637 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
639 DEBUG(10,("push_message: pushed message length %u on "
640 "deferred_open_queue\n", (unsigned int)msg_len));
645 /****************************************************************************
646 Function to delete a sharing violation open message by mid.
647 ****************************************************************************/
649 void remove_deferred_open_message_smb(uint64_t mid)
651 struct pending_message_list *pml;
653 if (smbd_server_conn->using_smb2) {
654 remove_deferred_open_message_smb2(smbd_server_conn, mid);
658 for (pml = deferred_open_queue; pml; pml = pml->next) {
659 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
660 DEBUG(10,("remove_deferred_open_message_smb: "
661 "deleting mid %llu len %u\n",
662 (unsigned long long)mid,
663 (unsigned int)pml->buf.length ));
664 DLIST_REMOVE(deferred_open_queue, pml);
671 /****************************************************************************
672 Move a sharing violation open retry message to the front of the list and
673 schedule it for immediate processing.
674 ****************************************************************************/
676 void schedule_deferred_open_message_smb(uint64_t mid)
678 struct pending_message_list *pml;
681 if (smbd_server_conn->using_smb2) {
682 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
686 for (pml = deferred_open_queue; pml; pml = pml->next) {
687 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
689 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
692 (unsigned long long)msg_mid ));
694 if (mid == msg_mid) {
695 struct timed_event *te;
697 if (pml->processed) {
698 /* A processed message should not be
700 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
701 "message mid %llu was already processed\n",
702 (unsigned long long)msg_mid ));
706 DEBUG(10,("schedule_deferred_open_message_smb: "
707 "scheduling mid %llu\n",
708 (unsigned long long)mid ));
710 te = event_add_timed(smbd_event_context(),
713 smbd_deferred_open_timer,
716 DEBUG(10,("schedule_deferred_open_message_smb: "
717 "event_add_timed() failed, "
718 "skipping mid %llu\n",
719 (unsigned long long)msg_mid ));
722 TALLOC_FREE(pml->te);
724 DLIST_PROMOTE(deferred_open_queue, pml);
729 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
730 "find message mid %llu\n",
731 (unsigned long long)mid ));
734 /****************************************************************************
735 Return true if this mid is on the deferred queue and was not yet processed.
736 ****************************************************************************/
738 bool open_was_deferred(uint64_t mid)
740 struct pending_message_list *pml;
742 if (smbd_server_conn->using_smb2) {
743 return open_was_deferred_smb2(smbd_server_conn, mid);
746 for (pml = deferred_open_queue; pml; pml = pml->next) {
747 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
754 /****************************************************************************
755 Return the message queued by this mid.
756 ****************************************************************************/
758 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
760 struct pending_message_list *pml;
762 for (pml = deferred_open_queue; pml; pml = pml->next) {
763 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
770 /****************************************************************************
771 Get the state data queued by this mid.
772 ****************************************************************************/
774 bool get_deferred_open_message_state(struct smb_request *smbreq,
775 struct timeval *p_request_time,
778 struct pending_message_list *pml;
780 if (smbd_server_conn->using_smb2) {
781 return get_deferred_open_message_state_smb2(smbreq->smb2req,
786 pml = get_deferred_open_message_smb(smbreq->mid);
790 if (p_request_time) {
791 *p_request_time = pml->request_time;
794 *pp_state = (void *)pml->private_data.data;
799 /****************************************************************************
800 Function to push a deferred open smb message onto a linked list of local smb
801 messages ready for processing.
802 ****************************************************************************/
804 bool push_deferred_open_message_smb(struct smb_request *req,
805 struct timeval request_time,
806 struct timeval timeout,
808 char *private_data, size_t priv_len)
810 struct timeval end_time;
813 return push_deferred_open_message_smb2(req->smb2req,
821 if (req->unread_bytes) {
822 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
823 "unread_bytes = %u\n",
824 (unsigned int)req->unread_bytes ));
825 smb_panic("push_deferred_open_message_smb: "
826 "logic error unread_bytes != 0" );
829 end_time = timeval_sum(&request_time, &timeout);
831 DEBUG(10,("push_deferred_open_message_smb: pushing message "
832 "len %u mid %llu timeout time [%u.%06u]\n",
833 (unsigned int) smb_len(req->inbuf)+4,
834 (unsigned long long)req->mid,
835 (unsigned int)end_time.tv_sec,
836 (unsigned int)end_time.tv_usec));
838 return push_queued_message(req, request_time, end_time,
839 private_data, priv_len);
843 struct timed_event *te;
844 struct timeval interval;
846 bool (*handler)(const struct timeval *now, void *private_data);
850 static void smbd_idle_event_handler(struct event_context *ctx,
851 struct timed_event *te,
855 struct idle_event *event =
856 talloc_get_type_abort(private_data, struct idle_event);
858 TALLOC_FREE(event->te);
860 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
861 event->name, event->te));
863 if (!event->handler(&now, event->private_data)) {
864 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
865 event->name, event->te));
866 /* Don't repeat, delete ourselves */
871 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
872 event->name, event->te));
874 event->te = event_add_timed(ctx, event,
875 timeval_sum(&now, &event->interval),
876 smbd_idle_event_handler, event);
878 /* We can't do much but fail here. */
879 SMB_ASSERT(event->te != NULL);
882 struct idle_event *event_add_idle(struct event_context *event_ctx,
884 struct timeval interval,
886 bool (*handler)(const struct timeval *now,
890 struct idle_event *result;
891 struct timeval now = timeval_current();
893 result = TALLOC_P(mem_ctx, struct idle_event);
894 if (result == NULL) {
895 DEBUG(0, ("talloc failed\n"));
899 result->interval = interval;
900 result->handler = handler;
901 result->private_data = private_data;
903 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
904 DEBUG(0, ("talloc failed\n"));
909 result->te = event_add_timed(event_ctx, result,
910 timeval_sum(&now, &interval),
911 smbd_idle_event_handler, result);
912 if (result->te == NULL) {
913 DEBUG(0, ("event_add_timed failed\n"));
918 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
922 static void smbd_sig_term_handler(struct tevent_context *ev,
923 struct tevent_signal *se,
929 exit_server_cleanly("termination signal");
932 void smbd_setup_sig_term_handler(void)
934 struct tevent_signal *se;
936 se = tevent_add_signal(smbd_event_context(),
937 smbd_event_context(),
939 smbd_sig_term_handler,
942 exit_server("failed to setup SIGTERM handler");
946 static void smbd_sig_hup_handler(struct tevent_context *ev,
947 struct tevent_signal *se,
953 struct messaging_context *msg_ctx = talloc_get_type_abort(
954 private_data, struct messaging_context);
955 change_to_root_user();
956 DEBUG(1,("Reloading services after SIGHUP\n"));
957 reload_services(msg_ctx, smbd_server_conn->sock, False);
959 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
963 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
964 struct messaging_context *msg_ctx)
966 struct tevent_signal *se;
968 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
971 exit_server("failed to setup SIGHUP handler");
975 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
982 timeout = SMBD_SELECT_TIMEOUT * 1000;
985 * Are there any timed events waiting ? If so, ensure we don't
986 * select for longer than it would take to wait for them.
989 event_add_to_poll_args(smbd_event_context(), conn,
990 &conn->pfds, &num_pfds, &timeout);
992 /* Process a signal and timed events now... */
993 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
994 return NT_STATUS_RETRY;
999 START_PROFILE(smbd_idle);
1001 ret = sys_poll(conn->pfds, num_pfds, timeout);
1004 END_PROFILE(smbd_idle);
1008 if (ret == -1 && errno != EINTR) {
1009 return map_nt_error_from_unix(errno);
1012 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1015 return NT_STATUS_RETRY;
1018 /* Did we timeout ? */
1020 return NT_STATUS_RETRY;
1023 /* should not be reached */
1024 return NT_STATUS_INTERNAL_ERROR;
1028 * Only allow 5 outstanding trans requests. We're allocating memory, so
1032 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1035 for (; list != NULL; list = list->next) {
1037 if (list->mid == mid) {
1038 return NT_STATUS_INVALID_PARAMETER;
1044 return NT_STATUS_INSUFFICIENT_RESOURCES;
1047 return NT_STATUS_OK;
1051 These flags determine some of the permissions required to do an operation
1053 Note that I don't set NEED_WRITE on some write operations because they
1054 are used by some brain-dead clients when printing, and I don't want to
1055 force write permissions on print services.
1057 #define AS_USER (1<<0)
1058 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1059 #define TIME_INIT (1<<2)
1060 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1061 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1062 #define DO_CHDIR (1<<6)
1065 define a list of possible SMB messages and their corresponding
1066 functions. Any message that has a NULL function is unimplemented -
1067 please feel free to contribute implementations!
1069 static const struct smb_message_struct {
1071 void (*fn)(struct smb_request *req);
1073 } smb_messages[256] = {
1075 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1076 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1077 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1078 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1079 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1080 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1081 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1082 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1083 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1084 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1085 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1086 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1087 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1088 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1089 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1090 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1091 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1092 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1093 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1094 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1095 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1096 /* 0x15 */ { NULL, NULL, 0 },
1097 /* 0x16 */ { NULL, NULL, 0 },
1098 /* 0x17 */ { NULL, NULL, 0 },
1099 /* 0x18 */ { NULL, NULL, 0 },
1100 /* 0x19 */ { NULL, NULL, 0 },
1101 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1102 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1103 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1104 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1105 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1106 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1107 /* 0x20 */ { "SMBwritec", NULL,0},
1108 /* 0x21 */ { NULL, NULL, 0 },
1109 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1110 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1111 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1112 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1113 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1114 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1115 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1116 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1117 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1118 /* 0x2b */ { "SMBecho",reply_echo,0},
1119 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1120 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1121 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1122 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1123 /* 0x30 */ { NULL, NULL, 0 },
1124 /* 0x31 */ { NULL, NULL, 0 },
1125 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1126 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1127 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1128 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1129 /* 0x36 */ { NULL, NULL, 0 },
1130 /* 0x37 */ { NULL, NULL, 0 },
1131 /* 0x38 */ { NULL, NULL, 0 },
1132 /* 0x39 */ { NULL, NULL, 0 },
1133 /* 0x3a */ { NULL, NULL, 0 },
1134 /* 0x3b */ { NULL, NULL, 0 },
1135 /* 0x3c */ { NULL, NULL, 0 },
1136 /* 0x3d */ { NULL, NULL, 0 },
1137 /* 0x3e */ { NULL, NULL, 0 },
1138 /* 0x3f */ { NULL, NULL, 0 },
1139 /* 0x40 */ { NULL, NULL, 0 },
1140 /* 0x41 */ { NULL, NULL, 0 },
1141 /* 0x42 */ { NULL, NULL, 0 },
1142 /* 0x43 */ { NULL, NULL, 0 },
1143 /* 0x44 */ { NULL, NULL, 0 },
1144 /* 0x45 */ { NULL, NULL, 0 },
1145 /* 0x46 */ { NULL, NULL, 0 },
1146 /* 0x47 */ { NULL, NULL, 0 },
1147 /* 0x48 */ { NULL, NULL, 0 },
1148 /* 0x49 */ { NULL, NULL, 0 },
1149 /* 0x4a */ { NULL, NULL, 0 },
1150 /* 0x4b */ { NULL, NULL, 0 },
1151 /* 0x4c */ { NULL, NULL, 0 },
1152 /* 0x4d */ { NULL, NULL, 0 },
1153 /* 0x4e */ { NULL, NULL, 0 },
1154 /* 0x4f */ { NULL, NULL, 0 },
1155 /* 0x50 */ { NULL, NULL, 0 },
1156 /* 0x51 */ { NULL, NULL, 0 },
1157 /* 0x52 */ { NULL, NULL, 0 },
1158 /* 0x53 */ { NULL, NULL, 0 },
1159 /* 0x54 */ { NULL, NULL, 0 },
1160 /* 0x55 */ { NULL, NULL, 0 },
1161 /* 0x56 */ { NULL, NULL, 0 },
1162 /* 0x57 */ { NULL, NULL, 0 },
1163 /* 0x58 */ { NULL, NULL, 0 },
1164 /* 0x59 */ { NULL, NULL, 0 },
1165 /* 0x5a */ { NULL, NULL, 0 },
1166 /* 0x5b */ { NULL, NULL, 0 },
1167 /* 0x5c */ { NULL, NULL, 0 },
1168 /* 0x5d */ { NULL, NULL, 0 },
1169 /* 0x5e */ { NULL, NULL, 0 },
1170 /* 0x5f */ { NULL, NULL, 0 },
1171 /* 0x60 */ { NULL, NULL, 0 },
1172 /* 0x61 */ { NULL, NULL, 0 },
1173 /* 0x62 */ { NULL, NULL, 0 },
1174 /* 0x63 */ { NULL, NULL, 0 },
1175 /* 0x64 */ { NULL, NULL, 0 },
1176 /* 0x65 */ { NULL, NULL, 0 },
1177 /* 0x66 */ { NULL, NULL, 0 },
1178 /* 0x67 */ { NULL, NULL, 0 },
1179 /* 0x68 */ { NULL, NULL, 0 },
1180 /* 0x69 */ { NULL, NULL, 0 },
1181 /* 0x6a */ { NULL, NULL, 0 },
1182 /* 0x6b */ { NULL, NULL, 0 },
1183 /* 0x6c */ { NULL, NULL, 0 },
1184 /* 0x6d */ { NULL, NULL, 0 },
1185 /* 0x6e */ { NULL, NULL, 0 },
1186 /* 0x6f */ { NULL, NULL, 0 },
1187 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1188 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1189 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1190 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1191 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1192 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1193 /* 0x76 */ { NULL, NULL, 0 },
1194 /* 0x77 */ { NULL, NULL, 0 },
1195 /* 0x78 */ { NULL, NULL, 0 },
1196 /* 0x79 */ { NULL, NULL, 0 },
1197 /* 0x7a */ { NULL, NULL, 0 },
1198 /* 0x7b */ { NULL, NULL, 0 },
1199 /* 0x7c */ { NULL, NULL, 0 },
1200 /* 0x7d */ { NULL, NULL, 0 },
1201 /* 0x7e */ { NULL, NULL, 0 },
1202 /* 0x7f */ { NULL, NULL, 0 },
1203 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1204 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1205 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1206 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1207 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1208 /* 0x85 */ { NULL, NULL, 0 },
1209 /* 0x86 */ { NULL, NULL, 0 },
1210 /* 0x87 */ { NULL, NULL, 0 },
1211 /* 0x88 */ { NULL, NULL, 0 },
1212 /* 0x89 */ { NULL, NULL, 0 },
1213 /* 0x8a */ { NULL, NULL, 0 },
1214 /* 0x8b */ { NULL, NULL, 0 },
1215 /* 0x8c */ { NULL, NULL, 0 },
1216 /* 0x8d */ { NULL, NULL, 0 },
1217 /* 0x8e */ { NULL, NULL, 0 },
1218 /* 0x8f */ { NULL, NULL, 0 },
1219 /* 0x90 */ { NULL, NULL, 0 },
1220 /* 0x91 */ { NULL, NULL, 0 },
1221 /* 0x92 */ { NULL, NULL, 0 },
1222 /* 0x93 */ { NULL, NULL, 0 },
1223 /* 0x94 */ { NULL, NULL, 0 },
1224 /* 0x95 */ { NULL, NULL, 0 },
1225 /* 0x96 */ { NULL, NULL, 0 },
1226 /* 0x97 */ { NULL, NULL, 0 },
1227 /* 0x98 */ { NULL, NULL, 0 },
1228 /* 0x99 */ { NULL, NULL, 0 },
1229 /* 0x9a */ { NULL, NULL, 0 },
1230 /* 0x9b */ { NULL, NULL, 0 },
1231 /* 0x9c */ { NULL, NULL, 0 },
1232 /* 0x9d */ { NULL, NULL, 0 },
1233 /* 0x9e */ { NULL, NULL, 0 },
1234 /* 0x9f */ { NULL, NULL, 0 },
1235 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1236 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1237 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1238 /* 0xa3 */ { NULL, NULL, 0 },
1239 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1240 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1241 /* 0xa6 */ { NULL, NULL, 0 },
1242 /* 0xa7 */ { NULL, NULL, 0 },
1243 /* 0xa8 */ { NULL, NULL, 0 },
1244 /* 0xa9 */ { NULL, NULL, 0 },
1245 /* 0xaa */ { NULL, NULL, 0 },
1246 /* 0xab */ { NULL, NULL, 0 },
1247 /* 0xac */ { NULL, NULL, 0 },
1248 /* 0xad */ { NULL, NULL, 0 },
1249 /* 0xae */ { NULL, NULL, 0 },
1250 /* 0xaf */ { NULL, NULL, 0 },
1251 /* 0xb0 */ { NULL, NULL, 0 },
1252 /* 0xb1 */ { NULL, NULL, 0 },
1253 /* 0xb2 */ { NULL, NULL, 0 },
1254 /* 0xb3 */ { NULL, NULL, 0 },
1255 /* 0xb4 */ { NULL, NULL, 0 },
1256 /* 0xb5 */ { NULL, NULL, 0 },
1257 /* 0xb6 */ { NULL, NULL, 0 },
1258 /* 0xb7 */ { NULL, NULL, 0 },
1259 /* 0xb8 */ { NULL, NULL, 0 },
1260 /* 0xb9 */ { NULL, NULL, 0 },
1261 /* 0xba */ { NULL, NULL, 0 },
1262 /* 0xbb */ { NULL, NULL, 0 },
1263 /* 0xbc */ { NULL, NULL, 0 },
1264 /* 0xbd */ { NULL, NULL, 0 },
1265 /* 0xbe */ { NULL, NULL, 0 },
1266 /* 0xbf */ { NULL, NULL, 0 },
1267 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1268 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1269 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1270 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1271 /* 0xc4 */ { NULL, NULL, 0 },
1272 /* 0xc5 */ { NULL, NULL, 0 },
1273 /* 0xc6 */ { NULL, NULL, 0 },
1274 /* 0xc7 */ { NULL, NULL, 0 },
1275 /* 0xc8 */ { NULL, NULL, 0 },
1276 /* 0xc9 */ { NULL, NULL, 0 },
1277 /* 0xca */ { NULL, NULL, 0 },
1278 /* 0xcb */ { NULL, NULL, 0 },
1279 /* 0xcc */ { NULL, NULL, 0 },
1280 /* 0xcd */ { NULL, NULL, 0 },
1281 /* 0xce */ { NULL, NULL, 0 },
1282 /* 0xcf */ { NULL, NULL, 0 },
1283 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1284 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1285 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1286 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1287 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1288 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1289 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1290 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1291 /* 0xd8 */ { NULL, NULL, 0 },
1292 /* 0xd9 */ { NULL, NULL, 0 },
1293 /* 0xda */ { NULL, NULL, 0 },
1294 /* 0xdb */ { NULL, NULL, 0 },
1295 /* 0xdc */ { NULL, NULL, 0 },
1296 /* 0xdd */ { NULL, NULL, 0 },
1297 /* 0xde */ { NULL, NULL, 0 },
1298 /* 0xdf */ { NULL, NULL, 0 },
1299 /* 0xe0 */ { NULL, NULL, 0 },
1300 /* 0xe1 */ { NULL, NULL, 0 },
1301 /* 0xe2 */ { NULL, NULL, 0 },
1302 /* 0xe3 */ { NULL, NULL, 0 },
1303 /* 0xe4 */ { NULL, NULL, 0 },
1304 /* 0xe5 */ { NULL, NULL, 0 },
1305 /* 0xe6 */ { NULL, NULL, 0 },
1306 /* 0xe7 */ { NULL, NULL, 0 },
1307 /* 0xe8 */ { NULL, NULL, 0 },
1308 /* 0xe9 */ { NULL, NULL, 0 },
1309 /* 0xea */ { NULL, NULL, 0 },
1310 /* 0xeb */ { NULL, NULL, 0 },
1311 /* 0xec */ { NULL, NULL, 0 },
1312 /* 0xed */ { NULL, NULL, 0 },
1313 /* 0xee */ { NULL, NULL, 0 },
1314 /* 0xef */ { NULL, NULL, 0 },
1315 /* 0xf0 */ { NULL, NULL, 0 },
1316 /* 0xf1 */ { NULL, NULL, 0 },
1317 /* 0xf2 */ { NULL, NULL, 0 },
1318 /* 0xf3 */ { NULL, NULL, 0 },
1319 /* 0xf4 */ { NULL, NULL, 0 },
1320 /* 0xf5 */ { NULL, NULL, 0 },
1321 /* 0xf6 */ { NULL, NULL, 0 },
1322 /* 0xf7 */ { NULL, NULL, 0 },
1323 /* 0xf8 */ { NULL, NULL, 0 },
1324 /* 0xf9 */ { NULL, NULL, 0 },
1325 /* 0xfa */ { NULL, NULL, 0 },
1326 /* 0xfb */ { NULL, NULL, 0 },
1327 /* 0xfc */ { NULL, NULL, 0 },
1328 /* 0xfd */ { NULL, NULL, 0 },
1329 /* 0xfe */ { NULL, NULL, 0 },
1330 /* 0xff */ { NULL, NULL, 0 }
1334 /*******************************************************************
1335 allocate and initialize a reply packet
1336 ********************************************************************/
1338 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1339 const char *inbuf, char **outbuf, uint8_t num_words,
1343 * Protect against integer wrap
1345 if ((num_bytes > 0xffffff)
1346 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1348 if (asprintf(&msg, "num_bytes too large: %u",
1349 (unsigned)num_bytes) == -1) {
1350 msg = CONST_DISCARD(char *, "num_bytes too large");
1355 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1356 smb_size + num_words*2 + num_bytes);
1357 if (*outbuf == NULL) {
1361 construct_reply_common(req, inbuf, *outbuf);
1362 srv_set_message(*outbuf, num_words, num_bytes, false);
1364 * Zero out the word area, the caller has to take care of the bcc area
1367 if (num_words != 0) {
1368 memset(*outbuf + smb_vwv0, 0, num_words*2);
1374 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1377 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1379 smb_panic("could not allocate output buffer\n");
1381 req->outbuf = (uint8_t *)outbuf;
1385 /*******************************************************************
1386 Dump a packet to a file.
1387 ********************************************************************/
1389 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1393 if (DEBUGLEVEL < 50) {
1397 if (len < 4) len = smb_len(data)+4;
1398 for (i=1;i<100;i++) {
1399 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1400 type ? "req" : "resp") == -1) {
1403 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1404 if (fd != -1 || errno != EEXIST) break;
1407 ssize_t ret = write(fd, data, len);
1409 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1411 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1416 /****************************************************************************
1417 Prepare everything for calling the actual request function, and potentially
1418 call the request function via the "new" interface.
1420 Return False if the "legacy" function needs to be called, everything is
1423 Return True if we're done.
1425 I know this API sucks, but it is the one with the least code change I could
1427 ****************************************************************************/
1429 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1433 connection_struct *conn = NULL;
1434 struct smbd_server_connection *sconn = req->sconn;
1438 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1439 * so subtract 4 from it. */
1440 if (!valid_smb_header(req->inbuf)
1441 || (size < (smb_size - 4))) {
1442 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1443 smb_len(req->inbuf)));
1444 exit_server_cleanly("Non-SMB packet");
1447 if (smb_messages[type].fn == NULL) {
1448 DEBUG(0,("Unknown message type %d!\n",type));
1449 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1450 reply_unknown_new(req, type);
1454 flags = smb_messages[type].flags;
1456 /* In share mode security we must ignore the vuid. */
1457 session_tag = (lp_security() == SEC_SHARE)
1458 ? UID_FIELD_INVALID : req->vuid;
1461 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1462 (int)sys_getpid(), (unsigned long)conn));
1464 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1466 /* Ensure this value is replaced in the incoming packet. */
1467 SSVAL(req->inbuf,smb_uid,session_tag);
1470 * Ensure the correct username is in current_user_info. This is a
1471 * really ugly bugfix for problems with multiple session_setup_and_X's
1472 * being done and allowing %U and %G substitutions to work correctly.
1473 * There is a reason this code is done here, don't move it unless you
1474 * know what you're doing... :-).
1478 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1479 user_struct *vuser = NULL;
1481 sconn->smb1.sessions.last_session_tag = session_tag;
1482 if(session_tag != UID_FIELD_INVALID) {
1483 vuser = get_valid_user_struct(sconn, session_tag);
1485 set_current_user_info(
1486 vuser->session_info->sanitized_username,
1487 vuser->session_info->unix_name,
1488 vuser->session_info->info3->base.domain.string);
1493 /* Does this call need to be run as the connected user? */
1494 if (flags & AS_USER) {
1496 /* Does this call need a valid tree connection? */
1499 * Amazingly, the error code depends on the command
1502 if (type == SMBntcreateX) {
1503 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1505 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1510 if (!change_to_user(conn,session_tag)) {
1511 DEBUG(0, ("Error: Could not change to user. Removing "
1512 "deferred open, mid=%llu.\n",
1513 (unsigned long long)req->mid));
1514 reply_force_doserror(req, ERRSRV, ERRbaduid);
1518 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1520 /* Does it need write permission? */
1521 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1522 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1526 /* IPC services are limited */
1527 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1528 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1532 /* This call needs to be run as root */
1533 change_to_root_user();
1536 /* load service specific parameters */
1538 if (req->encrypted) {
1539 conn->encrypted_tid = true;
1540 /* encrypted required from now on. */
1541 conn->encrypt_level = Required;
1542 } else if (ENCRYPTION_REQUIRED(conn)) {
1543 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1544 exit_server_cleanly("encryption required "
1550 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1551 (flags & (AS_USER|DO_CHDIR)
1553 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1556 conn->num_smb_operations++;
1559 /* does this protocol need to be run as guest? */
1560 if ((flags & AS_GUEST)
1561 && (!change_to_guest() ||
1562 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1563 sconn->client_id.name,
1564 sconn->client_id.addr))) {
1565 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1569 smb_messages[type].fn(req);
1573 /****************************************************************************
1574 Construct a reply to the incoming packet.
1575 ****************************************************************************/
1577 static void construct_reply(struct smbd_server_connection *sconn,
1578 char *inbuf, int size, size_t unread_bytes,
1579 uint32_t seqnum, bool encrypted,
1580 struct smb_perfcount_data *deferred_pcd)
1582 connection_struct *conn;
1583 struct smb_request *req;
1585 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1586 smb_panic("could not allocate smb_request");
1589 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1590 encrypted, seqnum)) {
1591 exit_server_cleanly("Invalid SMB request");
1594 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1596 /* we popped this message off the queue - keep original perf data */
1598 req->pcd = *deferred_pcd;
1600 SMB_PERFCOUNT_START(&req->pcd);
1601 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1602 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1605 conn = switch_message(req->cmd, req, size);
1607 if (req->unread_bytes) {
1608 /* writeX failed. drain socket. */
1609 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1610 req->unread_bytes) {
1611 smb_panic("failed to drain pending bytes");
1613 req->unread_bytes = 0;
1621 if (req->outbuf == NULL) {
1625 if (CVAL(req->outbuf,0) == 0) {
1626 show_msg((char *)req->outbuf);
1629 if (!srv_send_smb(req->sconn,
1630 (char *)req->outbuf,
1631 true, req->seqnum+1,
1632 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1634 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1642 /****************************************************************************
1643 Process an smb from the client
1644 ****************************************************************************/
1645 static void process_smb(struct smbd_server_connection *sconn,
1646 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1647 uint32_t seqnum, bool encrypted,
1648 struct smb_perfcount_data *deferred_pcd)
1650 int msg_type = CVAL(inbuf,0);
1652 DO_PROFILE_INC(smb_count);
1654 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1656 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1657 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1659 if (msg_type != 0) {
1661 * NetBIOS session request, keepalive, etc.
1663 reply_special(sconn, (char *)inbuf, nread);
1667 if (sconn->using_smb2) {
1668 /* At this point we're not really using smb2,
1669 * we make the decision here.. */
1670 if (smbd_is_smb2_header(inbuf, nread)) {
1671 smbd_smb2_first_negprot(sconn, inbuf, nread);
1673 } else if (nread >= smb_size && valid_smb_header(inbuf)
1674 && CVAL(inbuf, smb_com) != 0x72) {
1675 /* This is a non-negprot SMB1 packet.
1676 Disable SMB2 from now on. */
1677 sconn->using_smb2 = false;
1681 show_msg((char *)inbuf);
1683 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1684 encrypted, deferred_pcd);
1688 sconn->smb1.num_requests++;
1690 /* The timeout_processing function isn't run nearly
1691 often enough to implement 'max log size' without
1692 overrunning the size of the file by many megabytes.
1693 This is especially true if we are running at debug
1694 level 10. Checking every 50 SMBs is a nice
1695 tradeoff of performance vs log file size overrun. */
1697 if ((sconn->smb1.num_requests % 50) == 0 &&
1698 need_to_check_log_size()) {
1699 change_to_root_user();
1704 /****************************************************************************
1705 Return a string containing the function name of a SMB command.
1706 ****************************************************************************/
1708 const char *smb_fn_name(int type)
1710 const char *unknown_name = "SMBunknown";
1712 if (smb_messages[type].name == NULL)
1713 return(unknown_name);
1715 return(smb_messages[type].name);
1718 /****************************************************************************
1719 Helper functions for contruct_reply.
1720 ****************************************************************************/
1722 void add_to_common_flags2(uint32 v)
1727 void remove_from_common_flags2(uint32 v)
1729 common_flags2 &= ~v;
1732 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1735 srv_set_message(outbuf,0,0,false);
1737 SCVAL(outbuf, smb_com, req->cmd);
1738 SIVAL(outbuf,smb_rcls,0);
1739 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1740 SSVAL(outbuf,smb_flg2,
1741 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1743 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1745 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1746 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1747 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1748 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1751 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1753 construct_reply_common(req, (char *)req->inbuf, outbuf);
1757 * How many bytes have we already accumulated up to the current wct field
1761 size_t req_wct_ofs(struct smb_request *req)
1765 if (req->chain_outbuf == NULL) {
1768 buf_size = talloc_get_size(req->chain_outbuf);
1769 if ((buf_size % 4) != 0) {
1770 buf_size += (4 - (buf_size % 4));
1772 return buf_size - 4;
1776 * Hack around reply_nterror & friends not being aware of chained requests,
1777 * generating illegal (i.e. wct==0) chain replies.
1780 static void fixup_chain_error_packet(struct smb_request *req)
1782 uint8_t *outbuf = req->outbuf;
1784 reply_outbuf(req, 2, 0);
1785 memcpy(req->outbuf, outbuf, smb_wct);
1786 TALLOC_FREE(outbuf);
1787 SCVAL(req->outbuf, smb_vwv0, 0xff);
1791 * @brief Find the smb_cmd offset of the last command pushed
1792 * @param[in] buf The buffer we're building up
1793 * @retval Where can we put our next andx cmd?
1795 * While chaining requests, the "next" request we're looking at needs to put
1796 * its SMB_Command before the data the previous request already built up added
1797 * to the chain. Find the offset to the place where we have to put our cmd.
1800 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1805 cmd = CVAL(buf, smb_com);
1807 SMB_ASSERT(is_andx_req(cmd));
1811 while (CVAL(buf, ofs) != 0xff) {
1813 if (!is_andx_req(CVAL(buf, ofs))) {
1818 * ofs is from start of smb header, so add the 4 length
1819 * bytes. The next cmd is right after the wct field.
1821 ofs = SVAL(buf, ofs+2) + 4 + 1;
1823 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1831 * @brief Do the smb chaining at a buffer level
1832 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1833 * @param[in] smb_command The command that we want to issue
1834 * @param[in] wct How many words?
1835 * @param[in] vwv The words, already in network order
1836 * @param[in] bytes_alignment How shall we align "bytes"?
1837 * @param[in] num_bytes How many bytes?
1838 * @param[in] bytes The data the request ships
1840 * smb_splice_chain() adds the vwv and bytes to the request already present in
1844 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1845 uint8_t wct, const uint16_t *vwv,
1846 size_t bytes_alignment,
1847 uint32_t num_bytes, const uint8_t *bytes)
1850 size_t old_size, new_size;
1852 size_t chain_padding = 0;
1853 size_t bytes_padding = 0;
1856 old_size = talloc_get_size(*poutbuf);
1859 * old_size == smb_wct means we're pushing the first request in for
1863 first_request = (old_size == smb_wct);
1865 if (!first_request && ((old_size % 4) != 0)) {
1867 * Align the wct field of subsequent requests to a 4-byte
1870 chain_padding = 4 - (old_size % 4);
1874 * After the old request comes the new wct field (1 byte), the vwv's
1875 * and the num_bytes field. After at we might need to align the bytes
1876 * given to us to "bytes_alignment", increasing the num_bytes value.
1879 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1881 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1882 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1885 new_size += bytes_padding + num_bytes;
1887 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1888 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1889 (unsigned)new_size));
1893 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1894 if (outbuf == NULL) {
1895 DEBUG(0, ("talloc failed\n"));
1900 if (first_request) {
1901 SCVAL(outbuf, smb_com, smb_command);
1903 size_t andx_cmd_ofs;
1905 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1906 DEBUG(1, ("invalid command chain\n"));
1907 *poutbuf = TALLOC_REALLOC_ARRAY(
1908 NULL, *poutbuf, uint8_t, old_size);
1912 if (chain_padding != 0) {
1913 memset(outbuf + old_size, 0, chain_padding);
1914 old_size += chain_padding;
1917 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1918 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1924 * Push the chained request:
1929 SCVAL(outbuf, ofs, wct);
1936 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1937 ofs += sizeof(uint16_t) * wct;
1943 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1944 ofs += sizeof(uint16_t);
1950 if (bytes_padding != 0) {
1951 memset(outbuf + ofs, 0, bytes_padding);
1952 ofs += bytes_padding;
1959 memcpy(outbuf + ofs, bytes, num_bytes);
1964 /****************************************************************************
1965 Construct a chained reply and add it to the already made reply
1966 ****************************************************************************/
1968 void chain_reply(struct smb_request *req)
1970 size_t smblen = smb_len(req->inbuf);
1971 size_t already_used, length_needed;
1973 uint32_t chain_offset; /* uint32_t to avoid overflow */
1980 if (IVAL(req->outbuf, smb_rcls) != 0) {
1981 fixup_chain_error_packet(req);
1985 * Any of the AndX requests and replies have at least a wct of
1986 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1987 * beginning of the SMB header to the next wct field.
1989 * None of the AndX requests put anything valuable in vwv[0] and [1],
1990 * so we can overwrite it here to form the chain.
1993 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1994 if (req->chain_outbuf == NULL) {
1995 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1996 req, req->outbuf, uint8_t,
1997 smb_len(req->outbuf) + 4);
1998 if (req->chain_outbuf == NULL) {
1999 smb_panic("talloc failed");
2007 * Here we assume that this is the end of the chain. For that we need
2008 * to set "next command" to 0xff and the offset to 0. If we later find
2009 * more commands in the chain, this will be overwritten again.
2012 SCVAL(req->outbuf, smb_vwv0, 0xff);
2013 SCVAL(req->outbuf, smb_vwv0+1, 0);
2014 SSVAL(req->outbuf, smb_vwv1, 0);
2016 if (req->chain_outbuf == NULL) {
2018 * In req->chain_outbuf we collect all the replies. Start the
2019 * chain by copying in the first reply.
2021 * We do the realloc because later on we depend on
2022 * talloc_get_size to determine the length of
2023 * chain_outbuf. The reply_xxx routines might have
2024 * over-allocated (reply_pipe_read_and_X used to be such an
2027 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2028 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2029 if (req->chain_outbuf == NULL) {
2030 smb_panic("talloc failed");
2035 * Update smb headers where subsequent chained commands
2036 * may have updated them.
2038 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2039 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2041 if (!smb_splice_chain(&req->chain_outbuf,
2042 CVAL(req->outbuf, smb_com),
2043 CVAL(req->outbuf, smb_wct),
2044 (uint16_t *)(req->outbuf + smb_vwv),
2045 0, smb_buflen(req->outbuf),
2046 (uint8_t *)smb_buf(req->outbuf))) {
2049 TALLOC_FREE(req->outbuf);
2053 * We use the old request's vwv field to grab the next chained command
2054 * and offset into the chained fields.
2057 chain_cmd = CVAL(req->vwv+0, 0);
2058 chain_offset = SVAL(req->vwv+1, 0);
2060 if (chain_cmd == 0xff) {
2062 * End of chain, no more requests from the client. So ship the
2065 smb_setlen((char *)(req->chain_outbuf),
2066 talloc_get_size(req->chain_outbuf) - 4);
2068 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2069 true, req->seqnum+1,
2070 IS_CONN_ENCRYPTED(req->conn)
2073 exit_server_cleanly("chain_reply: srv_send_smb "
2076 TALLOC_FREE(req->chain_outbuf);
2081 /* add a new perfcounter for this element of chain */
2082 SMB_PERFCOUNT_ADD(&req->pcd);
2083 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2084 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2087 * Check if the client tries to fool us. The request so far uses the
2088 * space to the end of the byte buffer in the request just
2089 * processed. The chain_offset can't point into that area. If that was
2090 * the case, we could end up with an endless processing of the chain,
2091 * we would always handle the same request.
2094 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2095 if (chain_offset < already_used) {
2100 * Next check: Make sure the chain offset does not point beyond the
2101 * overall smb request length.
2104 length_needed = chain_offset+1; /* wct */
2105 if (length_needed > smblen) {
2110 * Now comes the pointer magic. Goal here is to set up req->vwv and
2111 * req->buf correctly again to be able to call the subsequent
2112 * switch_message(). The chain offset (the former vwv[1]) points at
2113 * the new wct field.
2116 wct = CVAL(smb_base(req->inbuf), chain_offset);
2119 * Next consistency check: Make the new vwv array fits in the overall
2123 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2124 if (length_needed > smblen) {
2127 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2130 * Now grab the new byte buffer....
2133 buflen = SVAL(vwv+wct, 0);
2136 * .. and check that it fits.
2139 length_needed += buflen;
2140 if (length_needed > smblen) {
2143 buf = (uint8_t *)(vwv+wct+1);
2145 req->cmd = chain_cmd;
2148 req->buflen = buflen;
2151 switch_message(chain_cmd, req, smblen);
2153 if (req->outbuf == NULL) {
2155 * This happens if the chained command has suspended itself or
2156 * if it has called srv_send_smb() itself.
2162 * We end up here if the chained command was not itself chained or
2163 * suspended, but for example a close() command. We now need to splice
2164 * the chained commands' outbuf into the already built up chain_outbuf
2165 * and ship the result.
2171 * We end up here if there's any error in the chain syntax. Report a
2172 * DOS error, just like Windows does.
2174 reply_force_doserror(req, ERRSRV, ERRerror);
2175 fixup_chain_error_packet(req);
2179 * This scary statement intends to set the
2180 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2181 * to the value req->outbuf carries
2183 SSVAL(req->chain_outbuf, smb_flg2,
2184 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2185 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2188 * Transfer the error codes from the subrequest to the main one
2190 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2191 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2193 if (!smb_splice_chain(&req->chain_outbuf,
2194 CVAL(req->outbuf, smb_com),
2195 CVAL(req->outbuf, smb_wct),
2196 (uint16_t *)(req->outbuf + smb_vwv),
2197 0, smb_buflen(req->outbuf),
2198 (uint8_t *)smb_buf(req->outbuf))) {
2199 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2201 TALLOC_FREE(req->outbuf);
2203 smb_setlen((char *)(req->chain_outbuf),
2204 talloc_get_size(req->chain_outbuf) - 4);
2206 show_msg((char *)(req->chain_outbuf));
2208 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2209 true, req->seqnum+1,
2210 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2212 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2214 TALLOC_FREE(req->chain_outbuf);
2218 /****************************************************************************
2219 Check if services need reloading.
2220 ****************************************************************************/
2222 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2225 if (last_smb_conf_reload_time == 0) {
2226 last_smb_conf_reload_time = t;
2229 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2230 reload_services(sconn->msg_ctx, sconn->sock, True);
2231 last_smb_conf_reload_time = t;
2235 static bool fd_is_readable(int fd)
2239 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2241 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2245 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2247 /* TODO: make write nonblocking */
2250 static void smbd_server_connection_read_handler(
2251 struct smbd_server_connection *conn, int fd)
2253 uint8_t *inbuf = NULL;
2254 size_t inbuf_len = 0;
2255 size_t unread_bytes = 0;
2256 bool encrypted = false;
2257 TALLOC_CTX *mem_ctx = talloc_tos();
2261 bool from_client = (conn->sock == fd);
2264 smbd_lock_socket(conn);
2266 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2267 DEBUG(10,("the echo listener was faster\n"));
2268 smbd_unlock_socket(conn);
2272 /* TODO: make this completely nonblocking */
2273 status = receive_smb_talloc(mem_ctx, conn, fd,
2274 (char **)(void *)&inbuf,
2278 &inbuf_len, &seqnum,
2279 false /* trusted channel */);
2280 smbd_unlock_socket(conn);
2282 /* TODO: make this completely nonblocking */
2283 status = receive_smb_talloc(mem_ctx, conn, fd,
2284 (char **)(void *)&inbuf,
2288 &inbuf_len, &seqnum,
2289 true /* trusted channel */);
2292 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2295 if (NT_STATUS_IS_ERR(status)) {
2296 exit_server_cleanly("failed to receive smb request");
2298 if (!NT_STATUS_IS_OK(status)) {
2303 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2304 seqnum, encrypted, NULL);
2307 static void smbd_server_connection_handler(struct event_context *ev,
2308 struct fd_event *fde,
2312 struct smbd_server_connection *conn = talloc_get_type(private_data,
2313 struct smbd_server_connection);
2315 if (flags & EVENT_FD_WRITE) {
2316 smbd_server_connection_write_handler(conn);
2319 if (flags & EVENT_FD_READ) {
2320 smbd_server_connection_read_handler(conn, conn->sock);
2325 static void smbd_server_echo_handler(struct event_context *ev,
2326 struct fd_event *fde,
2330 struct smbd_server_connection *conn = talloc_get_type(private_data,
2331 struct smbd_server_connection);
2333 if (flags & EVENT_FD_WRITE) {
2334 smbd_server_connection_write_handler(conn);
2337 if (flags & EVENT_FD_READ) {
2338 smbd_server_connection_read_handler(
2339 conn, conn->smb1.echo_handler.trusted_fd);
2344 /****************************************************************************
2345 received when we should release a specific IP
2346 ****************************************************************************/
2347 static void release_ip(const char *ip, void *priv)
2349 const char *addr = (const char *)priv;
2350 const char *p = addr;
2352 if (strncmp("::ffff:", addr, 7) == 0) {
2356 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2357 /* we can't afford to do a clean exit - that involves
2358 database writes, which would potentially mean we
2359 are still running after the failover has finished -
2360 we have to get rid of this process ID straight
2362 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2364 /* note we must exit with non-zero status so the unclean handler gets
2365 called in the parent, so that the brl database is tickled */
2370 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2371 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2373 struct smbd_server_connection *sconn = talloc_get_type_abort(
2374 private_data, struct smbd_server_connection);
2376 release_ip((char *)data->data, sconn->client_id.addr);
2379 #ifdef CLUSTER_SUPPORT
2380 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2381 struct sockaddr_storage *client)
2384 length = sizeof(*server);
2385 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2388 length = sizeof(*client);
2389 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2397 * Send keepalive packets to our client
2399 static bool keepalive_fn(const struct timeval *now, void *private_data)
2401 struct smbd_server_connection *sconn = smbd_server_conn;
2404 if (sconn->using_smb2) {
2405 /* Don't do keepalives on an SMB2 connection. */
2409 smbd_lock_socket(smbd_server_conn);
2410 ret = send_keepalive(sconn->sock);
2411 smbd_unlock_socket(smbd_server_conn);
2414 char addr[INET6_ADDRSTRLEN];
2416 * Try and give an error message saying what
2419 DEBUG(0, ("send_keepalive failed for client %s. "
2420 "Error %s - exiting\n",
2421 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2429 * Do the recurring check if we're idle
2431 static bool deadtime_fn(const struct timeval *now, void *private_data)
2433 struct smbd_server_connection *sconn =
2434 (struct smbd_server_connection *)private_data;
2436 if ((conn_num_open(sconn) == 0)
2437 || (conn_idle_all(sconn, now->tv_sec))) {
2438 DEBUG( 2, ( "Closing idle connection\n" ) );
2439 messaging_send(sconn->msg_ctx,
2440 messaging_server_id(sconn->msg_ctx),
2441 MSG_SHUTDOWN, &data_blob_null);
2449 * Do the recurring log file and smb.conf reload checks.
2452 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2454 struct smbd_server_connection *sconn = talloc_get_type_abort(
2455 private_data, struct smbd_server_connection);
2457 DEBUG(5, ("housekeeping\n"));
2459 change_to_root_user();
2461 /* update printer queue caches if necessary */
2462 update_monitored_printq_cache(sconn->msg_ctx);
2464 /* check if we need to reload services */
2465 check_reload(sconn, time_mono(NULL));
2467 /* Change machine password if neccessary. */
2468 attempt_machine_password_change();
2471 * Force a log file check.
2473 force_check_log_size();
2478 static int create_unlink_tmp(const char *dir)
2483 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2484 if (fname == NULL) {
2488 fd = mkstemp(fname);
2493 if (unlink(fname) == -1) {
2494 int sys_errno = errno;
2504 struct smbd_echo_state {
2505 struct tevent_context *ev;
2506 struct iovec *pending;
2507 struct smbd_server_connection *sconn;
2510 struct tevent_fd *parent_fde;
2512 struct tevent_fd *read_fde;
2513 struct tevent_req *write_req;
2516 static void smbd_echo_writer_done(struct tevent_req *req);
2518 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2522 if (state->write_req != NULL) {
2526 num_pending = talloc_array_length(state->pending);
2527 if (num_pending == 0) {
2531 state->write_req = writev_send(state, state->ev, NULL,
2532 state->parent_pipe, false,
2533 state->pending, num_pending);
2534 if (state->write_req == NULL) {
2535 DEBUG(1, ("writev_send failed\n"));
2539 talloc_steal(state->write_req, state->pending);
2540 state->pending = NULL;
2542 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2546 static void smbd_echo_writer_done(struct tevent_req *req)
2548 struct smbd_echo_state *state = tevent_req_callback_data(
2549 req, struct smbd_echo_state);
2553 written = writev_recv(req, &err);
2555 state->write_req = NULL;
2556 if (written == -1) {
2557 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2560 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2561 smbd_echo_activate_writer(state);
2564 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2567 struct smb_request req;
2568 uint16_t num_replies;
2573 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2574 DEBUG(10, ("Got netbios keepalive\n"));
2581 if (inbuf_len < smb_size) {
2582 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2585 if (!valid_smb_header(inbuf)) {
2586 DEBUG(10, ("Got invalid SMB header\n"));
2590 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2596 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2597 smb_messages[req.cmd].name
2598 ? smb_messages[req.cmd].name : "unknown"));
2600 if (req.cmd != SMBecho) {
2607 num_replies = SVAL(req.vwv+0, 0);
2608 if (num_replies != 1) {
2609 /* Not a Windows "Hey, you're still there?" request */
2613 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2615 DEBUG(10, ("create_outbuf failed\n"));
2618 req.outbuf = (uint8_t *)outbuf;
2620 SSVAL(req.outbuf, smb_vwv0, num_replies);
2622 if (req.buflen > 0) {
2623 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2626 out_len = smb_len(req.outbuf) + 4;
2628 ok = srv_send_smb(req.sconn,
2632 TALLOC_FREE(outbuf);
2640 static void smbd_echo_exit(struct tevent_context *ev,
2641 struct tevent_fd *fde, uint16_t flags,
2644 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2648 static void smbd_echo_reader(struct tevent_context *ev,
2649 struct tevent_fd *fde, uint16_t flags,
2652 struct smbd_echo_state *state = talloc_get_type_abort(
2653 private_data, struct smbd_echo_state);
2654 struct smbd_server_connection *sconn = state->sconn;
2655 size_t unread, num_pending;
2659 uint32_t seqnum = 0;
2662 bool encrypted = false;
2666 ok = smbd_lock_socket_internal(sconn);
2668 DEBUG(0, ("%s: failed to lock socket\n",
2673 if (!fd_is_readable(sconn->sock)) {
2674 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2675 (int)sys_getpid()));
2676 ok = smbd_unlock_socket_internal(sconn);
2678 DEBUG(1, ("%s: failed to unlock socket in\n",
2685 num_pending = talloc_array_length(state->pending);
2686 tmp = talloc_realloc(state, state->pending, struct iovec,
2689 DEBUG(1, ("talloc_realloc failed\n"));
2692 state->pending = tmp;
2694 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2696 status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2697 (char **)(void *)&state->pending[num_pending].iov_base,
2703 false /* trusted_channel*/);
2704 if (!NT_STATUS_IS_OK(status)) {
2705 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2706 (int)sys_getpid(), nt_errstr(status)));
2709 state->pending[num_pending].iov_len = iov_len;
2711 ok = smbd_unlock_socket_internal(sconn);
2713 DEBUG(1, ("%s: failed to unlock socket in\n",
2718 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2719 state->pending[num_pending].iov_len,
2722 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2723 /* no check, shrinking by some bytes does not fail */
2724 state->pending = talloc_realloc(state, state->pending,
2730 if (state->pending[num_pending].iov_len >= smb_size) {
2732 * place the seqnum in the packet so that the main process
2733 * can reply with signing
2735 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2736 smb_ss_field, seqnum);
2737 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2738 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2741 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2742 smbd_echo_activate_writer(state);
2745 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2748 struct smbd_echo_state *state;
2750 state = talloc_zero(sconn, struct smbd_echo_state);
2751 if (state == NULL) {
2752 DEBUG(1, ("talloc failed\n"));
2755 state->sconn = sconn;
2756 state->parent_pipe = parent_pipe;
2757 state->ev = s3_tevent_context_init(state);
2758 if (state->ev == NULL) {
2759 DEBUG(1, ("tevent_context_init failed\n"));
2763 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2764 TEVENT_FD_READ, smbd_echo_exit,
2766 if (state->parent_fde == NULL) {
2767 DEBUG(1, ("tevent_add_fd failed\n"));
2771 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2772 TEVENT_FD_READ, smbd_echo_reader,
2774 if (state->read_fde == NULL) {
2775 DEBUG(1, ("tevent_add_fd failed\n"));
2781 if (tevent_loop_once(state->ev) == -1) {
2782 DEBUG(1, ("tevent_loop_once failed: %s\n",
2791 * Handle SMBecho requests in a forked child process
2793 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2795 int listener_pipe[2];
2799 res = pipe(listener_pipe);
2801 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2804 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2805 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2806 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2814 close(listener_pipe[0]);
2815 set_blocking(listener_pipe[1], false);
2817 status = reinit_after_fork(sconn->msg_ctx,
2818 smbd_event_context(),
2819 procid_self(), false);
2820 if (!NT_STATUS_IS_OK(status)) {
2821 DEBUG(1, ("reinit_after_fork failed: %s\n",
2822 nt_errstr(status)));
2825 smbd_echo_loop(sconn, listener_pipe[1]);
2828 close(listener_pipe[1]);
2829 listener_pipe[1] = -1;
2830 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2832 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2835 * Without smb signing this is the same as the normal smbd
2836 * listener. This needs to change once signing comes in.
2838 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2840 sconn->smb1.echo_handler.trusted_fd,
2842 smbd_server_echo_handler,
2844 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2845 DEBUG(1, ("event_add_fd failed\n"));
2852 if (listener_pipe[0] != -1) {
2853 close(listener_pipe[0]);
2855 if (listener_pipe[1] != -1) {
2856 close(listener_pipe[1]);
2858 sconn->smb1.echo_handler.trusted_fd = -1;
2859 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2860 close(sconn->smb1.echo_handler.socket_lock_fd);
2862 sconn->smb1.echo_handler.trusted_fd = -1;
2863 sconn->smb1.echo_handler.socket_lock_fd = -1;
2869 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2870 struct sockaddr_storage *srv,
2871 struct sockaddr_storage *clnt)
2873 struct ctdbd_connection *cconn;
2874 char tmp_addr[INET6_ADDRSTRLEN];
2877 cconn = messaging_ctdbd_connection();
2878 if (cconn == NULL) {
2879 return NT_STATUS_NO_MEMORY;
2882 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2883 addr = talloc_strdup(cconn, tmp_addr);
2885 return NT_STATUS_NO_MEMORY;
2887 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2892 /****************************************************************************
2893 Process commands from the client
2894 ****************************************************************************/
2896 void smbd_process(struct smbd_server_connection *sconn)
2898 TALLOC_CTX *frame = talloc_stackframe();
2899 struct sockaddr_storage ss;
2900 struct sockaddr *sa = NULL;
2901 socklen_t sa_socklen;
2902 struct tsocket_address *local_address = NULL;
2903 struct tsocket_address *remote_address = NULL;
2904 const char *remaddr = NULL;
2907 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2908 !lp_async_smb_echo_handler()) {
2910 * We're not making the decision here,
2911 * we're just allowing the client
2912 * to decide between SMB1 and SMB2
2913 * with the first negprot
2916 sconn->using_smb2 = true;
2919 /* Ensure child is set to blocking mode */
2920 set_blocking(sconn->sock,True);
2922 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2923 set_socket_options(sconn->sock, lp_socket_options());
2925 sa = (struct sockaddr *)(void *)&ss;
2926 sa_socklen = sizeof(ss);
2927 ret = getpeername(sconn->sock, sa, &sa_socklen);
2929 int level = (errno == ENOTCONN)?2:0;
2930 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2931 exit_server_cleanly("getpeername() failed.\n");
2933 ret = tsocket_address_bsd_from_sockaddr(sconn,
2937 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2938 __location__, strerror(errno)));
2939 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2942 sa = (struct sockaddr *)(void *)&ss;
2943 sa_socklen = sizeof(ss);
2944 ret = getsockname(sconn->sock, sa, &sa_socklen);
2946 int level = (errno == ENOTCONN)?2:0;
2947 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2948 exit_server_cleanly("getsockname() failed.\n");
2950 ret = tsocket_address_bsd_from_sockaddr(sconn,
2954 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2955 __location__, strerror(errno)));
2956 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2959 sconn->local_address = local_address;
2960 sconn->remote_address = remote_address;
2962 if (tsocket_address_is_inet(remote_address, "ip")) {
2963 remaddr = tsocket_address_inet_addr_string(
2964 sconn->remote_address,
2966 if (remaddr == NULL) {
2970 remaddr = "0.0.0.0";
2973 /* this is needed so that we get decent entries
2974 in smbstatus for port 445 connects */
2975 set_remote_machine_name(remaddr, false);
2976 reload_services(sconn->msg_ctx, sconn->sock, true);
2979 * Before the first packet, check the global hosts allow/ hosts deny
2980 * parameters before doing any parsing of packets passed to us by the
2981 * client. This prevents attacks on our parsing code from hosts not in
2982 * the hosts allow list.
2985 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2986 sconn->client_id.name,
2987 sconn->client_id.addr)) {
2989 * send a negative session response "not listening on calling
2992 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2993 DEBUG( 1, ("Connection denied from %s to %s\n",
2994 tsocket_address_string(remote_address, talloc_tos()),
2995 tsocket_address_string(local_address, talloc_tos())));
2996 (void)srv_send_smb(sconn,(char *)buf, false,
2998 exit_server_cleanly("connection denied");
3001 DEBUG(10, ("Connection allowed from %s to %s\n",
3002 tsocket_address_string(remote_address, talloc_tos()),
3003 tsocket_address_string(local_address, talloc_tos())));
3007 smb_perfcount_init();
3009 if (!init_account_policy()) {
3010 exit_server("Could not open account policy tdb.\n");
3013 if (*lp_rootdir()) {
3014 if (chroot(lp_rootdir()) != 0) {
3015 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3016 exit_server("Failed to chroot()");
3018 if (chdir("/") == -1) {
3019 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3020 exit_server("Failed to chroot()");
3022 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3025 if (!srv_init_signing(sconn)) {
3026 exit_server("Failed to init smb_signing");
3029 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3030 exit_server("Failed to fork echo handler");
3034 if (!init_oplocks(sconn->msg_ctx))
3035 exit_server("Failed to init oplocks");
3037 /* register our message handlers */
3038 messaging_register(sconn->msg_ctx, NULL,
3039 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3040 messaging_register(sconn->msg_ctx, sconn,
3041 MSG_SMB_RELEASE_IP, msg_release_ip);
3042 messaging_register(sconn->msg_ctx, NULL,
3043 MSG_SMB_CLOSE_FILE, msg_close_file);
3046 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3047 * MSGs to all child processes
3049 messaging_deregister(sconn->msg_ctx,
3051 messaging_register(sconn->msg_ctx, NULL,
3052 MSG_DEBUG, debug_message);
3054 if ((lp_keepalive() != 0)
3055 && !(event_add_idle(smbd_event_context(), NULL,
3056 timeval_set(lp_keepalive(), 0),
3057 "keepalive", keepalive_fn,
3059 DEBUG(0, ("Could not add keepalive event\n"));
3063 if (!(event_add_idle(smbd_event_context(), NULL,
3064 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3065 "deadtime", deadtime_fn, sconn))) {
3066 DEBUG(0, ("Could not add deadtime event\n"));
3070 if (!(event_add_idle(smbd_event_context(), NULL,
3071 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3072 "housekeeping", housekeeping_fn, sconn))) {
3073 DEBUG(0, ("Could not add housekeeping event\n"));
3077 #ifdef CLUSTER_SUPPORT
3079 if (lp_clustering()) {
3081 * We need to tell ctdb about our client's TCP
3082 * connection, so that for failover ctdbd can send
3083 * tickle acks, triggering a reconnection by the
3087 struct sockaddr_storage srv, clnt;
3089 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3091 status = smbd_register_ips(sconn, &srv, &clnt);
3092 if (!NT_STATUS_IS_OK(status)) {
3093 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3094 nt_errstr(status)));
3098 DEBUG(0,("Unable to get tcp info for "
3099 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3106 sconn->nbt.got_session = false;
3108 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3110 sconn->smb1.sessions.done_sesssetup = false;
3111 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3112 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3113 /* users from session setup */
3114 sconn->smb1.sessions.session_userlist = NULL;
3115 /* workgroup from session setup. */
3116 sconn->smb1.sessions.session_workgroup = NULL;
3117 /* this holds info on user ids that are already validated for this VC */
3118 sconn->smb1.sessions.validated_users = NULL;
3119 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3120 sconn->smb1.sessions.num_validated_vuids = 0;
3123 if (!init_dptrs(sconn)) {
3124 exit_server("init_dptrs() failed");
3127 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3131 smbd_server_connection_handler,
3133 if (!sconn->smb1.fde) {
3134 exit_server("failed to create smbd_server_connection fde");
3142 frame = talloc_stackframe_pool(8192);
3146 status = smbd_server_connection_loop_once(sconn);
3147 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3148 !NT_STATUS_IS_OK(status)) {
3149 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3150 " exiting\n", nt_errstr(status)));
3157 exit_server_cleanly(NULL);
3160 bool req_is_in_chain(struct smb_request *req)
3162 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3164 * We're right now handling a subsequent request, so we must
3170 if (!is_andx_req(req->cmd)) {
3176 * Okay, an illegal request, but definitely not chained :-)
3181 return (CVAL(req->vwv+0, 0) != 0xFF);