2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/filesys.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "librpc/gen_ndr/netlogon.h"
26 #include "librpc/gen_ndr/messaging.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/pcap.h"
31 #include "system/select.h"
36 extern bool global_machine_password_needs_changing;
38 static void construct_reply_common(struct smb_request *req, const char *inbuf,
40 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
42 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
46 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
50 sconn->smb1.echo_handler.ref_count++;
52 if (sconn->smb1.echo_handler.ref_count > 1) {
56 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
60 sconn->smb1.echo_handler.socket_lock_fd,
61 SMB_F_SETLKW, 0, 0, F_WRLCK);
62 } while (!ok && (errno == EINTR));
65 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
69 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
74 void smbd_lock_socket(struct smbd_server_connection *sconn)
76 if (!smbd_lock_socket_internal(sconn)) {
77 exit_server_cleanly("failed to lock socket");
81 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
85 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
89 sconn->smb1.echo_handler.ref_count--;
91 if (sconn->smb1.echo_handler.ref_count > 0) {
97 sconn->smb1.echo_handler.socket_lock_fd,
98 SMB_F_SETLKW, 0, 0, F_UNLCK);
99 } while (!ok && (errno == EINTR));
102 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
106 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
111 void smbd_unlock_socket(struct smbd_server_connection *sconn)
113 if (!smbd_unlock_socket_internal(sconn)) {
114 exit_server_cleanly("failed to unlock socket");
118 /* Accessor function for smb_read_error for smbd functions. */
120 /****************************************************************************
122 ****************************************************************************/
124 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
125 bool do_signing, uint32_t seqnum,
127 struct smb_perfcount_data *pcd)
132 char *buf_out = buffer;
134 smbd_lock_socket(sconn);
137 /* Sign the outgoing packet if required. */
138 srv_calculate_sign_mac(sconn, buf_out, seqnum);
142 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
143 if (!NT_STATUS_IS_OK(status)) {
144 DEBUG(0, ("send_smb: SMB encryption failed "
145 "on outgoing packet! Error %s\n",
146 nt_errstr(status) ));
151 len = smb_len(buf_out) + 4;
153 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
156 char addr[INET6_ADDRSTRLEN];
158 * Try and give an error message saying what
161 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
162 (int)sys_getpid(), (int)len,
163 get_peer_addr(sconn->sock, addr, sizeof(addr)),
164 (int)ret, strerror(errno) ));
166 srv_free_enc_buffer(buf_out);
170 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
171 srv_free_enc_buffer(buf_out);
173 SMB_PERFCOUNT_END(pcd);
175 smbd_unlock_socket(sconn);
179 /*******************************************************************
180 Setup the word count and byte count for a smb message.
181 ********************************************************************/
183 int srv_set_message(char *buf,
188 if (zero && (num_words || num_bytes)) {
189 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
191 SCVAL(buf,smb_wct,num_words);
192 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
193 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
194 return (smb_size + num_words*2 + num_bytes);
197 static bool valid_smb_header(const uint8_t *inbuf)
199 if (is_encrypted_packet(inbuf)) {
203 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
204 * but it just looks weird to call strncmp for this one.
206 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
209 /* Socket functions for smbd packet processing. */
211 static bool valid_packet_size(size_t len)
214 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
215 * of header. Don't print the error if this fits.... JRA.
218 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
219 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
220 (unsigned long)len));
226 static NTSTATUS read_packet_remainder(int fd, char *buffer,
227 unsigned int timeout, ssize_t len)
235 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
236 if (!NT_STATUS_IS_OK(status)) {
237 char addr[INET6_ADDRSTRLEN];
238 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
240 get_peer_addr(fd, addr, sizeof(addr)),
246 /****************************************************************************
247 Attempt a zerocopy writeX read. We know here that len > smb_size-4
248 ****************************************************************************/
251 * Unfortunately, earlier versions of smbclient/libsmbclient
252 * don't send this "standard" writeX header. I've fixed this
253 * for 3.2 but we'll use the old method with earlier versions.
254 * Windows and CIFSFS at least use this standard size. Not
258 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
259 (2*14) + /* word count (including bcc) */ \
262 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
263 const char lenbuf[4],
264 struct smbd_server_connection *sconn,
266 unsigned int timeout,
270 /* Size of a WRITEX call (+4 byte len). */
271 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
272 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
276 memcpy(writeX_header, lenbuf, 4);
278 status = read_fd_with_timeout(
279 sconn->sock, writeX_header + 4,
280 STANDARD_WRITE_AND_X_HEADER_SIZE,
281 STANDARD_WRITE_AND_X_HEADER_SIZE,
284 if (!NT_STATUS_IS_OK(status)) {
285 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
286 "error = %s.\n", sconn->client_id.addr,
292 * Ok - now try and see if this is a possible
296 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
298 * If the data offset is beyond what
299 * we've read, drain the extra bytes.
301 uint16_t doff = SVAL(writeX_header,smb_vwv11);
304 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
305 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
306 if (drain_socket(sconn->sock, drain) != drain) {
307 smb_panic("receive_smb_raw_talloc_partial_read:"
308 " failed to drain pending bytes");
311 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
314 /* Spoof down the length and null out the bcc. */
315 set_message_bcc(writeX_header, 0);
316 newlen = smb_len(writeX_header);
318 /* Copy the header we've written. */
320 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
322 sizeof(writeX_header));
324 if (*buffer == NULL) {
325 DEBUG(0, ("Could not allocate inbuf of length %d\n",
326 (int)sizeof(writeX_header)));
327 return NT_STATUS_NO_MEMORY;
330 /* Work out the remaining bytes. */
331 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
332 *len_ret = newlen + 4;
336 if (!valid_packet_size(len)) {
337 return NT_STATUS_INVALID_PARAMETER;
341 * Not a valid writeX call. Just do the standard
345 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
347 if (*buffer == NULL) {
348 DEBUG(0, ("Could not allocate inbuf of length %d\n",
350 return NT_STATUS_NO_MEMORY;
353 /* Copy in what we already read. */
356 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
357 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
360 status = read_packet_remainder(
362 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
365 if (!NT_STATUS_IS_OK(status)) {
366 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
376 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
377 struct smbd_server_connection *sconn,
378 char **buffer, unsigned int timeout,
379 size_t *p_unread, size_t *plen)
383 int min_recv_size = lp_min_receive_file_size();
388 status = read_smb_length_return_keepalive(sconn->sock, lenbuf, timeout,
390 if (!NT_STATUS_IS_OK(status)) {
394 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
395 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
396 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
397 !srv_is_signing_active(sconn) &&
398 sconn->smb1.echo_handler.trusted_fde == NULL) {
400 return receive_smb_raw_talloc_partial_read(
401 mem_ctx, lenbuf, sconn, buffer, timeout,
405 if (!valid_packet_size(len)) {
406 return NT_STATUS_INVALID_PARAMETER;
410 * The +4 here can't wrap, we've checked the length above already.
413 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
415 if (*buffer == NULL) {
416 DEBUG(0, ("Could not allocate inbuf of length %d\n",
418 return NT_STATUS_NO_MEMORY;
421 memcpy(*buffer, lenbuf, sizeof(lenbuf));
423 status = read_packet_remainder(sconn->sock, (*buffer)+4, timeout, len);
424 if (!NT_STATUS_IS_OK(status)) {
432 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
433 struct smbd_server_connection *sconn,
434 char **buffer, unsigned int timeout,
435 size_t *p_unread, bool *p_encrypted,
438 bool trusted_channel)
443 *p_encrypted = false;
445 status = receive_smb_raw_talloc(mem_ctx, sconn, buffer, timeout,
447 if (!NT_STATUS_IS_OK(status)) {
448 DEBUG(1, ("read_smb_length_return_keepalive failed for "
449 "client %s read error = %s.\n",
450 sconn->client_id.addr, nt_errstr(status)));
454 if (is_encrypted_packet((uint8_t *)*buffer)) {
455 status = srv_decrypt_buffer(*buffer);
456 if (!NT_STATUS_IS_OK(status)) {
457 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
458 "incoming packet! Error %s\n",
459 nt_errstr(status) ));
465 /* Check the incoming SMB signature. */
466 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
467 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
468 "incoming packet!\n"));
469 return NT_STATUS_INVALID_NETWORK_RESPONSE;
477 * Initialize a struct smb_request from an inbuf
480 static bool init_smb_request(struct smb_request *req,
481 struct smbd_server_connection *sconn,
483 size_t unread_bytes, bool encrypted,
486 size_t req_size = smb_len(inbuf) + 4;
487 /* Ensure we have at least smb_size bytes. */
488 if (req_size < smb_size) {
489 DEBUG(0,("init_smb_request: invalid request size %u\n",
490 (unsigned int)req_size ));
493 req->cmd = CVAL(inbuf, smb_com);
494 req->flags2 = SVAL(inbuf, smb_flg2);
495 req->smbpid = SVAL(inbuf, smb_pid);
496 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
497 req->seqnum = seqnum;
498 req->vuid = SVAL(inbuf, smb_uid);
499 req->tid = SVAL(inbuf, smb_tid);
500 req->wct = CVAL(inbuf, smb_wct);
501 req->vwv = (uint16_t *)(inbuf+smb_vwv);
502 req->buflen = smb_buflen(inbuf);
503 req->buf = (const uint8_t *)smb_buf(inbuf);
504 req->unread_bytes = unread_bytes;
505 req->encrypted = encrypted;
507 req->conn = conn_find(sconn,req->tid);
508 req->chain_fsp = NULL;
509 req->chain_outbuf = NULL;
512 smb_init_perfcount_data(&req->pcd);
514 /* Ensure we have at least wct words and 2 bytes of bcc. */
515 if (smb_size + req->wct*2 > req_size) {
516 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
517 (unsigned int)req->wct,
518 (unsigned int)req_size));
521 /* Ensure bcc is correct. */
522 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
523 DEBUG(0,("init_smb_request: invalid bcc number %u "
524 "(wct = %u, size %u)\n",
525 (unsigned int)req->buflen,
526 (unsigned int)req->wct,
527 (unsigned int)req_size));
535 static void process_smb(struct smbd_server_connection *conn,
536 uint8_t *inbuf, size_t nread, size_t unread_bytes,
537 uint32_t seqnum, bool encrypted,
538 struct smb_perfcount_data *deferred_pcd);
540 static void smbd_deferred_open_timer(struct event_context *ev,
541 struct timed_event *te,
542 struct timeval _tval,
545 struct pending_message_list *msg = talloc_get_type(private_data,
546 struct pending_message_list);
547 TALLOC_CTX *mem_ctx = talloc_tos();
548 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
551 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
554 exit_server("smbd_deferred_open_timer: talloc failed\n");
558 /* We leave this message on the queue so the open code can
559 know this is a retry. */
560 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
561 (unsigned long long)mid ));
563 /* Mark the message as processed so this is not
564 * re-processed in error. */
565 msg->processed = true;
567 process_smb(smbd_server_conn, inbuf,
569 msg->seqnum, msg->encrypted, &msg->pcd);
571 /* If it's still there and was processed, remove it. */
572 msg = get_deferred_open_message_smb(mid);
573 if (msg && msg->processed) {
574 remove_deferred_open_message_smb(mid);
578 /****************************************************************************
579 Function to push a message onto the tail of a linked list of smb messages ready
581 ****************************************************************************/
583 static bool push_queued_message(struct smb_request *req,
584 struct timeval request_time,
585 struct timeval end_time,
586 char *private_data, size_t private_len)
588 int msg_len = smb_len(req->inbuf) + 4;
589 struct pending_message_list *msg;
591 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
594 DEBUG(0,("push_message: malloc fail (1)\n"));
598 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
599 if(msg->buf.data == NULL) {
600 DEBUG(0,("push_message: malloc fail (2)\n"));
605 msg->request_time = request_time;
606 msg->seqnum = req->seqnum;
607 msg->encrypted = req->encrypted;
608 msg->processed = false;
609 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
612 msg->private_data = data_blob_talloc(msg, private_data,
614 if (msg->private_data.data == NULL) {
615 DEBUG(0,("push_message: malloc fail (3)\n"));
621 msg->te = event_add_timed(smbd_event_context(),
624 smbd_deferred_open_timer,
627 DEBUG(0,("push_message: event_add_timed failed\n"));
632 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
634 DEBUG(10,("push_message: pushed message length %u on "
635 "deferred_open_queue\n", (unsigned int)msg_len));
640 /****************************************************************************
641 Function to delete a sharing violation open message by mid.
642 ****************************************************************************/
644 void remove_deferred_open_message_smb(uint64_t mid)
646 struct pending_message_list *pml;
648 if (smbd_server_conn->using_smb2) {
649 remove_deferred_open_message_smb2(smbd_server_conn, mid);
653 for (pml = deferred_open_queue; pml; pml = pml->next) {
654 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
655 DEBUG(10,("remove_deferred_open_message_smb: "
656 "deleting mid %llu len %u\n",
657 (unsigned long long)mid,
658 (unsigned int)pml->buf.length ));
659 DLIST_REMOVE(deferred_open_queue, pml);
666 /****************************************************************************
667 Move a sharing violation open retry message to the front of the list and
668 schedule it for immediate processing.
669 ****************************************************************************/
671 void schedule_deferred_open_message_smb(uint64_t mid)
673 struct pending_message_list *pml;
676 if (smbd_server_conn->using_smb2) {
677 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
681 for (pml = deferred_open_queue; pml; pml = pml->next) {
682 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
684 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
687 (unsigned long long)msg_mid ));
689 if (mid == msg_mid) {
690 struct timed_event *te;
692 if (pml->processed) {
693 /* A processed message should not be
695 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
696 "message mid %llu was already processed\n",
697 (unsigned long long)msg_mid ));
701 DEBUG(10,("schedule_deferred_open_message_smb: "
702 "scheduling mid %llu\n",
703 (unsigned long long)mid ));
705 te = event_add_timed(smbd_event_context(),
708 smbd_deferred_open_timer,
711 DEBUG(10,("schedule_deferred_open_message_smb: "
712 "event_add_timed() failed, "
713 "skipping mid %llu\n",
714 (unsigned long long)msg_mid ));
717 TALLOC_FREE(pml->te);
719 DLIST_PROMOTE(deferred_open_queue, pml);
724 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
725 "find message mid %llu\n",
726 (unsigned long long)mid ));
729 /****************************************************************************
730 Return true if this mid is on the deferred queue and was not yet processed.
731 ****************************************************************************/
733 bool open_was_deferred(uint64_t mid)
735 struct pending_message_list *pml;
737 if (smbd_server_conn->using_smb2) {
738 return open_was_deferred_smb2(smbd_server_conn, mid);
741 for (pml = deferred_open_queue; pml; pml = pml->next) {
742 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
749 /****************************************************************************
750 Return the message queued by this mid.
751 ****************************************************************************/
753 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
755 struct pending_message_list *pml;
757 for (pml = deferred_open_queue; pml; pml = pml->next) {
758 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
765 /****************************************************************************
766 Get the state data queued by this mid.
767 ****************************************************************************/
769 bool get_deferred_open_message_state(struct smb_request *smbreq,
770 struct timeval *p_request_time,
773 struct pending_message_list *pml;
775 if (smbd_server_conn->using_smb2) {
776 return get_deferred_open_message_state_smb2(smbreq->smb2req,
781 pml = get_deferred_open_message_smb(smbreq->mid);
785 if (p_request_time) {
786 *p_request_time = pml->request_time;
789 *pp_state = (void *)pml->private_data.data;
794 /****************************************************************************
795 Function to push a deferred open smb message onto a linked list of local smb
796 messages ready for processing.
797 ****************************************************************************/
799 bool push_deferred_open_message_smb(struct smb_request *req,
800 struct timeval request_time,
801 struct timeval timeout,
803 char *private_data, size_t priv_len)
805 struct timeval end_time;
808 return push_deferred_open_message_smb2(req->smb2req,
816 if (req->unread_bytes) {
817 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
818 "unread_bytes = %u\n",
819 (unsigned int)req->unread_bytes ));
820 smb_panic("push_deferred_open_message_smb: "
821 "logic error unread_bytes != 0" );
824 end_time = timeval_sum(&request_time, &timeout);
826 DEBUG(10,("push_deferred_open_message_smb: pushing message "
827 "len %u mid %llu timeout time [%u.%06u]\n",
828 (unsigned int) smb_len(req->inbuf)+4,
829 (unsigned long long)req->mid,
830 (unsigned int)end_time.tv_sec,
831 (unsigned int)end_time.tv_usec));
833 return push_queued_message(req, request_time, end_time,
834 private_data, priv_len);
838 struct timed_event *te;
839 struct timeval interval;
841 bool (*handler)(const struct timeval *now, void *private_data);
845 static void smbd_idle_event_handler(struct event_context *ctx,
846 struct timed_event *te,
850 struct idle_event *event =
851 talloc_get_type_abort(private_data, struct idle_event);
853 TALLOC_FREE(event->te);
855 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
856 event->name, event->te));
858 if (!event->handler(&now, event->private_data)) {
859 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
860 event->name, event->te));
861 /* Don't repeat, delete ourselves */
866 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
867 event->name, event->te));
869 event->te = event_add_timed(ctx, event,
870 timeval_sum(&now, &event->interval),
871 smbd_idle_event_handler, event);
873 /* We can't do much but fail here. */
874 SMB_ASSERT(event->te != NULL);
877 struct idle_event *event_add_idle(struct event_context *event_ctx,
879 struct timeval interval,
881 bool (*handler)(const struct timeval *now,
885 struct idle_event *result;
886 struct timeval now = timeval_current();
888 result = TALLOC_P(mem_ctx, struct idle_event);
889 if (result == NULL) {
890 DEBUG(0, ("talloc failed\n"));
894 result->interval = interval;
895 result->handler = handler;
896 result->private_data = private_data;
898 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
899 DEBUG(0, ("talloc failed\n"));
904 result->te = event_add_timed(event_ctx, result,
905 timeval_sum(&now, &interval),
906 smbd_idle_event_handler, result);
907 if (result->te == NULL) {
908 DEBUG(0, ("event_add_timed failed\n"));
913 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
917 static void smbd_sig_term_handler(struct tevent_context *ev,
918 struct tevent_signal *se,
924 exit_server_cleanly("termination signal");
927 void smbd_setup_sig_term_handler(void)
929 struct tevent_signal *se;
931 se = tevent_add_signal(smbd_event_context(),
932 smbd_event_context(),
934 smbd_sig_term_handler,
937 exit_server("failed to setup SIGTERM handler");
941 static void smbd_sig_hup_handler(struct tevent_context *ev,
942 struct tevent_signal *se,
948 struct messaging_context *msg_ctx = talloc_get_type_abort(
949 private_data, struct messaging_context);
950 change_to_root_user();
951 DEBUG(1,("Reloading services after SIGHUP\n"));
952 reload_services(msg_ctx, smbd_server_conn->sock, False);
954 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
958 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
959 struct messaging_context *msg_ctx)
961 struct tevent_signal *se;
963 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
966 exit_server("failed to setup SIGHUP handler");
970 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
977 timeout = SMBD_SELECT_TIMEOUT * 1000;
980 * Are there any timed events waiting ? If so, ensure we don't
981 * select for longer than it would take to wait for them.
984 event_add_to_poll_args(smbd_event_context(), conn,
985 &conn->pfds, &num_pfds, &timeout);
987 /* Process a signal and timed events now... */
988 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
989 return NT_STATUS_RETRY;
994 START_PROFILE(smbd_idle);
996 ret = sys_poll(conn->pfds, num_pfds, timeout);
999 END_PROFILE(smbd_idle);
1003 if (ret == -1 && errno != EINTR) {
1004 return map_nt_error_from_unix(errno);
1007 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1010 return NT_STATUS_RETRY;
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->session_info->sanitized_username,
1482 vuser->session_info->unix_name,
1483 vuser->session_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(struct smbd_server_connection *sconn,
1573 char *inbuf, int size, size_t unread_bytes,
1574 uint32_t seqnum, bool encrypted,
1575 struct smb_perfcount_data *deferred_pcd)
1577 connection_struct *conn;
1578 struct smb_request *req;
1580 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1581 smb_panic("could not allocate smb_request");
1584 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1585 encrypted, seqnum)) {
1586 exit_server_cleanly("Invalid SMB request");
1589 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1591 /* we popped this message off the queue - keep original perf data */
1593 req->pcd = *deferred_pcd;
1595 SMB_PERFCOUNT_START(&req->pcd);
1596 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1597 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1600 conn = switch_message(req->cmd, req, size);
1602 if (req->unread_bytes) {
1603 /* writeX failed. drain socket. */
1604 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1605 req->unread_bytes) {
1606 smb_panic("failed to drain pending bytes");
1608 req->unread_bytes = 0;
1616 if (req->outbuf == NULL) {
1620 if (CVAL(req->outbuf,0) == 0) {
1621 show_msg((char *)req->outbuf);
1624 if (!srv_send_smb(req->sconn,
1625 (char *)req->outbuf,
1626 true, req->seqnum+1,
1627 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1629 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1637 /****************************************************************************
1638 Process an smb from the client
1639 ****************************************************************************/
1640 static void process_smb(struct smbd_server_connection *sconn,
1641 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1642 uint32_t seqnum, bool encrypted,
1643 struct smb_perfcount_data *deferred_pcd)
1645 int msg_type = CVAL(inbuf,0);
1647 DO_PROFILE_INC(smb_count);
1649 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1651 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1652 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1654 if (msg_type != 0) {
1656 * NetBIOS session request, keepalive, etc.
1658 reply_special(sconn, (char *)inbuf, nread);
1662 if (sconn->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(sconn, 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 sconn->using_smb2 = false;
1676 show_msg((char *)inbuf);
1678 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1679 encrypted, deferred_pcd);
1683 sconn->smb1.num_requests++;
1685 /* The timeout_processing function isn't run nearly
1686 often enough to implement 'max log size' without
1687 overrunning the size of the file by many megabytes.
1688 This is especially true if we are running at debug
1689 level 10. Checking every 50 SMBs is a nice
1690 tradeoff of performance vs log file size overrun. */
1692 if ((sconn->smb1.num_requests % 50) == 0 &&
1693 need_to_check_log_size()) {
1694 change_to_root_user();
1699 /****************************************************************************
1700 Return a string containing the function name of a SMB command.
1701 ****************************************************************************/
1703 const char *smb_fn_name(int type)
1705 const char *unknown_name = "SMBunknown";
1707 if (smb_messages[type].name == NULL)
1708 return(unknown_name);
1710 return(smb_messages[type].name);
1713 /****************************************************************************
1714 Helper functions for contruct_reply.
1715 ****************************************************************************/
1717 void add_to_common_flags2(uint32 v)
1722 void remove_from_common_flags2(uint32 v)
1724 common_flags2 &= ~v;
1727 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1730 srv_set_message(outbuf,0,0,false);
1732 SCVAL(outbuf, smb_com, req->cmd);
1733 SIVAL(outbuf,smb_rcls,0);
1734 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1735 SSVAL(outbuf,smb_flg2,
1736 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1738 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1740 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1741 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1742 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1743 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1746 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1748 construct_reply_common(req, (char *)req->inbuf, outbuf);
1752 * How many bytes have we already accumulated up to the current wct field
1756 size_t req_wct_ofs(struct smb_request *req)
1760 if (req->chain_outbuf == NULL) {
1763 buf_size = talloc_get_size(req->chain_outbuf);
1764 if ((buf_size % 4) != 0) {
1765 buf_size += (4 - (buf_size % 4));
1767 return buf_size - 4;
1771 * Hack around reply_nterror & friends not being aware of chained requests,
1772 * generating illegal (i.e. wct==0) chain replies.
1775 static void fixup_chain_error_packet(struct smb_request *req)
1777 uint8_t *outbuf = req->outbuf;
1779 reply_outbuf(req, 2, 0);
1780 memcpy(req->outbuf, outbuf, smb_wct);
1781 TALLOC_FREE(outbuf);
1782 SCVAL(req->outbuf, smb_vwv0, 0xff);
1786 * @brief Find the smb_cmd offset of the last command pushed
1787 * @param[in] buf The buffer we're building up
1788 * @retval Where can we put our next andx cmd?
1790 * While chaining requests, the "next" request we're looking at needs to put
1791 * its SMB_Command before the data the previous request already built up added
1792 * to the chain. Find the offset to the place where we have to put our cmd.
1795 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1800 cmd = CVAL(buf, smb_com);
1802 SMB_ASSERT(is_andx_req(cmd));
1806 while (CVAL(buf, ofs) != 0xff) {
1808 if (!is_andx_req(CVAL(buf, ofs))) {
1813 * ofs is from start of smb header, so add the 4 length
1814 * bytes. The next cmd is right after the wct field.
1816 ofs = SVAL(buf, ofs+2) + 4 + 1;
1818 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1826 * @brief Do the smb chaining at a buffer level
1827 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1828 * @param[in] smb_command The command that we want to issue
1829 * @param[in] wct How many words?
1830 * @param[in] vwv The words, already in network order
1831 * @param[in] bytes_alignment How shall we align "bytes"?
1832 * @param[in] num_bytes How many bytes?
1833 * @param[in] bytes The data the request ships
1835 * smb_splice_chain() adds the vwv and bytes to the request already present in
1839 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1840 uint8_t wct, const uint16_t *vwv,
1841 size_t bytes_alignment,
1842 uint32_t num_bytes, const uint8_t *bytes)
1845 size_t old_size, new_size;
1847 size_t chain_padding = 0;
1848 size_t bytes_padding = 0;
1851 old_size = talloc_get_size(*poutbuf);
1854 * old_size == smb_wct means we're pushing the first request in for
1858 first_request = (old_size == smb_wct);
1860 if (!first_request && ((old_size % 4) != 0)) {
1862 * Align the wct field of subsequent requests to a 4-byte
1865 chain_padding = 4 - (old_size % 4);
1869 * After the old request comes the new wct field (1 byte), the vwv's
1870 * and the num_bytes field. After at we might need to align the bytes
1871 * given to us to "bytes_alignment", increasing the num_bytes value.
1874 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1876 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1877 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1880 new_size += bytes_padding + num_bytes;
1882 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1883 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1884 (unsigned)new_size));
1888 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1889 if (outbuf == NULL) {
1890 DEBUG(0, ("talloc failed\n"));
1895 if (first_request) {
1896 SCVAL(outbuf, smb_com, smb_command);
1898 size_t andx_cmd_ofs;
1900 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1901 DEBUG(1, ("invalid command chain\n"));
1902 *poutbuf = TALLOC_REALLOC_ARRAY(
1903 NULL, *poutbuf, uint8_t, old_size);
1907 if (chain_padding != 0) {
1908 memset(outbuf + old_size, 0, chain_padding);
1909 old_size += chain_padding;
1912 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1913 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1919 * Push the chained request:
1924 SCVAL(outbuf, ofs, wct);
1931 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1932 ofs += sizeof(uint16_t) * wct;
1938 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1939 ofs += sizeof(uint16_t);
1945 if (bytes_padding != 0) {
1946 memset(outbuf + ofs, 0, bytes_padding);
1947 ofs += bytes_padding;
1954 memcpy(outbuf + ofs, bytes, num_bytes);
1959 /****************************************************************************
1960 Construct a chained reply and add it to the already made reply
1961 ****************************************************************************/
1963 void chain_reply(struct smb_request *req)
1965 size_t smblen = smb_len(req->inbuf);
1966 size_t already_used, length_needed;
1968 uint32_t chain_offset; /* uint32_t to avoid overflow */
1975 if (IVAL(req->outbuf, smb_rcls) != 0) {
1976 fixup_chain_error_packet(req);
1980 * Any of the AndX requests and replies have at least a wct of
1981 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1982 * beginning of the SMB header to the next wct field.
1984 * None of the AndX requests put anything valuable in vwv[0] and [1],
1985 * so we can overwrite it here to form the chain.
1988 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1989 if (req->chain_outbuf == NULL) {
1990 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1991 req, req->outbuf, uint8_t,
1992 smb_len(req->outbuf) + 4);
1993 if (req->chain_outbuf == NULL) {
1994 smb_panic("talloc failed");
2002 * Here we assume that this is the end of the chain. For that we need
2003 * to set "next command" to 0xff and the offset to 0. If we later find
2004 * more commands in the chain, this will be overwritten again.
2007 SCVAL(req->outbuf, smb_vwv0, 0xff);
2008 SCVAL(req->outbuf, smb_vwv0+1, 0);
2009 SSVAL(req->outbuf, smb_vwv1, 0);
2011 if (req->chain_outbuf == NULL) {
2013 * In req->chain_outbuf we collect all the replies. Start the
2014 * chain by copying in the first reply.
2016 * We do the realloc because later on we depend on
2017 * talloc_get_size to determine the length of
2018 * chain_outbuf. The reply_xxx routines might have
2019 * over-allocated (reply_pipe_read_and_X used to be such an
2022 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2023 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2024 if (req->chain_outbuf == NULL) {
2025 smb_panic("talloc failed");
2030 * Update smb headers where subsequent chained commands
2031 * may have updated them.
2033 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2034 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2036 if (!smb_splice_chain(&req->chain_outbuf,
2037 CVAL(req->outbuf, smb_com),
2038 CVAL(req->outbuf, smb_wct),
2039 (uint16_t *)(req->outbuf + smb_vwv),
2040 0, smb_buflen(req->outbuf),
2041 (uint8_t *)smb_buf(req->outbuf))) {
2044 TALLOC_FREE(req->outbuf);
2048 * We use the old request's vwv field to grab the next chained command
2049 * and offset into the chained fields.
2052 chain_cmd = CVAL(req->vwv+0, 0);
2053 chain_offset = SVAL(req->vwv+1, 0);
2055 if (chain_cmd == 0xff) {
2057 * End of chain, no more requests from the client. So ship the
2060 smb_setlen((char *)(req->chain_outbuf),
2061 talloc_get_size(req->chain_outbuf) - 4);
2063 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2064 true, req->seqnum+1,
2065 IS_CONN_ENCRYPTED(req->conn)
2068 exit_server_cleanly("chain_reply: srv_send_smb "
2071 TALLOC_FREE(req->chain_outbuf);
2076 /* add a new perfcounter for this element of chain */
2077 SMB_PERFCOUNT_ADD(&req->pcd);
2078 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2079 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2082 * Check if the client tries to fool us. The request so far uses the
2083 * space to the end of the byte buffer in the request just
2084 * processed. The chain_offset can't point into that area. If that was
2085 * the case, we could end up with an endless processing of the chain,
2086 * we would always handle the same request.
2089 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2090 if (chain_offset < already_used) {
2095 * Next check: Make sure the chain offset does not point beyond the
2096 * overall smb request length.
2099 length_needed = chain_offset+1; /* wct */
2100 if (length_needed > smblen) {
2105 * Now comes the pointer magic. Goal here is to set up req->vwv and
2106 * req->buf correctly again to be able to call the subsequent
2107 * switch_message(). The chain offset (the former vwv[1]) points at
2108 * the new wct field.
2111 wct = CVAL(smb_base(req->inbuf), chain_offset);
2114 * Next consistency check: Make the new vwv array fits in the overall
2118 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2119 if (length_needed > smblen) {
2122 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2125 * Now grab the new byte buffer....
2128 buflen = SVAL(vwv+wct, 0);
2131 * .. and check that it fits.
2134 length_needed += buflen;
2135 if (length_needed > smblen) {
2138 buf = (uint8_t *)(vwv+wct+1);
2140 req->cmd = chain_cmd;
2143 req->buflen = buflen;
2146 switch_message(chain_cmd, req, smblen);
2148 if (req->outbuf == NULL) {
2150 * This happens if the chained command has suspended itself or
2151 * if it has called srv_send_smb() itself.
2157 * We end up here if the chained command was not itself chained or
2158 * suspended, but for example a close() command. We now need to splice
2159 * the chained commands' outbuf into the already built up chain_outbuf
2160 * and ship the result.
2166 * We end up here if there's any error in the chain syntax. Report a
2167 * DOS error, just like Windows does.
2169 reply_force_doserror(req, ERRSRV, ERRerror);
2170 fixup_chain_error_packet(req);
2174 * This scary statement intends to set the
2175 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2176 * to the value req->outbuf carries
2178 SSVAL(req->chain_outbuf, smb_flg2,
2179 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2180 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2183 * Transfer the error codes from the subrequest to the main one
2185 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2186 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2188 if (!smb_splice_chain(&req->chain_outbuf,
2189 CVAL(req->outbuf, smb_com),
2190 CVAL(req->outbuf, smb_wct),
2191 (uint16_t *)(req->outbuf + smb_vwv),
2192 0, smb_buflen(req->outbuf),
2193 (uint8_t *)smb_buf(req->outbuf))) {
2194 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2196 TALLOC_FREE(req->outbuf);
2198 smb_setlen((char *)(req->chain_outbuf),
2199 talloc_get_size(req->chain_outbuf) - 4);
2201 show_msg((char *)(req->chain_outbuf));
2203 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2204 true, req->seqnum+1,
2205 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2207 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2209 TALLOC_FREE(req->chain_outbuf);
2213 /****************************************************************************
2214 Check if services need reloading.
2215 ****************************************************************************/
2217 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2220 if (last_smb_conf_reload_time == 0) {
2221 last_smb_conf_reload_time = t;
2224 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2225 reload_services(sconn->msg_ctx, sconn->sock, True);
2226 last_smb_conf_reload_time = t;
2230 static bool fd_is_readable(int fd)
2234 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2236 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2240 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2242 /* TODO: make write nonblocking */
2245 static void smbd_server_connection_read_handler(
2246 struct smbd_server_connection *conn, int fd)
2248 uint8_t *inbuf = NULL;
2249 size_t inbuf_len = 0;
2250 size_t unread_bytes = 0;
2251 bool encrypted = false;
2252 TALLOC_CTX *mem_ctx = talloc_tos();
2256 bool from_client = (conn->sock == fd);
2259 smbd_lock_socket(conn);
2261 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2262 DEBUG(10,("the echo listener was faster\n"));
2263 smbd_unlock_socket(conn);
2267 /* TODO: make this completely nonblocking */
2268 status = receive_smb_talloc(mem_ctx, conn,
2269 (char **)(void *)&inbuf,
2273 &inbuf_len, &seqnum,
2274 false /* trusted channel */);
2275 smbd_unlock_socket(conn);
2277 /* TODO: make this completely nonblocking */
2278 status = receive_smb_talloc(mem_ctx, conn,
2279 (char **)(void *)&inbuf,
2283 &inbuf_len, &seqnum,
2284 true /* trusted channel */);
2287 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2290 if (NT_STATUS_IS_ERR(status)) {
2291 exit_server_cleanly("failed to receive smb request");
2293 if (!NT_STATUS_IS_OK(status)) {
2298 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2299 seqnum, encrypted, NULL);
2302 static void smbd_server_connection_handler(struct event_context *ev,
2303 struct fd_event *fde,
2307 struct smbd_server_connection *conn = talloc_get_type(private_data,
2308 struct smbd_server_connection);
2310 if (flags & EVENT_FD_WRITE) {
2311 smbd_server_connection_write_handler(conn);
2314 if (flags & EVENT_FD_READ) {
2315 smbd_server_connection_read_handler(conn, conn->sock);
2320 static void smbd_server_echo_handler(struct event_context *ev,
2321 struct fd_event *fde,
2325 struct smbd_server_connection *conn = talloc_get_type(private_data,
2326 struct smbd_server_connection);
2328 if (flags & EVENT_FD_WRITE) {
2329 smbd_server_connection_write_handler(conn);
2332 if (flags & EVENT_FD_READ) {
2333 smbd_server_connection_read_handler(
2334 conn, conn->smb1.echo_handler.trusted_fd);
2339 /****************************************************************************
2340 received when we should release a specific IP
2341 ****************************************************************************/
2342 static void release_ip(const char *ip, void *priv)
2344 const char *addr = (const char *)priv;
2345 const char *p = addr;
2347 if (strncmp("::ffff:", addr, 7) == 0) {
2351 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2352 /* we can't afford to do a clean exit - that involves
2353 database writes, which would potentially mean we
2354 are still running after the failover has finished -
2355 we have to get rid of this process ID straight
2357 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2359 /* note we must exit with non-zero status so the unclean handler gets
2360 called in the parent, so that the brl database is tickled */
2365 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2366 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2368 struct smbd_server_connection *sconn = talloc_get_type_abort(
2369 private_data, struct smbd_server_connection);
2371 release_ip((char *)data->data, sconn->client_id.addr);
2374 #ifdef CLUSTER_SUPPORT
2375 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2376 struct sockaddr_storage *client)
2379 length = sizeof(*server);
2380 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2383 length = sizeof(*client);
2384 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2392 * Send keepalive packets to our client
2394 static bool keepalive_fn(const struct timeval *now, void *private_data)
2396 struct smbd_server_connection *sconn = smbd_server_conn;
2399 if (sconn->using_smb2) {
2400 /* Don't do keepalives on an SMB2 connection. */
2404 smbd_lock_socket(smbd_server_conn);
2405 ret = send_keepalive(sconn->sock);
2406 smbd_unlock_socket(smbd_server_conn);
2409 char addr[INET6_ADDRSTRLEN];
2411 * Try and give an error message saying what
2414 DEBUG(0, ("send_keepalive failed for client %s. "
2415 "Error %s - exiting\n",
2416 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2424 * Do the recurring check if we're idle
2426 static bool deadtime_fn(const struct timeval *now, void *private_data)
2428 struct smbd_server_connection *sconn =
2429 (struct smbd_server_connection *)private_data;
2431 if ((conn_num_open(sconn) == 0)
2432 || (conn_idle_all(sconn, now->tv_sec))) {
2433 DEBUG( 2, ( "Closing idle connection\n" ) );
2434 messaging_send(sconn->msg_ctx,
2435 messaging_server_id(sconn->msg_ctx),
2436 MSG_SHUTDOWN, &data_blob_null);
2444 * Do the recurring log file and smb.conf reload checks.
2447 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2449 struct smbd_server_connection *sconn = talloc_get_type_abort(
2450 private_data, struct smbd_server_connection);
2452 DEBUG(5, ("housekeeping\n"));
2454 change_to_root_user();
2456 /* update printer queue caches if necessary */
2457 update_monitored_printq_cache(sconn->msg_ctx);
2459 /* check if we need to reload services */
2460 check_reload(sconn, time_mono(NULL));
2462 /* Change machine password if neccessary. */
2463 attempt_machine_password_change();
2466 * Force a log file check.
2468 force_check_log_size();
2473 static int create_unlink_tmp(const char *dir)
2478 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2479 if (fname == NULL) {
2483 fd = mkstemp(fname);
2488 if (unlink(fname) == -1) {
2489 int sys_errno = errno;
2499 struct smbd_echo_state {
2500 struct tevent_context *ev;
2501 struct iovec *pending;
2502 struct smbd_server_connection *sconn;
2505 struct tevent_fd *parent_fde;
2507 struct tevent_fd *read_fde;
2508 struct tevent_req *write_req;
2511 static void smbd_echo_writer_done(struct tevent_req *req);
2513 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2517 if (state->write_req != NULL) {
2521 num_pending = talloc_array_length(state->pending);
2522 if (num_pending == 0) {
2526 state->write_req = writev_send(state, state->ev, NULL,
2527 state->parent_pipe, false,
2528 state->pending, num_pending);
2529 if (state->write_req == NULL) {
2530 DEBUG(1, ("writev_send failed\n"));
2534 talloc_steal(state->write_req, state->pending);
2535 state->pending = NULL;
2537 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2541 static void smbd_echo_writer_done(struct tevent_req *req)
2543 struct smbd_echo_state *state = tevent_req_callback_data(
2544 req, struct smbd_echo_state);
2548 written = writev_recv(req, &err);
2550 state->write_req = NULL;
2551 if (written == -1) {
2552 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2555 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2556 smbd_echo_activate_writer(state);
2559 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2562 struct smb_request req;
2563 uint16_t num_replies;
2568 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2569 DEBUG(10, ("Got netbios keepalive\n"));
2576 if (inbuf_len < smb_size) {
2577 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2580 if (!valid_smb_header(inbuf)) {
2581 DEBUG(10, ("Got invalid SMB header\n"));
2585 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2591 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2592 smb_messages[req.cmd].name
2593 ? smb_messages[req.cmd].name : "unknown"));
2595 if (req.cmd != SMBecho) {
2602 num_replies = SVAL(req.vwv+0, 0);
2603 if (num_replies != 1) {
2604 /* Not a Windows "Hey, you're still there?" request */
2608 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2610 DEBUG(10, ("create_outbuf failed\n"));
2613 req.outbuf = (uint8_t *)outbuf;
2615 SSVAL(req.outbuf, smb_vwv0, num_replies);
2617 if (req.buflen > 0) {
2618 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2621 out_len = smb_len(req.outbuf) + 4;
2623 ok = srv_send_smb(req.sconn,
2627 TALLOC_FREE(outbuf);
2635 static void smbd_echo_exit(struct tevent_context *ev,
2636 struct tevent_fd *fde, uint16_t flags,
2639 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2643 static void smbd_echo_reader(struct tevent_context *ev,
2644 struct tevent_fd *fde, uint16_t flags,
2647 struct smbd_echo_state *state = talloc_get_type_abort(
2648 private_data, struct smbd_echo_state);
2649 struct smbd_server_connection *sconn = state->sconn;
2650 size_t unread, num_pending;
2654 uint32_t seqnum = 0;
2657 bool encrypted = false;
2661 ok = smbd_lock_socket_internal(sconn);
2663 DEBUG(0, ("%s: failed to lock socket\n",
2668 if (!fd_is_readable(sconn->sock)) {
2669 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2670 (int)sys_getpid()));
2671 ok = smbd_unlock_socket_internal(sconn);
2673 DEBUG(1, ("%s: failed to unlock socket in\n",
2680 num_pending = talloc_array_length(state->pending);
2681 tmp = talloc_realloc(state, state->pending, struct iovec,
2684 DEBUG(1, ("talloc_realloc failed\n"));
2687 state->pending = tmp;
2689 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2691 status = receive_smb_talloc(state->pending, sconn,
2692 (char **)(void *)&state->pending[num_pending].iov_base,
2698 false /* trusted_channel*/);
2699 if (!NT_STATUS_IS_OK(status)) {
2700 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2701 (int)sys_getpid(), nt_errstr(status)));
2704 state->pending[num_pending].iov_len = iov_len;
2706 ok = smbd_unlock_socket_internal(sconn);
2708 DEBUG(1, ("%s: failed to unlock socket in\n",
2713 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2714 state->pending[num_pending].iov_len,
2717 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2718 /* no check, shrinking by some bytes does not fail */
2719 state->pending = talloc_realloc(state, state->pending,
2725 if (state->pending[num_pending].iov_len >= smb_size) {
2727 * place the seqnum in the packet so that the main process
2728 * can reply with signing
2730 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2731 smb_ss_field, seqnum);
2732 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2733 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2736 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2737 smbd_echo_activate_writer(state);
2740 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2743 struct smbd_echo_state *state;
2745 state = talloc_zero(sconn, struct smbd_echo_state);
2746 if (state == NULL) {
2747 DEBUG(1, ("talloc failed\n"));
2750 state->sconn = sconn;
2751 state->parent_pipe = parent_pipe;
2752 state->ev = s3_tevent_context_init(state);
2753 if (state->ev == NULL) {
2754 DEBUG(1, ("tevent_context_init failed\n"));
2758 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2759 TEVENT_FD_READ, smbd_echo_exit,
2761 if (state->parent_fde == NULL) {
2762 DEBUG(1, ("tevent_add_fd failed\n"));
2766 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2767 TEVENT_FD_READ, smbd_echo_reader,
2769 if (state->read_fde == NULL) {
2770 DEBUG(1, ("tevent_add_fd failed\n"));
2776 if (tevent_loop_once(state->ev) == -1) {
2777 DEBUG(1, ("tevent_loop_once failed: %s\n",
2786 * Handle SMBecho requests in a forked child process
2788 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2790 int listener_pipe[2];
2794 res = pipe(listener_pipe);
2796 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2799 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2800 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2801 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2809 close(listener_pipe[0]);
2810 set_blocking(listener_pipe[1], false);
2812 status = reinit_after_fork(sconn->msg_ctx,
2813 smbd_event_context(),
2814 procid_self(), false);
2815 if (!NT_STATUS_IS_OK(status)) {
2816 DEBUG(1, ("reinit_after_fork failed: %s\n",
2817 nt_errstr(status)));
2820 smbd_echo_loop(sconn, listener_pipe[1]);
2823 close(listener_pipe[1]);
2824 listener_pipe[1] = -1;
2825 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2827 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2830 * Without smb signing this is the same as the normal smbd
2831 * listener. This needs to change once signing comes in.
2833 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2835 sconn->smb1.echo_handler.trusted_fd,
2837 smbd_server_echo_handler,
2839 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2840 DEBUG(1, ("event_add_fd failed\n"));
2847 if (listener_pipe[0] != -1) {
2848 close(listener_pipe[0]);
2850 if (listener_pipe[1] != -1) {
2851 close(listener_pipe[1]);
2853 sconn->smb1.echo_handler.trusted_fd = -1;
2854 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2855 close(sconn->smb1.echo_handler.socket_lock_fd);
2857 sconn->smb1.echo_handler.trusted_fd = -1;
2858 sconn->smb1.echo_handler.socket_lock_fd = -1;
2864 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2865 struct sockaddr_storage *srv,
2866 struct sockaddr_storage *clnt)
2868 struct ctdbd_connection *cconn;
2869 char tmp_addr[INET6_ADDRSTRLEN];
2872 cconn = messaging_ctdbd_connection();
2873 if (cconn == NULL) {
2874 return NT_STATUS_NO_MEMORY;
2877 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2878 addr = talloc_strdup(cconn, tmp_addr);
2880 return NT_STATUS_NO_MEMORY;
2882 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2887 /****************************************************************************
2888 Process commands from the client
2889 ****************************************************************************/
2891 void smbd_process(struct smbd_server_connection *sconn)
2893 TALLOC_CTX *frame = talloc_stackframe();
2894 struct sockaddr_storage ss;
2895 struct sockaddr *sa = NULL;
2896 socklen_t sa_socklen;
2897 struct tsocket_address *local_address = NULL;
2898 struct tsocket_address *remote_address = NULL;
2899 const char *remaddr = NULL;
2902 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2903 !lp_async_smb_echo_handler()) {
2905 * We're not making the desion here,
2906 * we're just allowing the client
2907 * to decide between SMB1 and SMB2
2908 * with the first negprot
2911 sconn->using_smb2 = true;
2914 /* Ensure child is set to blocking mode */
2915 set_blocking(sconn->sock,True);
2917 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2918 set_socket_options(sconn->sock, lp_socket_options());
2920 sa = (struct sockaddr *)(void *)&ss;
2921 sa_socklen = sizeof(ss);
2922 ret = getpeername(sconn->sock, sa, &sa_socklen);
2924 int level = (errno == ENOTCONN)?2:0;
2925 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2926 exit_server_cleanly("getpeername() failed.\n");
2928 ret = tsocket_address_bsd_from_sockaddr(sconn,
2932 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2933 __location__, strerror(errno)));
2934 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2937 sa = (struct sockaddr *)(void *)&ss;
2938 sa_socklen = sizeof(ss);
2939 ret = getsockname(sconn->sock, sa, &sa_socklen);
2941 int level = (errno == ENOTCONN)?2:0;
2942 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2943 exit_server_cleanly("getsockname() failed.\n");
2945 ret = tsocket_address_bsd_from_sockaddr(sconn,
2949 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2950 __location__, strerror(errno)));
2951 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2954 sconn->local_address = local_address;
2955 sconn->remote_address = remote_address;
2957 if (tsocket_address_is_inet(remote_address, "ip")) {
2958 remaddr = tsocket_address_inet_addr_string(
2959 sconn->remote_address,
2961 if (remaddr == NULL) {
2965 remaddr = "0.0.0.0";
2968 /* this is needed so that we get decent entries
2969 in smbstatus for port 445 connects */
2970 set_remote_machine_name(remaddr, false);
2971 reload_services(sconn->msg_ctx, sconn->sock, true);
2974 * Before the first packet, check the global hosts allow/ hosts deny
2975 * parameters before doing any parsing of packets passed to us by the
2976 * client. This prevents attacks on our parsing code from hosts not in
2977 * the hosts allow list.
2980 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2981 sconn->client_id.name,
2982 sconn->client_id.addr)) {
2984 * send a negative session response "not listening on calling
2987 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2988 DEBUG( 1, ("Connection denied from %s to %s\n",
2989 tsocket_address_string(remote_address, talloc_tos()),
2990 tsocket_address_string(local_address, talloc_tos())));
2991 (void)srv_send_smb(sconn,(char *)buf, false,
2993 exit_server_cleanly("connection denied");
2996 DEBUG(10, ("Connection allowed from %s to %s\n",
2997 tsocket_address_string(remote_address, talloc_tos()),
2998 tsocket_address_string(local_address, talloc_tos())));
3002 smb_perfcount_init();
3004 if (!init_account_policy()) {
3005 exit_server("Could not open account policy tdb.\n");
3008 if (*lp_rootdir()) {
3009 if (chroot(lp_rootdir()) != 0) {
3010 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3011 exit_server("Failed to chroot()");
3013 if (chdir("/") == -1) {
3014 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3015 exit_server("Failed to chroot()");
3017 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3020 if (!srv_init_signing(sconn)) {
3021 exit_server("Failed to init smb_signing");
3024 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3025 exit_server("Failed to fork echo handler");
3029 if (!init_oplocks(sconn->msg_ctx))
3030 exit_server("Failed to init oplocks");
3032 /* register our message handlers */
3033 messaging_register(sconn->msg_ctx, NULL,
3034 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3035 messaging_register(sconn->msg_ctx, sconn,
3036 MSG_SMB_RELEASE_IP, msg_release_ip);
3037 messaging_register(sconn->msg_ctx, NULL,
3038 MSG_SMB_CLOSE_FILE, msg_close_file);
3041 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3042 * MSGs to all child processes
3044 messaging_deregister(sconn->msg_ctx,
3046 messaging_register(sconn->msg_ctx, NULL,
3047 MSG_DEBUG, debug_message);
3049 if ((lp_keepalive() != 0)
3050 && !(event_add_idle(smbd_event_context(), NULL,
3051 timeval_set(lp_keepalive(), 0),
3052 "keepalive", keepalive_fn,
3054 DEBUG(0, ("Could not add keepalive event\n"));
3058 if (!(event_add_idle(smbd_event_context(), NULL,
3059 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3060 "deadtime", deadtime_fn, sconn))) {
3061 DEBUG(0, ("Could not add deadtime event\n"));
3065 if (!(event_add_idle(smbd_event_context(), NULL,
3066 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3067 "housekeeping", housekeeping_fn, sconn))) {
3068 DEBUG(0, ("Could not add housekeeping event\n"));
3072 #ifdef CLUSTER_SUPPORT
3074 if (lp_clustering()) {
3076 * We need to tell ctdb about our client's TCP
3077 * connection, so that for failover ctdbd can send
3078 * tickle acks, triggering a reconnection by the
3082 struct sockaddr_storage srv, clnt;
3084 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3086 status = smbd_register_ips(sconn, &srv, &clnt);
3087 if (!NT_STATUS_IS_OK(status)) {
3088 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3089 nt_errstr(status)));
3093 DEBUG(0,("Unable to get tcp info for "
3094 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3101 sconn->nbt.got_session = false;
3103 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3105 sconn->smb1.sessions.done_sesssetup = false;
3106 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3107 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3108 /* users from session setup */
3109 sconn->smb1.sessions.session_userlist = NULL;
3110 /* workgroup from session setup. */
3111 sconn->smb1.sessions.session_workgroup = NULL;
3112 /* this holds info on user ids that are already validated for this VC */
3113 sconn->smb1.sessions.validated_users = NULL;
3114 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3115 sconn->smb1.sessions.num_validated_vuids = 0;
3118 if (!init_dptrs(sconn)) {
3119 exit_server("init_dptrs() failed");
3122 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3126 smbd_server_connection_handler,
3128 if (!sconn->smb1.fde) {
3129 exit_server("failed to create smbd_server_connection fde");
3137 frame = talloc_stackframe_pool(8192);
3141 status = smbd_server_connection_loop_once(sconn);
3142 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3143 !NT_STATUS_IS_OK(status)) {
3144 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3145 " exiting\n", nt_errstr(status)));
3152 exit_server_cleanly(NULL);
3155 bool req_is_in_chain(struct smb_request *req)
3157 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3159 * We're right now handling a subsequent request, so we must
3165 if (!is_andx_req(req->cmd)) {
3171 * Okay, an illegal request, but definitely not chained :-)
3176 return (CVAL(req->vwv+0, 0) != 0xFF);