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 "smbd/globals.h"
23 #include "librpc/gen_ndr/netlogon.h"
24 #include "librpc/gen_ndr/messaging.h"
26 extern bool global_machine_password_needs_changing;
28 static void construct_reply_common(struct smb_request *req, const char *inbuf,
30 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
32 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
36 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
40 sconn->smb1.echo_handler.ref_count++;
42 if (sconn->smb1.echo_handler.ref_count > 1) {
46 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
48 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
49 SMB_F_SETLKW, 0, 0, F_WRLCK);
54 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
59 void smbd_lock_socket(struct smbd_server_connection *sconn)
61 if (!smbd_lock_socket_internal(sconn)) {
62 exit_server_cleanly("failed to lock socket");
66 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
70 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
74 sconn->smb1.echo_handler.ref_count--;
76 if (sconn->smb1.echo_handler.ref_count > 0) {
80 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
81 SMB_F_SETLKW, 0, 0, F_UNLCK);
86 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
91 void smbd_unlock_socket(struct smbd_server_connection *sconn)
93 if (!smbd_unlock_socket_internal(sconn)) {
94 exit_server_cleanly("failed to unlock socket");
98 /* Accessor function for smb_read_error for smbd functions. */
100 /****************************************************************************
102 ****************************************************************************/
104 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
105 bool do_signing, uint32_t seqnum,
107 struct smb_perfcount_data *pcd)
112 char *buf_out = buffer;
114 smbd_lock_socket(sconn);
117 /* Sign the outgoing packet if required. */
118 srv_calculate_sign_mac(sconn, buf_out, seqnum);
122 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
123 if (!NT_STATUS_IS_OK(status)) {
124 DEBUG(0, ("send_smb: SMB encryption failed "
125 "on outgoing packet! Error %s\n",
126 nt_errstr(status) ));
131 len = smb_len(buf_out) + 4;
133 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
136 char addr[INET6_ADDRSTRLEN];
138 * Try and give an error message saying what
141 DEBUG(0,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
142 (int)sys_getpid(), (int)len,
143 get_peer_addr(sconn->sock, addr, sizeof(addr)),
144 (int)ret, strerror(errno) ));
146 srv_free_enc_buffer(buf_out);
150 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
151 srv_free_enc_buffer(buf_out);
153 SMB_PERFCOUNT_END(pcd);
155 smbd_unlock_socket(sconn);
159 /*******************************************************************
160 Setup the word count and byte count for a smb message.
161 ********************************************************************/
163 int srv_set_message(char *buf,
168 if (zero && (num_words || num_bytes)) {
169 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
171 SCVAL(buf,smb_wct,num_words);
172 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
173 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
174 return (smb_size + num_words*2 + num_bytes);
177 static bool valid_smb_header(const uint8_t *inbuf)
179 if (is_encrypted_packet(inbuf)) {
183 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
184 * but it just looks weird to call strncmp for this one.
186 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
189 /* Socket functions for smbd packet processing. */
191 static bool valid_packet_size(size_t len)
194 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
195 * of header. Don't print the error if this fits.... JRA.
198 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
199 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
200 (unsigned long)len));
206 static NTSTATUS read_packet_remainder(int fd, char *buffer,
207 unsigned int timeout, ssize_t len)
215 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
216 if (!NT_STATUS_IS_OK(status)) {
217 char addr[INET6_ADDRSTRLEN];
218 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
220 get_peer_addr(fd, addr, sizeof(addr)),
226 /****************************************************************************
227 Attempt a zerocopy writeX read. We know here that len > smb_size-4
228 ****************************************************************************/
231 * Unfortunately, earlier versions of smbclient/libsmbclient
232 * don't send this "standard" writeX header. I've fixed this
233 * for 3.2 but we'll use the old method with earlier versions.
234 * Windows and CIFSFS at least use this standard size. Not
238 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
239 (2*14) + /* word count (including bcc) */ \
242 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
243 const char lenbuf[4],
244 int fd, char **buffer,
245 unsigned int timeout,
249 /* Size of a WRITEX call (+4 byte len). */
250 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
251 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
255 memcpy(writeX_header, lenbuf, 4);
257 status = read_fd_with_timeout(
258 fd, writeX_header + 4,
259 STANDARD_WRITE_AND_X_HEADER_SIZE,
260 STANDARD_WRITE_AND_X_HEADER_SIZE,
263 if (!NT_STATUS_IS_OK(status)) {
264 char addr[INET6_ADDRSTRLEN];
265 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
267 get_peer_addr(fd, addr, sizeof(addr)),
273 * Ok - now try and see if this is a possible
277 if (is_valid_writeX_buffer(smbd_server_conn,
278 (uint8_t *)writeX_header)) {
280 * If the data offset is beyond what
281 * we've read, drain the extra bytes.
283 uint16_t doff = SVAL(writeX_header,smb_vwv11);
286 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
287 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
288 if (drain_socket(fd, drain) != drain) {
289 smb_panic("receive_smb_raw_talloc_partial_read:"
290 " failed to drain pending bytes");
293 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
296 /* Spoof down the length and null out the bcc. */
297 set_message_bcc(writeX_header, 0);
298 newlen = smb_len(writeX_header);
300 /* Copy the header we've written. */
302 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
304 sizeof(writeX_header));
306 if (*buffer == NULL) {
307 DEBUG(0, ("Could not allocate inbuf of length %d\n",
308 (int)sizeof(writeX_header)));
309 return NT_STATUS_NO_MEMORY;
312 /* Work out the remaining bytes. */
313 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
314 *len_ret = newlen + 4;
318 if (!valid_packet_size(len)) {
319 return NT_STATUS_INVALID_PARAMETER;
323 * Not a valid writeX call. Just do the standard
327 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
329 if (*buffer == NULL) {
330 DEBUG(0, ("Could not allocate inbuf of length %d\n",
332 return NT_STATUS_NO_MEMORY;
335 /* Copy in what we already read. */
338 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
339 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
342 status = read_packet_remainder(
343 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
346 if (!NT_STATUS_IS_OK(status)) {
347 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
357 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
358 char **buffer, unsigned int timeout,
359 size_t *p_unread, size_t *plen)
363 int min_recv_size = lp_min_receive_file_size();
368 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
369 if (!NT_STATUS_IS_OK(status)) {
373 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
374 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
375 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
376 !srv_is_signing_active(smbd_server_conn) &&
377 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
379 return receive_smb_raw_talloc_partial_read(
380 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
383 if (!valid_packet_size(len)) {
384 return NT_STATUS_INVALID_PARAMETER;
388 * The +4 here can't wrap, we've checked the length above already.
391 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
393 if (*buffer == NULL) {
394 DEBUG(0, ("Could not allocate inbuf of length %d\n",
396 return NT_STATUS_NO_MEMORY;
399 memcpy(*buffer, lenbuf, sizeof(lenbuf));
401 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
402 if (!NT_STATUS_IS_OK(status)) {
410 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
411 char **buffer, unsigned int timeout,
412 size_t *p_unread, bool *p_encrypted,
415 bool trusted_channel)
420 *p_encrypted = false;
422 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
424 if (!NT_STATUS_IS_OK(status)) {
425 char addr[INET6_ADDRSTRLEN];
426 DEBUG(0, ("read_smb_length_return_keepalive failed for "
427 "client %s read error = %s.\n",
428 get_peer_addr(fd, addr, sizeof(addr)),
433 if (is_encrypted_packet((uint8_t *)*buffer)) {
434 status = srv_decrypt_buffer(*buffer);
435 if (!NT_STATUS_IS_OK(status)) {
436 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
437 "incoming packet! Error %s\n",
438 nt_errstr(status) ));
444 /* Check the incoming SMB signature. */
445 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
446 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
447 "incoming packet!\n"));
448 return NT_STATUS_INVALID_NETWORK_RESPONSE;
456 * Initialize a struct smb_request from an inbuf
459 static bool init_smb_request(struct smb_request *req,
460 struct smbd_server_connection *sconn,
462 size_t unread_bytes, bool encrypted,
465 size_t req_size = smb_len(inbuf) + 4;
466 /* Ensure we have at least smb_size bytes. */
467 if (req_size < smb_size) {
468 DEBUG(0,("init_smb_request: invalid request size %u\n",
469 (unsigned int)req_size ));
472 req->cmd = CVAL(inbuf, smb_com);
473 req->flags2 = SVAL(inbuf, smb_flg2);
474 req->smbpid = SVAL(inbuf, smb_pid);
475 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
476 req->seqnum = seqnum;
477 req->vuid = SVAL(inbuf, smb_uid);
478 req->tid = SVAL(inbuf, smb_tid);
479 req->wct = CVAL(inbuf, smb_wct);
480 req->vwv = (uint16_t *)(inbuf+smb_vwv);
481 req->buflen = smb_buflen(inbuf);
482 req->buf = (const uint8_t *)smb_buf(inbuf);
483 req->unread_bytes = unread_bytes;
484 req->encrypted = encrypted;
486 req->conn = conn_find(sconn,req->tid);
487 req->chain_fsp = NULL;
488 req->chain_outbuf = NULL;
491 smb_init_perfcount_data(&req->pcd);
493 /* Ensure we have at least wct words and 2 bytes of bcc. */
494 if (smb_size + req->wct*2 > req_size) {
495 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
496 (unsigned int)req->wct,
497 (unsigned int)req_size));
500 /* Ensure bcc is correct. */
501 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
502 DEBUG(0,("init_smb_request: invalid bcc number %u "
503 "(wct = %u, size %u)\n",
504 (unsigned int)req->buflen,
505 (unsigned int)req->wct,
506 (unsigned int)req_size));
514 static void process_smb(struct smbd_server_connection *conn,
515 uint8_t *inbuf, size_t nread, size_t unread_bytes,
516 uint32_t seqnum, bool encrypted,
517 struct smb_perfcount_data *deferred_pcd);
519 static void smbd_deferred_open_timer(struct event_context *ev,
520 struct timed_event *te,
521 struct timeval _tval,
524 struct pending_message_list *msg = talloc_get_type(private_data,
525 struct pending_message_list);
526 TALLOC_CTX *mem_ctx = talloc_tos();
527 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
530 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
533 exit_server("smbd_deferred_open_timer: talloc failed\n");
537 /* We leave this message on the queue so the open code can
538 know this is a retry. */
539 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
540 (unsigned long long)mid ));
542 /* Mark the message as processed so this is not
543 * re-processed in error. */
544 msg->processed = true;
546 process_smb(smbd_server_conn, inbuf,
548 msg->seqnum, msg->encrypted, &msg->pcd);
550 /* If it's still there and was processed, remove it. */
551 msg = get_deferred_open_message_smb(mid);
552 if (msg && msg->processed) {
553 remove_deferred_open_message_smb(mid);
557 /****************************************************************************
558 Function to push a message onto the tail of a linked list of smb messages ready
560 ****************************************************************************/
562 static bool push_queued_message(struct smb_request *req,
563 struct timeval request_time,
564 struct timeval end_time,
565 char *private_data, size_t private_len)
567 int msg_len = smb_len(req->inbuf) + 4;
568 struct pending_message_list *msg;
570 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
573 DEBUG(0,("push_message: malloc fail (1)\n"));
577 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
578 if(msg->buf.data == NULL) {
579 DEBUG(0,("push_message: malloc fail (2)\n"));
584 msg->request_time = request_time;
585 msg->seqnum = req->seqnum;
586 msg->encrypted = req->encrypted;
587 msg->processed = false;
588 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
591 msg->private_data = data_blob_talloc(msg, private_data,
593 if (msg->private_data.data == NULL) {
594 DEBUG(0,("push_message: malloc fail (3)\n"));
600 msg->te = event_add_timed(smbd_event_context(),
603 smbd_deferred_open_timer,
606 DEBUG(0,("push_message: event_add_timed failed\n"));
611 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
613 DEBUG(10,("push_message: pushed message length %u on "
614 "deferred_open_queue\n", (unsigned int)msg_len));
619 /****************************************************************************
620 Function to delete a sharing violation open message by mid.
621 ****************************************************************************/
623 void remove_deferred_open_message_smb(uint64_t mid)
625 struct pending_message_list *pml;
627 if (smbd_server_conn->using_smb2) {
628 remove_deferred_open_message_smb2(smbd_server_conn, mid);
632 for (pml = deferred_open_queue; pml; pml = pml->next) {
633 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
634 DEBUG(10,("remove_deferred_open_message_smb: "
635 "deleting mid %llu len %u\n",
636 (unsigned long long)mid,
637 (unsigned int)pml->buf.length ));
638 DLIST_REMOVE(deferred_open_queue, pml);
645 /****************************************************************************
646 Move a sharing violation open retry message to the front of the list and
647 schedule it for immediate processing.
648 ****************************************************************************/
650 void schedule_deferred_open_message_smb(uint64_t mid)
652 struct pending_message_list *pml;
655 if (smbd_server_conn->using_smb2) {
656 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
660 for (pml = deferred_open_queue; pml; pml = pml->next) {
661 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
663 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
666 (unsigned long long)msg_mid ));
668 if (mid == msg_mid) {
669 struct timed_event *te;
671 if (pml->processed) {
672 /* A processed message should not be
674 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
675 "message mid %llu was already processed\n",
676 (unsigned long long)msg_mid ));
680 DEBUG(10,("schedule_deferred_open_message_smb: "
681 "scheduling mid %llu\n",
682 (unsigned long long)mid ));
684 te = event_add_timed(smbd_event_context(),
687 smbd_deferred_open_timer,
690 DEBUG(10,("schedule_deferred_open_message_smb: "
691 "event_add_timed() failed, "
692 "skipping mid %llu\n",
693 (unsigned long long)msg_mid ));
696 TALLOC_FREE(pml->te);
698 DLIST_PROMOTE(deferred_open_queue, pml);
703 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
704 "find message mid %llu\n",
705 (unsigned long long)mid ));
708 /****************************************************************************
709 Return true if this mid is on the deferred queue and was not yet processed.
710 ****************************************************************************/
712 bool open_was_deferred(uint64_t mid)
714 struct pending_message_list *pml;
716 if (smbd_server_conn->using_smb2) {
717 return open_was_deferred_smb2(smbd_server_conn, mid);
720 for (pml = deferred_open_queue; pml; pml = pml->next) {
721 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
728 /****************************************************************************
729 Return the message queued by this mid.
730 ****************************************************************************/
732 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
734 struct pending_message_list *pml;
736 for (pml = deferred_open_queue; pml; pml = pml->next) {
737 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
744 /****************************************************************************
745 Get the state data queued by this mid.
746 ****************************************************************************/
748 bool get_deferred_open_message_state(struct smb_request *smbreq,
749 struct timeval *p_request_time,
752 struct pending_message_list *pml;
754 if (smbd_server_conn->using_smb2) {
755 return get_deferred_open_message_state_smb2(smbreq->smb2req,
760 pml = get_deferred_open_message_smb(smbreq->mid);
764 if (p_request_time) {
765 *p_request_time = pml->request_time;
768 *pp_state = (void *)pml->private_data.data;
773 /****************************************************************************
774 Function to push a deferred open smb message onto a linked list of local smb
775 messages ready for processing.
776 ****************************************************************************/
778 bool push_deferred_open_message_smb(struct smb_request *req,
779 struct timeval request_time,
780 struct timeval timeout,
782 char *private_data, size_t priv_len)
784 struct timeval end_time;
787 return push_deferred_open_message_smb2(req->smb2req,
795 if (req->unread_bytes) {
796 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
797 "unread_bytes = %u\n",
798 (unsigned int)req->unread_bytes ));
799 smb_panic("push_deferred_open_message_smb: "
800 "logic error unread_bytes != 0" );
803 end_time = timeval_sum(&request_time, &timeout);
805 DEBUG(10,("push_deferred_open_message_smb: pushing message "
806 "len %u mid %llu timeout time [%u.%06u]\n",
807 (unsigned int) smb_len(req->inbuf)+4,
808 (unsigned long long)req->mid,
809 (unsigned int)end_time.tv_sec,
810 (unsigned int)end_time.tv_usec));
812 return push_queued_message(req, request_time, end_time,
813 private_data, priv_len);
817 struct timed_event *te;
818 struct timeval interval;
820 bool (*handler)(const struct timeval *now, void *private_data);
824 static void smbd_idle_event_handler(struct event_context *ctx,
825 struct timed_event *te,
829 struct idle_event *event =
830 talloc_get_type_abort(private_data, struct idle_event);
832 TALLOC_FREE(event->te);
834 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
835 event->name, event->te));
837 if (!event->handler(&now, event->private_data)) {
838 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
839 event->name, event->te));
840 /* Don't repeat, delete ourselves */
845 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
846 event->name, event->te));
848 event->te = event_add_timed(ctx, event,
849 timeval_sum(&now, &event->interval),
850 smbd_idle_event_handler, event);
852 /* We can't do much but fail here. */
853 SMB_ASSERT(event->te != NULL);
856 struct idle_event *event_add_idle(struct event_context *event_ctx,
858 struct timeval interval,
860 bool (*handler)(const struct timeval *now,
864 struct idle_event *result;
865 struct timeval now = timeval_current();
867 result = TALLOC_P(mem_ctx, struct idle_event);
868 if (result == NULL) {
869 DEBUG(0, ("talloc failed\n"));
873 result->interval = interval;
874 result->handler = handler;
875 result->private_data = private_data;
877 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
878 DEBUG(0, ("talloc failed\n"));
883 result->te = event_add_timed(event_ctx, result,
884 timeval_sum(&now, &interval),
885 smbd_idle_event_handler, result);
886 if (result->te == NULL) {
887 DEBUG(0, ("event_add_timed failed\n"));
892 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
896 static void smbd_sig_term_handler(struct tevent_context *ev,
897 struct tevent_signal *se,
903 exit_server_cleanly("termination signal");
906 void smbd_setup_sig_term_handler(void)
908 struct tevent_signal *se;
910 se = tevent_add_signal(smbd_event_context(),
911 smbd_event_context(),
913 smbd_sig_term_handler,
916 exit_server("failed to setup SIGTERM handler");
920 static void smbd_sig_hup_handler(struct tevent_context *ev,
921 struct tevent_signal *se,
927 struct messaging_context *msg_ctx = talloc_get_type_abort(
928 private_data, struct messaging_context);
929 change_to_root_user();
930 DEBUG(1,("Reloading services after SIGHUP\n"));
931 reload_services(msg_ctx, smbd_server_fd(), False);
934 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
935 struct messaging_context *msg_ctx)
937 struct tevent_signal *se;
939 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
942 exit_server("failed to setup SIGHUP handler");
946 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
953 to.tv_sec = SMBD_SELECT_TIMEOUT;
957 * Setup the select fd sets.
964 * Are there any timed events waiting ? If so, ensure we don't
965 * select for longer than it would take to wait for them.
972 event_add_to_select_args(smbd_event_context(), &now,
973 &r_fds, &w_fds, &to, &maxfd);
976 /* Process a signal and timed events now... */
977 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
978 return NT_STATUS_RETRY;
983 START_PROFILE(smbd_idle);
985 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
988 END_PROFILE(smbd_idle);
992 if ((conn->smb1.echo_handler.trusted_fd != -1)
993 && FD_ISSET(conn->sock, &r_fds)
994 && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
996 * Prefer to read pending requests from the echo handler. To
997 * quote Jeremy (da70f8ab1): This is a hack of monstrous
1000 FD_CLR(conn->sock, &r_fds);
1003 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
1004 return NT_STATUS_RETRY;
1007 /* Check if error */
1009 /* something is wrong. Maybe the socket is dead? */
1010 return map_nt_error_from_unix(errno);
1013 /* Did we timeout ? */
1015 return NT_STATUS_RETRY;
1018 /* should not be reached */
1019 return NT_STATUS_INTERNAL_ERROR;
1023 * Only allow 5 outstanding trans requests. We're allocating memory, so
1027 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1030 for (; list != NULL; list = list->next) {
1032 if (list->mid == mid) {
1033 return NT_STATUS_INVALID_PARAMETER;
1039 return NT_STATUS_INSUFFICIENT_RESOURCES;
1042 return NT_STATUS_OK;
1046 These flags determine some of the permissions required to do an operation
1048 Note that I don't set NEED_WRITE on some write operations because they
1049 are used by some brain-dead clients when printing, and I don't want to
1050 force write permissions on print services.
1052 #define AS_USER (1<<0)
1053 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1054 #define TIME_INIT (1<<2)
1055 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1056 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1057 #define DO_CHDIR (1<<6)
1060 define a list of possible SMB messages and their corresponding
1061 functions. Any message that has a NULL function is unimplemented -
1062 please feel free to contribute implementations!
1064 static const struct smb_message_struct {
1066 void (*fn)(struct smb_request *req);
1068 } smb_messages[256] = {
1070 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1071 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1072 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1073 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1074 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1075 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1076 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1077 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1078 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1079 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1080 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1081 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1082 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1083 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1084 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1085 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1086 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1087 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1088 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1089 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1090 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1091 /* 0x15 */ { NULL, NULL, 0 },
1092 /* 0x16 */ { NULL, NULL, 0 },
1093 /* 0x17 */ { NULL, NULL, 0 },
1094 /* 0x18 */ { NULL, NULL, 0 },
1095 /* 0x19 */ { NULL, NULL, 0 },
1096 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1097 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1098 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1099 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1100 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1101 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1102 /* 0x20 */ { "SMBwritec", NULL,0},
1103 /* 0x21 */ { NULL, NULL, 0 },
1104 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1105 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1106 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1107 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1108 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1109 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1110 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1111 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1112 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1113 /* 0x2b */ { "SMBecho",reply_echo,0},
1114 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1115 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1116 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1117 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1118 /* 0x30 */ { NULL, NULL, 0 },
1119 /* 0x31 */ { NULL, NULL, 0 },
1120 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1121 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1122 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1123 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1124 /* 0x36 */ { NULL, NULL, 0 },
1125 /* 0x37 */ { NULL, NULL, 0 },
1126 /* 0x38 */ { NULL, NULL, 0 },
1127 /* 0x39 */ { NULL, NULL, 0 },
1128 /* 0x3a */ { NULL, NULL, 0 },
1129 /* 0x3b */ { NULL, NULL, 0 },
1130 /* 0x3c */ { NULL, NULL, 0 },
1131 /* 0x3d */ { NULL, NULL, 0 },
1132 /* 0x3e */ { NULL, NULL, 0 },
1133 /* 0x3f */ { NULL, NULL, 0 },
1134 /* 0x40 */ { NULL, NULL, 0 },
1135 /* 0x41 */ { NULL, NULL, 0 },
1136 /* 0x42 */ { NULL, NULL, 0 },
1137 /* 0x43 */ { NULL, NULL, 0 },
1138 /* 0x44 */ { NULL, NULL, 0 },
1139 /* 0x45 */ { NULL, NULL, 0 },
1140 /* 0x46 */ { NULL, NULL, 0 },
1141 /* 0x47 */ { NULL, NULL, 0 },
1142 /* 0x48 */ { NULL, NULL, 0 },
1143 /* 0x49 */ { NULL, NULL, 0 },
1144 /* 0x4a */ { NULL, NULL, 0 },
1145 /* 0x4b */ { NULL, NULL, 0 },
1146 /* 0x4c */ { NULL, NULL, 0 },
1147 /* 0x4d */ { NULL, NULL, 0 },
1148 /* 0x4e */ { NULL, NULL, 0 },
1149 /* 0x4f */ { NULL, NULL, 0 },
1150 /* 0x50 */ { NULL, NULL, 0 },
1151 /* 0x51 */ { NULL, NULL, 0 },
1152 /* 0x52 */ { NULL, NULL, 0 },
1153 /* 0x53 */ { NULL, NULL, 0 },
1154 /* 0x54 */ { NULL, NULL, 0 },
1155 /* 0x55 */ { NULL, NULL, 0 },
1156 /* 0x56 */ { NULL, NULL, 0 },
1157 /* 0x57 */ { NULL, NULL, 0 },
1158 /* 0x58 */ { NULL, NULL, 0 },
1159 /* 0x59 */ { NULL, NULL, 0 },
1160 /* 0x5a */ { NULL, NULL, 0 },
1161 /* 0x5b */ { NULL, NULL, 0 },
1162 /* 0x5c */ { NULL, NULL, 0 },
1163 /* 0x5d */ { NULL, NULL, 0 },
1164 /* 0x5e */ { NULL, NULL, 0 },
1165 /* 0x5f */ { NULL, NULL, 0 },
1166 /* 0x60 */ { NULL, NULL, 0 },
1167 /* 0x61 */ { NULL, NULL, 0 },
1168 /* 0x62 */ { NULL, NULL, 0 },
1169 /* 0x63 */ { NULL, NULL, 0 },
1170 /* 0x64 */ { NULL, NULL, 0 },
1171 /* 0x65 */ { NULL, NULL, 0 },
1172 /* 0x66 */ { NULL, NULL, 0 },
1173 /* 0x67 */ { NULL, NULL, 0 },
1174 /* 0x68 */ { NULL, NULL, 0 },
1175 /* 0x69 */ { NULL, NULL, 0 },
1176 /* 0x6a */ { NULL, NULL, 0 },
1177 /* 0x6b */ { NULL, NULL, 0 },
1178 /* 0x6c */ { NULL, NULL, 0 },
1179 /* 0x6d */ { NULL, NULL, 0 },
1180 /* 0x6e */ { NULL, NULL, 0 },
1181 /* 0x6f */ { NULL, NULL, 0 },
1182 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1183 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1184 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1185 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1186 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1187 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1188 /* 0x76 */ { NULL, NULL, 0 },
1189 /* 0x77 */ { NULL, NULL, 0 },
1190 /* 0x78 */ { NULL, NULL, 0 },
1191 /* 0x79 */ { NULL, NULL, 0 },
1192 /* 0x7a */ { NULL, NULL, 0 },
1193 /* 0x7b */ { NULL, NULL, 0 },
1194 /* 0x7c */ { NULL, NULL, 0 },
1195 /* 0x7d */ { NULL, NULL, 0 },
1196 /* 0x7e */ { NULL, NULL, 0 },
1197 /* 0x7f */ { NULL, NULL, 0 },
1198 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1199 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1200 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1201 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1202 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1203 /* 0x85 */ { NULL, NULL, 0 },
1204 /* 0x86 */ { NULL, NULL, 0 },
1205 /* 0x87 */ { NULL, NULL, 0 },
1206 /* 0x88 */ { NULL, NULL, 0 },
1207 /* 0x89 */ { NULL, NULL, 0 },
1208 /* 0x8a */ { NULL, NULL, 0 },
1209 /* 0x8b */ { NULL, NULL, 0 },
1210 /* 0x8c */ { NULL, NULL, 0 },
1211 /* 0x8d */ { NULL, NULL, 0 },
1212 /* 0x8e */ { NULL, NULL, 0 },
1213 /* 0x8f */ { NULL, NULL, 0 },
1214 /* 0x90 */ { NULL, NULL, 0 },
1215 /* 0x91 */ { NULL, NULL, 0 },
1216 /* 0x92 */ { NULL, NULL, 0 },
1217 /* 0x93 */ { NULL, NULL, 0 },
1218 /* 0x94 */ { NULL, NULL, 0 },
1219 /* 0x95 */ { NULL, NULL, 0 },
1220 /* 0x96 */ { NULL, NULL, 0 },
1221 /* 0x97 */ { NULL, NULL, 0 },
1222 /* 0x98 */ { NULL, NULL, 0 },
1223 /* 0x99 */ { NULL, NULL, 0 },
1224 /* 0x9a */ { NULL, NULL, 0 },
1225 /* 0x9b */ { NULL, NULL, 0 },
1226 /* 0x9c */ { NULL, NULL, 0 },
1227 /* 0x9d */ { NULL, NULL, 0 },
1228 /* 0x9e */ { NULL, NULL, 0 },
1229 /* 0x9f */ { NULL, NULL, 0 },
1230 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1231 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1232 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1233 /* 0xa3 */ { NULL, NULL, 0 },
1234 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1235 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1236 /* 0xa6 */ { NULL, NULL, 0 },
1237 /* 0xa7 */ { NULL, NULL, 0 },
1238 /* 0xa8 */ { NULL, NULL, 0 },
1239 /* 0xa9 */ { NULL, NULL, 0 },
1240 /* 0xaa */ { NULL, NULL, 0 },
1241 /* 0xab */ { NULL, NULL, 0 },
1242 /* 0xac */ { NULL, NULL, 0 },
1243 /* 0xad */ { NULL, NULL, 0 },
1244 /* 0xae */ { NULL, NULL, 0 },
1245 /* 0xaf */ { NULL, NULL, 0 },
1246 /* 0xb0 */ { NULL, NULL, 0 },
1247 /* 0xb1 */ { NULL, NULL, 0 },
1248 /* 0xb2 */ { NULL, NULL, 0 },
1249 /* 0xb3 */ { NULL, NULL, 0 },
1250 /* 0xb4 */ { NULL, NULL, 0 },
1251 /* 0xb5 */ { NULL, NULL, 0 },
1252 /* 0xb6 */ { NULL, NULL, 0 },
1253 /* 0xb7 */ { NULL, NULL, 0 },
1254 /* 0xb8 */ { NULL, NULL, 0 },
1255 /* 0xb9 */ { NULL, NULL, 0 },
1256 /* 0xba */ { NULL, NULL, 0 },
1257 /* 0xbb */ { NULL, NULL, 0 },
1258 /* 0xbc */ { NULL, NULL, 0 },
1259 /* 0xbd */ { NULL, NULL, 0 },
1260 /* 0xbe */ { NULL, NULL, 0 },
1261 /* 0xbf */ { NULL, NULL, 0 },
1262 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1263 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1264 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1265 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1266 /* 0xc4 */ { NULL, NULL, 0 },
1267 /* 0xc5 */ { NULL, NULL, 0 },
1268 /* 0xc6 */ { NULL, NULL, 0 },
1269 /* 0xc7 */ { NULL, NULL, 0 },
1270 /* 0xc8 */ { NULL, NULL, 0 },
1271 /* 0xc9 */ { NULL, NULL, 0 },
1272 /* 0xca */ { NULL, NULL, 0 },
1273 /* 0xcb */ { NULL, NULL, 0 },
1274 /* 0xcc */ { NULL, NULL, 0 },
1275 /* 0xcd */ { NULL, NULL, 0 },
1276 /* 0xce */ { NULL, NULL, 0 },
1277 /* 0xcf */ { NULL, NULL, 0 },
1278 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1279 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1280 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1281 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1282 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1283 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1284 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1285 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1286 /* 0xd8 */ { NULL, NULL, 0 },
1287 /* 0xd9 */ { NULL, NULL, 0 },
1288 /* 0xda */ { NULL, NULL, 0 },
1289 /* 0xdb */ { NULL, NULL, 0 },
1290 /* 0xdc */ { NULL, NULL, 0 },
1291 /* 0xdd */ { NULL, NULL, 0 },
1292 /* 0xde */ { NULL, NULL, 0 },
1293 /* 0xdf */ { NULL, NULL, 0 },
1294 /* 0xe0 */ { NULL, NULL, 0 },
1295 /* 0xe1 */ { NULL, NULL, 0 },
1296 /* 0xe2 */ { NULL, NULL, 0 },
1297 /* 0xe3 */ { NULL, NULL, 0 },
1298 /* 0xe4 */ { NULL, NULL, 0 },
1299 /* 0xe5 */ { NULL, NULL, 0 },
1300 /* 0xe6 */ { NULL, NULL, 0 },
1301 /* 0xe7 */ { NULL, NULL, 0 },
1302 /* 0xe8 */ { NULL, NULL, 0 },
1303 /* 0xe9 */ { NULL, NULL, 0 },
1304 /* 0xea */ { NULL, NULL, 0 },
1305 /* 0xeb */ { NULL, NULL, 0 },
1306 /* 0xec */ { NULL, NULL, 0 },
1307 /* 0xed */ { NULL, NULL, 0 },
1308 /* 0xee */ { NULL, NULL, 0 },
1309 /* 0xef */ { NULL, NULL, 0 },
1310 /* 0xf0 */ { NULL, NULL, 0 },
1311 /* 0xf1 */ { NULL, NULL, 0 },
1312 /* 0xf2 */ { NULL, NULL, 0 },
1313 /* 0xf3 */ { NULL, NULL, 0 },
1314 /* 0xf4 */ { NULL, NULL, 0 },
1315 /* 0xf5 */ { NULL, NULL, 0 },
1316 /* 0xf6 */ { NULL, NULL, 0 },
1317 /* 0xf7 */ { NULL, NULL, 0 },
1318 /* 0xf8 */ { NULL, NULL, 0 },
1319 /* 0xf9 */ { NULL, NULL, 0 },
1320 /* 0xfa */ { NULL, NULL, 0 },
1321 /* 0xfb */ { NULL, NULL, 0 },
1322 /* 0xfc */ { NULL, NULL, 0 },
1323 /* 0xfd */ { NULL, NULL, 0 },
1324 /* 0xfe */ { NULL, NULL, 0 },
1325 /* 0xff */ { NULL, NULL, 0 }
1329 /*******************************************************************
1330 allocate and initialize a reply packet
1331 ********************************************************************/
1333 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1334 const char *inbuf, char **outbuf, uint8_t num_words,
1338 * Protect against integer wrap
1340 if ((num_bytes > 0xffffff)
1341 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1343 if (asprintf(&msg, "num_bytes too large: %u",
1344 (unsigned)num_bytes) == -1) {
1345 msg = CONST_DISCARD(char *, "num_bytes too large");
1350 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1351 smb_size + num_words*2 + num_bytes);
1352 if (*outbuf == NULL) {
1356 construct_reply_common(req, inbuf, *outbuf);
1357 srv_set_message(*outbuf, num_words, num_bytes, false);
1359 * Zero out the word area, the caller has to take care of the bcc area
1362 if (num_words != 0) {
1363 memset(*outbuf + smb_vwv0, 0, num_words*2);
1369 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1372 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1374 smb_panic("could not allocate output buffer\n");
1376 req->outbuf = (uint8_t *)outbuf;
1380 /*******************************************************************
1381 Dump a packet to a file.
1382 ********************************************************************/
1384 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1388 if (DEBUGLEVEL < 50) {
1392 if (len < 4) len = smb_len(data)+4;
1393 for (i=1;i<100;i++) {
1394 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1395 type ? "req" : "resp") == -1) {
1398 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1399 if (fd != -1 || errno != EEXIST) break;
1402 ssize_t ret = write(fd, data, len);
1404 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1406 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1411 /****************************************************************************
1412 Prepare everything for calling the actual request function, and potentially
1413 call the request function via the "new" interface.
1415 Return False if the "legacy" function needs to be called, everything is
1418 Return True if we're done.
1420 I know this API sucks, but it is the one with the least code change I could
1422 ****************************************************************************/
1424 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1428 connection_struct *conn = NULL;
1429 struct smbd_server_connection *sconn = req->sconn;
1433 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1434 * so subtract 4 from it. */
1435 if (!valid_smb_header(req->inbuf)
1436 || (size < (smb_size - 4))) {
1437 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1438 smb_len(req->inbuf)));
1439 exit_server_cleanly("Non-SMB packet");
1442 if (smb_messages[type].fn == NULL) {
1443 DEBUG(0,("Unknown message type %d!\n",type));
1444 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1445 reply_unknown_new(req, type);
1449 flags = smb_messages[type].flags;
1451 /* In share mode security we must ignore the vuid. */
1452 session_tag = (lp_security() == SEC_SHARE)
1453 ? UID_FIELD_INVALID : req->vuid;
1456 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1457 (int)sys_getpid(), (unsigned long)conn));
1459 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1461 /* Ensure this value is replaced in the incoming packet. */
1462 SSVAL(req->inbuf,smb_uid,session_tag);
1465 * Ensure the correct username is in current_user_info. This is a
1466 * really ugly bugfix for problems with multiple session_setup_and_X's
1467 * being done and allowing %U and %G substitutions to work correctly.
1468 * There is a reason this code is done here, don't move it unless you
1469 * know what you're doing... :-).
1473 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1474 user_struct *vuser = NULL;
1476 sconn->smb1.sessions.last_session_tag = session_tag;
1477 if(session_tag != UID_FIELD_INVALID) {
1478 vuser = get_valid_user_struct(sconn, session_tag);
1480 set_current_user_info(
1481 vuser->server_info->sanitized_username,
1482 vuser->server_info->unix_name,
1483 vuser->server_info->info3->base.domain.string);
1488 /* Does this call need to be run as the connected user? */
1489 if (flags & AS_USER) {
1491 /* Does this call need a valid tree connection? */
1494 * Amazingly, the error code depends on the command
1497 if (type == SMBntcreateX) {
1498 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1500 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1505 if (!change_to_user(conn,session_tag)) {
1506 DEBUG(0, ("Error: Could not change to user. Removing "
1507 "deferred open, mid=%llu.\n",
1508 (unsigned long long)req->mid));
1509 reply_force_doserror(req, ERRSRV, ERRbaduid);
1513 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1515 /* Does it need write permission? */
1516 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1517 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1521 /* IPC services are limited */
1522 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1523 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1527 /* This call needs to be run as root */
1528 change_to_root_user();
1531 /* load service specific parameters */
1533 if (req->encrypted) {
1534 conn->encrypted_tid = true;
1535 /* encrypted required from now on. */
1536 conn->encrypt_level = Required;
1537 } else if (ENCRYPTION_REQUIRED(conn)) {
1538 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1539 exit_server_cleanly("encryption required "
1545 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1546 (flags & (AS_USER|DO_CHDIR)
1548 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1551 conn->num_smb_operations++;
1554 /* does this protocol need to be run as guest? */
1555 if ((flags & AS_GUEST)
1556 && (!change_to_guest() ||
1557 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1558 sconn->client_id.name,
1559 sconn->client_id.addr))) {
1560 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1564 smb_messages[type].fn(req);
1568 /****************************************************************************
1569 Construct a reply to the incoming packet.
1570 ****************************************************************************/
1572 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1573 uint32_t seqnum, bool encrypted,
1574 struct smb_perfcount_data *deferred_pcd)
1576 connection_struct *conn;
1577 struct smb_request *req;
1579 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1580 smb_panic("could not allocate smb_request");
1583 if (!init_smb_request(req, smbd_server_conn, (uint8 *)inbuf,
1584 unread_bytes, encrypted, seqnum)) {
1585 exit_server_cleanly("Invalid SMB request");
1588 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1590 /* we popped this message off the queue - keep original perf data */
1592 req->pcd = *deferred_pcd;
1594 SMB_PERFCOUNT_START(&req->pcd);
1595 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1596 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1599 conn = switch_message(req->cmd, req, size);
1601 if (req->unread_bytes) {
1602 /* writeX failed. drain socket. */
1603 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1604 req->unread_bytes) {
1605 smb_panic("failed to drain pending bytes");
1607 req->unread_bytes = 0;
1615 if (req->outbuf == NULL) {
1619 if (CVAL(req->outbuf,0) == 0) {
1620 show_msg((char *)req->outbuf);
1623 if (!srv_send_smb(req->sconn,
1624 (char *)req->outbuf,
1625 true, req->seqnum+1,
1626 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1628 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1636 /****************************************************************************
1637 Process an smb from the client
1638 ****************************************************************************/
1639 static void process_smb(struct smbd_server_connection *conn,
1640 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1641 uint32_t seqnum, bool encrypted,
1642 struct smb_perfcount_data *deferred_pcd)
1644 int msg_type = CVAL(inbuf,0);
1646 DO_PROFILE_INC(smb_count);
1648 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1650 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1652 (unsigned int)unread_bytes ));
1654 if (msg_type != 0) {
1656 * NetBIOS session request, keepalive, etc.
1658 reply_special(conn, (char *)inbuf);
1662 if (smbd_server_conn->using_smb2) {
1663 /* At this point we're not really using smb2,
1664 * we make the decision here.. */
1665 if (smbd_is_smb2_header(inbuf, nread)) {
1666 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1668 } else if (nread >= smb_size && valid_smb_header(inbuf)
1669 && CVAL(inbuf, smb_com) != 0x72) {
1670 /* This is a non-negprot SMB1 packet.
1671 Disable SMB2 from now on. */
1672 smbd_server_conn->using_smb2 = false;
1676 show_msg((char *)inbuf);
1678 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1682 conn->smb1.num_requests++;
1684 /* The timeout_processing function isn't run nearly
1685 often enough to implement 'max log size' without
1686 overrunning the size of the file by many megabytes.
1687 This is especially true if we are running at debug
1688 level 10. Checking every 50 SMBs is a nice
1689 tradeoff of performance vs log file size overrun. */
1691 if ((conn->smb1.num_requests % 50) == 0 &&
1692 need_to_check_log_size()) {
1693 change_to_root_user();
1698 /****************************************************************************
1699 Return a string containing the function name of a SMB command.
1700 ****************************************************************************/
1702 const char *smb_fn_name(int type)
1704 const char *unknown_name = "SMBunknown";
1706 if (smb_messages[type].name == NULL)
1707 return(unknown_name);
1709 return(smb_messages[type].name);
1712 /****************************************************************************
1713 Helper functions for contruct_reply.
1714 ****************************************************************************/
1716 void add_to_common_flags2(uint32 v)
1721 void remove_from_common_flags2(uint32 v)
1723 common_flags2 &= ~v;
1726 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1729 srv_set_message(outbuf,0,0,false);
1731 SCVAL(outbuf, smb_com, req->cmd);
1732 SIVAL(outbuf,smb_rcls,0);
1733 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1734 SSVAL(outbuf,smb_flg2,
1735 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1737 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1739 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1740 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1741 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1742 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1745 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1747 construct_reply_common(req, (char *)req->inbuf, outbuf);
1751 * How many bytes have we already accumulated up to the current wct field
1755 size_t req_wct_ofs(struct smb_request *req)
1759 if (req->chain_outbuf == NULL) {
1762 buf_size = talloc_get_size(req->chain_outbuf);
1763 if ((buf_size % 4) != 0) {
1764 buf_size += (4 - (buf_size % 4));
1766 return buf_size - 4;
1770 * Hack around reply_nterror & friends not being aware of chained requests,
1771 * generating illegal (i.e. wct==0) chain replies.
1774 static void fixup_chain_error_packet(struct smb_request *req)
1776 uint8_t *outbuf = req->outbuf;
1778 reply_outbuf(req, 2, 0);
1779 memcpy(req->outbuf, outbuf, smb_wct);
1780 TALLOC_FREE(outbuf);
1781 SCVAL(req->outbuf, smb_vwv0, 0xff);
1785 * @brief Find the smb_cmd offset of the last command pushed
1786 * @param[in] buf The buffer we're building up
1787 * @retval Where can we put our next andx cmd?
1789 * While chaining requests, the "next" request we're looking at needs to put
1790 * its SMB_Command before the data the previous request already built up added
1791 * to the chain. Find the offset to the place where we have to put our cmd.
1794 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1799 cmd = CVAL(buf, smb_com);
1801 SMB_ASSERT(is_andx_req(cmd));
1805 while (CVAL(buf, ofs) != 0xff) {
1807 if (!is_andx_req(CVAL(buf, ofs))) {
1812 * ofs is from start of smb header, so add the 4 length
1813 * bytes. The next cmd is right after the wct field.
1815 ofs = SVAL(buf, ofs+2) + 4 + 1;
1817 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1825 * @brief Do the smb chaining at a buffer level
1826 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1827 * @param[in] smb_command The command that we want to issue
1828 * @param[in] wct How many words?
1829 * @param[in] vwv The words, already in network order
1830 * @param[in] bytes_alignment How shall we align "bytes"?
1831 * @param[in] num_bytes How many bytes?
1832 * @param[in] bytes The data the request ships
1834 * smb_splice_chain() adds the vwv and bytes to the request already present in
1838 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1839 uint8_t wct, const uint16_t *vwv,
1840 size_t bytes_alignment,
1841 uint32_t num_bytes, const uint8_t *bytes)
1844 size_t old_size, new_size;
1846 size_t chain_padding = 0;
1847 size_t bytes_padding = 0;
1850 old_size = talloc_get_size(*poutbuf);
1853 * old_size == smb_wct means we're pushing the first request in for
1857 first_request = (old_size == smb_wct);
1859 if (!first_request && ((old_size % 4) != 0)) {
1861 * Align the wct field of subsequent requests to a 4-byte
1864 chain_padding = 4 - (old_size % 4);
1868 * After the old request comes the new wct field (1 byte), the vwv's
1869 * and the num_bytes field. After at we might need to align the bytes
1870 * given to us to "bytes_alignment", increasing the num_bytes value.
1873 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1875 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1876 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1879 new_size += bytes_padding + num_bytes;
1881 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1882 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1883 (unsigned)new_size));
1887 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1888 if (outbuf == NULL) {
1889 DEBUG(0, ("talloc failed\n"));
1894 if (first_request) {
1895 SCVAL(outbuf, smb_com, smb_command);
1897 size_t andx_cmd_ofs;
1899 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1900 DEBUG(1, ("invalid command chain\n"));
1901 *poutbuf = TALLOC_REALLOC_ARRAY(
1902 NULL, *poutbuf, uint8_t, old_size);
1906 if (chain_padding != 0) {
1907 memset(outbuf + old_size, 0, chain_padding);
1908 old_size += chain_padding;
1911 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1912 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1918 * Push the chained request:
1923 SCVAL(outbuf, ofs, wct);
1930 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1931 ofs += sizeof(uint16_t) * wct;
1937 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1938 ofs += sizeof(uint16_t);
1944 if (bytes_padding != 0) {
1945 memset(outbuf + ofs, 0, bytes_padding);
1946 ofs += bytes_padding;
1953 memcpy(outbuf + ofs, bytes, num_bytes);
1958 /****************************************************************************
1959 Construct a chained reply and add it to the already made reply
1960 ****************************************************************************/
1962 void chain_reply(struct smb_request *req)
1964 size_t smblen = smb_len(req->inbuf);
1965 size_t already_used, length_needed;
1967 uint32_t chain_offset; /* uint32_t to avoid overflow */
1974 if (IVAL(req->outbuf, smb_rcls) != 0) {
1975 fixup_chain_error_packet(req);
1979 * Any of the AndX requests and replies have at least a wct of
1980 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1981 * beginning of the SMB header to the next wct field.
1983 * None of the AndX requests put anything valuable in vwv[0] and [1],
1984 * so we can overwrite it here to form the chain.
1987 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1988 if (req->chain_outbuf == NULL) {
1989 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1990 req, req->outbuf, uint8_t,
1991 smb_len(req->outbuf) + 4);
1992 if (req->chain_outbuf == NULL) {
1993 smb_panic("talloc failed");
2001 * Here we assume that this is the end of the chain. For that we need
2002 * to set "next command" to 0xff and the offset to 0. If we later find
2003 * more commands in the chain, this will be overwritten again.
2006 SCVAL(req->outbuf, smb_vwv0, 0xff);
2007 SCVAL(req->outbuf, smb_vwv0+1, 0);
2008 SSVAL(req->outbuf, smb_vwv1, 0);
2010 if (req->chain_outbuf == NULL) {
2012 * In req->chain_outbuf we collect all the replies. Start the
2013 * chain by copying in the first reply.
2015 * We do the realloc because later on we depend on
2016 * talloc_get_size to determine the length of
2017 * chain_outbuf. The reply_xxx routines might have
2018 * over-allocated (reply_pipe_read_and_X used to be such an
2021 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2022 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2023 if (req->chain_outbuf == NULL) {
2024 smb_panic("talloc failed");
2029 * Update smb headers where subsequent chained commands
2030 * may have updated them.
2032 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2033 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2035 if (!smb_splice_chain(&req->chain_outbuf,
2036 CVAL(req->outbuf, smb_com),
2037 CVAL(req->outbuf, smb_wct),
2038 (uint16_t *)(req->outbuf + smb_vwv),
2039 0, smb_buflen(req->outbuf),
2040 (uint8_t *)smb_buf(req->outbuf))) {
2043 TALLOC_FREE(req->outbuf);
2047 * We use the old request's vwv field to grab the next chained command
2048 * and offset into the chained fields.
2051 chain_cmd = CVAL(req->vwv+0, 0);
2052 chain_offset = SVAL(req->vwv+1, 0);
2054 if (chain_cmd == 0xff) {
2056 * End of chain, no more requests from the client. So ship the
2059 smb_setlen((char *)(req->chain_outbuf),
2060 talloc_get_size(req->chain_outbuf) - 4);
2062 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2063 true, req->seqnum+1,
2064 IS_CONN_ENCRYPTED(req->conn)
2067 exit_server_cleanly("chain_reply: srv_send_smb "
2070 TALLOC_FREE(req->chain_outbuf);
2075 /* add a new perfcounter for this element of chain */
2076 SMB_PERFCOUNT_ADD(&req->pcd);
2077 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2078 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2081 * Check if the client tries to fool us. The request so far uses the
2082 * space to the end of the byte buffer in the request just
2083 * processed. The chain_offset can't point into that area. If that was
2084 * the case, we could end up with an endless processing of the chain,
2085 * we would always handle the same request.
2088 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2089 if (chain_offset < already_used) {
2094 * Next check: Make sure the chain offset does not point beyond the
2095 * overall smb request length.
2098 length_needed = chain_offset+1; /* wct */
2099 if (length_needed > smblen) {
2104 * Now comes the pointer magic. Goal here is to set up req->vwv and
2105 * req->buf correctly again to be able to call the subsequent
2106 * switch_message(). The chain offset (the former vwv[1]) points at
2107 * the new wct field.
2110 wct = CVAL(smb_base(req->inbuf), chain_offset);
2113 * Next consistency check: Make the new vwv array fits in the overall
2117 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2118 if (length_needed > smblen) {
2121 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2124 * Now grab the new byte buffer....
2127 buflen = SVAL(vwv+wct, 0);
2130 * .. and check that it fits.
2133 length_needed += buflen;
2134 if (length_needed > smblen) {
2137 buf = (uint8_t *)(vwv+wct+1);
2139 req->cmd = chain_cmd;
2142 req->buflen = buflen;
2145 switch_message(chain_cmd, req, smblen);
2147 if (req->outbuf == NULL) {
2149 * This happens if the chained command has suspended itself or
2150 * if it has called srv_send_smb() itself.
2156 * We end up here if the chained command was not itself chained or
2157 * suspended, but for example a close() command. We now need to splice
2158 * the chained commands' outbuf into the already built up chain_outbuf
2159 * and ship the result.
2165 * We end up here if there's any error in the chain syntax. Report a
2166 * DOS error, just like Windows does.
2168 reply_force_doserror(req, ERRSRV, ERRerror);
2169 fixup_chain_error_packet(req);
2173 * This scary statement intends to set the
2174 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2175 * to the value req->outbuf carries
2177 SSVAL(req->chain_outbuf, smb_flg2,
2178 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2179 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2182 * Transfer the error codes from the subrequest to the main one
2184 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2185 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2187 if (!smb_splice_chain(&req->chain_outbuf,
2188 CVAL(req->outbuf, smb_com),
2189 CVAL(req->outbuf, smb_wct),
2190 (uint16_t *)(req->outbuf + smb_vwv),
2191 0, smb_buflen(req->outbuf),
2192 (uint8_t *)smb_buf(req->outbuf))) {
2193 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2195 TALLOC_FREE(req->outbuf);
2197 smb_setlen((char *)(req->chain_outbuf),
2198 talloc_get_size(req->chain_outbuf) - 4);
2200 show_msg((char *)(req->chain_outbuf));
2202 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2203 true, req->seqnum+1,
2204 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2206 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2208 TALLOC_FREE(req->chain_outbuf);
2212 /****************************************************************************
2213 Check if services need reloading.
2214 ****************************************************************************/
2216 static void check_reload(struct messaging_context *msg_ctx, time_t t)
2218 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2220 if(last_smb_conf_reload_time == 0) {
2221 last_smb_conf_reload_time = t;
2222 /* Our printing subsystem might not be ready at smbd start up.
2223 Then no printer is available till the first printers check
2224 is performed. A lower initial interval circumvents this. */
2225 if ( printcap_cache_time > 60 )
2226 last_printer_reload_time = t - printcap_cache_time + 60;
2228 last_printer_reload_time = t;
2231 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2232 /* randomize over 60 second the printcap reload to avoid all
2233 * process hitting cupsd at the same time */
2234 int time_range = 60;
2236 last_printer_reload_time += random() % time_range;
2240 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2241 reload_services(msg_ctx, smbd_server_fd(), True);
2242 last_smb_conf_reload_time = t;
2245 /* 'printcap cache time = 0' disable the feature */
2247 if ( printcap_cache_time != 0 )
2249 /* see if it's time to reload or if the clock has been set back */
2251 if ( (t >= last_printer_reload_time+printcap_cache_time)
2252 || (t-last_printer_reload_time < 0) )
2254 DEBUG( 3,( "Printcap cache time expired.\n"));
2255 reload_printers(msg_ctx);
2256 last_printer_reload_time = t;
2261 static bool fd_is_readable(int fd)
2264 struct timeval timeout = {0, };
2270 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2274 return FD_ISSET(fd, &fds);
2277 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2279 /* TODO: make write nonblocking */
2282 static void smbd_server_connection_read_handler(
2283 struct smbd_server_connection *conn, int fd)
2285 uint8_t *inbuf = NULL;
2286 size_t inbuf_len = 0;
2287 size_t unread_bytes = 0;
2288 bool encrypted = false;
2289 TALLOC_CTX *mem_ctx = talloc_tos();
2293 bool from_client = (conn->sock == fd);
2296 smbd_lock_socket(conn);
2298 if (!fd_is_readable(fd)) {
2299 DEBUG(10,("the echo listener was faster\n"));
2300 smbd_unlock_socket(conn);
2304 /* TODO: make this completely nonblocking */
2305 status = receive_smb_talloc(mem_ctx, fd,
2306 (char **)(void *)&inbuf,
2310 &inbuf_len, &seqnum,
2311 false /* trusted channel */);
2312 smbd_unlock_socket(conn);
2314 /* TODO: make this completely nonblocking */
2315 status = receive_smb_talloc(mem_ctx, fd,
2316 (char **)(void *)&inbuf,
2320 &inbuf_len, &seqnum,
2321 true /* trusted channel */);
2324 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2327 if (NT_STATUS_IS_ERR(status)) {
2328 exit_server_cleanly("failed to receive smb request");
2330 if (!NT_STATUS_IS_OK(status)) {
2335 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2336 seqnum, encrypted, NULL);
2339 static void smbd_server_connection_handler(struct event_context *ev,
2340 struct fd_event *fde,
2344 struct smbd_server_connection *conn = talloc_get_type(private_data,
2345 struct smbd_server_connection);
2347 if (flags & EVENT_FD_WRITE) {
2348 smbd_server_connection_write_handler(conn);
2351 if (flags & EVENT_FD_READ) {
2352 smbd_server_connection_read_handler(conn, conn->sock);
2357 static void smbd_server_echo_handler(struct event_context *ev,
2358 struct fd_event *fde,
2362 struct smbd_server_connection *conn = talloc_get_type(private_data,
2363 struct smbd_server_connection);
2365 if (flags & EVENT_FD_WRITE) {
2366 smbd_server_connection_write_handler(conn);
2369 if (flags & EVENT_FD_READ) {
2370 smbd_server_connection_read_handler(
2371 conn, conn->smb1.echo_handler.trusted_fd);
2376 /****************************************************************************
2377 received when we should release a specific IP
2378 ****************************************************************************/
2379 static void release_ip(const char *ip, void *priv)
2381 char addr[INET6_ADDRSTRLEN];
2384 client_socket_addr(smbd_server_fd(),addr,sizeof(addr));
2386 if (strncmp("::ffff:", addr, 7) == 0) {
2390 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2391 /* we can't afford to do a clean exit - that involves
2392 database writes, which would potentially mean we
2393 are still running after the failover has finished -
2394 we have to get rid of this process ID straight
2396 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2398 /* note we must exit with non-zero status so the unclean handler gets
2399 called in the parent, so that the brl database is tickled */
2404 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2405 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2407 release_ip((char *)data->data, NULL);
2410 #ifdef CLUSTER_SUPPORT
2411 static int client_get_tcp_info(struct sockaddr_storage *server,
2412 struct sockaddr_storage *client)
2415 if (server_fd == -1) {
2418 length = sizeof(*server);
2419 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2422 length = sizeof(*client);
2423 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2431 * Send keepalive packets to our client
2433 static bool keepalive_fn(const struct timeval *now, void *private_data)
2435 struct smbd_server_connection *sconn = smbd_server_conn;
2438 if (sconn->using_smb2) {
2439 /* Don't do keepalives on an SMB2 connection. */
2443 smbd_lock_socket(smbd_server_conn);
2444 ret = send_keepalive(sconn->sock);
2445 smbd_unlock_socket(smbd_server_conn);
2448 char addr[INET6_ADDRSTRLEN];
2450 * Try and give an error message saying what
2453 DEBUG(0, ("send_keepalive failed for client %s. "
2454 "Error %s - exiting\n",
2455 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2463 * Do the recurring check if we're idle
2465 static bool deadtime_fn(const struct timeval *now, void *private_data)
2467 struct smbd_server_connection *sconn =
2468 (struct smbd_server_connection *)private_data;
2470 if (sconn->using_smb2) {
2471 /* TODO: implement real idle check */
2472 if (sconn->smb2.sessions.list) {
2475 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2476 messaging_send(sconn->msg_ctx, procid_self(),
2477 MSG_SHUTDOWN, &data_blob_null);
2481 if ((conn_num_open(sconn) == 0)
2482 || (conn_idle_all(sconn, now->tv_sec))) {
2483 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2484 messaging_send(sconn->msg_ctx, procid_self(),
2485 MSG_SHUTDOWN, &data_blob_null);
2493 * Do the recurring log file and smb.conf reload checks.
2496 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2498 struct messaging_context *msg_ctx = talloc_get_type_abort(
2499 private_data, struct messaging_context);
2500 change_to_root_user();
2502 /* update printer queue caches if necessary */
2503 update_monitored_printq_cache(msg_ctx);
2505 /* check if we need to reload services */
2506 check_reload(msg_ctx, time(NULL));
2508 /* Change machine password if neccessary. */
2509 attempt_machine_password_change();
2512 * Force a log file check.
2514 force_check_log_size();
2519 static int create_unlink_tmp(const char *dir)
2524 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2525 if (fname == NULL) {
2529 fd = mkstemp(fname);
2534 if (unlink(fname) == -1) {
2535 int sys_errno = errno;
2545 struct smbd_echo_state {
2546 struct tevent_context *ev;
2547 struct iovec *pending;
2548 struct smbd_server_connection *sconn;
2551 struct tevent_fd *parent_fde;
2553 struct tevent_fd *read_fde;
2554 struct tevent_req *write_req;
2557 static void smbd_echo_writer_done(struct tevent_req *req);
2559 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2563 if (state->write_req != NULL) {
2567 num_pending = talloc_array_length(state->pending);
2568 if (num_pending == 0) {
2572 state->write_req = writev_send(state, state->ev, NULL,
2573 state->parent_pipe, false,
2574 state->pending, num_pending);
2575 if (state->write_req == NULL) {
2576 DEBUG(1, ("writev_send failed\n"));
2580 talloc_steal(state->write_req, state->pending);
2581 state->pending = NULL;
2583 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2587 static void smbd_echo_writer_done(struct tevent_req *req)
2589 struct smbd_echo_state *state = tevent_req_callback_data(
2590 req, struct smbd_echo_state);
2594 written = writev_recv(req, &err);
2596 state->write_req = NULL;
2597 if (written == -1) {
2598 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2601 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2602 smbd_echo_activate_writer(state);
2605 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2608 struct smb_request req;
2609 uint16_t num_replies;
2614 if (inbuf_len < smb_size) {
2615 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2618 if (!valid_smb_header(inbuf)) {
2619 DEBUG(10, ("Got invalid SMB header\n"));
2623 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2629 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2630 smb_messages[req.cmd].name
2631 ? smb_messages[req.cmd].name : "unknown"));
2633 if (req.cmd != SMBecho) {
2640 num_replies = SVAL(req.vwv+0, 0);
2641 if (num_replies != 1) {
2642 /* Not a Windows "Hey, you're still there?" request */
2646 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2648 DEBUG(10, ("create_outbuf failed\n"));
2651 req.outbuf = (uint8_t *)outbuf;
2653 SSVAL(req.outbuf, smb_vwv0, num_replies);
2655 if (req.buflen > 0) {
2656 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2659 out_len = smb_len(req.outbuf) + 4;
2661 ok = srv_send_smb(req.sconn,
2665 TALLOC_FREE(outbuf);
2673 static void smbd_echo_exit(struct tevent_context *ev,
2674 struct tevent_fd *fde, uint16_t flags,
2677 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2681 static void smbd_echo_reader(struct tevent_context *ev,
2682 struct tevent_fd *fde, uint16_t flags,
2685 struct smbd_echo_state *state = talloc_get_type_abort(
2686 private_data, struct smbd_echo_state);
2687 struct smbd_server_connection *sconn = state->sconn;
2688 size_t unread, num_pending;
2691 uint32_t seqnum = 0;
2694 bool encrypted = false;
2698 ok = smbd_lock_socket_internal(sconn);
2700 DEBUG(0, ("%s: failed to lock socket\n",
2705 if (!fd_is_readable(sconn->sock)) {
2706 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2707 (int)sys_getpid()));
2708 ok = smbd_unlock_socket_internal(sconn);
2710 DEBUG(1, ("%s: failed to unlock socket in\n",
2717 num_pending = talloc_array_length(state->pending);
2718 tmp = talloc_realloc(state, state->pending, struct iovec,
2721 DEBUG(1, ("talloc_realloc failed\n"));
2724 state->pending = tmp;
2726 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2728 status = receive_smb_talloc(state->pending, sconn->sock,
2729 (char **)(void *)&state->pending[num_pending].iov_base,
2733 &state->pending[num_pending].iov_len,
2735 false /* trusted_channel*/);
2736 if (!NT_STATUS_IS_OK(status)) {
2737 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2738 (int)sys_getpid(), nt_errstr(status)));
2742 ok = smbd_unlock_socket_internal(sconn);
2744 DEBUG(1, ("%s: failed to unlock socket in\n",
2750 * place the seqnum in the packet so that the main process can reply
2753 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2754 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2756 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2757 state->pending[num_pending].iov_len,
2760 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2761 /* no check, shrinking by some bytes does not fail */
2762 state->pending = talloc_realloc(state, state->pending,
2766 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2767 smbd_echo_activate_writer(state);
2771 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2774 struct smbd_echo_state *state;
2776 state = talloc_zero(sconn, struct smbd_echo_state);
2777 if (state == NULL) {
2778 DEBUG(1, ("talloc failed\n"));
2781 state->sconn = sconn;
2782 state->parent_pipe = parent_pipe;
2783 state->ev = s3_tevent_context_init(state);
2784 if (state->ev == NULL) {
2785 DEBUG(1, ("tevent_context_init failed\n"));
2789 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2790 TEVENT_FD_READ, smbd_echo_exit,
2792 if (state->parent_fde == NULL) {
2793 DEBUG(1, ("tevent_add_fd failed\n"));
2797 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2798 TEVENT_FD_READ, smbd_echo_reader,
2800 if (state->read_fde == NULL) {
2801 DEBUG(1, ("tevent_add_fd failed\n"));
2807 if (tevent_loop_once(state->ev) == -1) {
2808 DEBUG(1, ("tevent_loop_once failed: %s\n",
2817 * Handle SMBecho requests in a forked child process
2819 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2821 int listener_pipe[2];
2825 res = pipe(listener_pipe);
2827 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2830 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2831 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2832 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2840 close(listener_pipe[0]);
2842 status = reinit_after_fork(sconn->msg_ctx,
2843 smbd_event_context(),
2844 procid_self(), false);
2845 if (!NT_STATUS_IS_OK(status)) {
2846 DEBUG(1, ("reinit_after_fork failed: %s\n",
2847 nt_errstr(status)));
2850 smbd_echo_loop(sconn, listener_pipe[1]);
2853 close(listener_pipe[1]);
2854 listener_pipe[1] = -1;
2855 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2857 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2860 * Without smb signing this is the same as the normal smbd
2861 * listener. This needs to change once signing comes in.
2863 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2865 sconn->smb1.echo_handler.trusted_fd,
2867 smbd_server_echo_handler,
2869 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2870 DEBUG(1, ("event_add_fd failed\n"));
2877 if (listener_pipe[0] != -1) {
2878 close(listener_pipe[0]);
2880 if (listener_pipe[1] != -1) {
2881 close(listener_pipe[1]);
2883 sconn->smb1.echo_handler.trusted_fd = -1;
2884 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2885 close(sconn->smb1.echo_handler.socket_lock_fd);
2887 sconn->smb1.echo_handler.trusted_fd = -1;
2888 sconn->smb1.echo_handler.socket_lock_fd = -1;
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;
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_security() != SEC_SHARE &&
2909 !lp_async_smb_echo_handler()) {
2911 * We're not making the desion here,
2912 * we're just allowing the client
2913 * to decide between SMB1 and SMB2
2914 * with the first negprot
2917 sconn->using_smb2 = true;
2920 /* Ensure child is set to blocking mode */
2921 set_blocking(sconn->sock,True);
2923 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2924 set_socket_options(sconn->sock, lp_socket_options());
2926 sa = (struct sockaddr *)(void *)&ss;
2927 sa_len = sizeof(ss);
2928 ret = getpeername(sconn->sock, sa, &sa_len);
2930 int level = (errno == ENOTCONN)?2:0;
2931 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2932 exit_server_cleanly("getpeername() failed.\n");
2934 ret = tsocket_address_bsd_from_sockaddr(sconn,
2938 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2939 __location__, strerror(errno)));
2940 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2943 sa = (struct sockaddr *)(void *)&ss;
2944 sa_len = sizeof(ss);
2945 ret = getsockname(sconn->sock, sa, &sa_len);
2947 int level = (errno == ENOTCONN)?2:0;
2948 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2949 exit_server_cleanly("getsockname() failed.\n");
2951 ret = tsocket_address_bsd_from_sockaddr(sconn,
2955 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2956 __location__, strerror(errno)));
2957 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2960 sconn->local_address = local_address;
2961 sconn->remote_address = remote_address;
2963 if (tsocket_address_is_inet(remote_address, "ip")) {
2964 remaddr = tsocket_address_inet_addr_string(
2965 sconn->remote_address,
2967 if (remaddr == NULL) {
2971 remaddr = "0.0.0.0";
2974 /* this is needed so that we get decent entries
2975 in smbstatus for port 445 connects */
2976 set_remote_machine_name(remaddr, false);
2977 reload_services(sconn->msg_ctx, sconn->sock, true);
2980 * Before the first packet, check the global hosts allow/ hosts deny
2981 * parameters before doing any parsing of packets passed to us by the
2982 * client. This prevents attacks on our parsing code from hosts not in
2983 * the hosts allow list.
2986 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2987 sconn->client_id.name,
2988 sconn->client_id.addr)) {
2990 * send a negative session response "not listening on calling
2993 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2994 DEBUG( 1, ("Connection denied from %s to %s\n",
2995 tsocket_address_string(remote_address, talloc_tos()),
2996 tsocket_address_string(local_address, talloc_tos())));
2997 (void)srv_send_smb(sconn,(char *)buf, false,
2999 exit_server_cleanly("connection denied");
3002 DEBUG(10, ("Connection allowed from %s to %s\n",
3003 tsocket_address_string(remote_address, talloc_tos()),
3004 tsocket_address_string(local_address, talloc_tos())));
3008 smb_perfcount_init();
3010 if (!init_account_policy()) {
3011 exit_server("Could not open account policy tdb.\n");
3014 if (*lp_rootdir()) {
3015 if (chroot(lp_rootdir()) != 0) {
3016 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3017 exit_server("Failed to chroot()");
3019 if (chdir("/") == -1) {
3020 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3021 exit_server("Failed to chroot()");
3023 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3026 if (!srv_init_signing(sconn)) {
3027 exit_server("Failed to init smb_signing");
3030 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3031 exit_server("Failed to fork echo handler");
3035 if (!init_oplocks(sconn->msg_ctx))
3036 exit_server("Failed to init oplocks");
3038 /* register our message handlers */
3039 messaging_register(sconn->msg_ctx, NULL,
3040 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3041 messaging_register(sconn->msg_ctx, NULL,
3042 MSG_SMB_RELEASE_IP, msg_release_ip);
3043 messaging_register(sconn->msg_ctx, NULL,
3044 MSG_SMB_CLOSE_FILE, msg_close_file);
3047 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3048 * MSGs to all child processes
3050 messaging_deregister(sconn->msg_ctx,
3052 messaging_register(sconn->msg_ctx, NULL,
3053 MSG_DEBUG, debug_message);
3055 if ((lp_keepalive() != 0)
3056 && !(event_add_idle(smbd_event_context(), NULL,
3057 timeval_set(lp_keepalive(), 0),
3058 "keepalive", keepalive_fn,
3060 DEBUG(0, ("Could not add keepalive event\n"));
3064 if (!(event_add_idle(smbd_event_context(), NULL,
3065 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3066 "deadtime", deadtime_fn, sconn))) {
3067 DEBUG(0, ("Could not add deadtime event\n"));
3071 if (!(event_add_idle(smbd_event_context(), NULL,
3072 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3073 "housekeeping", housekeeping_fn,
3075 DEBUG(0, ("Could not add housekeeping event\n"));
3079 #ifdef CLUSTER_SUPPORT
3081 if (lp_clustering()) {
3083 * We need to tell ctdb about our client's TCP
3084 * connection, so that for failover ctdbd can send
3085 * tickle acks, triggering a reconnection by the
3089 struct sockaddr_storage srv, clnt;
3091 if (client_get_tcp_info(&srv, &clnt) == 0) {
3095 status = ctdbd_register_ips(
3096 messaging_ctdbd_connection(procid_self()),
3097 &srv, &clnt, release_ip, NULL);
3099 if (!NT_STATUS_IS_OK(status)) {
3100 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3101 nt_errstr(status)));
3105 DEBUG(0,("Unable to get tcp info for "
3106 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3113 sconn->nbt.got_session = false;
3115 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3117 sconn->smb1.sessions.done_sesssetup = false;
3118 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3119 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3120 /* users from session setup */
3121 sconn->smb1.sessions.session_userlist = NULL;
3122 /* workgroup from session setup. */
3123 sconn->smb1.sessions.session_workgroup = NULL;
3124 /* this holds info on user ids that are already validated for this VC */
3125 sconn->smb1.sessions.validated_users = NULL;
3126 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3127 sconn->smb1.sessions.num_validated_vuids = 0;
3130 if (!init_dptrs(sconn)) {
3131 exit_server("init_dptrs() failed");
3134 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3138 smbd_server_connection_handler,
3140 if (!sconn->smb1.fde) {
3141 exit_server("failed to create smbd_server_connection fde");
3149 frame = talloc_stackframe_pool(8192);
3153 status = smbd_server_connection_loop_once(sconn);
3154 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3155 !NT_STATUS_IS_OK(status)) {
3156 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3157 " exiting\n", nt_errstr(status)));
3164 exit_server_cleanly(NULL);
3167 bool req_is_in_chain(struct smb_request *req)
3169 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3171 * We're right now handling a subsequent request, so we must
3177 if (!is_andx_req(req->cmd)) {
3183 * Okay, an illegal request, but definitely not chained :-)
3188 return (CVAL(req->vwv+0, 0) != 0xFF);