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"
25 #include "../lib/async_req/async_sock.h"
26 #include "ctdbd_conn.h"
27 #include "../lib/util/select.h"
29 extern bool global_machine_password_needs_changing;
31 static void construct_reply_common(struct smb_request *req, const char *inbuf,
33 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
35 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
39 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
43 sconn->smb1.echo_handler.ref_count++;
45 if (sconn->smb1.echo_handler.ref_count > 1) {
49 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
53 sconn->smb1.echo_handler.socket_lock_fd,
54 SMB_F_SETLKW, 0, 0, F_WRLCK);
55 } while (!ok && (errno == EINTR));
58 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
62 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
67 void smbd_lock_socket(struct smbd_server_connection *sconn)
69 if (!smbd_lock_socket_internal(sconn)) {
70 exit_server_cleanly("failed to lock socket");
74 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
78 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
82 sconn->smb1.echo_handler.ref_count--;
84 if (sconn->smb1.echo_handler.ref_count > 0) {
90 sconn->smb1.echo_handler.socket_lock_fd,
91 SMB_F_SETLKW, 0, 0, F_UNLCK);
92 } while (!ok && (errno == EINTR));
95 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
99 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
104 void smbd_unlock_socket(struct smbd_server_connection *sconn)
106 if (!smbd_unlock_socket_internal(sconn)) {
107 exit_server_cleanly("failed to unlock socket");
111 /* Accessor function for smb_read_error for smbd functions. */
113 /****************************************************************************
115 ****************************************************************************/
117 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
118 bool do_signing, uint32_t seqnum,
120 struct smb_perfcount_data *pcd)
125 char *buf_out = buffer;
127 smbd_lock_socket(sconn);
130 /* Sign the outgoing packet if required. */
131 srv_calculate_sign_mac(sconn, buf_out, seqnum);
135 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
136 if (!NT_STATUS_IS_OK(status)) {
137 DEBUG(0, ("send_smb: SMB encryption failed "
138 "on outgoing packet! Error %s\n",
139 nt_errstr(status) ));
144 len = smb_len(buf_out) + 4;
146 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
149 char addr[INET6_ADDRSTRLEN];
151 * Try and give an error message saying what
154 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
155 (int)sys_getpid(), (int)len,
156 get_peer_addr(sconn->sock, addr, sizeof(addr)),
157 (int)ret, strerror(errno) ));
159 srv_free_enc_buffer(buf_out);
163 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
164 srv_free_enc_buffer(buf_out);
166 SMB_PERFCOUNT_END(pcd);
168 smbd_unlock_socket(sconn);
172 /*******************************************************************
173 Setup the word count and byte count for a smb message.
174 ********************************************************************/
176 int srv_set_message(char *buf,
181 if (zero && (num_words || num_bytes)) {
182 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
184 SCVAL(buf,smb_wct,num_words);
185 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
186 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
187 return (smb_size + num_words*2 + num_bytes);
190 static bool valid_smb_header(const uint8_t *inbuf)
192 if (is_encrypted_packet(inbuf)) {
196 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
197 * but it just looks weird to call strncmp for this one.
199 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
202 /* Socket functions for smbd packet processing. */
204 static bool valid_packet_size(size_t len)
207 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
208 * of header. Don't print the error if this fits.... JRA.
211 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
212 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
213 (unsigned long)len));
219 static NTSTATUS read_packet_remainder(int fd, char *buffer,
220 unsigned int timeout, ssize_t len)
228 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
229 if (!NT_STATUS_IS_OK(status)) {
230 char addr[INET6_ADDRSTRLEN];
231 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
233 get_peer_addr(fd, addr, sizeof(addr)),
239 /****************************************************************************
240 Attempt a zerocopy writeX read. We know here that len > smb_size-4
241 ****************************************************************************/
244 * Unfortunately, earlier versions of smbclient/libsmbclient
245 * don't send this "standard" writeX header. I've fixed this
246 * for 3.2 but we'll use the old method with earlier versions.
247 * Windows and CIFSFS at least use this standard size. Not
251 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
252 (2*14) + /* word count (including bcc) */ \
255 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
256 const char lenbuf[4],
257 struct smbd_server_connection *sconn,
259 unsigned int timeout,
263 /* Size of a WRITEX call (+4 byte len). */
264 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
265 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
269 memcpy(writeX_header, lenbuf, 4);
271 status = read_fd_with_timeout(
272 sconn->sock, writeX_header + 4,
273 STANDARD_WRITE_AND_X_HEADER_SIZE,
274 STANDARD_WRITE_AND_X_HEADER_SIZE,
277 if (!NT_STATUS_IS_OK(status)) {
278 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
279 "error = %s.\n", sconn->client_id.addr,
285 * Ok - now try and see if this is a possible
289 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
291 * If the data offset is beyond what
292 * we've read, drain the extra bytes.
294 uint16_t doff = SVAL(writeX_header,smb_vwv11);
297 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
298 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
299 if (drain_socket(sconn->sock, drain) != drain) {
300 smb_panic("receive_smb_raw_talloc_partial_read:"
301 " failed to drain pending bytes");
304 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
307 /* Spoof down the length and null out the bcc. */
308 set_message_bcc(writeX_header, 0);
309 newlen = smb_len(writeX_header);
311 /* Copy the header we've written. */
313 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
315 sizeof(writeX_header));
317 if (*buffer == NULL) {
318 DEBUG(0, ("Could not allocate inbuf of length %d\n",
319 (int)sizeof(writeX_header)));
320 return NT_STATUS_NO_MEMORY;
323 /* Work out the remaining bytes. */
324 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
325 *len_ret = newlen + 4;
329 if (!valid_packet_size(len)) {
330 return NT_STATUS_INVALID_PARAMETER;
334 * Not a valid writeX call. Just do the standard
338 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
340 if (*buffer == NULL) {
341 DEBUG(0, ("Could not allocate inbuf of length %d\n",
343 return NT_STATUS_NO_MEMORY;
346 /* Copy in what we already read. */
349 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
350 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
353 status = read_packet_remainder(
355 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
358 if (!NT_STATUS_IS_OK(status)) {
359 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
369 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
370 struct smbd_server_connection *sconn,
371 char **buffer, unsigned int timeout,
372 size_t *p_unread, size_t *plen)
376 int min_recv_size = lp_min_receive_file_size();
381 status = read_smb_length_return_keepalive(sconn->sock, lenbuf, timeout,
383 if (!NT_STATUS_IS_OK(status)) {
387 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
388 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
389 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
390 !srv_is_signing_active(sconn) &&
391 sconn->smb1.echo_handler.trusted_fde == NULL) {
393 return receive_smb_raw_talloc_partial_read(
394 mem_ctx, lenbuf, sconn, buffer, timeout,
398 if (!valid_packet_size(len)) {
399 return NT_STATUS_INVALID_PARAMETER;
403 * The +4 here can't wrap, we've checked the length above already.
406 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
408 if (*buffer == NULL) {
409 DEBUG(0, ("Could not allocate inbuf of length %d\n",
411 return NT_STATUS_NO_MEMORY;
414 memcpy(*buffer, lenbuf, sizeof(lenbuf));
416 status = read_packet_remainder(sconn->sock, (*buffer)+4, timeout, len);
417 if (!NT_STATUS_IS_OK(status)) {
425 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
426 struct smbd_server_connection *sconn,
427 char **buffer, unsigned int timeout,
428 size_t *p_unread, bool *p_encrypted,
431 bool trusted_channel)
436 *p_encrypted = false;
438 status = receive_smb_raw_talloc(mem_ctx, sconn, buffer, timeout,
440 if (!NT_STATUS_IS_OK(status)) {
441 DEBUG(1, ("read_smb_length_return_keepalive failed for "
442 "client %s read error = %s.\n",
443 sconn->client_id.addr, nt_errstr(status)));
447 if (is_encrypted_packet((uint8_t *)*buffer)) {
448 status = srv_decrypt_buffer(*buffer);
449 if (!NT_STATUS_IS_OK(status)) {
450 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
451 "incoming packet! Error %s\n",
452 nt_errstr(status) ));
458 /* Check the incoming SMB signature. */
459 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
460 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
461 "incoming packet!\n"));
462 return NT_STATUS_INVALID_NETWORK_RESPONSE;
470 * Initialize a struct smb_request from an inbuf
473 static bool init_smb_request(struct smb_request *req,
474 struct smbd_server_connection *sconn,
476 size_t unread_bytes, bool encrypted,
479 size_t req_size = smb_len(inbuf) + 4;
480 /* Ensure we have at least smb_size bytes. */
481 if (req_size < smb_size) {
482 DEBUG(0,("init_smb_request: invalid request size %u\n",
483 (unsigned int)req_size ));
486 req->cmd = CVAL(inbuf, smb_com);
487 req->flags2 = SVAL(inbuf, smb_flg2);
488 req->smbpid = SVAL(inbuf, smb_pid);
489 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
490 req->seqnum = seqnum;
491 req->vuid = SVAL(inbuf, smb_uid);
492 req->tid = SVAL(inbuf, smb_tid);
493 req->wct = CVAL(inbuf, smb_wct);
494 req->vwv = (uint16_t *)(inbuf+smb_vwv);
495 req->buflen = smb_buflen(inbuf);
496 req->buf = (const uint8_t *)smb_buf(inbuf);
497 req->unread_bytes = unread_bytes;
498 req->encrypted = encrypted;
500 req->conn = conn_find(sconn,req->tid);
501 req->chain_fsp = NULL;
502 req->chain_outbuf = NULL;
505 smb_init_perfcount_data(&req->pcd);
507 /* Ensure we have at least wct words and 2 bytes of bcc. */
508 if (smb_size + req->wct*2 > req_size) {
509 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
510 (unsigned int)req->wct,
511 (unsigned int)req_size));
514 /* Ensure bcc is correct. */
515 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
516 DEBUG(0,("init_smb_request: invalid bcc number %u "
517 "(wct = %u, size %u)\n",
518 (unsigned int)req->buflen,
519 (unsigned int)req->wct,
520 (unsigned int)req_size));
528 static void process_smb(struct smbd_server_connection *conn,
529 uint8_t *inbuf, size_t nread, size_t unread_bytes,
530 uint32_t seqnum, bool encrypted,
531 struct smb_perfcount_data *deferred_pcd);
533 static void smbd_deferred_open_timer(struct event_context *ev,
534 struct timed_event *te,
535 struct timeval _tval,
538 struct pending_message_list *msg = talloc_get_type(private_data,
539 struct pending_message_list);
540 TALLOC_CTX *mem_ctx = talloc_tos();
541 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
544 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
547 exit_server("smbd_deferred_open_timer: talloc failed\n");
551 /* We leave this message on the queue so the open code can
552 know this is a retry. */
553 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
554 (unsigned long long)mid ));
556 /* Mark the message as processed so this is not
557 * re-processed in error. */
558 msg->processed = true;
560 process_smb(smbd_server_conn, inbuf,
562 msg->seqnum, msg->encrypted, &msg->pcd);
564 /* If it's still there and was processed, remove it. */
565 msg = get_deferred_open_message_smb(mid);
566 if (msg && msg->processed) {
567 remove_deferred_open_message_smb(mid);
571 /****************************************************************************
572 Function to push a message onto the tail of a linked list of smb messages ready
574 ****************************************************************************/
576 static bool push_queued_message(struct smb_request *req,
577 struct timeval request_time,
578 struct timeval end_time,
579 char *private_data, size_t private_len)
581 int msg_len = smb_len(req->inbuf) + 4;
582 struct pending_message_list *msg;
584 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
587 DEBUG(0,("push_message: malloc fail (1)\n"));
591 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
592 if(msg->buf.data == NULL) {
593 DEBUG(0,("push_message: malloc fail (2)\n"));
598 msg->request_time = request_time;
599 msg->seqnum = req->seqnum;
600 msg->encrypted = req->encrypted;
601 msg->processed = false;
602 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
605 msg->private_data = data_blob_talloc(msg, private_data,
607 if (msg->private_data.data == NULL) {
608 DEBUG(0,("push_message: malloc fail (3)\n"));
614 msg->te = event_add_timed(smbd_event_context(),
617 smbd_deferred_open_timer,
620 DEBUG(0,("push_message: event_add_timed failed\n"));
625 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
627 DEBUG(10,("push_message: pushed message length %u on "
628 "deferred_open_queue\n", (unsigned int)msg_len));
633 /****************************************************************************
634 Function to delete a sharing violation open message by mid.
635 ****************************************************************************/
637 void remove_deferred_open_message_smb(uint64_t mid)
639 struct pending_message_list *pml;
641 if (smbd_server_conn->using_smb2) {
642 remove_deferred_open_message_smb2(smbd_server_conn, mid);
646 for (pml = deferred_open_queue; pml; pml = pml->next) {
647 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
648 DEBUG(10,("remove_deferred_open_message_smb: "
649 "deleting mid %llu len %u\n",
650 (unsigned long long)mid,
651 (unsigned int)pml->buf.length ));
652 DLIST_REMOVE(deferred_open_queue, pml);
659 /****************************************************************************
660 Move a sharing violation open retry message to the front of the list and
661 schedule it for immediate processing.
662 ****************************************************************************/
664 void schedule_deferred_open_message_smb(uint64_t mid)
666 struct pending_message_list *pml;
669 if (smbd_server_conn->using_smb2) {
670 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
674 for (pml = deferred_open_queue; pml; pml = pml->next) {
675 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
677 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
680 (unsigned long long)msg_mid ));
682 if (mid == msg_mid) {
683 struct timed_event *te;
685 if (pml->processed) {
686 /* A processed message should not be
688 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
689 "message mid %llu was already processed\n",
690 (unsigned long long)msg_mid ));
694 DEBUG(10,("schedule_deferred_open_message_smb: "
695 "scheduling mid %llu\n",
696 (unsigned long long)mid ));
698 te = event_add_timed(smbd_event_context(),
701 smbd_deferred_open_timer,
704 DEBUG(10,("schedule_deferred_open_message_smb: "
705 "event_add_timed() failed, "
706 "skipping mid %llu\n",
707 (unsigned long long)msg_mid ));
710 TALLOC_FREE(pml->te);
712 DLIST_PROMOTE(deferred_open_queue, pml);
717 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
718 "find message mid %llu\n",
719 (unsigned long long)mid ));
722 /****************************************************************************
723 Return true if this mid is on the deferred queue and was not yet processed.
724 ****************************************************************************/
726 bool open_was_deferred(uint64_t mid)
728 struct pending_message_list *pml;
730 if (smbd_server_conn->using_smb2) {
731 return open_was_deferred_smb2(smbd_server_conn, mid);
734 for (pml = deferred_open_queue; pml; pml = pml->next) {
735 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
742 /****************************************************************************
743 Return the message queued by this mid.
744 ****************************************************************************/
746 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
748 struct pending_message_list *pml;
750 for (pml = deferred_open_queue; pml; pml = pml->next) {
751 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
758 /****************************************************************************
759 Get the state data queued by this mid.
760 ****************************************************************************/
762 bool get_deferred_open_message_state(struct smb_request *smbreq,
763 struct timeval *p_request_time,
766 struct pending_message_list *pml;
768 if (smbd_server_conn->using_smb2) {
769 return get_deferred_open_message_state_smb2(smbreq->smb2req,
774 pml = get_deferred_open_message_smb(smbreq->mid);
778 if (p_request_time) {
779 *p_request_time = pml->request_time;
782 *pp_state = (void *)pml->private_data.data;
787 /****************************************************************************
788 Function to push a deferred open smb message onto a linked list of local smb
789 messages ready for processing.
790 ****************************************************************************/
792 bool push_deferred_open_message_smb(struct smb_request *req,
793 struct timeval request_time,
794 struct timeval timeout,
796 char *private_data, size_t priv_len)
798 struct timeval end_time;
801 return push_deferred_open_message_smb2(req->smb2req,
809 if (req->unread_bytes) {
810 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
811 "unread_bytes = %u\n",
812 (unsigned int)req->unread_bytes ));
813 smb_panic("push_deferred_open_message_smb: "
814 "logic error unread_bytes != 0" );
817 end_time = timeval_sum(&request_time, &timeout);
819 DEBUG(10,("push_deferred_open_message_smb: pushing message "
820 "len %u mid %llu timeout time [%u.%06u]\n",
821 (unsigned int) smb_len(req->inbuf)+4,
822 (unsigned long long)req->mid,
823 (unsigned int)end_time.tv_sec,
824 (unsigned int)end_time.tv_usec));
826 return push_queued_message(req, request_time, end_time,
827 private_data, priv_len);
831 struct timed_event *te;
832 struct timeval interval;
834 bool (*handler)(const struct timeval *now, void *private_data);
838 static void smbd_idle_event_handler(struct event_context *ctx,
839 struct timed_event *te,
843 struct idle_event *event =
844 talloc_get_type_abort(private_data, struct idle_event);
846 TALLOC_FREE(event->te);
848 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
849 event->name, event->te));
851 if (!event->handler(&now, event->private_data)) {
852 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
853 event->name, event->te));
854 /* Don't repeat, delete ourselves */
859 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
860 event->name, event->te));
862 event->te = event_add_timed(ctx, event,
863 timeval_sum(&now, &event->interval),
864 smbd_idle_event_handler, event);
866 /* We can't do much but fail here. */
867 SMB_ASSERT(event->te != NULL);
870 struct idle_event *event_add_idle(struct event_context *event_ctx,
872 struct timeval interval,
874 bool (*handler)(const struct timeval *now,
878 struct idle_event *result;
879 struct timeval now = timeval_current();
881 result = TALLOC_P(mem_ctx, struct idle_event);
882 if (result == NULL) {
883 DEBUG(0, ("talloc failed\n"));
887 result->interval = interval;
888 result->handler = handler;
889 result->private_data = private_data;
891 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
892 DEBUG(0, ("talloc failed\n"));
897 result->te = event_add_timed(event_ctx, result,
898 timeval_sum(&now, &interval),
899 smbd_idle_event_handler, result);
900 if (result->te == NULL) {
901 DEBUG(0, ("event_add_timed failed\n"));
906 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
910 static void smbd_sig_term_handler(struct tevent_context *ev,
911 struct tevent_signal *se,
917 exit_server_cleanly("termination signal");
920 void smbd_setup_sig_term_handler(void)
922 struct tevent_signal *se;
924 se = tevent_add_signal(smbd_event_context(),
925 smbd_event_context(),
927 smbd_sig_term_handler,
930 exit_server("failed to setup SIGTERM handler");
934 static void smbd_sig_hup_handler(struct tevent_context *ev,
935 struct tevent_signal *se,
941 struct messaging_context *msg_ctx = talloc_get_type_abort(
942 private_data, struct messaging_context);
943 change_to_root_user();
944 DEBUG(1,("Reloading services after SIGHUP\n"));
945 reload_services(msg_ctx, smbd_server_conn->sock, False);
947 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
951 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
952 struct messaging_context *msg_ctx)
954 struct tevent_signal *se;
956 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
959 exit_server("failed to setup SIGHUP handler");
963 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
970 to.tv_sec = SMBD_SELECT_TIMEOUT;
974 * Setup the select fd sets.
981 * Are there any timed events waiting ? If so, ensure we don't
982 * select for longer than it would take to wait for them.
985 event_add_to_select_args(smbd_event_context(),
986 &r_fds, &w_fds, &to, &maxfd);
988 /* Process a signal and timed events now... */
989 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
990 return NT_STATUS_RETRY;
995 START_PROFILE(smbd_idle);
997 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
1000 END_PROFILE(smbd_idle);
1004 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
1005 return NT_STATUS_RETRY;
1008 /* Did we timeout ? */
1010 return NT_STATUS_RETRY;
1013 /* should not be reached */
1014 return NT_STATUS_INTERNAL_ERROR;
1018 * Only allow 5 outstanding trans requests. We're allocating memory, so
1022 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1025 for (; list != NULL; list = list->next) {
1027 if (list->mid == mid) {
1028 return NT_STATUS_INVALID_PARAMETER;
1034 return NT_STATUS_INSUFFICIENT_RESOURCES;
1037 return NT_STATUS_OK;
1041 These flags determine some of the permissions required to do an operation
1043 Note that I don't set NEED_WRITE on some write operations because they
1044 are used by some brain-dead clients when printing, and I don't want to
1045 force write permissions on print services.
1047 #define AS_USER (1<<0)
1048 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1049 #define TIME_INIT (1<<2)
1050 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1051 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1052 #define DO_CHDIR (1<<6)
1055 define a list of possible SMB messages and their corresponding
1056 functions. Any message that has a NULL function is unimplemented -
1057 please feel free to contribute implementations!
1059 static const struct smb_message_struct {
1061 void (*fn)(struct smb_request *req);
1063 } smb_messages[256] = {
1065 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1066 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1067 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1068 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1069 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1070 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1071 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1072 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1073 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1074 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1075 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1076 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1077 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1078 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1079 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1080 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1081 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1082 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1083 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1084 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1085 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1086 /* 0x15 */ { NULL, NULL, 0 },
1087 /* 0x16 */ { NULL, NULL, 0 },
1088 /* 0x17 */ { NULL, NULL, 0 },
1089 /* 0x18 */ { NULL, NULL, 0 },
1090 /* 0x19 */ { NULL, NULL, 0 },
1091 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1092 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1093 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1094 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1095 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1096 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1097 /* 0x20 */ { "SMBwritec", NULL,0},
1098 /* 0x21 */ { NULL, NULL, 0 },
1099 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1100 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1101 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1102 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1103 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1104 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1105 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1106 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1107 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1108 /* 0x2b */ { "SMBecho",reply_echo,0},
1109 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1110 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1111 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1112 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1113 /* 0x30 */ { NULL, NULL, 0 },
1114 /* 0x31 */ { NULL, NULL, 0 },
1115 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1116 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1117 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1118 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1119 /* 0x36 */ { NULL, NULL, 0 },
1120 /* 0x37 */ { NULL, NULL, 0 },
1121 /* 0x38 */ { NULL, NULL, 0 },
1122 /* 0x39 */ { NULL, NULL, 0 },
1123 /* 0x3a */ { NULL, NULL, 0 },
1124 /* 0x3b */ { NULL, NULL, 0 },
1125 /* 0x3c */ { NULL, NULL, 0 },
1126 /* 0x3d */ { NULL, NULL, 0 },
1127 /* 0x3e */ { NULL, NULL, 0 },
1128 /* 0x3f */ { NULL, NULL, 0 },
1129 /* 0x40 */ { NULL, NULL, 0 },
1130 /* 0x41 */ { NULL, NULL, 0 },
1131 /* 0x42 */ { NULL, NULL, 0 },
1132 /* 0x43 */ { NULL, NULL, 0 },
1133 /* 0x44 */ { NULL, NULL, 0 },
1134 /* 0x45 */ { NULL, NULL, 0 },
1135 /* 0x46 */ { NULL, NULL, 0 },
1136 /* 0x47 */ { NULL, NULL, 0 },
1137 /* 0x48 */ { NULL, NULL, 0 },
1138 /* 0x49 */ { NULL, NULL, 0 },
1139 /* 0x4a */ { NULL, NULL, 0 },
1140 /* 0x4b */ { NULL, NULL, 0 },
1141 /* 0x4c */ { NULL, NULL, 0 },
1142 /* 0x4d */ { NULL, NULL, 0 },
1143 /* 0x4e */ { NULL, NULL, 0 },
1144 /* 0x4f */ { NULL, NULL, 0 },
1145 /* 0x50 */ { NULL, NULL, 0 },
1146 /* 0x51 */ { NULL, NULL, 0 },
1147 /* 0x52 */ { NULL, NULL, 0 },
1148 /* 0x53 */ { NULL, NULL, 0 },
1149 /* 0x54 */ { NULL, NULL, 0 },
1150 /* 0x55 */ { NULL, NULL, 0 },
1151 /* 0x56 */ { NULL, NULL, 0 },
1152 /* 0x57 */ { NULL, NULL, 0 },
1153 /* 0x58 */ { NULL, NULL, 0 },
1154 /* 0x59 */ { NULL, NULL, 0 },
1155 /* 0x5a */ { NULL, NULL, 0 },
1156 /* 0x5b */ { NULL, NULL, 0 },
1157 /* 0x5c */ { NULL, NULL, 0 },
1158 /* 0x5d */ { NULL, NULL, 0 },
1159 /* 0x5e */ { NULL, NULL, 0 },
1160 /* 0x5f */ { NULL, NULL, 0 },
1161 /* 0x60 */ { NULL, NULL, 0 },
1162 /* 0x61 */ { NULL, NULL, 0 },
1163 /* 0x62 */ { NULL, NULL, 0 },
1164 /* 0x63 */ { NULL, NULL, 0 },
1165 /* 0x64 */ { NULL, NULL, 0 },
1166 /* 0x65 */ { NULL, NULL, 0 },
1167 /* 0x66 */ { NULL, NULL, 0 },
1168 /* 0x67 */ { NULL, NULL, 0 },
1169 /* 0x68 */ { NULL, NULL, 0 },
1170 /* 0x69 */ { NULL, NULL, 0 },
1171 /* 0x6a */ { NULL, NULL, 0 },
1172 /* 0x6b */ { NULL, NULL, 0 },
1173 /* 0x6c */ { NULL, NULL, 0 },
1174 /* 0x6d */ { NULL, NULL, 0 },
1175 /* 0x6e */ { NULL, NULL, 0 },
1176 /* 0x6f */ { NULL, NULL, 0 },
1177 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1178 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1179 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1180 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1181 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1182 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1183 /* 0x76 */ { NULL, NULL, 0 },
1184 /* 0x77 */ { NULL, NULL, 0 },
1185 /* 0x78 */ { NULL, NULL, 0 },
1186 /* 0x79 */ { NULL, NULL, 0 },
1187 /* 0x7a */ { NULL, NULL, 0 },
1188 /* 0x7b */ { NULL, NULL, 0 },
1189 /* 0x7c */ { NULL, NULL, 0 },
1190 /* 0x7d */ { NULL, NULL, 0 },
1191 /* 0x7e */ { NULL, NULL, 0 },
1192 /* 0x7f */ { NULL, NULL, 0 },
1193 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1194 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1195 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1196 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1197 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1198 /* 0x85 */ { NULL, NULL, 0 },
1199 /* 0x86 */ { NULL, NULL, 0 },
1200 /* 0x87 */ { NULL, NULL, 0 },
1201 /* 0x88 */ { NULL, NULL, 0 },
1202 /* 0x89 */ { NULL, NULL, 0 },
1203 /* 0x8a */ { NULL, NULL, 0 },
1204 /* 0x8b */ { NULL, NULL, 0 },
1205 /* 0x8c */ { NULL, NULL, 0 },
1206 /* 0x8d */ { NULL, NULL, 0 },
1207 /* 0x8e */ { NULL, NULL, 0 },
1208 /* 0x8f */ { NULL, NULL, 0 },
1209 /* 0x90 */ { NULL, NULL, 0 },
1210 /* 0x91 */ { NULL, NULL, 0 },
1211 /* 0x92 */ { NULL, NULL, 0 },
1212 /* 0x93 */ { NULL, NULL, 0 },
1213 /* 0x94 */ { NULL, NULL, 0 },
1214 /* 0x95 */ { NULL, NULL, 0 },
1215 /* 0x96 */ { NULL, NULL, 0 },
1216 /* 0x97 */ { NULL, NULL, 0 },
1217 /* 0x98 */ { NULL, NULL, 0 },
1218 /* 0x99 */ { NULL, NULL, 0 },
1219 /* 0x9a */ { NULL, NULL, 0 },
1220 /* 0x9b */ { NULL, NULL, 0 },
1221 /* 0x9c */ { NULL, NULL, 0 },
1222 /* 0x9d */ { NULL, NULL, 0 },
1223 /* 0x9e */ { NULL, NULL, 0 },
1224 /* 0x9f */ { NULL, NULL, 0 },
1225 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1226 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1227 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1228 /* 0xa3 */ { NULL, NULL, 0 },
1229 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1230 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1231 /* 0xa6 */ { NULL, NULL, 0 },
1232 /* 0xa7 */ { NULL, NULL, 0 },
1233 /* 0xa8 */ { NULL, NULL, 0 },
1234 /* 0xa9 */ { NULL, NULL, 0 },
1235 /* 0xaa */ { NULL, NULL, 0 },
1236 /* 0xab */ { NULL, NULL, 0 },
1237 /* 0xac */ { NULL, NULL, 0 },
1238 /* 0xad */ { NULL, NULL, 0 },
1239 /* 0xae */ { NULL, NULL, 0 },
1240 /* 0xaf */ { NULL, NULL, 0 },
1241 /* 0xb0 */ { NULL, NULL, 0 },
1242 /* 0xb1 */ { NULL, NULL, 0 },
1243 /* 0xb2 */ { NULL, NULL, 0 },
1244 /* 0xb3 */ { NULL, NULL, 0 },
1245 /* 0xb4 */ { NULL, NULL, 0 },
1246 /* 0xb5 */ { NULL, NULL, 0 },
1247 /* 0xb6 */ { NULL, NULL, 0 },
1248 /* 0xb7 */ { NULL, NULL, 0 },
1249 /* 0xb8 */ { NULL, NULL, 0 },
1250 /* 0xb9 */ { NULL, NULL, 0 },
1251 /* 0xba */ { NULL, NULL, 0 },
1252 /* 0xbb */ { NULL, NULL, 0 },
1253 /* 0xbc */ { NULL, NULL, 0 },
1254 /* 0xbd */ { NULL, NULL, 0 },
1255 /* 0xbe */ { NULL, NULL, 0 },
1256 /* 0xbf */ { NULL, NULL, 0 },
1257 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1258 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1259 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1260 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1261 /* 0xc4 */ { NULL, NULL, 0 },
1262 /* 0xc5 */ { NULL, NULL, 0 },
1263 /* 0xc6 */ { NULL, NULL, 0 },
1264 /* 0xc7 */ { NULL, NULL, 0 },
1265 /* 0xc8 */ { NULL, NULL, 0 },
1266 /* 0xc9 */ { NULL, NULL, 0 },
1267 /* 0xca */ { NULL, NULL, 0 },
1268 /* 0xcb */ { NULL, NULL, 0 },
1269 /* 0xcc */ { NULL, NULL, 0 },
1270 /* 0xcd */ { NULL, NULL, 0 },
1271 /* 0xce */ { NULL, NULL, 0 },
1272 /* 0xcf */ { NULL, NULL, 0 },
1273 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1274 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1275 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1276 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1277 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1278 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1279 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1280 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1281 /* 0xd8 */ { NULL, NULL, 0 },
1282 /* 0xd9 */ { NULL, NULL, 0 },
1283 /* 0xda */ { NULL, NULL, 0 },
1284 /* 0xdb */ { NULL, NULL, 0 },
1285 /* 0xdc */ { NULL, NULL, 0 },
1286 /* 0xdd */ { NULL, NULL, 0 },
1287 /* 0xde */ { NULL, NULL, 0 },
1288 /* 0xdf */ { NULL, NULL, 0 },
1289 /* 0xe0 */ { NULL, NULL, 0 },
1290 /* 0xe1 */ { NULL, NULL, 0 },
1291 /* 0xe2 */ { NULL, NULL, 0 },
1292 /* 0xe3 */ { NULL, NULL, 0 },
1293 /* 0xe4 */ { NULL, NULL, 0 },
1294 /* 0xe5 */ { NULL, NULL, 0 },
1295 /* 0xe6 */ { NULL, NULL, 0 },
1296 /* 0xe7 */ { NULL, NULL, 0 },
1297 /* 0xe8 */ { NULL, NULL, 0 },
1298 /* 0xe9 */ { NULL, NULL, 0 },
1299 /* 0xea */ { NULL, NULL, 0 },
1300 /* 0xeb */ { NULL, NULL, 0 },
1301 /* 0xec */ { NULL, NULL, 0 },
1302 /* 0xed */ { NULL, NULL, 0 },
1303 /* 0xee */ { NULL, NULL, 0 },
1304 /* 0xef */ { NULL, NULL, 0 },
1305 /* 0xf0 */ { NULL, NULL, 0 },
1306 /* 0xf1 */ { NULL, NULL, 0 },
1307 /* 0xf2 */ { NULL, NULL, 0 },
1308 /* 0xf3 */ { NULL, NULL, 0 },
1309 /* 0xf4 */ { NULL, NULL, 0 },
1310 /* 0xf5 */ { NULL, NULL, 0 },
1311 /* 0xf6 */ { NULL, NULL, 0 },
1312 /* 0xf7 */ { NULL, NULL, 0 },
1313 /* 0xf8 */ { NULL, NULL, 0 },
1314 /* 0xf9 */ { NULL, NULL, 0 },
1315 /* 0xfa */ { NULL, NULL, 0 },
1316 /* 0xfb */ { NULL, NULL, 0 },
1317 /* 0xfc */ { NULL, NULL, 0 },
1318 /* 0xfd */ { NULL, NULL, 0 },
1319 /* 0xfe */ { NULL, NULL, 0 },
1320 /* 0xff */ { NULL, NULL, 0 }
1324 /*******************************************************************
1325 allocate and initialize a reply packet
1326 ********************************************************************/
1328 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1329 const char *inbuf, char **outbuf, uint8_t num_words,
1333 * Protect against integer wrap
1335 if ((num_bytes > 0xffffff)
1336 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1338 if (asprintf(&msg, "num_bytes too large: %u",
1339 (unsigned)num_bytes) == -1) {
1340 msg = CONST_DISCARD(char *, "num_bytes too large");
1345 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1346 smb_size + num_words*2 + num_bytes);
1347 if (*outbuf == NULL) {
1351 construct_reply_common(req, inbuf, *outbuf);
1352 srv_set_message(*outbuf, num_words, num_bytes, false);
1354 * Zero out the word area, the caller has to take care of the bcc area
1357 if (num_words != 0) {
1358 memset(*outbuf + smb_vwv0, 0, num_words*2);
1364 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1367 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1369 smb_panic("could not allocate output buffer\n");
1371 req->outbuf = (uint8_t *)outbuf;
1375 /*******************************************************************
1376 Dump a packet to a file.
1377 ********************************************************************/
1379 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1383 if (DEBUGLEVEL < 50) {
1387 if (len < 4) len = smb_len(data)+4;
1388 for (i=1;i<100;i++) {
1389 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1390 type ? "req" : "resp") == -1) {
1393 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1394 if (fd != -1 || errno != EEXIST) break;
1397 ssize_t ret = write(fd, data, len);
1399 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1401 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1406 /****************************************************************************
1407 Prepare everything for calling the actual request function, and potentially
1408 call the request function via the "new" interface.
1410 Return False if the "legacy" function needs to be called, everything is
1413 Return True if we're done.
1415 I know this API sucks, but it is the one with the least code change I could
1417 ****************************************************************************/
1419 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1423 connection_struct *conn = NULL;
1424 struct smbd_server_connection *sconn = req->sconn;
1428 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1429 * so subtract 4 from it. */
1430 if (!valid_smb_header(req->inbuf)
1431 || (size < (smb_size - 4))) {
1432 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1433 smb_len(req->inbuf)));
1434 exit_server_cleanly("Non-SMB packet");
1437 if (smb_messages[type].fn == NULL) {
1438 DEBUG(0,("Unknown message type %d!\n",type));
1439 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1440 reply_unknown_new(req, type);
1444 flags = smb_messages[type].flags;
1446 /* In share mode security we must ignore the vuid. */
1447 session_tag = (lp_security() == SEC_SHARE)
1448 ? UID_FIELD_INVALID : req->vuid;
1451 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1452 (int)sys_getpid(), (unsigned long)conn));
1454 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1456 /* Ensure this value is replaced in the incoming packet. */
1457 SSVAL(req->inbuf,smb_uid,session_tag);
1460 * Ensure the correct username is in current_user_info. This is a
1461 * really ugly bugfix for problems with multiple session_setup_and_X's
1462 * being done and allowing %U and %G substitutions to work correctly.
1463 * There is a reason this code is done here, don't move it unless you
1464 * know what you're doing... :-).
1468 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1469 user_struct *vuser = NULL;
1471 sconn->smb1.sessions.last_session_tag = session_tag;
1472 if(session_tag != UID_FIELD_INVALID) {
1473 vuser = get_valid_user_struct(sconn, session_tag);
1475 set_current_user_info(
1476 vuser->server_info->sanitized_username,
1477 vuser->server_info->unix_name,
1478 vuser->server_info->info3->base.domain.string);
1483 /* Does this call need to be run as the connected user? */
1484 if (flags & AS_USER) {
1486 /* Does this call need a valid tree connection? */
1489 * Amazingly, the error code depends on the command
1492 if (type == SMBntcreateX) {
1493 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1495 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1500 if (!change_to_user(conn,session_tag)) {
1501 DEBUG(0, ("Error: Could not change to user. Removing "
1502 "deferred open, mid=%llu.\n",
1503 (unsigned long long)req->mid));
1504 reply_force_doserror(req, ERRSRV, ERRbaduid);
1508 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1510 /* Does it need write permission? */
1511 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1512 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1516 /* IPC services are limited */
1517 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1518 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1522 /* This call needs to be run as root */
1523 change_to_root_user();
1526 /* load service specific parameters */
1528 if (req->encrypted) {
1529 conn->encrypted_tid = true;
1530 /* encrypted required from now on. */
1531 conn->encrypt_level = Required;
1532 } else if (ENCRYPTION_REQUIRED(conn)) {
1533 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1534 exit_server_cleanly("encryption required "
1540 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1541 (flags & (AS_USER|DO_CHDIR)
1543 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1546 conn->num_smb_operations++;
1549 /* does this protocol need to be run as guest? */
1550 if ((flags & AS_GUEST)
1551 && (!change_to_guest() ||
1552 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1553 sconn->client_id.name,
1554 sconn->client_id.addr))) {
1555 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1559 smb_messages[type].fn(req);
1563 /****************************************************************************
1564 Construct a reply to the incoming packet.
1565 ****************************************************************************/
1567 static void construct_reply(struct smbd_server_connection *sconn,
1568 char *inbuf, int size, size_t unread_bytes,
1569 uint32_t seqnum, bool encrypted,
1570 struct smb_perfcount_data *deferred_pcd)
1572 connection_struct *conn;
1573 struct smb_request *req;
1575 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1576 smb_panic("could not allocate smb_request");
1579 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1580 encrypted, seqnum)) {
1581 exit_server_cleanly("Invalid SMB request");
1584 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1586 /* we popped this message off the queue - keep original perf data */
1588 req->pcd = *deferred_pcd;
1590 SMB_PERFCOUNT_START(&req->pcd);
1591 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1592 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1595 conn = switch_message(req->cmd, req, size);
1597 if (req->unread_bytes) {
1598 /* writeX failed. drain socket. */
1599 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1600 req->unread_bytes) {
1601 smb_panic("failed to drain pending bytes");
1603 req->unread_bytes = 0;
1611 if (req->outbuf == NULL) {
1615 if (CVAL(req->outbuf,0) == 0) {
1616 show_msg((char *)req->outbuf);
1619 if (!srv_send_smb(req->sconn,
1620 (char *)req->outbuf,
1621 true, req->seqnum+1,
1622 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1624 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1632 /****************************************************************************
1633 Process an smb from the client
1634 ****************************************************************************/
1635 static void process_smb(struct smbd_server_connection *sconn,
1636 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1637 uint32_t seqnum, bool encrypted,
1638 struct smb_perfcount_data *deferred_pcd)
1640 int msg_type = CVAL(inbuf,0);
1642 DO_PROFILE_INC(smb_count);
1644 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1646 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1647 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1649 if (msg_type != 0) {
1651 * NetBIOS session request, keepalive, etc.
1653 reply_special(sconn, (char *)inbuf, nread);
1657 if (sconn->using_smb2) {
1658 /* At this point we're not really using smb2,
1659 * we make the decision here.. */
1660 if (smbd_is_smb2_header(inbuf, nread)) {
1661 smbd_smb2_first_negprot(sconn, inbuf, nread);
1663 } else if (nread >= smb_size && valid_smb_header(inbuf)
1664 && CVAL(inbuf, smb_com) != 0x72) {
1665 /* This is a non-negprot SMB1 packet.
1666 Disable SMB2 from now on. */
1667 sconn->using_smb2 = false;
1671 show_msg((char *)inbuf);
1673 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1674 encrypted, deferred_pcd);
1678 sconn->smb1.num_requests++;
1680 /* The timeout_processing function isn't run nearly
1681 often enough to implement 'max log size' without
1682 overrunning the size of the file by many megabytes.
1683 This is especially true if we are running at debug
1684 level 10. Checking every 50 SMBs is a nice
1685 tradeoff of performance vs log file size overrun. */
1687 if ((sconn->smb1.num_requests % 50) == 0 &&
1688 need_to_check_log_size()) {
1689 change_to_root_user();
1694 /****************************************************************************
1695 Return a string containing the function name of a SMB command.
1696 ****************************************************************************/
1698 const char *smb_fn_name(int type)
1700 const char *unknown_name = "SMBunknown";
1702 if (smb_messages[type].name == NULL)
1703 return(unknown_name);
1705 return(smb_messages[type].name);
1708 /****************************************************************************
1709 Helper functions for contruct_reply.
1710 ****************************************************************************/
1712 void add_to_common_flags2(uint32 v)
1717 void remove_from_common_flags2(uint32 v)
1719 common_flags2 &= ~v;
1722 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1725 srv_set_message(outbuf,0,0,false);
1727 SCVAL(outbuf, smb_com, req->cmd);
1728 SIVAL(outbuf,smb_rcls,0);
1729 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1730 SSVAL(outbuf,smb_flg2,
1731 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1733 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1735 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1736 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1737 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1738 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1741 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1743 construct_reply_common(req, (char *)req->inbuf, outbuf);
1747 * How many bytes have we already accumulated up to the current wct field
1751 size_t req_wct_ofs(struct smb_request *req)
1755 if (req->chain_outbuf == NULL) {
1758 buf_size = talloc_get_size(req->chain_outbuf);
1759 if ((buf_size % 4) != 0) {
1760 buf_size += (4 - (buf_size % 4));
1762 return buf_size - 4;
1766 * Hack around reply_nterror & friends not being aware of chained requests,
1767 * generating illegal (i.e. wct==0) chain replies.
1770 static void fixup_chain_error_packet(struct smb_request *req)
1772 uint8_t *outbuf = req->outbuf;
1774 reply_outbuf(req, 2, 0);
1775 memcpy(req->outbuf, outbuf, smb_wct);
1776 TALLOC_FREE(outbuf);
1777 SCVAL(req->outbuf, smb_vwv0, 0xff);
1781 * @brief Find the smb_cmd offset of the last command pushed
1782 * @param[in] buf The buffer we're building up
1783 * @retval Where can we put our next andx cmd?
1785 * While chaining requests, the "next" request we're looking at needs to put
1786 * its SMB_Command before the data the previous request already built up added
1787 * to the chain. Find the offset to the place where we have to put our cmd.
1790 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1795 cmd = CVAL(buf, smb_com);
1797 SMB_ASSERT(is_andx_req(cmd));
1801 while (CVAL(buf, ofs) != 0xff) {
1803 if (!is_andx_req(CVAL(buf, ofs))) {
1808 * ofs is from start of smb header, so add the 4 length
1809 * bytes. The next cmd is right after the wct field.
1811 ofs = SVAL(buf, ofs+2) + 4 + 1;
1813 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1821 * @brief Do the smb chaining at a buffer level
1822 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1823 * @param[in] smb_command The command that we want to issue
1824 * @param[in] wct How many words?
1825 * @param[in] vwv The words, already in network order
1826 * @param[in] bytes_alignment How shall we align "bytes"?
1827 * @param[in] num_bytes How many bytes?
1828 * @param[in] bytes The data the request ships
1830 * smb_splice_chain() adds the vwv and bytes to the request already present in
1834 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1835 uint8_t wct, const uint16_t *vwv,
1836 size_t bytes_alignment,
1837 uint32_t num_bytes, const uint8_t *bytes)
1840 size_t old_size, new_size;
1842 size_t chain_padding = 0;
1843 size_t bytes_padding = 0;
1846 old_size = talloc_get_size(*poutbuf);
1849 * old_size == smb_wct means we're pushing the first request in for
1853 first_request = (old_size == smb_wct);
1855 if (!first_request && ((old_size % 4) != 0)) {
1857 * Align the wct field of subsequent requests to a 4-byte
1860 chain_padding = 4 - (old_size % 4);
1864 * After the old request comes the new wct field (1 byte), the vwv's
1865 * and the num_bytes field. After at we might need to align the bytes
1866 * given to us to "bytes_alignment", increasing the num_bytes value.
1869 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1871 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1872 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1875 new_size += bytes_padding + num_bytes;
1877 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1878 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1879 (unsigned)new_size));
1883 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1884 if (outbuf == NULL) {
1885 DEBUG(0, ("talloc failed\n"));
1890 if (first_request) {
1891 SCVAL(outbuf, smb_com, smb_command);
1893 size_t andx_cmd_ofs;
1895 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1896 DEBUG(1, ("invalid command chain\n"));
1897 *poutbuf = TALLOC_REALLOC_ARRAY(
1898 NULL, *poutbuf, uint8_t, old_size);
1902 if (chain_padding != 0) {
1903 memset(outbuf + old_size, 0, chain_padding);
1904 old_size += chain_padding;
1907 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1908 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1914 * Push the chained request:
1919 SCVAL(outbuf, ofs, wct);
1926 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1927 ofs += sizeof(uint16_t) * wct;
1933 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1934 ofs += sizeof(uint16_t);
1940 if (bytes_padding != 0) {
1941 memset(outbuf + ofs, 0, bytes_padding);
1942 ofs += bytes_padding;
1949 memcpy(outbuf + ofs, bytes, num_bytes);
1954 /****************************************************************************
1955 Construct a chained reply and add it to the already made reply
1956 ****************************************************************************/
1958 void chain_reply(struct smb_request *req)
1960 size_t smblen = smb_len(req->inbuf);
1961 size_t already_used, length_needed;
1963 uint32_t chain_offset; /* uint32_t to avoid overflow */
1970 if (IVAL(req->outbuf, smb_rcls) != 0) {
1971 fixup_chain_error_packet(req);
1975 * Any of the AndX requests and replies have at least a wct of
1976 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1977 * beginning of the SMB header to the next wct field.
1979 * None of the AndX requests put anything valuable in vwv[0] and [1],
1980 * so we can overwrite it here to form the chain.
1983 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1984 if (req->chain_outbuf == NULL) {
1985 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1986 req, req->outbuf, uint8_t,
1987 smb_len(req->outbuf) + 4);
1988 if (req->chain_outbuf == NULL) {
1989 smb_panic("talloc failed");
1997 * Here we assume that this is the end of the chain. For that we need
1998 * to set "next command" to 0xff and the offset to 0. If we later find
1999 * more commands in the chain, this will be overwritten again.
2002 SCVAL(req->outbuf, smb_vwv0, 0xff);
2003 SCVAL(req->outbuf, smb_vwv0+1, 0);
2004 SSVAL(req->outbuf, smb_vwv1, 0);
2006 if (req->chain_outbuf == NULL) {
2008 * In req->chain_outbuf we collect all the replies. Start the
2009 * chain by copying in the first reply.
2011 * We do the realloc because later on we depend on
2012 * talloc_get_size to determine the length of
2013 * chain_outbuf. The reply_xxx routines might have
2014 * over-allocated (reply_pipe_read_and_X used to be such an
2017 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2018 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2019 if (req->chain_outbuf == NULL) {
2020 smb_panic("talloc failed");
2025 * Update smb headers where subsequent chained commands
2026 * may have updated them.
2028 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2029 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2031 if (!smb_splice_chain(&req->chain_outbuf,
2032 CVAL(req->outbuf, smb_com),
2033 CVAL(req->outbuf, smb_wct),
2034 (uint16_t *)(req->outbuf + smb_vwv),
2035 0, smb_buflen(req->outbuf),
2036 (uint8_t *)smb_buf(req->outbuf))) {
2039 TALLOC_FREE(req->outbuf);
2043 * We use the old request's vwv field to grab the next chained command
2044 * and offset into the chained fields.
2047 chain_cmd = CVAL(req->vwv+0, 0);
2048 chain_offset = SVAL(req->vwv+1, 0);
2050 if (chain_cmd == 0xff) {
2052 * End of chain, no more requests from the client. So ship the
2055 smb_setlen((char *)(req->chain_outbuf),
2056 talloc_get_size(req->chain_outbuf) - 4);
2058 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2059 true, req->seqnum+1,
2060 IS_CONN_ENCRYPTED(req->conn)
2063 exit_server_cleanly("chain_reply: srv_send_smb "
2066 TALLOC_FREE(req->chain_outbuf);
2071 /* add a new perfcounter for this element of chain */
2072 SMB_PERFCOUNT_ADD(&req->pcd);
2073 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2074 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2077 * Check if the client tries to fool us. The request so far uses the
2078 * space to the end of the byte buffer in the request just
2079 * processed. The chain_offset can't point into that area. If that was
2080 * the case, we could end up with an endless processing of the chain,
2081 * we would always handle the same request.
2084 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2085 if (chain_offset < already_used) {
2090 * Next check: Make sure the chain offset does not point beyond the
2091 * overall smb request length.
2094 length_needed = chain_offset+1; /* wct */
2095 if (length_needed > smblen) {
2100 * Now comes the pointer magic. Goal here is to set up req->vwv and
2101 * req->buf correctly again to be able to call the subsequent
2102 * switch_message(). The chain offset (the former vwv[1]) points at
2103 * the new wct field.
2106 wct = CVAL(smb_base(req->inbuf), chain_offset);
2109 * Next consistency check: Make the new vwv array fits in the overall
2113 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2114 if (length_needed > smblen) {
2117 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2120 * Now grab the new byte buffer....
2123 buflen = SVAL(vwv+wct, 0);
2126 * .. and check that it fits.
2129 length_needed += buflen;
2130 if (length_needed > smblen) {
2133 buf = (uint8_t *)(vwv+wct+1);
2135 req->cmd = chain_cmd;
2138 req->buflen = buflen;
2141 switch_message(chain_cmd, req, smblen);
2143 if (req->outbuf == NULL) {
2145 * This happens if the chained command has suspended itself or
2146 * if it has called srv_send_smb() itself.
2152 * We end up here if the chained command was not itself chained or
2153 * suspended, but for example a close() command. We now need to splice
2154 * the chained commands' outbuf into the already built up chain_outbuf
2155 * and ship the result.
2161 * We end up here if there's any error in the chain syntax. Report a
2162 * DOS error, just like Windows does.
2164 reply_force_doserror(req, ERRSRV, ERRerror);
2165 fixup_chain_error_packet(req);
2169 * This scary statement intends to set the
2170 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2171 * to the value req->outbuf carries
2173 SSVAL(req->chain_outbuf, smb_flg2,
2174 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2175 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2178 * Transfer the error codes from the subrequest to the main one
2180 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2181 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2183 if (!smb_splice_chain(&req->chain_outbuf,
2184 CVAL(req->outbuf, smb_com),
2185 CVAL(req->outbuf, smb_wct),
2186 (uint16_t *)(req->outbuf + smb_vwv),
2187 0, smb_buflen(req->outbuf),
2188 (uint8_t *)smb_buf(req->outbuf))) {
2189 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2191 TALLOC_FREE(req->outbuf);
2193 smb_setlen((char *)(req->chain_outbuf),
2194 talloc_get_size(req->chain_outbuf) - 4);
2196 show_msg((char *)(req->chain_outbuf));
2198 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2199 true, req->seqnum+1,
2200 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2202 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2204 TALLOC_FREE(req->chain_outbuf);
2208 /****************************************************************************
2209 Check if services need reloading.
2210 ****************************************************************************/
2212 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2215 if (last_smb_conf_reload_time == 0) {
2216 last_smb_conf_reload_time = t;
2219 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2220 reload_services(sconn->msg_ctx, sconn->sock, True);
2221 last_smb_conf_reload_time = t;
2225 static bool fd_is_readable(int fd)
2228 struct timeval timeout = {0, };
2234 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2238 return FD_ISSET(fd, &fds);
2241 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2243 /* TODO: make write nonblocking */
2246 static void smbd_server_connection_read_handler(
2247 struct smbd_server_connection *conn, int fd)
2249 uint8_t *inbuf = NULL;
2250 size_t inbuf_len = 0;
2251 size_t unread_bytes = 0;
2252 bool encrypted = false;
2253 TALLOC_CTX *mem_ctx = talloc_tos();
2257 bool from_client = (conn->sock == fd);
2260 smbd_lock_socket(conn);
2262 if (!fd_is_readable(fd)) {
2263 DEBUG(10,("the echo listener was faster\n"));
2264 smbd_unlock_socket(conn);
2268 /* TODO: make this completely nonblocking */
2269 status = receive_smb_talloc(mem_ctx, conn,
2270 (char **)(void *)&inbuf,
2274 &inbuf_len, &seqnum,
2275 false /* trusted channel */);
2276 smbd_unlock_socket(conn);
2278 /* TODO: make this completely nonblocking */
2279 status = receive_smb_talloc(mem_ctx, conn,
2280 (char **)(void *)&inbuf,
2284 &inbuf_len, &seqnum,
2285 true /* trusted channel */);
2288 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2291 if (NT_STATUS_IS_ERR(status)) {
2292 exit_server_cleanly("failed to receive smb request");
2294 if (!NT_STATUS_IS_OK(status)) {
2299 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2300 seqnum, encrypted, NULL);
2303 static void smbd_server_connection_handler(struct event_context *ev,
2304 struct fd_event *fde,
2308 struct smbd_server_connection *conn = talloc_get_type(private_data,
2309 struct smbd_server_connection);
2311 if (flags & EVENT_FD_WRITE) {
2312 smbd_server_connection_write_handler(conn);
2315 if (flags & EVENT_FD_READ) {
2316 smbd_server_connection_read_handler(conn, conn->sock);
2321 static void smbd_server_echo_handler(struct event_context *ev,
2322 struct fd_event *fde,
2326 struct smbd_server_connection *conn = talloc_get_type(private_data,
2327 struct smbd_server_connection);
2329 if (flags & EVENT_FD_WRITE) {
2330 smbd_server_connection_write_handler(conn);
2333 if (flags & EVENT_FD_READ) {
2334 smbd_server_connection_read_handler(
2335 conn, conn->smb1.echo_handler.trusted_fd);
2340 /****************************************************************************
2341 received when we should release a specific IP
2342 ****************************************************************************/
2343 static void release_ip(const char *ip, void *priv)
2345 const char *addr = (const char *)priv;
2346 const char *p = addr;
2348 if (strncmp("::ffff:", addr, 7) == 0) {
2352 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2353 /* we can't afford to do a clean exit - that involves
2354 database writes, which would potentially mean we
2355 are still running after the failover has finished -
2356 we have to get rid of this process ID straight
2358 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2360 /* note we must exit with non-zero status so the unclean handler gets
2361 called in the parent, so that the brl database is tickled */
2366 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2367 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2369 struct smbd_server_connection *sconn = talloc_get_type_abort(
2370 private_data, struct smbd_server_connection);
2372 release_ip((char *)data->data, sconn->client_id.addr);
2375 #ifdef CLUSTER_SUPPORT
2376 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2377 struct sockaddr_storage *client)
2380 length = sizeof(*server);
2381 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2384 length = sizeof(*client);
2385 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2393 * Send keepalive packets to our client
2395 static bool keepalive_fn(const struct timeval *now, void *private_data)
2397 struct smbd_server_connection *sconn = smbd_server_conn;
2400 if (sconn->using_smb2) {
2401 /* Don't do keepalives on an SMB2 connection. */
2405 smbd_lock_socket(smbd_server_conn);
2406 ret = send_keepalive(sconn->sock);
2407 smbd_unlock_socket(smbd_server_conn);
2410 char addr[INET6_ADDRSTRLEN];
2412 * Try and give an error message saying what
2415 DEBUG(0, ("send_keepalive failed for client %s. "
2416 "Error %s - exiting\n",
2417 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2425 * Do the recurring check if we're idle
2427 static bool deadtime_fn(const struct timeval *now, void *private_data)
2429 struct smbd_server_connection *sconn =
2430 (struct smbd_server_connection *)private_data;
2432 if ((conn_num_open(sconn) == 0)
2433 || (conn_idle_all(sconn, now->tv_sec))) {
2434 DEBUG( 2, ( "Closing idle connection\n" ) );
2435 messaging_send(sconn->msg_ctx,
2436 messaging_server_id(sconn->msg_ctx),
2437 MSG_SHUTDOWN, &data_blob_null);
2445 * Do the recurring log file and smb.conf reload checks.
2448 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2450 struct smbd_server_connection *sconn = talloc_get_type_abort(
2451 private_data, struct smbd_server_connection);
2453 DEBUG(5, ("housekeeping\n"));
2455 change_to_root_user();
2457 /* update printer queue caches if necessary */
2458 update_monitored_printq_cache(sconn->msg_ctx);
2460 /* check if we need to reload services */
2461 check_reload(sconn, time_mono(NULL));
2463 /* Change machine password if neccessary. */
2464 attempt_machine_password_change();
2467 * Force a log file check.
2469 force_check_log_size();
2474 static int create_unlink_tmp(const char *dir)
2479 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2480 if (fname == NULL) {
2484 fd = mkstemp(fname);
2489 if (unlink(fname) == -1) {
2490 int sys_errno = errno;
2500 struct smbd_echo_state {
2501 struct tevent_context *ev;
2502 struct iovec *pending;
2503 struct smbd_server_connection *sconn;
2506 struct tevent_fd *parent_fde;
2508 struct tevent_fd *read_fde;
2509 struct tevent_req *write_req;
2512 static void smbd_echo_writer_done(struct tevent_req *req);
2514 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2518 if (state->write_req != NULL) {
2522 num_pending = talloc_array_length(state->pending);
2523 if (num_pending == 0) {
2527 state->write_req = writev_send(state, state->ev, NULL,
2528 state->parent_pipe, false,
2529 state->pending, num_pending);
2530 if (state->write_req == NULL) {
2531 DEBUG(1, ("writev_send failed\n"));
2535 talloc_steal(state->write_req, state->pending);
2536 state->pending = NULL;
2538 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2542 static void smbd_echo_writer_done(struct tevent_req *req)
2544 struct smbd_echo_state *state = tevent_req_callback_data(
2545 req, struct smbd_echo_state);
2549 written = writev_recv(req, &err);
2551 state->write_req = NULL;
2552 if (written == -1) {
2553 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2556 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2557 smbd_echo_activate_writer(state);
2560 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2563 struct smb_request req;
2564 uint16_t num_replies;
2569 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2570 DEBUG(10, ("Got netbios keepalive\n"));
2577 if (inbuf_len < smb_size) {
2578 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2581 if (!valid_smb_header(inbuf)) {
2582 DEBUG(10, ("Got invalid SMB header\n"));
2586 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2592 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2593 smb_messages[req.cmd].name
2594 ? smb_messages[req.cmd].name : "unknown"));
2596 if (req.cmd != SMBecho) {
2603 num_replies = SVAL(req.vwv+0, 0);
2604 if (num_replies != 1) {
2605 /* Not a Windows "Hey, you're still there?" request */
2609 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2611 DEBUG(10, ("create_outbuf failed\n"));
2614 req.outbuf = (uint8_t *)outbuf;
2616 SSVAL(req.outbuf, smb_vwv0, num_replies);
2618 if (req.buflen > 0) {
2619 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2622 out_len = smb_len(req.outbuf) + 4;
2624 ok = srv_send_smb(req.sconn,
2628 TALLOC_FREE(outbuf);
2636 static void smbd_echo_exit(struct tevent_context *ev,
2637 struct tevent_fd *fde, uint16_t flags,
2640 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2644 static void smbd_echo_reader(struct tevent_context *ev,
2645 struct tevent_fd *fde, uint16_t flags,
2648 struct smbd_echo_state *state = talloc_get_type_abort(
2649 private_data, struct smbd_echo_state);
2650 struct smbd_server_connection *sconn = state->sconn;
2651 size_t unread, num_pending;
2655 uint32_t seqnum = 0;
2658 bool encrypted = false;
2662 ok = smbd_lock_socket_internal(sconn);
2664 DEBUG(0, ("%s: failed to lock socket\n",
2669 if (!fd_is_readable(sconn->sock)) {
2670 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2671 (int)sys_getpid()));
2672 ok = smbd_unlock_socket_internal(sconn);
2674 DEBUG(1, ("%s: failed to unlock socket in\n",
2681 num_pending = talloc_array_length(state->pending);
2682 tmp = talloc_realloc(state, state->pending, struct iovec,
2685 DEBUG(1, ("talloc_realloc failed\n"));
2688 state->pending = tmp;
2690 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2692 status = receive_smb_talloc(state->pending, sconn,
2693 (char **)(void *)&state->pending[num_pending].iov_base,
2699 false /* trusted_channel*/);
2700 if (!NT_STATUS_IS_OK(status)) {
2701 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2702 (int)sys_getpid(), nt_errstr(status)));
2705 state->pending[num_pending].iov_len = iov_len;
2707 ok = smbd_unlock_socket_internal(sconn);
2709 DEBUG(1, ("%s: failed to unlock socket in\n",
2714 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2715 state->pending[num_pending].iov_len,
2718 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2719 /* no check, shrinking by some bytes does not fail */
2720 state->pending = talloc_realloc(state, state->pending,
2726 if (state->pending[num_pending].iov_len >= smb_size) {
2728 * place the seqnum in the packet so that the main process
2729 * can reply with signing
2731 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2732 smb_ss_field, seqnum);
2733 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2734 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2737 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2738 smbd_echo_activate_writer(state);
2741 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2744 struct smbd_echo_state *state;
2746 state = talloc_zero(sconn, struct smbd_echo_state);
2747 if (state == NULL) {
2748 DEBUG(1, ("talloc failed\n"));
2751 state->sconn = sconn;
2752 state->parent_pipe = parent_pipe;
2753 state->ev = s3_tevent_context_init(state);
2754 if (state->ev == NULL) {
2755 DEBUG(1, ("tevent_context_init failed\n"));
2759 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2760 TEVENT_FD_READ, smbd_echo_exit,
2762 if (state->parent_fde == NULL) {
2763 DEBUG(1, ("tevent_add_fd failed\n"));
2767 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2768 TEVENT_FD_READ, smbd_echo_reader,
2770 if (state->read_fde == NULL) {
2771 DEBUG(1, ("tevent_add_fd failed\n"));
2777 if (tevent_loop_once(state->ev) == -1) {
2778 DEBUG(1, ("tevent_loop_once failed: %s\n",
2787 * Handle SMBecho requests in a forked child process
2789 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2791 int listener_pipe[2];
2795 res = pipe(listener_pipe);
2797 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2800 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2801 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2802 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2810 close(listener_pipe[0]);
2811 set_blocking(listener_pipe[1], false);
2813 status = reinit_after_fork(sconn->msg_ctx,
2814 smbd_event_context(),
2815 procid_self(), false);
2816 if (!NT_STATUS_IS_OK(status)) {
2817 DEBUG(1, ("reinit_after_fork failed: %s\n",
2818 nt_errstr(status)));
2821 smbd_echo_loop(sconn, listener_pipe[1]);
2824 close(listener_pipe[1]);
2825 listener_pipe[1] = -1;
2826 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2828 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2831 * Without smb signing this is the same as the normal smbd
2832 * listener. This needs to change once signing comes in.
2834 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2836 sconn->smb1.echo_handler.trusted_fd,
2838 smbd_server_echo_handler,
2840 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2841 DEBUG(1, ("event_add_fd failed\n"));
2848 if (listener_pipe[0] != -1) {
2849 close(listener_pipe[0]);
2851 if (listener_pipe[1] != -1) {
2852 close(listener_pipe[1]);
2854 sconn->smb1.echo_handler.trusted_fd = -1;
2855 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2856 close(sconn->smb1.echo_handler.socket_lock_fd);
2858 sconn->smb1.echo_handler.trusted_fd = -1;
2859 sconn->smb1.echo_handler.socket_lock_fd = -1;
2865 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2866 struct sockaddr_storage *srv,
2867 struct sockaddr_storage *clnt)
2869 struct ctdbd_connection *cconn;
2870 char tmp_addr[INET6_ADDRSTRLEN];
2873 cconn = messaging_ctdbd_connection();
2874 if (cconn == NULL) {
2875 return NT_STATUS_NO_MEMORY;
2878 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2879 addr = talloc_strdup(cconn, tmp_addr);
2881 return NT_STATUS_NO_MEMORY;
2883 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2888 /****************************************************************************
2889 Process commands from the client
2890 ****************************************************************************/
2892 void smbd_process(struct smbd_server_connection *sconn)
2894 TALLOC_CTX *frame = talloc_stackframe();
2895 struct sockaddr_storage ss;
2896 struct sockaddr *sa = NULL;
2897 socklen_t sa_socklen;
2898 struct tsocket_address *local_address = NULL;
2899 struct tsocket_address *remote_address = NULL;
2900 const char *remaddr = NULL;
2903 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2904 !lp_async_smb_echo_handler()) {
2906 * We're not making the desion here,
2907 * we're just allowing the client
2908 * to decide between SMB1 and SMB2
2909 * with the first negprot
2912 sconn->using_smb2 = true;
2915 /* Ensure child is set to blocking mode */
2916 set_blocking(sconn->sock,True);
2918 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2919 set_socket_options(sconn->sock, lp_socket_options());
2921 sa = (struct sockaddr *)(void *)&ss;
2922 sa_socklen = sizeof(ss);
2923 ret = getpeername(sconn->sock, sa, &sa_socklen);
2925 int level = (errno == ENOTCONN)?2:0;
2926 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2927 exit_server_cleanly("getpeername() failed.\n");
2929 ret = tsocket_address_bsd_from_sockaddr(sconn,
2933 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2934 __location__, strerror(errno)));
2935 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2938 sa = (struct sockaddr *)(void *)&ss;
2939 sa_socklen = sizeof(ss);
2940 ret = getsockname(sconn->sock, sa, &sa_socklen);
2942 int level = (errno == ENOTCONN)?2:0;
2943 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2944 exit_server_cleanly("getsockname() failed.\n");
2946 ret = tsocket_address_bsd_from_sockaddr(sconn,
2950 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2951 __location__, strerror(errno)));
2952 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2955 sconn->local_address = local_address;
2956 sconn->remote_address = remote_address;
2958 if (tsocket_address_is_inet(remote_address, "ip")) {
2959 remaddr = tsocket_address_inet_addr_string(
2960 sconn->remote_address,
2962 if (remaddr == NULL) {
2966 remaddr = "0.0.0.0";
2969 /* this is needed so that we get decent entries
2970 in smbstatus for port 445 connects */
2971 set_remote_machine_name(remaddr, false);
2972 reload_services(sconn->msg_ctx, sconn->sock, true);
2975 * Before the first packet, check the global hosts allow/ hosts deny
2976 * parameters before doing any parsing of packets passed to us by the
2977 * client. This prevents attacks on our parsing code from hosts not in
2978 * the hosts allow list.
2981 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2982 sconn->client_id.name,
2983 sconn->client_id.addr)) {
2985 * send a negative session response "not listening on calling
2988 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2989 DEBUG( 1, ("Connection denied from %s to %s\n",
2990 tsocket_address_string(remote_address, talloc_tos()),
2991 tsocket_address_string(local_address, talloc_tos())));
2992 (void)srv_send_smb(sconn,(char *)buf, false,
2994 exit_server_cleanly("connection denied");
2997 DEBUG(10, ("Connection allowed from %s to %s\n",
2998 tsocket_address_string(remote_address, talloc_tos()),
2999 tsocket_address_string(local_address, talloc_tos())));
3003 smb_perfcount_init();
3005 if (!init_account_policy()) {
3006 exit_server("Could not open account policy tdb.\n");
3009 if (*lp_rootdir()) {
3010 if (chroot(lp_rootdir()) != 0) {
3011 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3012 exit_server("Failed to chroot()");
3014 if (chdir("/") == -1) {
3015 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3016 exit_server("Failed to chroot()");
3018 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3021 if (!srv_init_signing(sconn)) {
3022 exit_server("Failed to init smb_signing");
3025 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3026 exit_server("Failed to fork echo handler");
3030 if (!init_oplocks(sconn->msg_ctx))
3031 exit_server("Failed to init oplocks");
3033 /* register our message handlers */
3034 messaging_register(sconn->msg_ctx, NULL,
3035 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3036 messaging_register(sconn->msg_ctx, sconn,
3037 MSG_SMB_RELEASE_IP, msg_release_ip);
3038 messaging_register(sconn->msg_ctx, NULL,
3039 MSG_SMB_CLOSE_FILE, msg_close_file);
3042 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3043 * MSGs to all child processes
3045 messaging_deregister(sconn->msg_ctx,
3047 messaging_register(sconn->msg_ctx, NULL,
3048 MSG_DEBUG, debug_message);
3050 if ((lp_keepalive() != 0)
3051 && !(event_add_idle(smbd_event_context(), NULL,
3052 timeval_set(lp_keepalive(), 0),
3053 "keepalive", keepalive_fn,
3055 DEBUG(0, ("Could not add keepalive event\n"));
3059 if (!(event_add_idle(smbd_event_context(), NULL,
3060 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3061 "deadtime", deadtime_fn, sconn))) {
3062 DEBUG(0, ("Could not add deadtime event\n"));
3066 if (!(event_add_idle(smbd_event_context(), NULL,
3067 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3068 "housekeeping", housekeeping_fn, sconn))) {
3069 DEBUG(0, ("Could not add housekeeping event\n"));
3073 #ifdef CLUSTER_SUPPORT
3075 if (lp_clustering()) {
3077 * We need to tell ctdb about our client's TCP
3078 * connection, so that for failover ctdbd can send
3079 * tickle acks, triggering a reconnection by the
3083 struct sockaddr_storage srv, clnt;
3085 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3087 status = smbd_register_ips(sconn, &srv, &clnt);
3088 if (!NT_STATUS_IS_OK(status)) {
3089 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3090 nt_errstr(status)));
3094 DEBUG(0,("Unable to get tcp info for "
3095 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3102 sconn->nbt.got_session = false;
3104 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3106 sconn->smb1.sessions.done_sesssetup = false;
3107 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3108 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3109 /* users from session setup */
3110 sconn->smb1.sessions.session_userlist = NULL;
3111 /* workgroup from session setup. */
3112 sconn->smb1.sessions.session_workgroup = NULL;
3113 /* this holds info on user ids that are already validated for this VC */
3114 sconn->smb1.sessions.validated_users = NULL;
3115 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3116 sconn->smb1.sessions.num_validated_vuids = 0;
3119 if (!init_dptrs(sconn)) {
3120 exit_server("init_dptrs() failed");
3123 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3127 smbd_server_connection_handler,
3129 if (!sconn->smb1.fde) {
3130 exit_server("failed to create smbd_server_connection fde");
3138 frame = talloc_stackframe_pool(8192);
3142 status = smbd_server_connection_loop_once(sconn);
3143 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3144 !NT_STATUS_IS_OK(status)) {
3145 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3146 " exiting\n", nt_errstr(status)));
3153 exit_server_cleanly(NULL);
3156 bool req_is_in_chain(struct smb_request *req)
3158 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3160 * We're right now handling a subsequent request, so we must
3166 if (!is_andx_req(req->cmd)) {
3172 * Okay, an illegal request, but definitely not chained :-)
3177 return (CVAL(req->vwv+0, 0) != 0xFF);