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 = discard_const_p(uint16_t, (inbuf+smb_vwv));
507 req->buflen = smb_buflen(inbuf);
508 req->buf = (const uint8_t *)smb_buf_const(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 (((const uint8_t *)smb_buf_const(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);
1009 if (errno == EINTR) {
1010 return NT_STATUS_RETRY;
1012 return map_nt_error_from_unix(errno);
1015 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1018 return NT_STATUS_RETRY;
1021 /* Did we timeout ? */
1023 return NT_STATUS_RETRY;
1026 /* should not be reached */
1027 return NT_STATUS_INTERNAL_ERROR;
1031 * Only allow 5 outstanding trans requests. We're allocating memory, so
1035 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1038 for (; list != NULL; list = list->next) {
1040 if (list->mid == mid) {
1041 return NT_STATUS_INVALID_PARAMETER;
1047 return NT_STATUS_INSUFFICIENT_RESOURCES;
1050 return NT_STATUS_OK;
1054 These flags determine some of the permissions required to do an operation
1056 Note that I don't set NEED_WRITE on some write operations because they
1057 are used by some brain-dead clients when printing, and I don't want to
1058 force write permissions on print services.
1060 #define AS_USER (1<<0)
1061 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1062 #define TIME_INIT (1<<2)
1063 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1064 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1065 #define DO_CHDIR (1<<6)
1068 define a list of possible SMB messages and their corresponding
1069 functions. Any message that has a NULL function is unimplemented -
1070 please feel free to contribute implementations!
1072 static const struct smb_message_struct {
1074 void (*fn)(struct smb_request *req);
1076 } smb_messages[256] = {
1078 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1079 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1080 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1081 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1082 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1083 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1084 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1085 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1086 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1087 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1088 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1089 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1090 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1091 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1092 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1093 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1094 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1095 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1096 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1097 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1098 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1099 /* 0x15 */ { NULL, NULL, 0 },
1100 /* 0x16 */ { NULL, NULL, 0 },
1101 /* 0x17 */ { NULL, NULL, 0 },
1102 /* 0x18 */ { NULL, NULL, 0 },
1103 /* 0x19 */ { NULL, NULL, 0 },
1104 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1105 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1106 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1107 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1108 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1109 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1110 /* 0x20 */ { "SMBwritec", NULL,0},
1111 /* 0x21 */ { NULL, NULL, 0 },
1112 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1113 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1114 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1115 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1116 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1117 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1118 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1119 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1120 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1121 /* 0x2b */ { "SMBecho",reply_echo,0},
1122 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1123 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1124 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1125 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1126 /* 0x30 */ { NULL, NULL, 0 },
1127 /* 0x31 */ { NULL, NULL, 0 },
1128 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1129 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1130 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1131 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1132 /* 0x36 */ { NULL, NULL, 0 },
1133 /* 0x37 */ { NULL, NULL, 0 },
1134 /* 0x38 */ { NULL, NULL, 0 },
1135 /* 0x39 */ { NULL, NULL, 0 },
1136 /* 0x3a */ { NULL, NULL, 0 },
1137 /* 0x3b */ { NULL, NULL, 0 },
1138 /* 0x3c */ { NULL, NULL, 0 },
1139 /* 0x3d */ { NULL, NULL, 0 },
1140 /* 0x3e */ { NULL, NULL, 0 },
1141 /* 0x3f */ { NULL, NULL, 0 },
1142 /* 0x40 */ { NULL, NULL, 0 },
1143 /* 0x41 */ { NULL, NULL, 0 },
1144 /* 0x42 */ { NULL, NULL, 0 },
1145 /* 0x43 */ { NULL, NULL, 0 },
1146 /* 0x44 */ { NULL, NULL, 0 },
1147 /* 0x45 */ { NULL, NULL, 0 },
1148 /* 0x46 */ { NULL, NULL, 0 },
1149 /* 0x47 */ { NULL, NULL, 0 },
1150 /* 0x48 */ { NULL, NULL, 0 },
1151 /* 0x49 */ { NULL, NULL, 0 },
1152 /* 0x4a */ { NULL, NULL, 0 },
1153 /* 0x4b */ { NULL, NULL, 0 },
1154 /* 0x4c */ { NULL, NULL, 0 },
1155 /* 0x4d */ { NULL, NULL, 0 },
1156 /* 0x4e */ { NULL, NULL, 0 },
1157 /* 0x4f */ { NULL, NULL, 0 },
1158 /* 0x50 */ { NULL, NULL, 0 },
1159 /* 0x51 */ { NULL, NULL, 0 },
1160 /* 0x52 */ { NULL, NULL, 0 },
1161 /* 0x53 */ { NULL, NULL, 0 },
1162 /* 0x54 */ { NULL, NULL, 0 },
1163 /* 0x55 */ { NULL, NULL, 0 },
1164 /* 0x56 */ { NULL, NULL, 0 },
1165 /* 0x57 */ { NULL, NULL, 0 },
1166 /* 0x58 */ { NULL, NULL, 0 },
1167 /* 0x59 */ { NULL, NULL, 0 },
1168 /* 0x5a */ { NULL, NULL, 0 },
1169 /* 0x5b */ { NULL, NULL, 0 },
1170 /* 0x5c */ { NULL, NULL, 0 },
1171 /* 0x5d */ { NULL, NULL, 0 },
1172 /* 0x5e */ { NULL, NULL, 0 },
1173 /* 0x5f */ { NULL, NULL, 0 },
1174 /* 0x60 */ { NULL, NULL, 0 },
1175 /* 0x61 */ { NULL, NULL, 0 },
1176 /* 0x62 */ { NULL, NULL, 0 },
1177 /* 0x63 */ { NULL, NULL, 0 },
1178 /* 0x64 */ { NULL, NULL, 0 },
1179 /* 0x65 */ { NULL, NULL, 0 },
1180 /* 0x66 */ { NULL, NULL, 0 },
1181 /* 0x67 */ { NULL, NULL, 0 },
1182 /* 0x68 */ { NULL, NULL, 0 },
1183 /* 0x69 */ { NULL, NULL, 0 },
1184 /* 0x6a */ { NULL, NULL, 0 },
1185 /* 0x6b */ { NULL, NULL, 0 },
1186 /* 0x6c */ { NULL, NULL, 0 },
1187 /* 0x6d */ { NULL, NULL, 0 },
1188 /* 0x6e */ { NULL, NULL, 0 },
1189 /* 0x6f */ { NULL, NULL, 0 },
1190 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1191 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1192 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1193 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1194 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1195 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1196 /* 0x76 */ { NULL, NULL, 0 },
1197 /* 0x77 */ { NULL, NULL, 0 },
1198 /* 0x78 */ { NULL, NULL, 0 },
1199 /* 0x79 */ { NULL, NULL, 0 },
1200 /* 0x7a */ { NULL, NULL, 0 },
1201 /* 0x7b */ { NULL, NULL, 0 },
1202 /* 0x7c */ { NULL, NULL, 0 },
1203 /* 0x7d */ { NULL, NULL, 0 },
1204 /* 0x7e */ { NULL, NULL, 0 },
1205 /* 0x7f */ { NULL, NULL, 0 },
1206 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1207 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1208 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1209 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1210 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1211 /* 0x85 */ { NULL, NULL, 0 },
1212 /* 0x86 */ { NULL, NULL, 0 },
1213 /* 0x87 */ { NULL, NULL, 0 },
1214 /* 0x88 */ { NULL, NULL, 0 },
1215 /* 0x89 */ { NULL, NULL, 0 },
1216 /* 0x8a */ { NULL, NULL, 0 },
1217 /* 0x8b */ { NULL, NULL, 0 },
1218 /* 0x8c */ { NULL, NULL, 0 },
1219 /* 0x8d */ { NULL, NULL, 0 },
1220 /* 0x8e */ { NULL, NULL, 0 },
1221 /* 0x8f */ { NULL, NULL, 0 },
1222 /* 0x90 */ { NULL, NULL, 0 },
1223 /* 0x91 */ { NULL, NULL, 0 },
1224 /* 0x92 */ { NULL, NULL, 0 },
1225 /* 0x93 */ { NULL, NULL, 0 },
1226 /* 0x94 */ { NULL, NULL, 0 },
1227 /* 0x95 */ { NULL, NULL, 0 },
1228 /* 0x96 */ { NULL, NULL, 0 },
1229 /* 0x97 */ { NULL, NULL, 0 },
1230 /* 0x98 */ { NULL, NULL, 0 },
1231 /* 0x99 */ { NULL, NULL, 0 },
1232 /* 0x9a */ { NULL, NULL, 0 },
1233 /* 0x9b */ { NULL, NULL, 0 },
1234 /* 0x9c */ { NULL, NULL, 0 },
1235 /* 0x9d */ { NULL, NULL, 0 },
1236 /* 0x9e */ { NULL, NULL, 0 },
1237 /* 0x9f */ { NULL, NULL, 0 },
1238 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1239 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1240 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1241 /* 0xa3 */ { NULL, NULL, 0 },
1242 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1243 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1244 /* 0xa6 */ { NULL, NULL, 0 },
1245 /* 0xa7 */ { NULL, NULL, 0 },
1246 /* 0xa8 */ { NULL, NULL, 0 },
1247 /* 0xa9 */ { NULL, NULL, 0 },
1248 /* 0xaa */ { NULL, NULL, 0 },
1249 /* 0xab */ { NULL, NULL, 0 },
1250 /* 0xac */ { NULL, NULL, 0 },
1251 /* 0xad */ { NULL, NULL, 0 },
1252 /* 0xae */ { NULL, NULL, 0 },
1253 /* 0xaf */ { NULL, NULL, 0 },
1254 /* 0xb0 */ { NULL, NULL, 0 },
1255 /* 0xb1 */ { NULL, NULL, 0 },
1256 /* 0xb2 */ { NULL, NULL, 0 },
1257 /* 0xb3 */ { NULL, NULL, 0 },
1258 /* 0xb4 */ { NULL, NULL, 0 },
1259 /* 0xb5 */ { NULL, NULL, 0 },
1260 /* 0xb6 */ { NULL, NULL, 0 },
1261 /* 0xb7 */ { NULL, NULL, 0 },
1262 /* 0xb8 */ { NULL, NULL, 0 },
1263 /* 0xb9 */ { NULL, NULL, 0 },
1264 /* 0xba */ { NULL, NULL, 0 },
1265 /* 0xbb */ { NULL, NULL, 0 },
1266 /* 0xbc */ { NULL, NULL, 0 },
1267 /* 0xbd */ { NULL, NULL, 0 },
1268 /* 0xbe */ { NULL, NULL, 0 },
1269 /* 0xbf */ { NULL, NULL, 0 },
1270 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1271 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1272 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1273 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1274 /* 0xc4 */ { NULL, NULL, 0 },
1275 /* 0xc5 */ { NULL, NULL, 0 },
1276 /* 0xc6 */ { NULL, NULL, 0 },
1277 /* 0xc7 */ { NULL, NULL, 0 },
1278 /* 0xc8 */ { NULL, NULL, 0 },
1279 /* 0xc9 */ { NULL, NULL, 0 },
1280 /* 0xca */ { NULL, NULL, 0 },
1281 /* 0xcb */ { NULL, NULL, 0 },
1282 /* 0xcc */ { NULL, NULL, 0 },
1283 /* 0xcd */ { NULL, NULL, 0 },
1284 /* 0xce */ { NULL, NULL, 0 },
1285 /* 0xcf */ { NULL, NULL, 0 },
1286 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1287 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1288 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1289 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1290 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1291 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1292 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1293 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1294 /* 0xd8 */ { NULL, NULL, 0 },
1295 /* 0xd9 */ { NULL, NULL, 0 },
1296 /* 0xda */ { NULL, NULL, 0 },
1297 /* 0xdb */ { NULL, NULL, 0 },
1298 /* 0xdc */ { NULL, NULL, 0 },
1299 /* 0xdd */ { NULL, NULL, 0 },
1300 /* 0xde */ { NULL, NULL, 0 },
1301 /* 0xdf */ { NULL, NULL, 0 },
1302 /* 0xe0 */ { NULL, NULL, 0 },
1303 /* 0xe1 */ { NULL, NULL, 0 },
1304 /* 0xe2 */ { NULL, NULL, 0 },
1305 /* 0xe3 */ { NULL, NULL, 0 },
1306 /* 0xe4 */ { NULL, NULL, 0 },
1307 /* 0xe5 */ { NULL, NULL, 0 },
1308 /* 0xe6 */ { NULL, NULL, 0 },
1309 /* 0xe7 */ { NULL, NULL, 0 },
1310 /* 0xe8 */ { NULL, NULL, 0 },
1311 /* 0xe9 */ { NULL, NULL, 0 },
1312 /* 0xea */ { NULL, NULL, 0 },
1313 /* 0xeb */ { NULL, NULL, 0 },
1314 /* 0xec */ { NULL, NULL, 0 },
1315 /* 0xed */ { NULL, NULL, 0 },
1316 /* 0xee */ { NULL, NULL, 0 },
1317 /* 0xef */ { NULL, NULL, 0 },
1318 /* 0xf0 */ { NULL, NULL, 0 },
1319 /* 0xf1 */ { NULL, NULL, 0 },
1320 /* 0xf2 */ { NULL, NULL, 0 },
1321 /* 0xf3 */ { NULL, NULL, 0 },
1322 /* 0xf4 */ { NULL, NULL, 0 },
1323 /* 0xf5 */ { NULL, NULL, 0 },
1324 /* 0xf6 */ { NULL, NULL, 0 },
1325 /* 0xf7 */ { NULL, NULL, 0 },
1326 /* 0xf8 */ { NULL, NULL, 0 },
1327 /* 0xf9 */ { NULL, NULL, 0 },
1328 /* 0xfa */ { NULL, NULL, 0 },
1329 /* 0xfb */ { NULL, NULL, 0 },
1330 /* 0xfc */ { NULL, NULL, 0 },
1331 /* 0xfd */ { NULL, NULL, 0 },
1332 /* 0xfe */ { NULL, NULL, 0 },
1333 /* 0xff */ { NULL, NULL, 0 }
1337 /*******************************************************************
1338 allocate and initialize a reply packet
1339 ********************************************************************/
1341 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1342 const char *inbuf, char **outbuf, uint8_t num_words,
1346 * Protect against integer wrap
1348 if ((num_bytes > 0xffffff)
1349 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1351 if (asprintf(&msg, "num_bytes too large: %u",
1352 (unsigned)num_bytes) == -1) {
1353 msg = discard_const_p(char, "num_bytes too large");
1358 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1359 smb_size + num_words*2 + num_bytes);
1360 if (*outbuf == NULL) {
1364 construct_reply_common(req, inbuf, *outbuf);
1365 srv_set_message(*outbuf, num_words, num_bytes, false);
1367 * Zero out the word area, the caller has to take care of the bcc area
1370 if (num_words != 0) {
1371 memset(*outbuf + smb_vwv0, 0, num_words*2);
1377 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1380 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1382 smb_panic("could not allocate output buffer\n");
1384 req->outbuf = (uint8_t *)outbuf;
1388 /*******************************************************************
1389 Dump a packet to a file.
1390 ********************************************************************/
1392 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1396 if (DEBUGLEVEL < 50) {
1400 if (len < 4) len = smb_len(data)+4;
1401 for (i=1;i<100;i++) {
1402 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1403 type ? "req" : "resp") == -1) {
1406 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1407 if (fd != -1 || errno != EEXIST) break;
1410 ssize_t ret = write(fd, data, len);
1412 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1414 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1419 /****************************************************************************
1420 Prepare everything for calling the actual request function, and potentially
1421 call the request function via the "new" interface.
1423 Return False if the "legacy" function needs to be called, everything is
1426 Return True if we're done.
1428 I know this API sucks, but it is the one with the least code change I could
1430 ****************************************************************************/
1432 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1436 connection_struct *conn = NULL;
1437 struct smbd_server_connection *sconn = req->sconn;
1441 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1442 * so subtract 4 from it. */
1443 if (!valid_smb_header(req->inbuf)
1444 || (size < (smb_size - 4))) {
1445 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1446 smb_len(req->inbuf)));
1447 exit_server_cleanly("Non-SMB packet");
1450 if (smb_messages[type].fn == NULL) {
1451 DEBUG(0,("Unknown message type %d!\n",type));
1452 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1453 reply_unknown_new(req, type);
1457 flags = smb_messages[type].flags;
1459 /* In share mode security we must ignore the vuid. */
1460 session_tag = (lp_security() == SEC_SHARE)
1461 ? UID_FIELD_INVALID : req->vuid;
1464 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1465 (int)sys_getpid(), (unsigned long)conn));
1467 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1469 /* Ensure this value is replaced in the incoming packet. */
1470 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1473 * Ensure the correct username is in current_user_info. This is a
1474 * really ugly bugfix for problems with multiple session_setup_and_X's
1475 * being done and allowing %U and %G substitutions to work correctly.
1476 * There is a reason this code is done here, don't move it unless you
1477 * know what you're doing... :-).
1481 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1482 user_struct *vuser = NULL;
1484 sconn->smb1.sessions.last_session_tag = session_tag;
1485 if(session_tag != UID_FIELD_INVALID) {
1486 vuser = get_valid_user_struct(sconn, session_tag);
1488 set_current_user_info(
1489 vuser->session_info->sanitized_username,
1490 vuser->session_info->unix_name,
1491 vuser->session_info->info3->base.domain.string);
1496 /* Does this call need to be run as the connected user? */
1497 if (flags & AS_USER) {
1499 /* Does this call need a valid tree connection? */
1502 * Amazingly, the error code depends on the command
1505 if (type == SMBntcreateX) {
1506 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1508 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1513 if (!change_to_user(conn,session_tag)) {
1514 DEBUG(0, ("Error: Could not change to user. Removing "
1515 "deferred open, mid=%llu.\n",
1516 (unsigned long long)req->mid));
1517 reply_force_doserror(req, ERRSRV, ERRbaduid);
1521 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1523 /* Does it need write permission? */
1524 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1525 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1529 /* IPC services are limited */
1530 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1531 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1535 /* This call needs to be run as root */
1536 change_to_root_user();
1539 /* load service specific parameters */
1541 if (req->encrypted) {
1542 conn->encrypted_tid = true;
1543 /* encrypted required from now on. */
1544 conn->encrypt_level = Required;
1545 } else if (ENCRYPTION_REQUIRED(conn)) {
1546 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1547 exit_server_cleanly("encryption required "
1553 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1554 (flags & (AS_USER|DO_CHDIR)
1556 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1559 conn->num_smb_operations++;
1562 /* does this protocol need to be run as guest? */
1563 if ((flags & AS_GUEST)
1564 && (!change_to_guest() ||
1565 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1566 sconn->client_id.name,
1567 sconn->client_id.addr))) {
1568 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1572 smb_messages[type].fn(req);
1576 /****************************************************************************
1577 Construct a reply to the incoming packet.
1578 ****************************************************************************/
1580 static void construct_reply(struct smbd_server_connection *sconn,
1581 char *inbuf, int size, size_t unread_bytes,
1582 uint32_t seqnum, bool encrypted,
1583 struct smb_perfcount_data *deferred_pcd)
1585 connection_struct *conn;
1586 struct smb_request *req;
1588 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1589 smb_panic("could not allocate smb_request");
1592 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1593 encrypted, seqnum)) {
1594 exit_server_cleanly("Invalid SMB request");
1597 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1599 /* we popped this message off the queue - keep original perf data */
1601 req->pcd = *deferred_pcd;
1603 SMB_PERFCOUNT_START(&req->pcd);
1604 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1605 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1608 conn = switch_message(req->cmd, req, size);
1610 if (req->unread_bytes) {
1611 /* writeX failed. drain socket. */
1612 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1613 req->unread_bytes) {
1614 smb_panic("failed to drain pending bytes");
1616 req->unread_bytes = 0;
1624 if (req->outbuf == NULL) {
1628 if (CVAL(req->outbuf,0) == 0) {
1629 show_msg((char *)req->outbuf);
1632 if (!srv_send_smb(req->sconn,
1633 (char *)req->outbuf,
1634 true, req->seqnum+1,
1635 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1637 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1645 /****************************************************************************
1646 Process an smb from the client
1647 ****************************************************************************/
1648 static void process_smb(struct smbd_server_connection *sconn,
1649 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1650 uint32_t seqnum, bool encrypted,
1651 struct smb_perfcount_data *deferred_pcd)
1653 int msg_type = CVAL(inbuf,0);
1655 DO_PROFILE_INC(smb_count);
1657 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1659 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1660 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1662 if (msg_type != 0) {
1664 * NetBIOS session request, keepalive, etc.
1666 reply_special(sconn, (char *)inbuf, nread);
1670 if (sconn->using_smb2) {
1671 /* At this point we're not really using smb2,
1672 * we make the decision here.. */
1673 if (smbd_is_smb2_header(inbuf, nread)) {
1674 smbd_smb2_first_negprot(sconn, inbuf, nread);
1676 } else if (nread >= smb_size && valid_smb_header(inbuf)
1677 && CVAL(inbuf, smb_com) != 0x72) {
1678 /* This is a non-negprot SMB1 packet.
1679 Disable SMB2 from now on. */
1680 sconn->using_smb2 = false;
1684 show_msg((char *)inbuf);
1686 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1687 encrypted, deferred_pcd);
1691 sconn->smb1.num_requests++;
1693 /* The timeout_processing function isn't run nearly
1694 often enough to implement 'max log size' without
1695 overrunning the size of the file by many megabytes.
1696 This is especially true if we are running at debug
1697 level 10. Checking every 50 SMBs is a nice
1698 tradeoff of performance vs log file size overrun. */
1700 if ((sconn->smb1.num_requests % 50) == 0 &&
1701 need_to_check_log_size()) {
1702 change_to_root_user();
1707 /****************************************************************************
1708 Return a string containing the function name of a SMB command.
1709 ****************************************************************************/
1711 const char *smb_fn_name(int type)
1713 const char *unknown_name = "SMBunknown";
1715 if (smb_messages[type].name == NULL)
1716 return(unknown_name);
1718 return(smb_messages[type].name);
1721 /****************************************************************************
1722 Helper functions for contruct_reply.
1723 ****************************************************************************/
1725 void add_to_common_flags2(uint32 v)
1730 void remove_from_common_flags2(uint32 v)
1732 common_flags2 &= ~v;
1735 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1738 srv_set_message(outbuf,0,0,false);
1740 SCVAL(outbuf, smb_com, req->cmd);
1741 SIVAL(outbuf,smb_rcls,0);
1742 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1743 SSVAL(outbuf,smb_flg2,
1744 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1746 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1748 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1749 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1750 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1751 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1754 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1756 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1760 * How many bytes have we already accumulated up to the current wct field
1764 size_t req_wct_ofs(struct smb_request *req)
1768 if (req->chain_outbuf == NULL) {
1771 buf_size = talloc_get_size(req->chain_outbuf);
1772 if ((buf_size % 4) != 0) {
1773 buf_size += (4 - (buf_size % 4));
1775 return buf_size - 4;
1779 * Hack around reply_nterror & friends not being aware of chained requests,
1780 * generating illegal (i.e. wct==0) chain replies.
1783 static void fixup_chain_error_packet(struct smb_request *req)
1785 uint8_t *outbuf = req->outbuf;
1787 reply_outbuf(req, 2, 0);
1788 memcpy(req->outbuf, outbuf, smb_wct);
1789 TALLOC_FREE(outbuf);
1790 SCVAL(req->outbuf, smb_vwv0, 0xff);
1794 * @brief Find the smb_cmd offset of the last command pushed
1795 * @param[in] buf The buffer we're building up
1796 * @retval Where can we put our next andx cmd?
1798 * While chaining requests, the "next" request we're looking at needs to put
1799 * its SMB_Command before the data the previous request already built up added
1800 * to the chain. Find the offset to the place where we have to put our cmd.
1803 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1808 cmd = CVAL(buf, smb_com);
1810 SMB_ASSERT(is_andx_req(cmd));
1814 while (CVAL(buf, ofs) != 0xff) {
1816 if (!is_andx_req(CVAL(buf, ofs))) {
1821 * ofs is from start of smb header, so add the 4 length
1822 * bytes. The next cmd is right after the wct field.
1824 ofs = SVAL(buf, ofs+2) + 4 + 1;
1826 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1834 * @brief Do the smb chaining at a buffer level
1835 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1836 * @param[in] smb_command The command that we want to issue
1837 * @param[in] wct How many words?
1838 * @param[in] vwv The words, already in network order
1839 * @param[in] bytes_alignment How shall we align "bytes"?
1840 * @param[in] num_bytes How many bytes?
1841 * @param[in] bytes The data the request ships
1843 * smb_splice_chain() adds the vwv and bytes to the request already present in
1847 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1848 uint8_t wct, const uint16_t *vwv,
1849 size_t bytes_alignment,
1850 uint32_t num_bytes, const uint8_t *bytes)
1853 size_t old_size, new_size;
1855 size_t chain_padding = 0;
1856 size_t bytes_padding = 0;
1859 old_size = talloc_get_size(*poutbuf);
1862 * old_size == smb_wct means we're pushing the first request in for
1866 first_request = (old_size == smb_wct);
1868 if (!first_request && ((old_size % 4) != 0)) {
1870 * Align the wct field of subsequent requests to a 4-byte
1873 chain_padding = 4 - (old_size % 4);
1877 * After the old request comes the new wct field (1 byte), the vwv's
1878 * and the num_bytes field. After at we might need to align the bytes
1879 * given to us to "bytes_alignment", increasing the num_bytes value.
1882 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1884 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1885 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1888 new_size += bytes_padding + num_bytes;
1890 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1891 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1892 (unsigned)new_size));
1896 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1897 if (outbuf == NULL) {
1898 DEBUG(0, ("talloc failed\n"));
1903 if (first_request) {
1904 SCVAL(outbuf, smb_com, smb_command);
1906 size_t andx_cmd_ofs;
1908 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1909 DEBUG(1, ("invalid command chain\n"));
1910 *poutbuf = TALLOC_REALLOC_ARRAY(
1911 NULL, *poutbuf, uint8_t, old_size);
1915 if (chain_padding != 0) {
1916 memset(outbuf + old_size, 0, chain_padding);
1917 old_size += chain_padding;
1920 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1921 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1927 * Push the chained request:
1932 SCVAL(outbuf, ofs, wct);
1939 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1940 ofs += sizeof(uint16_t) * wct;
1946 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1947 ofs += sizeof(uint16_t);
1953 if (bytes_padding != 0) {
1954 memset(outbuf + ofs, 0, bytes_padding);
1955 ofs += bytes_padding;
1962 memcpy(outbuf + ofs, bytes, num_bytes);
1967 /****************************************************************************
1968 Construct a chained reply and add it to the already made reply
1969 ****************************************************************************/
1971 void chain_reply(struct smb_request *req)
1973 size_t smblen = smb_len(req->inbuf);
1974 size_t already_used, length_needed;
1976 uint32_t chain_offset; /* uint32_t to avoid overflow */
1979 const uint16_t *vwv;
1983 if (IVAL(req->outbuf, smb_rcls) != 0) {
1984 fixup_chain_error_packet(req);
1988 * Any of the AndX requests and replies have at least a wct of
1989 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1990 * beginning of the SMB header to the next wct field.
1992 * None of the AndX requests put anything valuable in vwv[0] and [1],
1993 * so we can overwrite it here to form the chain.
1996 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1997 if (req->chain_outbuf == NULL) {
1998 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1999 req, req->outbuf, uint8_t,
2000 smb_len(req->outbuf) + 4);
2001 if (req->chain_outbuf == NULL) {
2002 smb_panic("talloc failed");
2010 * Here we assume that this is the end of the chain. For that we need
2011 * to set "next command" to 0xff and the offset to 0. If we later find
2012 * more commands in the chain, this will be overwritten again.
2015 SCVAL(req->outbuf, smb_vwv0, 0xff);
2016 SCVAL(req->outbuf, smb_vwv0+1, 0);
2017 SSVAL(req->outbuf, smb_vwv1, 0);
2019 if (req->chain_outbuf == NULL) {
2021 * In req->chain_outbuf we collect all the replies. Start the
2022 * chain by copying in the first reply.
2024 * We do the realloc because later on we depend on
2025 * talloc_get_size to determine the length of
2026 * chain_outbuf. The reply_xxx routines might have
2027 * over-allocated (reply_pipe_read_and_X used to be such an
2030 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2031 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2032 if (req->chain_outbuf == NULL) {
2033 smb_panic("talloc failed");
2038 * Update smb headers where subsequent chained commands
2039 * may have updated them.
2041 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2042 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2044 if (!smb_splice_chain(&req->chain_outbuf,
2045 CVAL(req->outbuf, smb_com),
2046 CVAL(req->outbuf, smb_wct),
2047 (uint16_t *)(req->outbuf + smb_vwv),
2048 0, smb_buflen(req->outbuf),
2049 (uint8_t *)smb_buf(req->outbuf))) {
2052 TALLOC_FREE(req->outbuf);
2056 * We use the old request's vwv field to grab the next chained command
2057 * and offset into the chained fields.
2060 chain_cmd = CVAL(req->vwv+0, 0);
2061 chain_offset = SVAL(req->vwv+1, 0);
2063 if (chain_cmd == 0xff) {
2065 * End of chain, no more requests from the client. So ship the
2068 smb_setlen((char *)(req->chain_outbuf),
2069 talloc_get_size(req->chain_outbuf) - 4);
2071 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2072 true, req->seqnum+1,
2073 IS_CONN_ENCRYPTED(req->conn)
2076 exit_server_cleanly("chain_reply: srv_send_smb "
2079 TALLOC_FREE(req->chain_outbuf);
2084 /* add a new perfcounter for this element of chain */
2085 SMB_PERFCOUNT_ADD(&req->pcd);
2086 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2087 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2090 * Check if the client tries to fool us. The request so far uses the
2091 * space to the end of the byte buffer in the request just
2092 * processed. The chain_offset can't point into that area. If that was
2093 * the case, we could end up with an endless processing of the chain,
2094 * we would always handle the same request.
2097 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2098 if (chain_offset < already_used) {
2103 * Next check: Make sure the chain offset does not point beyond the
2104 * overall smb request length.
2107 length_needed = chain_offset+1; /* wct */
2108 if (length_needed > smblen) {
2113 * Now comes the pointer magic. Goal here is to set up req->vwv and
2114 * req->buf correctly again to be able to call the subsequent
2115 * switch_message(). The chain offset (the former vwv[1]) points at
2116 * the new wct field.
2119 wct = CVAL(smb_base(req->inbuf), chain_offset);
2122 * Next consistency check: Make the new vwv array fits in the overall
2126 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2127 if (length_needed > smblen) {
2130 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2133 * Now grab the new byte buffer....
2136 buflen = SVAL(vwv+wct, 0);
2139 * .. and check that it fits.
2142 length_needed += buflen;
2143 if (length_needed > smblen) {
2146 buf = (const uint8_t *)(vwv+wct+1);
2148 req->cmd = chain_cmd;
2150 req->vwv = discard_const_p(uint16_t, vwv);
2151 req->buflen = buflen;
2154 switch_message(chain_cmd, req, smblen);
2156 if (req->outbuf == NULL) {
2158 * This happens if the chained command has suspended itself or
2159 * if it has called srv_send_smb() itself.
2165 * We end up here if the chained command was not itself chained or
2166 * suspended, but for example a close() command. We now need to splice
2167 * the chained commands' outbuf into the already built up chain_outbuf
2168 * and ship the result.
2174 * We end up here if there's any error in the chain syntax. Report a
2175 * DOS error, just like Windows does.
2177 reply_force_doserror(req, ERRSRV, ERRerror);
2178 fixup_chain_error_packet(req);
2182 * This scary statement intends to set the
2183 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2184 * to the value req->outbuf carries
2186 SSVAL(req->chain_outbuf, smb_flg2,
2187 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2188 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2191 * Transfer the error codes from the subrequest to the main one
2193 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2194 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2196 if (!smb_splice_chain(&req->chain_outbuf,
2197 CVAL(req->outbuf, smb_com),
2198 CVAL(req->outbuf, smb_wct),
2199 (uint16_t *)(req->outbuf + smb_vwv),
2200 0, smb_buflen(req->outbuf),
2201 (uint8_t *)smb_buf(req->outbuf))) {
2202 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2204 TALLOC_FREE(req->outbuf);
2206 smb_setlen((char *)(req->chain_outbuf),
2207 talloc_get_size(req->chain_outbuf) - 4);
2209 show_msg((char *)(req->chain_outbuf));
2211 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2212 true, req->seqnum+1,
2213 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2215 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2217 TALLOC_FREE(req->chain_outbuf);
2221 /****************************************************************************
2222 Check if services need reloading.
2223 ****************************************************************************/
2225 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2228 if (last_smb_conf_reload_time == 0) {
2229 last_smb_conf_reload_time = t;
2232 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2233 reload_services(sconn->msg_ctx, sconn->sock, True);
2234 last_smb_conf_reload_time = t;
2238 static bool fd_is_readable(int fd)
2242 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2244 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2248 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2250 /* TODO: make write nonblocking */
2253 static void smbd_server_connection_read_handler(
2254 struct smbd_server_connection *conn, int fd)
2256 uint8_t *inbuf = NULL;
2257 size_t inbuf_len = 0;
2258 size_t unread_bytes = 0;
2259 bool encrypted = false;
2260 TALLOC_CTX *mem_ctx = talloc_tos();
2264 bool from_client = (conn->sock == fd);
2267 smbd_lock_socket(conn);
2269 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2270 DEBUG(10,("the echo listener was faster\n"));
2271 smbd_unlock_socket(conn);
2275 /* TODO: make this completely nonblocking */
2276 status = receive_smb_talloc(mem_ctx, conn, fd,
2277 (char **)(void *)&inbuf,
2281 &inbuf_len, &seqnum,
2282 false /* trusted channel */);
2283 smbd_unlock_socket(conn);
2285 /* TODO: make this completely nonblocking */
2286 status = receive_smb_talloc(mem_ctx, conn, fd,
2287 (char **)(void *)&inbuf,
2291 &inbuf_len, &seqnum,
2292 true /* trusted channel */);
2295 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2298 if (NT_STATUS_IS_ERR(status)) {
2299 exit_server_cleanly("failed to receive smb request");
2301 if (!NT_STATUS_IS_OK(status)) {
2306 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2307 seqnum, encrypted, NULL);
2310 static void smbd_server_connection_handler(struct event_context *ev,
2311 struct fd_event *fde,
2315 struct smbd_server_connection *conn = talloc_get_type(private_data,
2316 struct smbd_server_connection);
2318 if (flags & EVENT_FD_WRITE) {
2319 smbd_server_connection_write_handler(conn);
2322 if (flags & EVENT_FD_READ) {
2323 smbd_server_connection_read_handler(conn, conn->sock);
2328 static void smbd_server_echo_handler(struct event_context *ev,
2329 struct fd_event *fde,
2333 struct smbd_server_connection *conn = talloc_get_type(private_data,
2334 struct smbd_server_connection);
2336 if (flags & EVENT_FD_WRITE) {
2337 smbd_server_connection_write_handler(conn);
2340 if (flags & EVENT_FD_READ) {
2341 smbd_server_connection_read_handler(
2342 conn, conn->smb1.echo_handler.trusted_fd);
2347 /****************************************************************************
2348 received when we should release a specific IP
2349 ****************************************************************************/
2350 static void release_ip(const char *ip, void *priv)
2352 const char *addr = (const char *)priv;
2353 const char *p = addr;
2355 if (strncmp("::ffff:", addr, 7) == 0) {
2359 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2360 /* we can't afford to do a clean exit - that involves
2361 database writes, which would potentially mean we
2362 are still running after the failover has finished -
2363 we have to get rid of this process ID straight
2365 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2367 /* note we must exit with non-zero status so the unclean handler gets
2368 called in the parent, so that the brl database is tickled */
2373 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2374 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2376 struct smbd_server_connection *sconn = talloc_get_type_abort(
2377 private_data, struct smbd_server_connection);
2379 release_ip((char *)data->data, sconn->client_id.addr);
2382 #ifdef CLUSTER_SUPPORT
2383 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2384 struct sockaddr_storage *client)
2387 length = sizeof(*server);
2388 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2391 length = sizeof(*client);
2392 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2400 * Send keepalive packets to our client
2402 static bool keepalive_fn(const struct timeval *now, void *private_data)
2404 struct smbd_server_connection *sconn = smbd_server_conn;
2407 if (sconn->using_smb2) {
2408 /* Don't do keepalives on an SMB2 connection. */
2412 smbd_lock_socket(smbd_server_conn);
2413 ret = send_keepalive(sconn->sock);
2414 smbd_unlock_socket(smbd_server_conn);
2417 char addr[INET6_ADDRSTRLEN];
2419 * Try and give an error message saying what
2422 DEBUG(0, ("send_keepalive failed for client %s. "
2423 "Error %s - exiting\n",
2424 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2432 * Do the recurring check if we're idle
2434 static bool deadtime_fn(const struct timeval *now, void *private_data)
2436 struct smbd_server_connection *sconn =
2437 (struct smbd_server_connection *)private_data;
2439 if ((conn_num_open(sconn) == 0)
2440 || (conn_idle_all(sconn, now->tv_sec))) {
2441 DEBUG( 2, ( "Closing idle connection\n" ) );
2442 messaging_send(sconn->msg_ctx,
2443 messaging_server_id(sconn->msg_ctx),
2444 MSG_SHUTDOWN, &data_blob_null);
2452 * Do the recurring log file and smb.conf reload checks.
2455 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2457 struct smbd_server_connection *sconn = talloc_get_type_abort(
2458 private_data, struct smbd_server_connection);
2460 DEBUG(5, ("housekeeping\n"));
2462 change_to_root_user();
2464 /* update printer queue caches if necessary */
2465 update_monitored_printq_cache(sconn->msg_ctx);
2467 /* check if we need to reload services */
2468 check_reload(sconn, time_mono(NULL));
2470 /* Change machine password if neccessary. */
2471 attempt_machine_password_change();
2474 * Force a log file check.
2476 force_check_log_size();
2481 static int create_unlink_tmp(const char *dir)
2486 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2487 if (fname == NULL) {
2491 fd = mkstemp(fname);
2496 if (unlink(fname) == -1) {
2497 int sys_errno = errno;
2507 struct smbd_echo_state {
2508 struct tevent_context *ev;
2509 struct iovec *pending;
2510 struct smbd_server_connection *sconn;
2513 struct tevent_fd *parent_fde;
2515 struct tevent_fd *read_fde;
2516 struct tevent_req *write_req;
2519 static void smbd_echo_writer_done(struct tevent_req *req);
2521 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2525 if (state->write_req != NULL) {
2529 num_pending = talloc_array_length(state->pending);
2530 if (num_pending == 0) {
2534 state->write_req = writev_send(state, state->ev, NULL,
2535 state->parent_pipe, false,
2536 state->pending, num_pending);
2537 if (state->write_req == NULL) {
2538 DEBUG(1, ("writev_send failed\n"));
2542 talloc_steal(state->write_req, state->pending);
2543 state->pending = NULL;
2545 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2549 static void smbd_echo_writer_done(struct tevent_req *req)
2551 struct smbd_echo_state *state = tevent_req_callback_data(
2552 req, struct smbd_echo_state);
2556 written = writev_recv(req, &err);
2558 state->write_req = NULL;
2559 if (written == -1) {
2560 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2563 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2564 smbd_echo_activate_writer(state);
2567 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2570 struct smb_request req;
2571 uint16_t num_replies;
2576 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2577 DEBUG(10, ("Got netbios keepalive\n"));
2584 if (inbuf_len < smb_size) {
2585 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2588 if (!valid_smb_header(inbuf)) {
2589 DEBUG(10, ("Got invalid SMB header\n"));
2593 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2599 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2600 smb_messages[req.cmd].name
2601 ? smb_messages[req.cmd].name : "unknown"));
2603 if (req.cmd != SMBecho) {
2610 num_replies = SVAL(req.vwv+0, 0);
2611 if (num_replies != 1) {
2612 /* Not a Windows "Hey, you're still there?" request */
2616 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2618 DEBUG(10, ("create_outbuf failed\n"));
2621 req.outbuf = (uint8_t *)outbuf;
2623 SSVAL(req.outbuf, smb_vwv0, num_replies);
2625 if (req.buflen > 0) {
2626 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2629 out_len = smb_len(req.outbuf) + 4;
2631 ok = srv_send_smb(req.sconn,
2635 TALLOC_FREE(outbuf);
2643 static void smbd_echo_exit(struct tevent_context *ev,
2644 struct tevent_fd *fde, uint16_t flags,
2647 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2651 static void smbd_echo_reader(struct tevent_context *ev,
2652 struct tevent_fd *fde, uint16_t flags,
2655 struct smbd_echo_state *state = talloc_get_type_abort(
2656 private_data, struct smbd_echo_state);
2657 struct smbd_server_connection *sconn = state->sconn;
2658 size_t unread, num_pending;
2662 uint32_t seqnum = 0;
2665 bool encrypted = false;
2669 ok = smbd_lock_socket_internal(sconn);
2671 DEBUG(0, ("%s: failed to lock socket\n",
2676 if (!fd_is_readable(sconn->sock)) {
2677 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2678 (int)sys_getpid()));
2679 ok = smbd_unlock_socket_internal(sconn);
2681 DEBUG(1, ("%s: failed to unlock socket in\n",
2688 num_pending = talloc_array_length(state->pending);
2689 tmp = talloc_realloc(state, state->pending, struct iovec,
2692 DEBUG(1, ("talloc_realloc failed\n"));
2695 state->pending = tmp;
2697 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2699 status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2700 (char **)(void *)&state->pending[num_pending].iov_base,
2706 false /* trusted_channel*/);
2707 if (!NT_STATUS_IS_OK(status)) {
2708 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2709 (int)sys_getpid(), nt_errstr(status)));
2712 state->pending[num_pending].iov_len = iov_len;
2714 ok = smbd_unlock_socket_internal(sconn);
2716 DEBUG(1, ("%s: failed to unlock socket in\n",
2721 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2722 state->pending[num_pending].iov_len,
2725 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2726 /* no check, shrinking by some bytes does not fail */
2727 state->pending = talloc_realloc(state, state->pending,
2733 if (state->pending[num_pending].iov_len >= smb_size) {
2735 * place the seqnum in the packet so that the main process
2736 * can reply with signing
2738 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2739 smb_ss_field, seqnum);
2740 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2741 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2744 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2745 smbd_echo_activate_writer(state);
2748 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2751 struct smbd_echo_state *state;
2753 state = talloc_zero(sconn, struct smbd_echo_state);
2754 if (state == NULL) {
2755 DEBUG(1, ("talloc failed\n"));
2758 state->sconn = sconn;
2759 state->parent_pipe = parent_pipe;
2760 state->ev = s3_tevent_context_init(state);
2761 if (state->ev == NULL) {
2762 DEBUG(1, ("tevent_context_init failed\n"));
2766 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2767 TEVENT_FD_READ, smbd_echo_exit,
2769 if (state->parent_fde == NULL) {
2770 DEBUG(1, ("tevent_add_fd failed\n"));
2774 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2775 TEVENT_FD_READ, smbd_echo_reader,
2777 if (state->read_fde == NULL) {
2778 DEBUG(1, ("tevent_add_fd failed\n"));
2784 if (tevent_loop_once(state->ev) == -1) {
2785 DEBUG(1, ("tevent_loop_once failed: %s\n",
2794 * Handle SMBecho requests in a forked child process
2796 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2798 int listener_pipe[2];
2802 res = pipe(listener_pipe);
2804 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2807 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2808 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2809 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2817 close(listener_pipe[0]);
2818 set_blocking(listener_pipe[1], false);
2820 status = reinit_after_fork(sconn->msg_ctx,
2821 smbd_event_context(),
2822 procid_self(), false);
2823 if (!NT_STATUS_IS_OK(status)) {
2824 DEBUG(1, ("reinit_after_fork failed: %s\n",
2825 nt_errstr(status)));
2828 smbd_echo_loop(sconn, listener_pipe[1]);
2831 close(listener_pipe[1]);
2832 listener_pipe[1] = -1;
2833 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2835 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2838 * Without smb signing this is the same as the normal smbd
2839 * listener. This needs to change once signing comes in.
2841 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2843 sconn->smb1.echo_handler.trusted_fd,
2845 smbd_server_echo_handler,
2847 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2848 DEBUG(1, ("event_add_fd failed\n"));
2855 if (listener_pipe[0] != -1) {
2856 close(listener_pipe[0]);
2858 if (listener_pipe[1] != -1) {
2859 close(listener_pipe[1]);
2861 sconn->smb1.echo_handler.trusted_fd = -1;
2862 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2863 close(sconn->smb1.echo_handler.socket_lock_fd);
2865 sconn->smb1.echo_handler.trusted_fd = -1;
2866 sconn->smb1.echo_handler.socket_lock_fd = -1;
2872 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2873 struct sockaddr_storage *srv,
2874 struct sockaddr_storage *clnt)
2876 struct ctdbd_connection *cconn;
2877 char tmp_addr[INET6_ADDRSTRLEN];
2880 cconn = messaging_ctdbd_connection();
2881 if (cconn == NULL) {
2882 return NT_STATUS_NO_MEMORY;
2885 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2886 addr = talloc_strdup(cconn, tmp_addr);
2888 return NT_STATUS_NO_MEMORY;
2890 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2895 /****************************************************************************
2896 Process commands from the client
2897 ****************************************************************************/
2899 void smbd_process(struct smbd_server_connection *sconn)
2901 TALLOC_CTX *frame = talloc_stackframe();
2902 struct sockaddr_storage ss;
2903 struct sockaddr *sa = NULL;
2904 socklen_t sa_socklen;
2905 struct tsocket_address *local_address = NULL;
2906 struct tsocket_address *remote_address = NULL;
2907 const char *remaddr = NULL;
2910 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2911 !lp_async_smb_echo_handler()) {
2913 * We're not making the decision here,
2914 * we're just allowing the client
2915 * to decide between SMB1 and SMB2
2916 * with the first negprot
2919 sconn->using_smb2 = true;
2922 /* Ensure child is set to blocking mode */
2923 set_blocking(sconn->sock,True);
2925 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2926 set_socket_options(sconn->sock, lp_socket_options());
2928 sa = (struct sockaddr *)(void *)&ss;
2929 sa_socklen = sizeof(ss);
2930 ret = getpeername(sconn->sock, sa, &sa_socklen);
2932 int level = (errno == ENOTCONN)?2:0;
2933 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2934 exit_server_cleanly("getpeername() failed.\n");
2936 ret = tsocket_address_bsd_from_sockaddr(sconn,
2940 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2941 __location__, strerror(errno)));
2942 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2945 sa = (struct sockaddr *)(void *)&ss;
2946 sa_socklen = sizeof(ss);
2947 ret = getsockname(sconn->sock, sa, &sa_socklen);
2949 int level = (errno == ENOTCONN)?2:0;
2950 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2951 exit_server_cleanly("getsockname() failed.\n");
2953 ret = tsocket_address_bsd_from_sockaddr(sconn,
2957 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2958 __location__, strerror(errno)));
2959 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2962 sconn->local_address = local_address;
2963 sconn->remote_address = remote_address;
2965 if (tsocket_address_is_inet(remote_address, "ip")) {
2966 remaddr = tsocket_address_inet_addr_string(
2967 sconn->remote_address,
2969 if (remaddr == NULL) {
2973 remaddr = "0.0.0.0";
2976 /* this is needed so that we get decent entries
2977 in smbstatus for port 445 connects */
2978 set_remote_machine_name(remaddr, false);
2979 reload_services(sconn->msg_ctx, sconn->sock, true);
2982 * Before the first packet, check the global hosts allow/ hosts deny
2983 * parameters before doing any parsing of packets passed to us by the
2984 * client. This prevents attacks on our parsing code from hosts not in
2985 * the hosts allow list.
2988 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2989 sconn->client_id.name,
2990 sconn->client_id.addr)) {
2992 * send a negative session response "not listening on calling
2995 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2996 DEBUG( 1, ("Connection denied from %s to %s\n",
2997 tsocket_address_string(remote_address, talloc_tos()),
2998 tsocket_address_string(local_address, talloc_tos())));
2999 (void)srv_send_smb(sconn,(char *)buf, false,
3001 exit_server_cleanly("connection denied");
3004 DEBUG(10, ("Connection allowed from %s to %s\n",
3005 tsocket_address_string(remote_address, talloc_tos()),
3006 tsocket_address_string(local_address, talloc_tos())));
3010 smb_perfcount_init();
3012 if (!init_account_policy()) {
3013 exit_server("Could not open account policy tdb.\n");
3016 if (*lp_rootdir()) {
3017 if (chroot(lp_rootdir()) != 0) {
3018 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3019 exit_server("Failed to chroot()");
3021 if (chdir("/") == -1) {
3022 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3023 exit_server("Failed to chroot()");
3025 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3028 if (!srv_init_signing(sconn)) {
3029 exit_server("Failed to init smb_signing");
3032 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3033 exit_server("Failed to fork echo handler");
3037 if (!init_oplocks(sconn->msg_ctx))
3038 exit_server("Failed to init oplocks");
3040 /* register our message handlers */
3041 messaging_register(sconn->msg_ctx, NULL,
3042 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3043 messaging_register(sconn->msg_ctx, sconn,
3044 MSG_SMB_RELEASE_IP, msg_release_ip);
3045 messaging_register(sconn->msg_ctx, NULL,
3046 MSG_SMB_CLOSE_FILE, msg_close_file);
3049 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3050 * MSGs to all child processes
3052 messaging_deregister(sconn->msg_ctx,
3054 messaging_register(sconn->msg_ctx, NULL,
3055 MSG_DEBUG, debug_message);
3057 if ((lp_keepalive() != 0)
3058 && !(event_add_idle(smbd_event_context(), NULL,
3059 timeval_set(lp_keepalive(), 0),
3060 "keepalive", keepalive_fn,
3062 DEBUG(0, ("Could not add keepalive event\n"));
3066 if (!(event_add_idle(smbd_event_context(), NULL,
3067 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3068 "deadtime", deadtime_fn, sconn))) {
3069 DEBUG(0, ("Could not add deadtime event\n"));
3073 if (!(event_add_idle(smbd_event_context(), NULL,
3074 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3075 "housekeeping", housekeeping_fn, sconn))) {
3076 DEBUG(0, ("Could not add housekeeping event\n"));
3080 #ifdef CLUSTER_SUPPORT
3082 if (lp_clustering()) {
3084 * We need to tell ctdb about our client's TCP
3085 * connection, so that for failover ctdbd can send
3086 * tickle acks, triggering a reconnection by the
3090 struct sockaddr_storage srv, clnt;
3092 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3094 status = smbd_register_ips(sconn, &srv, &clnt);
3095 if (!NT_STATUS_IS_OK(status)) {
3096 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3097 nt_errstr(status)));
3101 DEBUG(0,("Unable to get tcp info for "
3102 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3109 sconn->nbt.got_session = false;
3111 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3113 sconn->smb1.sessions.done_sesssetup = false;
3114 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3115 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3116 /* users from session setup */
3117 sconn->smb1.sessions.session_userlist = NULL;
3118 /* workgroup from session setup. */
3119 sconn->smb1.sessions.session_workgroup = NULL;
3120 /* this holds info on user ids that are already validated for this VC */
3121 sconn->smb1.sessions.validated_users = NULL;
3122 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3123 sconn->smb1.sessions.num_validated_vuids = 0;
3126 if (!init_dptrs(sconn)) {
3127 exit_server("init_dptrs() failed");
3130 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3134 smbd_server_connection_handler,
3136 if (!sconn->smb1.fde) {
3137 exit_server("failed to create smbd_server_connection fde");
3145 frame = talloc_stackframe_pool(8192);
3149 status = smbd_server_connection_loop_once(sconn);
3150 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3151 !NT_STATUS_IS_OK(status)) {
3152 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3153 " exiting\n", nt_errstr(status)));
3160 exit_server_cleanly(NULL);
3163 bool req_is_in_chain(struct smb_request *req)
3165 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3167 * We're right now handling a subsequent request, so we must
3173 if (!is_andx_req(req->cmd)) {
3179 * Okay, an illegal request, but definitely not chained :-)
3184 return (CVAL(req->vwv+0, 0) != 0xFF);