2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/pcap.h"
31 #include "system/select.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
39 extern bool global_machine_password_needs_changing;
41 static void construct_reply_common(struct smb_request *req, const char *inbuf,
43 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
45 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
49 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
53 sconn->smb1.echo_handler.ref_count++;
55 if (sconn->smb1.echo_handler.ref_count > 1) {
59 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
63 sconn->smb1.echo_handler.socket_lock_fd,
64 SMB_F_SETLKW, 0, 0, F_WRLCK);
65 } while (!ok && (errno == EINTR));
68 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
72 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
77 void smbd_lock_socket(struct smbd_server_connection *sconn)
79 if (!smbd_lock_socket_internal(sconn)) {
80 exit_server_cleanly("failed to lock socket");
84 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
88 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
92 sconn->smb1.echo_handler.ref_count--;
94 if (sconn->smb1.echo_handler.ref_count > 0) {
100 sconn->smb1.echo_handler.socket_lock_fd,
101 SMB_F_SETLKW, 0, 0, F_UNLCK);
102 } while (!ok && (errno == EINTR));
105 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
109 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
114 void smbd_unlock_socket(struct smbd_server_connection *sconn)
116 if (!smbd_unlock_socket_internal(sconn)) {
117 exit_server_cleanly("failed to unlock socket");
121 /* Accessor function for smb_read_error for smbd functions. */
123 /****************************************************************************
125 ****************************************************************************/
127 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
128 bool do_signing, uint32_t seqnum,
130 struct smb_perfcount_data *pcd)
135 char *buf_out = buffer;
137 smbd_lock_socket(sconn);
140 /* Sign the outgoing packet if required. */
141 srv_calculate_sign_mac(sconn, buf_out, seqnum);
145 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
146 if (!NT_STATUS_IS_OK(status)) {
147 DEBUG(0, ("send_smb: SMB encryption failed "
148 "on outgoing packet! Error %s\n",
149 nt_errstr(status) ));
154 len = smb_len(buf_out) + 4;
156 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
159 char addr[INET6_ADDRSTRLEN];
161 * Try and give an error message saying what
164 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
165 (int)sys_getpid(), (int)len,
166 get_peer_addr(sconn->sock, addr, sizeof(addr)),
167 (int)ret, strerror(errno) ));
169 srv_free_enc_buffer(buf_out);
173 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
174 srv_free_enc_buffer(buf_out);
176 SMB_PERFCOUNT_END(pcd);
178 smbd_unlock_socket(sconn);
182 /*******************************************************************
183 Setup the word count and byte count for a smb message.
184 ********************************************************************/
186 int srv_set_message(char *buf,
191 if (zero && (num_words || num_bytes)) {
192 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
194 SCVAL(buf,smb_wct,num_words);
195 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
196 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
197 return (smb_size + num_words*2 + num_bytes);
200 static bool valid_smb_header(const uint8_t *inbuf)
202 if (is_encrypted_packet(inbuf)) {
206 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
207 * but it just looks weird to call strncmp for this one.
209 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
212 /* Socket functions for smbd packet processing. */
214 static bool valid_packet_size(size_t len)
217 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
218 * of header. Don't print the error if this fits.... JRA.
221 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
222 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
223 (unsigned long)len));
229 static NTSTATUS read_packet_remainder(int fd, char *buffer,
230 unsigned int timeout, ssize_t len)
238 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
239 if (!NT_STATUS_IS_OK(status)) {
240 char addr[INET6_ADDRSTRLEN];
241 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
243 get_peer_addr(fd, addr, sizeof(addr)),
249 /****************************************************************************
250 Attempt a zerocopy writeX read. We know here that len > smb_size-4
251 ****************************************************************************/
254 * Unfortunately, earlier versions of smbclient/libsmbclient
255 * don't send this "standard" writeX header. I've fixed this
256 * for 3.2 but we'll use the old method with earlier versions.
257 * Windows and CIFSFS at least use this standard size. Not
261 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
262 (2*14) + /* word count (including bcc) */ \
265 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
266 const char lenbuf[4],
267 struct smbd_server_connection *sconn,
270 unsigned int timeout,
274 /* Size of a WRITEX call (+4 byte len). */
275 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
276 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
280 memcpy(writeX_header, lenbuf, 4);
282 status = read_fd_with_timeout(
283 sock, writeX_header + 4,
284 STANDARD_WRITE_AND_X_HEADER_SIZE,
285 STANDARD_WRITE_AND_X_HEADER_SIZE,
288 if (!NT_STATUS_IS_OK(status)) {
289 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
291 tsocket_address_string(sconn->remote_address,
298 * Ok - now try and see if this is a possible
302 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
304 * If the data offset is beyond what
305 * we've read, drain the extra bytes.
307 uint16_t doff = SVAL(writeX_header,smb_vwv11);
310 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
311 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
312 if (drain_socket(sock, drain) != drain) {
313 smb_panic("receive_smb_raw_talloc_partial_read:"
314 " failed to drain pending bytes");
317 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
320 /* Spoof down the length and null out the bcc. */
321 set_message_bcc(writeX_header, 0);
322 newlen = smb_len(writeX_header);
324 /* Copy the header we've written. */
326 *buffer = (char *)talloc_memdup(mem_ctx,
328 sizeof(writeX_header));
330 if (*buffer == NULL) {
331 DEBUG(0, ("Could not allocate inbuf of length %d\n",
332 (int)sizeof(writeX_header)));
333 return NT_STATUS_NO_MEMORY;
336 /* Work out the remaining bytes. */
337 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
338 *len_ret = newlen + 4;
342 if (!valid_packet_size(len)) {
343 return NT_STATUS_INVALID_PARAMETER;
347 * Not a valid writeX call. Just do the standard
351 *buffer = talloc_array(mem_ctx, char, len+4);
353 if (*buffer == NULL) {
354 DEBUG(0, ("Could not allocate inbuf of length %d\n",
356 return NT_STATUS_NO_MEMORY;
359 /* Copy in what we already read. */
362 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
363 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
366 status = read_packet_remainder(
368 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
371 if (!NT_STATUS_IS_OK(status)) {
372 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
382 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
383 struct smbd_server_connection *sconn,
385 char **buffer, unsigned int timeout,
386 size_t *p_unread, size_t *plen)
390 int min_recv_size = lp_min_receive_file_size();
395 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
397 if (!NT_STATUS_IS_OK(status)) {
401 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
402 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
403 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
404 !srv_is_signing_active(sconn) &&
405 sconn->smb1.echo_handler.trusted_fde == NULL) {
407 return receive_smb_raw_talloc_partial_read(
408 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
412 if (!valid_packet_size(len)) {
413 return NT_STATUS_INVALID_PARAMETER;
417 * The +4 here can't wrap, we've checked the length above already.
420 *buffer = talloc_array(mem_ctx, char, len+4);
422 if (*buffer == NULL) {
423 DEBUG(0, ("Could not allocate inbuf of length %d\n",
425 return NT_STATUS_NO_MEMORY;
428 memcpy(*buffer, lenbuf, sizeof(lenbuf));
430 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
431 if (!NT_STATUS_IS_OK(status)) {
439 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
440 struct smbd_server_connection *sconn,
442 char **buffer, unsigned int timeout,
443 size_t *p_unread, bool *p_encrypted,
446 bool trusted_channel)
451 *p_encrypted = false;
453 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
455 if (!NT_STATUS_IS_OK(status)) {
456 DEBUG(1, ("read_smb_length_return_keepalive failed for "
457 "client %s read error = %s.\n",
458 tsocket_address_string(sconn->remote_address,
464 if (is_encrypted_packet((uint8_t *)*buffer)) {
465 status = srv_decrypt_buffer(*buffer);
466 if (!NT_STATUS_IS_OK(status)) {
467 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
468 "incoming packet! Error %s\n",
469 nt_errstr(status) ));
475 /* Check the incoming SMB signature. */
476 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
477 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
478 "incoming packet!\n"));
479 return NT_STATUS_INVALID_NETWORK_RESPONSE;
487 * Initialize a struct smb_request from an inbuf
490 static bool init_smb_request(struct smb_request *req,
491 struct smbd_server_connection *sconn,
493 size_t unread_bytes, bool encrypted,
496 size_t req_size = smb_len(inbuf) + 4;
497 /* Ensure we have at least smb_size bytes. */
498 if (req_size < smb_size) {
499 DEBUG(0,("init_smb_request: invalid request size %u\n",
500 (unsigned int)req_size ));
503 req->cmd = CVAL(inbuf, smb_com);
504 req->flags2 = SVAL(inbuf, smb_flg2);
505 req->smbpid = SVAL(inbuf, smb_pid);
506 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
507 req->seqnum = seqnum;
508 req->vuid = SVAL(inbuf, smb_uid);
509 req->tid = SVAL(inbuf, smb_tid);
510 req->wct = CVAL(inbuf, smb_wct);
511 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
512 req->buflen = smb_buflen(inbuf);
513 req->buf = (const uint8_t *)smb_buf_const(inbuf);
514 req->unread_bytes = unread_bytes;
515 req->encrypted = encrypted;
517 req->conn = conn_find(sconn,req->tid);
518 req->chain_fsp = NULL;
519 req->chain_outbuf = NULL;
522 smb_init_perfcount_data(&req->pcd);
524 /* Ensure we have at least wct words and 2 bytes of bcc. */
525 if (smb_size + req->wct*2 > req_size) {
526 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
527 (unsigned int)req->wct,
528 (unsigned int)req_size));
531 /* Ensure bcc is correct. */
532 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
533 DEBUG(0,("init_smb_request: invalid bcc number %u "
534 "(wct = %u, size %u)\n",
535 (unsigned int)req->buflen,
536 (unsigned int)req->wct,
537 (unsigned int)req_size));
545 static void process_smb(struct smbd_server_connection *conn,
546 uint8_t *inbuf, size_t nread, size_t unread_bytes,
547 uint32_t seqnum, bool encrypted,
548 struct smb_perfcount_data *deferred_pcd);
550 static void smbd_deferred_open_timer(struct event_context *ev,
551 struct timed_event *te,
552 struct timeval _tval,
555 struct pending_message_list *msg = talloc_get_type(private_data,
556 struct pending_message_list);
557 TALLOC_CTX *mem_ctx = talloc_tos();
558 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
561 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
564 exit_server("smbd_deferred_open_timer: talloc failed\n");
568 /* We leave this message on the queue so the open code can
569 know this is a retry. */
570 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
571 (unsigned long long)mid ));
573 /* Mark the message as processed so this is not
574 * re-processed in error. */
575 msg->processed = true;
577 process_smb(smbd_server_conn, inbuf,
579 msg->seqnum, msg->encrypted, &msg->pcd);
581 /* If it's still there and was processed, remove it. */
582 msg = get_deferred_open_message_smb(mid);
583 if (msg && msg->processed) {
584 remove_deferred_open_message_smb(mid);
588 /****************************************************************************
589 Function to push a message onto the tail of a linked list of smb messages ready
591 ****************************************************************************/
593 static bool push_queued_message(struct smb_request *req,
594 struct timeval request_time,
595 struct timeval end_time,
596 char *private_data, size_t private_len)
598 int msg_len = smb_len(req->inbuf) + 4;
599 struct pending_message_list *msg;
601 msg = talloc_zero(NULL, struct pending_message_list);
604 DEBUG(0,("push_message: malloc fail (1)\n"));
608 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
609 if(msg->buf.data == NULL) {
610 DEBUG(0,("push_message: malloc fail (2)\n"));
615 msg->request_time = request_time;
616 msg->seqnum = req->seqnum;
617 msg->encrypted = req->encrypted;
618 msg->processed = false;
619 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
622 msg->private_data = data_blob_talloc(msg, private_data,
624 if (msg->private_data.data == NULL) {
625 DEBUG(0,("push_message: malloc fail (3)\n"));
631 msg->te = event_add_timed(server_event_context(),
634 smbd_deferred_open_timer,
637 DEBUG(0,("push_message: event_add_timed failed\n"));
642 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
644 DEBUG(10,("push_message: pushed message length %u on "
645 "deferred_open_queue\n", (unsigned int)msg_len));
650 /****************************************************************************
651 Function to delete a sharing violation open message by mid.
652 ****************************************************************************/
654 void remove_deferred_open_message_smb(uint64_t mid)
656 struct pending_message_list *pml;
658 if (smbd_server_conn->using_smb2) {
659 remove_deferred_open_message_smb2(smbd_server_conn, mid);
663 for (pml = deferred_open_queue; pml; pml = pml->next) {
664 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
665 DEBUG(10,("remove_deferred_open_message_smb: "
666 "deleting mid %llu len %u\n",
667 (unsigned long long)mid,
668 (unsigned int)pml->buf.length ));
669 DLIST_REMOVE(deferred_open_queue, pml);
676 /****************************************************************************
677 Move a sharing violation open retry message to the front of the list and
678 schedule it for immediate processing.
679 ****************************************************************************/
681 void schedule_deferred_open_message_smb(uint64_t mid)
683 struct pending_message_list *pml;
686 if (smbd_server_conn->using_smb2) {
687 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
691 for (pml = deferred_open_queue; pml; pml = pml->next) {
692 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
694 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
697 (unsigned long long)msg_mid ));
699 if (mid == msg_mid) {
700 struct timed_event *te;
702 if (pml->processed) {
703 /* A processed message should not be
705 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
706 "message mid %llu was already processed\n",
707 (unsigned long long)msg_mid ));
711 DEBUG(10,("schedule_deferred_open_message_smb: "
712 "scheduling mid %llu\n",
713 (unsigned long long)mid ));
715 te = event_add_timed(server_event_context(),
718 smbd_deferred_open_timer,
721 DEBUG(10,("schedule_deferred_open_message_smb: "
722 "event_add_timed() failed, "
723 "skipping mid %llu\n",
724 (unsigned long long)msg_mid ));
727 TALLOC_FREE(pml->te);
729 DLIST_PROMOTE(deferred_open_queue, pml);
734 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
735 "find message mid %llu\n",
736 (unsigned long long)mid ));
739 /****************************************************************************
740 Return true if this mid is on the deferred queue and was not yet processed.
741 ****************************************************************************/
743 bool open_was_deferred(uint64_t mid)
745 struct pending_message_list *pml;
747 if (smbd_server_conn->using_smb2) {
748 return open_was_deferred_smb2(smbd_server_conn, mid);
751 for (pml = deferred_open_queue; pml; pml = pml->next) {
752 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
759 /****************************************************************************
760 Return the message queued by this mid.
761 ****************************************************************************/
763 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
765 struct pending_message_list *pml;
767 for (pml = deferred_open_queue; pml; pml = pml->next) {
768 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
775 /****************************************************************************
776 Get the state data queued by this mid.
777 ****************************************************************************/
779 bool get_deferred_open_message_state(struct smb_request *smbreq,
780 struct timeval *p_request_time,
783 struct pending_message_list *pml;
785 if (smbd_server_conn->using_smb2) {
786 return get_deferred_open_message_state_smb2(smbreq->smb2req,
791 pml = get_deferred_open_message_smb(smbreq->mid);
795 if (p_request_time) {
796 *p_request_time = pml->request_time;
799 *pp_state = (void *)pml->private_data.data;
804 /****************************************************************************
805 Function to push a deferred open smb message onto a linked list of local smb
806 messages ready for processing.
807 ****************************************************************************/
809 bool push_deferred_open_message_smb(struct smb_request *req,
810 struct timeval request_time,
811 struct timeval timeout,
813 char *private_data, size_t priv_len)
815 struct timeval end_time;
818 return push_deferred_open_message_smb2(req->smb2req,
826 if (req->unread_bytes) {
827 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
828 "unread_bytes = %u\n",
829 (unsigned int)req->unread_bytes ));
830 smb_panic("push_deferred_open_message_smb: "
831 "logic error unread_bytes != 0" );
834 end_time = timeval_sum(&request_time, &timeout);
836 DEBUG(10,("push_deferred_open_message_smb: pushing message "
837 "len %u mid %llu timeout time [%u.%06u]\n",
838 (unsigned int) smb_len(req->inbuf)+4,
839 (unsigned long long)req->mid,
840 (unsigned int)end_time.tv_sec,
841 (unsigned int)end_time.tv_usec));
843 return push_queued_message(req, request_time, end_time,
844 private_data, priv_len);
848 struct timed_event *te;
849 struct timeval interval;
851 bool (*handler)(const struct timeval *now, void *private_data);
855 static void smbd_idle_event_handler(struct event_context *ctx,
856 struct timed_event *te,
860 struct idle_event *event =
861 talloc_get_type_abort(private_data, struct idle_event);
863 TALLOC_FREE(event->te);
865 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
866 event->name, event->te));
868 if (!event->handler(&now, event->private_data)) {
869 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
870 event->name, event->te));
871 /* Don't repeat, delete ourselves */
876 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
877 event->name, event->te));
879 event->te = event_add_timed(ctx, event,
880 timeval_sum(&now, &event->interval),
881 smbd_idle_event_handler, event);
883 /* We can't do much but fail here. */
884 SMB_ASSERT(event->te != NULL);
887 struct idle_event *event_add_idle(struct event_context *event_ctx,
889 struct timeval interval,
891 bool (*handler)(const struct timeval *now,
895 struct idle_event *result;
896 struct timeval now = timeval_current();
898 result = talloc(mem_ctx, struct idle_event);
899 if (result == NULL) {
900 DEBUG(0, ("talloc failed\n"));
904 result->interval = interval;
905 result->handler = handler;
906 result->private_data = private_data;
908 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
909 DEBUG(0, ("talloc failed\n"));
914 result->te = event_add_timed(event_ctx, result,
915 timeval_sum(&now, &interval),
916 smbd_idle_event_handler, result);
917 if (result->te == NULL) {
918 DEBUG(0, ("event_add_timed failed\n"));
923 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
927 static void smbd_sig_term_handler(struct tevent_context *ev,
928 struct tevent_signal *se,
934 exit_server_cleanly("termination signal");
937 void smbd_setup_sig_term_handler(void)
939 struct tevent_signal *se;
941 se = tevent_add_signal(server_event_context(),
942 server_event_context(),
944 smbd_sig_term_handler,
947 exit_server("failed to setup SIGTERM handler");
951 static void smbd_sig_hup_handler(struct tevent_context *ev,
952 struct tevent_signal *se,
958 struct messaging_context *msg_ctx = talloc_get_type_abort(
959 private_data, struct messaging_context);
960 change_to_root_user();
961 DEBUG(1,("Reloading services after SIGHUP\n"));
962 reload_services(msg_ctx, smbd_server_conn->sock, False);
964 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
968 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
969 struct messaging_context *msg_ctx)
971 struct tevent_signal *se;
973 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
976 exit_server("failed to setup SIGHUP handler");
980 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
987 timeout = SMBD_SELECT_TIMEOUT * 1000;
990 * Are there any timed events waiting ? If so, ensure we don't
991 * select for longer than it would take to wait for them.
994 event_add_to_poll_args(server_event_context(), conn,
995 &conn->pfds, &num_pfds, &timeout);
997 /* Process a signal and timed events now... */
998 if (run_events_poll(server_event_context(), 0, NULL, 0)) {
999 return NT_STATUS_RETRY;
1004 START_PROFILE(smbd_idle);
1006 ret = sys_poll(conn->pfds, num_pfds, timeout);
1009 END_PROFILE(smbd_idle);
1014 if (errno == EINTR) {
1015 return NT_STATUS_RETRY;
1017 return map_nt_error_from_unix(errno);
1020 retry = run_events_poll(server_event_context(), ret, conn->pfds,
1023 return NT_STATUS_RETRY;
1026 /* Did we timeout ? */
1028 return NT_STATUS_RETRY;
1031 /* should not be reached */
1032 return NT_STATUS_INTERNAL_ERROR;
1036 * Only allow 5 outstanding trans requests. We're allocating memory, so
1040 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1043 for (; list != NULL; list = list->next) {
1045 if (list->mid == mid) {
1046 return NT_STATUS_INVALID_PARAMETER;
1052 return NT_STATUS_INSUFFICIENT_RESOURCES;
1055 return NT_STATUS_OK;
1059 These flags determine some of the permissions required to do an operation
1061 Note that I don't set NEED_WRITE on some write operations because they
1062 are used by some brain-dead clients when printing, and I don't want to
1063 force write permissions on print services.
1065 #define AS_USER (1<<0)
1066 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1067 #define TIME_INIT (1<<2)
1068 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1069 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1070 #define DO_CHDIR (1<<6)
1073 define a list of possible SMB messages and their corresponding
1074 functions. Any message that has a NULL function is unimplemented -
1075 please feel free to contribute implementations!
1077 static const struct smb_message_struct {
1079 void (*fn)(struct smb_request *req);
1081 } smb_messages[256] = {
1083 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1084 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1085 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1086 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1087 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1088 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1089 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1090 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1091 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1092 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1093 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1094 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1095 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1096 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1097 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1098 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1099 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1100 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1101 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1102 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1103 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1104 /* 0x15 */ { NULL, NULL, 0 },
1105 /* 0x16 */ { NULL, NULL, 0 },
1106 /* 0x17 */ { NULL, NULL, 0 },
1107 /* 0x18 */ { NULL, NULL, 0 },
1108 /* 0x19 */ { NULL, NULL, 0 },
1109 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1110 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1111 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1112 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1113 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1114 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1115 /* 0x20 */ { "SMBwritec", NULL,0},
1116 /* 0x21 */ { NULL, NULL, 0 },
1117 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1118 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1119 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1120 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1121 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1122 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1123 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1124 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1125 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1126 /* 0x2b */ { "SMBecho",reply_echo,0},
1127 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1128 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1129 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1130 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1131 /* 0x30 */ { NULL, NULL, 0 },
1132 /* 0x31 */ { NULL, NULL, 0 },
1133 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1134 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1135 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1136 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1137 /* 0x36 */ { NULL, NULL, 0 },
1138 /* 0x37 */ { NULL, NULL, 0 },
1139 /* 0x38 */ { NULL, NULL, 0 },
1140 /* 0x39 */ { NULL, NULL, 0 },
1141 /* 0x3a */ { NULL, NULL, 0 },
1142 /* 0x3b */ { NULL, NULL, 0 },
1143 /* 0x3c */ { NULL, NULL, 0 },
1144 /* 0x3d */ { NULL, NULL, 0 },
1145 /* 0x3e */ { NULL, NULL, 0 },
1146 /* 0x3f */ { NULL, NULL, 0 },
1147 /* 0x40 */ { NULL, NULL, 0 },
1148 /* 0x41 */ { NULL, NULL, 0 },
1149 /* 0x42 */ { NULL, NULL, 0 },
1150 /* 0x43 */ { NULL, NULL, 0 },
1151 /* 0x44 */ { NULL, NULL, 0 },
1152 /* 0x45 */ { NULL, NULL, 0 },
1153 /* 0x46 */ { NULL, NULL, 0 },
1154 /* 0x47 */ { NULL, NULL, 0 },
1155 /* 0x48 */ { NULL, NULL, 0 },
1156 /* 0x49 */ { NULL, NULL, 0 },
1157 /* 0x4a */ { NULL, NULL, 0 },
1158 /* 0x4b */ { NULL, NULL, 0 },
1159 /* 0x4c */ { NULL, NULL, 0 },
1160 /* 0x4d */ { NULL, NULL, 0 },
1161 /* 0x4e */ { NULL, NULL, 0 },
1162 /* 0x4f */ { NULL, NULL, 0 },
1163 /* 0x50 */ { NULL, NULL, 0 },
1164 /* 0x51 */ { NULL, NULL, 0 },
1165 /* 0x52 */ { NULL, NULL, 0 },
1166 /* 0x53 */ { NULL, NULL, 0 },
1167 /* 0x54 */ { NULL, NULL, 0 },
1168 /* 0x55 */ { NULL, NULL, 0 },
1169 /* 0x56 */ { NULL, NULL, 0 },
1170 /* 0x57 */ { NULL, NULL, 0 },
1171 /* 0x58 */ { NULL, NULL, 0 },
1172 /* 0x59 */ { NULL, NULL, 0 },
1173 /* 0x5a */ { NULL, NULL, 0 },
1174 /* 0x5b */ { NULL, NULL, 0 },
1175 /* 0x5c */ { NULL, NULL, 0 },
1176 /* 0x5d */ { NULL, NULL, 0 },
1177 /* 0x5e */ { NULL, NULL, 0 },
1178 /* 0x5f */ { NULL, NULL, 0 },
1179 /* 0x60 */ { NULL, NULL, 0 },
1180 /* 0x61 */ { NULL, NULL, 0 },
1181 /* 0x62 */ { NULL, NULL, 0 },
1182 /* 0x63 */ { NULL, NULL, 0 },
1183 /* 0x64 */ { NULL, NULL, 0 },
1184 /* 0x65 */ { NULL, NULL, 0 },
1185 /* 0x66 */ { NULL, NULL, 0 },
1186 /* 0x67 */ { NULL, NULL, 0 },
1187 /* 0x68 */ { NULL, NULL, 0 },
1188 /* 0x69 */ { NULL, NULL, 0 },
1189 /* 0x6a */ { NULL, NULL, 0 },
1190 /* 0x6b */ { NULL, NULL, 0 },
1191 /* 0x6c */ { NULL, NULL, 0 },
1192 /* 0x6d */ { NULL, NULL, 0 },
1193 /* 0x6e */ { NULL, NULL, 0 },
1194 /* 0x6f */ { NULL, NULL, 0 },
1195 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1196 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1197 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1198 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1199 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1200 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1201 /* 0x76 */ { NULL, NULL, 0 },
1202 /* 0x77 */ { NULL, NULL, 0 },
1203 /* 0x78 */ { NULL, NULL, 0 },
1204 /* 0x79 */ { NULL, NULL, 0 },
1205 /* 0x7a */ { NULL, NULL, 0 },
1206 /* 0x7b */ { NULL, NULL, 0 },
1207 /* 0x7c */ { NULL, NULL, 0 },
1208 /* 0x7d */ { NULL, NULL, 0 },
1209 /* 0x7e */ { NULL, NULL, 0 },
1210 /* 0x7f */ { NULL, NULL, 0 },
1211 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1212 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1213 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1214 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1215 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1216 /* 0x85 */ { NULL, NULL, 0 },
1217 /* 0x86 */ { NULL, NULL, 0 },
1218 /* 0x87 */ { NULL, NULL, 0 },
1219 /* 0x88 */ { NULL, NULL, 0 },
1220 /* 0x89 */ { NULL, NULL, 0 },
1221 /* 0x8a */ { NULL, NULL, 0 },
1222 /* 0x8b */ { NULL, NULL, 0 },
1223 /* 0x8c */ { NULL, NULL, 0 },
1224 /* 0x8d */ { NULL, NULL, 0 },
1225 /* 0x8e */ { NULL, NULL, 0 },
1226 /* 0x8f */ { NULL, NULL, 0 },
1227 /* 0x90 */ { NULL, NULL, 0 },
1228 /* 0x91 */ { NULL, NULL, 0 },
1229 /* 0x92 */ { NULL, NULL, 0 },
1230 /* 0x93 */ { NULL, NULL, 0 },
1231 /* 0x94 */ { NULL, NULL, 0 },
1232 /* 0x95 */ { NULL, NULL, 0 },
1233 /* 0x96 */ { NULL, NULL, 0 },
1234 /* 0x97 */ { NULL, NULL, 0 },
1235 /* 0x98 */ { NULL, NULL, 0 },
1236 /* 0x99 */ { NULL, NULL, 0 },
1237 /* 0x9a */ { NULL, NULL, 0 },
1238 /* 0x9b */ { NULL, NULL, 0 },
1239 /* 0x9c */ { NULL, NULL, 0 },
1240 /* 0x9d */ { NULL, NULL, 0 },
1241 /* 0x9e */ { NULL, NULL, 0 },
1242 /* 0x9f */ { NULL, NULL, 0 },
1243 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1244 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1245 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1246 /* 0xa3 */ { NULL, NULL, 0 },
1247 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1248 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1249 /* 0xa6 */ { NULL, NULL, 0 },
1250 /* 0xa7 */ { NULL, NULL, 0 },
1251 /* 0xa8 */ { NULL, NULL, 0 },
1252 /* 0xa9 */ { NULL, NULL, 0 },
1253 /* 0xaa */ { NULL, NULL, 0 },
1254 /* 0xab */ { NULL, NULL, 0 },
1255 /* 0xac */ { NULL, NULL, 0 },
1256 /* 0xad */ { NULL, NULL, 0 },
1257 /* 0xae */ { NULL, NULL, 0 },
1258 /* 0xaf */ { NULL, NULL, 0 },
1259 /* 0xb0 */ { NULL, NULL, 0 },
1260 /* 0xb1 */ { NULL, NULL, 0 },
1261 /* 0xb2 */ { NULL, NULL, 0 },
1262 /* 0xb3 */ { NULL, NULL, 0 },
1263 /* 0xb4 */ { NULL, NULL, 0 },
1264 /* 0xb5 */ { NULL, NULL, 0 },
1265 /* 0xb6 */ { NULL, NULL, 0 },
1266 /* 0xb7 */ { NULL, NULL, 0 },
1267 /* 0xb8 */ { NULL, NULL, 0 },
1268 /* 0xb9 */ { NULL, NULL, 0 },
1269 /* 0xba */ { NULL, NULL, 0 },
1270 /* 0xbb */ { NULL, NULL, 0 },
1271 /* 0xbc */ { NULL, NULL, 0 },
1272 /* 0xbd */ { NULL, NULL, 0 },
1273 /* 0xbe */ { NULL, NULL, 0 },
1274 /* 0xbf */ { NULL, NULL, 0 },
1275 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1276 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1277 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1278 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1279 /* 0xc4 */ { NULL, NULL, 0 },
1280 /* 0xc5 */ { NULL, NULL, 0 },
1281 /* 0xc6 */ { NULL, NULL, 0 },
1282 /* 0xc7 */ { NULL, NULL, 0 },
1283 /* 0xc8 */ { NULL, NULL, 0 },
1284 /* 0xc9 */ { NULL, NULL, 0 },
1285 /* 0xca */ { NULL, NULL, 0 },
1286 /* 0xcb */ { NULL, NULL, 0 },
1287 /* 0xcc */ { NULL, NULL, 0 },
1288 /* 0xcd */ { NULL, NULL, 0 },
1289 /* 0xce */ { NULL, NULL, 0 },
1290 /* 0xcf */ { NULL, NULL, 0 },
1291 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1292 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1293 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1294 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1295 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1296 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1297 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1298 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1299 /* 0xd8 */ { NULL, NULL, 0 },
1300 /* 0xd9 */ { NULL, NULL, 0 },
1301 /* 0xda */ { NULL, NULL, 0 },
1302 /* 0xdb */ { NULL, NULL, 0 },
1303 /* 0xdc */ { NULL, NULL, 0 },
1304 /* 0xdd */ { NULL, NULL, 0 },
1305 /* 0xde */ { NULL, NULL, 0 },
1306 /* 0xdf */ { NULL, NULL, 0 },
1307 /* 0xe0 */ { NULL, NULL, 0 },
1308 /* 0xe1 */ { NULL, NULL, 0 },
1309 /* 0xe2 */ { NULL, NULL, 0 },
1310 /* 0xe3 */ { NULL, NULL, 0 },
1311 /* 0xe4 */ { NULL, NULL, 0 },
1312 /* 0xe5 */ { NULL, NULL, 0 },
1313 /* 0xe6 */ { NULL, NULL, 0 },
1314 /* 0xe7 */ { NULL, NULL, 0 },
1315 /* 0xe8 */ { NULL, NULL, 0 },
1316 /* 0xe9 */ { NULL, NULL, 0 },
1317 /* 0xea */ { NULL, NULL, 0 },
1318 /* 0xeb */ { NULL, NULL, 0 },
1319 /* 0xec */ { NULL, NULL, 0 },
1320 /* 0xed */ { NULL, NULL, 0 },
1321 /* 0xee */ { NULL, NULL, 0 },
1322 /* 0xef */ { NULL, NULL, 0 },
1323 /* 0xf0 */ { NULL, NULL, 0 },
1324 /* 0xf1 */ { NULL, NULL, 0 },
1325 /* 0xf2 */ { NULL, NULL, 0 },
1326 /* 0xf3 */ { NULL, NULL, 0 },
1327 /* 0xf4 */ { NULL, NULL, 0 },
1328 /* 0xf5 */ { NULL, NULL, 0 },
1329 /* 0xf6 */ { NULL, NULL, 0 },
1330 /* 0xf7 */ { NULL, NULL, 0 },
1331 /* 0xf8 */ { NULL, NULL, 0 },
1332 /* 0xf9 */ { NULL, NULL, 0 },
1333 /* 0xfa */ { NULL, NULL, 0 },
1334 /* 0xfb */ { NULL, NULL, 0 },
1335 /* 0xfc */ { NULL, NULL, 0 },
1336 /* 0xfd */ { NULL, NULL, 0 },
1337 /* 0xfe */ { NULL, NULL, 0 },
1338 /* 0xff */ { NULL, NULL, 0 }
1342 /*******************************************************************
1343 allocate and initialize a reply packet
1344 ********************************************************************/
1346 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1347 const char *inbuf, char **outbuf, uint8_t num_words,
1351 * Protect against integer wrap
1353 if ((num_bytes > 0xffffff)
1354 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1356 if (asprintf(&msg, "num_bytes too large: %u",
1357 (unsigned)num_bytes) == -1) {
1358 msg = discard_const_p(char, "num_bytes too large");
1363 *outbuf = talloc_array(mem_ctx, char,
1364 smb_size + num_words*2 + num_bytes);
1365 if (*outbuf == NULL) {
1369 construct_reply_common(req, inbuf, *outbuf);
1370 srv_set_message(*outbuf, num_words, num_bytes, false);
1372 * Zero out the word area, the caller has to take care of the bcc area
1375 if (num_words != 0) {
1376 memset(*outbuf + smb_vwv0, 0, num_words*2);
1382 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1385 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1387 smb_panic("could not allocate output buffer\n");
1389 req->outbuf = (uint8_t *)outbuf;
1393 /*******************************************************************
1394 Dump a packet to a file.
1395 ********************************************************************/
1397 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1401 if (DEBUGLEVEL < 50) {
1405 if (len < 4) len = smb_len(data)+4;
1406 for (i=1;i<100;i++) {
1407 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1408 type ? "req" : "resp") == -1) {
1411 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1412 if (fd != -1 || errno != EEXIST) break;
1415 ssize_t ret = write(fd, data, len);
1417 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1419 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1424 /****************************************************************************
1425 Prepare everything for calling the actual request function, and potentially
1426 call the request function via the "new" interface.
1428 Return False if the "legacy" function needs to be called, everything is
1431 Return True if we're done.
1433 I know this API sucks, but it is the one with the least code change I could
1435 ****************************************************************************/
1437 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1441 connection_struct *conn = NULL;
1442 struct smbd_server_connection *sconn = req->sconn;
1447 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1448 * so subtract 4 from it. */
1449 if (!valid_smb_header(req->inbuf)
1450 || (size < (smb_size - 4))) {
1451 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1452 smb_len(req->inbuf)));
1453 exit_server_cleanly("Non-SMB packet");
1456 if (smb_messages[type].fn == NULL) {
1457 DEBUG(0,("Unknown message type %d!\n",type));
1458 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1459 reply_unknown_new(req, type);
1463 flags = smb_messages[type].flags;
1465 /* In share mode security we must ignore the vuid. */
1466 session_tag = (lp_security() == SEC_SHARE)
1467 ? UID_FIELD_INVALID : req->vuid;
1470 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1471 (int)sys_getpid(), (unsigned long)conn));
1473 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1475 /* Ensure this value is replaced in the incoming packet. */
1476 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1479 * Ensure the correct username is in current_user_info. This is a
1480 * really ugly bugfix for problems with multiple session_setup_and_X's
1481 * being done and allowing %U and %G substitutions to work correctly.
1482 * There is a reason this code is done here, don't move it unless you
1483 * know what you're doing... :-).
1487 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1488 user_struct *vuser = NULL;
1490 sconn->smb1.sessions.last_session_tag = session_tag;
1491 if(session_tag != UID_FIELD_INVALID) {
1492 vuser = get_valid_user_struct(sconn, session_tag);
1494 set_current_user_info(
1495 vuser->session_info->sanitized_username,
1496 vuser->session_info->unix_name,
1497 vuser->session_info->info3->base.domain.string);
1502 /* Does this call need to be run as the connected user? */
1503 if (flags & AS_USER) {
1505 /* Does this call need a valid tree connection? */
1508 * Amazingly, the error code depends on the command
1511 if (type == SMBntcreateX) {
1512 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1514 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1519 if (!change_to_user(conn,session_tag)) {
1520 DEBUG(0, ("Error: Could not change to user. Removing "
1521 "deferred open, mid=%llu.\n",
1522 (unsigned long long)req->mid));
1523 reply_force_doserror(req, ERRSRV, ERRbaduid);
1527 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1529 /* Does it need write permission? */
1530 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1531 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1535 /* IPC services are limited */
1536 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1537 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1541 /* This call needs to be run as root */
1542 change_to_root_user();
1545 /* load service specific parameters */
1547 if (req->encrypted) {
1548 conn->encrypted_tid = true;
1549 /* encrypted required from now on. */
1550 conn->encrypt_level = Required;
1551 } else if (ENCRYPTION_REQUIRED(conn)) {
1552 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1553 exit_server_cleanly("encryption required "
1559 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1560 (flags & (AS_USER|DO_CHDIR)
1562 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1565 conn->num_smb_operations++;
1568 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1570 if (raddr == NULL) {
1571 reply_nterror(req, NT_STATUS_NO_MEMORY);
1575 /* does this protocol need to be run as guest? */
1576 if ((flags & AS_GUEST)
1577 && (!change_to_guest() ||
1578 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1579 sconn->remote_hostname,
1581 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1585 smb_messages[type].fn(req);
1589 /****************************************************************************
1590 Construct a reply to the incoming packet.
1591 ****************************************************************************/
1593 static void construct_reply(struct smbd_server_connection *sconn,
1594 char *inbuf, int size, size_t unread_bytes,
1595 uint32_t seqnum, bool encrypted,
1596 struct smb_perfcount_data *deferred_pcd)
1598 connection_struct *conn;
1599 struct smb_request *req;
1601 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1602 smb_panic("could not allocate smb_request");
1605 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1606 encrypted, seqnum)) {
1607 exit_server_cleanly("Invalid SMB request");
1610 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1612 /* we popped this message off the queue - keep original perf data */
1614 req->pcd = *deferred_pcd;
1616 SMB_PERFCOUNT_START(&req->pcd);
1617 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1618 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1621 conn = switch_message(req->cmd, req, size);
1623 if (req->unread_bytes) {
1624 /* writeX failed. drain socket. */
1625 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1626 req->unread_bytes) {
1627 smb_panic("failed to drain pending bytes");
1629 req->unread_bytes = 0;
1637 if (req->outbuf == NULL) {
1641 if (CVAL(req->outbuf,0) == 0) {
1642 show_msg((char *)req->outbuf);
1645 if (!srv_send_smb(req->sconn,
1646 (char *)req->outbuf,
1647 true, req->seqnum+1,
1648 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1650 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1658 /****************************************************************************
1659 Process an smb from the client
1660 ****************************************************************************/
1661 static void process_smb(struct smbd_server_connection *sconn,
1662 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1663 uint32_t seqnum, bool encrypted,
1664 struct smb_perfcount_data *deferred_pcd)
1666 int msg_type = CVAL(inbuf,0);
1668 DO_PROFILE_INC(smb_count);
1670 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1672 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1673 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1675 if (msg_type != 0) {
1677 * NetBIOS session request, keepalive, etc.
1679 reply_special(sconn, (char *)inbuf, nread);
1683 if (sconn->using_smb2) {
1684 /* At this point we're not really using smb2,
1685 * we make the decision here.. */
1686 if (smbd_is_smb2_header(inbuf, nread)) {
1687 smbd_smb2_first_negprot(sconn, inbuf, nread);
1689 } else if (nread >= smb_size && valid_smb_header(inbuf)
1690 && CVAL(inbuf, smb_com) != 0x72) {
1691 /* This is a non-negprot SMB1 packet.
1692 Disable SMB2 from now on. */
1693 sconn->using_smb2 = false;
1697 show_msg((char *)inbuf);
1699 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1700 encrypted, deferred_pcd);
1704 sconn->smb1.num_requests++;
1706 /* The timeout_processing function isn't run nearly
1707 often enough to implement 'max log size' without
1708 overrunning the size of the file by many megabytes.
1709 This is especially true if we are running at debug
1710 level 10. Checking every 50 SMBs is a nice
1711 tradeoff of performance vs log file size overrun. */
1713 if ((sconn->smb1.num_requests % 50) == 0 &&
1714 need_to_check_log_size()) {
1715 change_to_root_user();
1720 /****************************************************************************
1721 Return a string containing the function name of a SMB command.
1722 ****************************************************************************/
1724 const char *smb_fn_name(int type)
1726 const char *unknown_name = "SMBunknown";
1728 if (smb_messages[type].name == NULL)
1729 return(unknown_name);
1731 return(smb_messages[type].name);
1734 /****************************************************************************
1735 Helper functions for contruct_reply.
1736 ****************************************************************************/
1738 void add_to_common_flags2(uint32 v)
1743 void remove_from_common_flags2(uint32 v)
1745 common_flags2 &= ~v;
1748 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1751 srv_set_message(outbuf,0,0,false);
1753 SCVAL(outbuf, smb_com, req->cmd);
1754 SIVAL(outbuf,smb_rcls,0);
1755 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1756 SSVAL(outbuf,smb_flg2,
1757 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1759 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1761 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1762 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1763 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1764 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1767 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1769 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1773 * How many bytes have we already accumulated up to the current wct field
1777 size_t req_wct_ofs(struct smb_request *req)
1781 if (req->chain_outbuf == NULL) {
1784 buf_size = talloc_get_size(req->chain_outbuf);
1785 if ((buf_size % 4) != 0) {
1786 buf_size += (4 - (buf_size % 4));
1788 return buf_size - 4;
1792 * Hack around reply_nterror & friends not being aware of chained requests,
1793 * generating illegal (i.e. wct==0) chain replies.
1796 static void fixup_chain_error_packet(struct smb_request *req)
1798 uint8_t *outbuf = req->outbuf;
1800 reply_outbuf(req, 2, 0);
1801 memcpy(req->outbuf, outbuf, smb_wct);
1802 TALLOC_FREE(outbuf);
1803 SCVAL(req->outbuf, smb_vwv0, 0xff);
1807 * @brief Find the smb_cmd offset of the last command pushed
1808 * @param[in] buf The buffer we're building up
1809 * @retval Where can we put our next andx cmd?
1811 * While chaining requests, the "next" request we're looking at needs to put
1812 * its SMB_Command before the data the previous request already built up added
1813 * to the chain. Find the offset to the place where we have to put our cmd.
1816 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1821 cmd = CVAL(buf, smb_com);
1823 SMB_ASSERT(is_andx_req(cmd));
1827 while (CVAL(buf, ofs) != 0xff) {
1829 if (!is_andx_req(CVAL(buf, ofs))) {
1834 * ofs is from start of smb header, so add the 4 length
1835 * bytes. The next cmd is right after the wct field.
1837 ofs = SVAL(buf, ofs+2) + 4 + 1;
1839 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1847 * @brief Do the smb chaining at a buffer level
1848 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1849 * @param[in] smb_command The command that we want to issue
1850 * @param[in] wct How many words?
1851 * @param[in] vwv The words, already in network order
1852 * @param[in] bytes_alignment How shall we align "bytes"?
1853 * @param[in] num_bytes How many bytes?
1854 * @param[in] bytes The data the request ships
1856 * smb_splice_chain() adds the vwv and bytes to the request already present in
1860 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1861 uint8_t wct, const uint16_t *vwv,
1862 size_t bytes_alignment,
1863 uint32_t num_bytes, const uint8_t *bytes)
1866 size_t old_size, new_size;
1868 size_t chain_padding = 0;
1869 size_t bytes_padding = 0;
1872 old_size = talloc_get_size(*poutbuf);
1875 * old_size == smb_wct means we're pushing the first request in for
1879 first_request = (old_size == smb_wct);
1881 if (!first_request && ((old_size % 4) != 0)) {
1883 * Align the wct field of subsequent requests to a 4-byte
1886 chain_padding = 4 - (old_size % 4);
1890 * After the old request comes the new wct field (1 byte), the vwv's
1891 * and the num_bytes field. After at we might need to align the bytes
1892 * given to us to "bytes_alignment", increasing the num_bytes value.
1895 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1897 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1898 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1901 new_size += bytes_padding + num_bytes;
1903 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1904 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1905 (unsigned)new_size));
1909 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1910 if (outbuf == NULL) {
1911 DEBUG(0, ("talloc failed\n"));
1916 if (first_request) {
1917 SCVAL(outbuf, smb_com, smb_command);
1919 size_t andx_cmd_ofs;
1921 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1922 DEBUG(1, ("invalid command chain\n"));
1923 *poutbuf = talloc_realloc(
1924 NULL, *poutbuf, uint8_t, old_size);
1928 if (chain_padding != 0) {
1929 memset(outbuf + old_size, 0, chain_padding);
1930 old_size += chain_padding;
1933 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1934 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1940 * Push the chained request:
1945 SCVAL(outbuf, ofs, wct);
1952 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1953 ofs += sizeof(uint16_t) * wct;
1959 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1960 ofs += sizeof(uint16_t);
1966 if (bytes_padding != 0) {
1967 memset(outbuf + ofs, 0, bytes_padding);
1968 ofs += bytes_padding;
1975 memcpy(outbuf + ofs, bytes, num_bytes);
1980 /****************************************************************************
1981 Construct a chained reply and add it to the already made reply
1982 ****************************************************************************/
1984 void chain_reply(struct smb_request *req)
1986 size_t smblen = smb_len(req->inbuf);
1987 size_t already_used, length_needed;
1989 uint32_t chain_offset; /* uint32_t to avoid overflow */
1992 const uint16_t *vwv;
1996 if (IVAL(req->outbuf, smb_rcls) != 0) {
1997 fixup_chain_error_packet(req);
2001 * Any of the AndX requests and replies have at least a wct of
2002 * 2. vwv[0] is the next command, vwv[1] is the offset from the
2003 * beginning of the SMB header to the next wct field.
2005 * None of the AndX requests put anything valuable in vwv[0] and [1],
2006 * so we can overwrite it here to form the chain.
2009 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
2010 if (req->chain_outbuf == NULL) {
2011 req->chain_outbuf = talloc_realloc(
2012 req, req->outbuf, uint8_t,
2013 smb_len(req->outbuf) + 4);
2014 if (req->chain_outbuf == NULL) {
2015 smb_panic("talloc failed");
2023 * Here we assume that this is the end of the chain. For that we need
2024 * to set "next command" to 0xff and the offset to 0. If we later find
2025 * more commands in the chain, this will be overwritten again.
2028 SCVAL(req->outbuf, smb_vwv0, 0xff);
2029 SCVAL(req->outbuf, smb_vwv0+1, 0);
2030 SSVAL(req->outbuf, smb_vwv1, 0);
2032 if (req->chain_outbuf == NULL) {
2034 * In req->chain_outbuf we collect all the replies. Start the
2035 * chain by copying in the first reply.
2037 * We do the realloc because later on we depend on
2038 * talloc_get_size to determine the length of
2039 * chain_outbuf. The reply_xxx routines might have
2040 * over-allocated (reply_pipe_read_and_X used to be such an
2043 req->chain_outbuf = talloc_realloc(
2044 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2045 if (req->chain_outbuf == NULL) {
2046 smb_panic("talloc failed");
2051 * Update smb headers where subsequent chained commands
2052 * may have updated them.
2054 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2055 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2057 if (!smb_splice_chain(&req->chain_outbuf,
2058 CVAL(req->outbuf, smb_com),
2059 CVAL(req->outbuf, smb_wct),
2060 (uint16_t *)(req->outbuf + smb_vwv),
2061 0, smb_buflen(req->outbuf),
2062 (uint8_t *)smb_buf(req->outbuf))) {
2065 TALLOC_FREE(req->outbuf);
2069 * We use the old request's vwv field to grab the next chained command
2070 * and offset into the chained fields.
2073 chain_cmd = CVAL(req->vwv+0, 0);
2074 chain_offset = SVAL(req->vwv+1, 0);
2076 if (chain_cmd == 0xff) {
2078 * End of chain, no more requests from the client. So ship the
2081 smb_setlen((char *)(req->chain_outbuf),
2082 talloc_get_size(req->chain_outbuf) - 4);
2084 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2085 true, req->seqnum+1,
2086 IS_CONN_ENCRYPTED(req->conn)
2089 exit_server_cleanly("chain_reply: srv_send_smb "
2092 TALLOC_FREE(req->chain_outbuf);
2097 /* add a new perfcounter for this element of chain */
2098 SMB_PERFCOUNT_ADD(&req->pcd);
2099 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2100 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2103 * Check if the client tries to fool us. The request so far uses the
2104 * space to the end of the byte buffer in the request just
2105 * processed. The chain_offset can't point into that area. If that was
2106 * the case, we could end up with an endless processing of the chain,
2107 * we would always handle the same request.
2110 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2111 if (chain_offset < already_used) {
2116 * Next check: Make sure the chain offset does not point beyond the
2117 * overall smb request length.
2120 length_needed = chain_offset+1; /* wct */
2121 if (length_needed > smblen) {
2126 * Now comes the pointer magic. Goal here is to set up req->vwv and
2127 * req->buf correctly again to be able to call the subsequent
2128 * switch_message(). The chain offset (the former vwv[1]) points at
2129 * the new wct field.
2132 wct = CVAL(smb_base(req->inbuf), chain_offset);
2135 * Next consistency check: Make the new vwv array fits in the overall
2139 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2140 if (length_needed > smblen) {
2143 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2146 * Now grab the new byte buffer....
2149 buflen = SVAL(vwv+wct, 0);
2152 * .. and check that it fits.
2155 length_needed += buflen;
2156 if (length_needed > smblen) {
2159 buf = (const uint8_t *)(vwv+wct+1);
2161 req->cmd = chain_cmd;
2163 req->vwv = discard_const_p(uint16_t, vwv);
2164 req->buflen = buflen;
2167 switch_message(chain_cmd, req, smblen);
2169 if (req->outbuf == NULL) {
2171 * This happens if the chained command has suspended itself or
2172 * if it has called srv_send_smb() itself.
2178 * We end up here if the chained command was not itself chained or
2179 * suspended, but for example a close() command. We now need to splice
2180 * the chained commands' outbuf into the already built up chain_outbuf
2181 * and ship the result.
2187 * We end up here if there's any error in the chain syntax. Report a
2188 * DOS error, just like Windows does.
2190 reply_force_doserror(req, ERRSRV, ERRerror);
2191 fixup_chain_error_packet(req);
2195 * This scary statement intends to set the
2196 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2197 * to the value req->outbuf carries
2199 SSVAL(req->chain_outbuf, smb_flg2,
2200 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2201 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2204 * Transfer the error codes from the subrequest to the main one
2206 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2207 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2209 if (!smb_splice_chain(&req->chain_outbuf,
2210 CVAL(req->outbuf, smb_com),
2211 CVAL(req->outbuf, smb_wct),
2212 (uint16_t *)(req->outbuf + smb_vwv),
2213 0, smb_buflen(req->outbuf),
2214 (uint8_t *)smb_buf(req->outbuf))) {
2215 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2217 TALLOC_FREE(req->outbuf);
2219 smb_setlen((char *)(req->chain_outbuf),
2220 talloc_get_size(req->chain_outbuf) - 4);
2222 show_msg((char *)(req->chain_outbuf));
2224 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2225 true, req->seqnum+1,
2226 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2228 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2230 TALLOC_FREE(req->chain_outbuf);
2234 /****************************************************************************
2235 Check if services need reloading.
2236 ****************************************************************************/
2238 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2241 if (last_smb_conf_reload_time == 0) {
2242 last_smb_conf_reload_time = t;
2245 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2246 reload_services(sconn->msg_ctx, sconn->sock, True);
2247 last_smb_conf_reload_time = t;
2251 static bool fd_is_readable(int fd)
2255 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2257 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2261 static void smbd_server_connection_write_handler(
2262 struct smbd_server_connection *sconn)
2264 /* TODO: make write nonblocking */
2267 static void smbd_server_connection_read_handler(
2268 struct smbd_server_connection *sconn, int fd)
2270 uint8_t *inbuf = NULL;
2271 size_t inbuf_len = 0;
2272 size_t unread_bytes = 0;
2273 bool encrypted = false;
2274 TALLOC_CTX *mem_ctx = talloc_tos();
2278 bool from_client = (sconn->sock == fd);
2281 smbd_lock_socket(sconn);
2283 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2284 DEBUG(10,("the echo listener was faster\n"));
2285 smbd_unlock_socket(sconn);
2289 /* TODO: make this completely nonblocking */
2290 status = receive_smb_talloc(mem_ctx, sconn, fd,
2291 (char **)(void *)&inbuf,
2295 &inbuf_len, &seqnum,
2296 false /* trusted channel */);
2297 smbd_unlock_socket(sconn);
2299 /* TODO: make this completely nonblocking */
2300 status = receive_smb_talloc(mem_ctx, sconn, fd,
2301 (char **)(void *)&inbuf,
2305 &inbuf_len, &seqnum,
2306 true /* trusted channel */);
2309 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2312 if (NT_STATUS_IS_ERR(status)) {
2313 exit_server_cleanly("failed to receive smb request");
2315 if (!NT_STATUS_IS_OK(status)) {
2320 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2321 seqnum, encrypted, NULL);
2324 static void smbd_server_connection_handler(struct event_context *ev,
2325 struct fd_event *fde,
2329 struct smbd_server_connection *conn = talloc_get_type(private_data,
2330 struct smbd_server_connection);
2332 if (flags & EVENT_FD_WRITE) {
2333 smbd_server_connection_write_handler(conn);
2336 if (flags & EVENT_FD_READ) {
2337 smbd_server_connection_read_handler(conn, conn->sock);
2342 static void smbd_server_echo_handler(struct event_context *ev,
2343 struct fd_event *fde,
2347 struct smbd_server_connection *conn = talloc_get_type(private_data,
2348 struct smbd_server_connection);
2350 if (flags & EVENT_FD_WRITE) {
2351 smbd_server_connection_write_handler(conn);
2354 if (flags & EVENT_FD_READ) {
2355 smbd_server_connection_read_handler(
2356 conn, conn->smb1.echo_handler.trusted_fd);
2361 #ifdef CLUSTER_SUPPORT
2362 /****************************************************************************
2363 received when we should release a specific IP
2364 ****************************************************************************/
2365 static void release_ip(const char *ip, void *priv)
2367 const char *addr = (const char *)priv;
2368 const char *p = addr;
2370 if (strncmp("::ffff:", addr, 7) == 0) {
2374 DEBUG(10, ("Got release IP message for %s, "
2375 "our address is %s\n", ip, p));
2377 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2378 /* we can't afford to do a clean exit - that involves
2379 database writes, which would potentially mean we
2380 are still running after the failover has finished -
2381 we have to get rid of this process ID straight
2383 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2385 /* note we must exit with non-zero status so the unclean handler gets
2386 called in the parent, so that the brl database is tickled */
2391 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2392 struct sockaddr_storage *client)
2395 length = sizeof(*server);
2396 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2399 length = sizeof(*client);
2400 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2408 * Send keepalive packets to our client
2410 static bool keepalive_fn(const struct timeval *now, void *private_data)
2412 struct smbd_server_connection *sconn = smbd_server_conn;
2415 if (sconn->using_smb2) {
2416 /* Don't do keepalives on an SMB2 connection. */
2420 smbd_lock_socket(smbd_server_conn);
2421 ret = send_keepalive(sconn->sock);
2422 smbd_unlock_socket(smbd_server_conn);
2425 char addr[INET6_ADDRSTRLEN];
2427 * Try and give an error message saying what
2430 DEBUG(0, ("send_keepalive failed for client %s. "
2431 "Error %s - exiting\n",
2432 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2440 * Do the recurring check if we're idle
2442 static bool deadtime_fn(const struct timeval *now, void *private_data)
2444 struct smbd_server_connection *sconn =
2445 (struct smbd_server_connection *)private_data;
2447 if ((conn_num_open(sconn) == 0)
2448 || (conn_idle_all(sconn, now->tv_sec))) {
2449 DEBUG( 2, ( "Closing idle connection\n" ) );
2450 messaging_send(sconn->msg_ctx,
2451 messaging_server_id(sconn->msg_ctx),
2452 MSG_SHUTDOWN, &data_blob_null);
2460 * Do the recurring log file and smb.conf reload checks.
2463 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2465 struct smbd_server_connection *sconn = talloc_get_type_abort(
2466 private_data, struct smbd_server_connection);
2468 DEBUG(5, ("housekeeping\n"));
2470 change_to_root_user();
2472 /* update printer queue caches if necessary */
2473 update_monitored_printq_cache(sconn->msg_ctx);
2475 /* check if we need to reload services */
2476 check_reload(sconn, time_mono(NULL));
2478 /* Change machine password if neccessary. */
2479 attempt_machine_password_change();
2482 * Force a log file check.
2484 force_check_log_size();
2489 static int create_unlink_tmp(const char *dir)
2494 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2495 if (fname == NULL) {
2499 fd = mkstemp(fname);
2504 if (unlink(fname) == -1) {
2505 int sys_errno = errno;
2515 struct smbd_echo_state {
2516 struct tevent_context *ev;
2517 struct iovec *pending;
2518 struct smbd_server_connection *sconn;
2521 struct tevent_fd *parent_fde;
2523 struct tevent_fd *read_fde;
2524 struct tevent_req *write_req;
2527 static void smbd_echo_writer_done(struct tevent_req *req);
2529 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2533 if (state->write_req != NULL) {
2537 num_pending = talloc_array_length(state->pending);
2538 if (num_pending == 0) {
2542 state->write_req = writev_send(state, state->ev, NULL,
2543 state->parent_pipe, false,
2544 state->pending, num_pending);
2545 if (state->write_req == NULL) {
2546 DEBUG(1, ("writev_send failed\n"));
2550 talloc_steal(state->write_req, state->pending);
2551 state->pending = NULL;
2553 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2557 static void smbd_echo_writer_done(struct tevent_req *req)
2559 struct smbd_echo_state *state = tevent_req_callback_data(
2560 req, struct smbd_echo_state);
2564 written = writev_recv(req, &err);
2566 state->write_req = NULL;
2567 if (written == -1) {
2568 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2571 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2572 smbd_echo_activate_writer(state);
2575 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2578 struct smb_request req;
2579 uint16_t num_replies;
2584 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2585 DEBUG(10, ("Got netbios keepalive\n"));
2592 if (inbuf_len < smb_size) {
2593 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2596 if (!valid_smb_header(inbuf)) {
2597 DEBUG(10, ("Got invalid SMB header\n"));
2601 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2607 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2608 smb_messages[req.cmd].name
2609 ? smb_messages[req.cmd].name : "unknown"));
2611 if (req.cmd != SMBecho) {
2618 num_replies = SVAL(req.vwv+0, 0);
2619 if (num_replies != 1) {
2620 /* Not a Windows "Hey, you're still there?" request */
2624 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2626 DEBUG(10, ("create_outbuf failed\n"));
2629 req.outbuf = (uint8_t *)outbuf;
2631 SSVAL(req.outbuf, smb_vwv0, num_replies);
2633 if (req.buflen > 0) {
2634 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2637 out_len = smb_len(req.outbuf) + 4;
2639 ok = srv_send_smb(req.sconn,
2643 TALLOC_FREE(outbuf);
2651 static void smbd_echo_exit(struct tevent_context *ev,
2652 struct tevent_fd *fde, uint16_t flags,
2655 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2659 static void smbd_echo_reader(struct tevent_context *ev,
2660 struct tevent_fd *fde, uint16_t flags,
2663 struct smbd_echo_state *state = talloc_get_type_abort(
2664 private_data, struct smbd_echo_state);
2665 struct smbd_server_connection *sconn = state->sconn;
2666 size_t unread, num_pending;
2670 uint32_t seqnum = 0;
2673 bool encrypted = false;
2677 ok = smbd_lock_socket_internal(sconn);
2679 DEBUG(0, ("%s: failed to lock socket\n",
2684 if (!fd_is_readable(sconn->sock)) {
2685 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2686 (int)sys_getpid()));
2687 ok = smbd_unlock_socket_internal(sconn);
2689 DEBUG(1, ("%s: failed to unlock socket in\n",
2696 num_pending = talloc_array_length(state->pending);
2697 tmp = talloc_realloc(state, state->pending, struct iovec,
2700 DEBUG(1, ("talloc_realloc failed\n"));
2703 state->pending = tmp;
2705 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2707 status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2708 (char **)(void *)&state->pending[num_pending].iov_base,
2714 false /* trusted_channel*/);
2715 if (!NT_STATUS_IS_OK(status)) {
2716 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2717 (int)sys_getpid(), nt_errstr(status)));
2720 state->pending[num_pending].iov_len = iov_len;
2722 ok = smbd_unlock_socket_internal(sconn);
2724 DEBUG(1, ("%s: failed to unlock socket in\n",
2729 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2730 state->pending[num_pending].iov_len,
2733 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2734 /* no check, shrinking by some bytes does not fail */
2735 state->pending = talloc_realloc(state, state->pending,
2741 if (state->pending[num_pending].iov_len >= smb_size) {
2743 * place the seqnum in the packet so that the main process
2744 * can reply with signing
2746 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2747 smb_ss_field, seqnum);
2748 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2749 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2752 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2753 smbd_echo_activate_writer(state);
2756 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2759 struct smbd_echo_state *state;
2761 state = talloc_zero(sconn, struct smbd_echo_state);
2762 if (state == NULL) {
2763 DEBUG(1, ("talloc failed\n"));
2766 state->sconn = sconn;
2767 state->parent_pipe = parent_pipe;
2768 state->ev = s3_tevent_context_init(state);
2769 if (state->ev == NULL) {
2770 DEBUG(1, ("tevent_context_init failed\n"));
2774 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2775 TEVENT_FD_READ, smbd_echo_exit,
2777 if (state->parent_fde == NULL) {
2778 DEBUG(1, ("tevent_add_fd failed\n"));
2782 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2783 TEVENT_FD_READ, smbd_echo_reader,
2785 if (state->read_fde == NULL) {
2786 DEBUG(1, ("tevent_add_fd failed\n"));
2792 if (tevent_loop_once(state->ev) == -1) {
2793 DEBUG(1, ("tevent_loop_once failed: %s\n",
2802 * Handle SMBecho requests in a forked child process
2804 bool fork_echo_handler(struct smbd_server_connection *sconn)
2806 int listener_pipe[2];
2810 res = pipe(listener_pipe);
2812 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2815 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2816 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2817 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2825 close(listener_pipe[0]);
2826 set_blocking(listener_pipe[1], false);
2828 status = reinit_after_fork(sconn->msg_ctx,
2829 server_event_context(),
2830 procid_self(), false);
2831 if (!NT_STATUS_IS_OK(status)) {
2832 DEBUG(1, ("reinit_after_fork failed: %s\n",
2833 nt_errstr(status)));
2836 smbd_echo_loop(sconn, listener_pipe[1]);
2839 close(listener_pipe[1]);
2840 listener_pipe[1] = -1;
2841 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2843 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2846 * Without smb signing this is the same as the normal smbd
2847 * listener. This needs to change once signing comes in.
2849 sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
2851 sconn->smb1.echo_handler.trusted_fd,
2853 smbd_server_echo_handler,
2855 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2856 DEBUG(1, ("event_add_fd failed\n"));
2863 if (listener_pipe[0] != -1) {
2864 close(listener_pipe[0]);
2866 if (listener_pipe[1] != -1) {
2867 close(listener_pipe[1]);
2869 sconn->smb1.echo_handler.trusted_fd = -1;
2870 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2871 close(sconn->smb1.echo_handler.socket_lock_fd);
2873 sconn->smb1.echo_handler.trusted_fd = -1;
2874 sconn->smb1.echo_handler.socket_lock_fd = -1;
2880 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2881 struct sockaddr_storage *srv,
2882 struct sockaddr_storage *clnt)
2884 struct ctdbd_connection *cconn;
2885 char tmp_addr[INET6_ADDRSTRLEN];
2888 cconn = messaging_ctdbd_connection();
2889 if (cconn == NULL) {
2890 return NT_STATUS_NO_MEMORY;
2893 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2894 addr = talloc_strdup(cconn, tmp_addr);
2896 return NT_STATUS_NO_MEMORY;
2898 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2903 /****************************************************************************
2904 Process commands from the client
2905 ****************************************************************************/
2907 void smbd_process(struct smbd_server_connection *sconn)
2909 TALLOC_CTX *frame = talloc_stackframe();
2910 struct sockaddr_storage ss;
2911 struct sockaddr *sa = NULL;
2912 socklen_t sa_socklen;
2913 struct tsocket_address *local_address = NULL;
2914 struct tsocket_address *remote_address = NULL;
2915 const char *remaddr = NULL;
2919 if (lp_maxprotocol() == PROTOCOL_SMB2) {
2921 * We're not making the decision here,
2922 * we're just allowing the client
2923 * to decide between SMB1 and SMB2
2924 * with the first negprot
2927 sconn->using_smb2 = true;
2930 /* Ensure child is set to blocking mode */
2931 set_blocking(sconn->sock,True);
2933 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2934 set_socket_options(sconn->sock, lp_socket_options());
2936 sa = (struct sockaddr *)(void *)&ss;
2937 sa_socklen = sizeof(ss);
2938 ret = getpeername(sconn->sock, sa, &sa_socklen);
2940 int level = (errno == ENOTCONN)?2:0;
2941 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2942 exit_server_cleanly("getpeername() failed.\n");
2944 ret = tsocket_address_bsd_from_sockaddr(sconn,
2948 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2949 __location__, strerror(errno)));
2950 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2953 sa = (struct sockaddr *)(void *)&ss;
2954 sa_socklen = sizeof(ss);
2955 ret = getsockname(sconn->sock, sa, &sa_socklen);
2957 int level = (errno == ENOTCONN)?2:0;
2958 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2959 exit_server_cleanly("getsockname() failed.\n");
2961 ret = tsocket_address_bsd_from_sockaddr(sconn,
2965 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2966 __location__, strerror(errno)));
2967 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2970 sconn->local_address = local_address;
2971 sconn->remote_address = remote_address;
2973 if (tsocket_address_is_inet(remote_address, "ip")) {
2974 remaddr = tsocket_address_inet_addr_string(
2975 sconn->remote_address,
2977 if (remaddr == NULL) {
2981 remaddr = "0.0.0.0";
2984 /* this is needed so that we get decent entries
2985 in smbstatus for port 445 connects */
2986 set_remote_machine_name(remaddr, false);
2987 reload_services(sconn->msg_ctx, sconn->sock, true);
2990 * Before the first packet, check the global hosts allow/ hosts deny
2991 * parameters before doing any parsing of packets passed to us by the
2992 * client. This prevents attacks on our parsing code from hosts not in
2993 * the hosts allow list.
2996 ret = get_remote_hostname(remote_address,
3000 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3001 __location__, strerror(errno)));
3002 exit_server_cleanly("get_remote_hostname failed.\n");
3004 if (strequal(rhost, "UNKNOWN")) {
3005 rhost = talloc_strdup(talloc_tos(), remaddr);
3007 sconn->remote_hostname = talloc_move(sconn, &rhost);
3009 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3010 sconn->remote_hostname,
3013 * send a negative session response "not listening on calling
3016 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3017 DEBUG( 1, ("Connection denied from %s to %s\n",
3018 tsocket_address_string(remote_address, talloc_tos()),
3019 tsocket_address_string(local_address, talloc_tos())));
3020 (void)srv_send_smb(sconn,(char *)buf, false,
3022 exit_server_cleanly("connection denied");
3025 DEBUG(10, ("Connection allowed from %s to %s\n",
3026 tsocket_address_string(remote_address, talloc_tos()),
3027 tsocket_address_string(local_address, talloc_tos())));
3031 smb_perfcount_init();
3033 if (!init_account_policy()) {
3034 exit_server("Could not open account policy tdb.\n");
3037 if (*lp_rootdir()) {
3038 if (chroot(lp_rootdir()) != 0) {
3039 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3040 exit_server("Failed to chroot()");
3042 if (chdir("/") == -1) {
3043 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3044 exit_server("Failed to chroot()");
3046 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3049 if (!srv_init_signing(sconn)) {
3050 exit_server("Failed to init smb_signing");
3054 if (!init_oplocks(sconn->msg_ctx))
3055 exit_server("Failed to init oplocks");
3057 /* register our message handlers */
3058 messaging_register(sconn->msg_ctx, NULL,
3059 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3060 messaging_register(sconn->msg_ctx, NULL,
3061 MSG_SMB_CLOSE_FILE, msg_close_file);
3064 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3065 * MSGs to all child processes
3067 messaging_deregister(sconn->msg_ctx,
3069 messaging_register(sconn->msg_ctx, NULL,
3070 MSG_DEBUG, debug_message);
3072 if ((lp_keepalive() != 0)
3073 && !(event_add_idle(server_event_context(), NULL,
3074 timeval_set(lp_keepalive(), 0),
3075 "keepalive", keepalive_fn,
3077 DEBUG(0, ("Could not add keepalive event\n"));
3081 if (!(event_add_idle(server_event_context(), NULL,
3082 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3083 "deadtime", deadtime_fn, sconn))) {
3084 DEBUG(0, ("Could not add deadtime event\n"));
3088 if (!(event_add_idle(server_event_context(), NULL,
3089 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3090 "housekeeping", housekeeping_fn, sconn))) {
3091 DEBUG(0, ("Could not add housekeeping event\n"));
3095 #ifdef CLUSTER_SUPPORT
3097 if (lp_clustering()) {
3099 * We need to tell ctdb about our client's TCP
3100 * connection, so that for failover ctdbd can send
3101 * tickle acks, triggering a reconnection by the
3105 struct sockaddr_storage srv, clnt;
3107 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3109 status = smbd_register_ips(sconn, &srv, &clnt);
3110 if (!NT_STATUS_IS_OK(status)) {
3111 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3112 nt_errstr(status)));
3116 DEBUG(0,("Unable to get tcp info for "
3117 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3124 sconn->nbt.got_session = false;
3126 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3128 sconn->smb1.sessions.done_sesssetup = false;
3129 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3130 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3131 /* users from session setup */
3132 sconn->smb1.sessions.session_userlist = NULL;
3133 /* workgroup from session setup. */
3134 sconn->smb1.sessions.session_workgroup = NULL;
3135 /* this holds info on user ids that are already validated for this VC */
3136 sconn->smb1.sessions.validated_users = NULL;
3137 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3138 sconn->smb1.sessions.num_validated_vuids = 0;
3141 if (!init_dptrs(sconn)) {
3142 exit_server("init_dptrs() failed");
3145 sconn->smb1.fde = event_add_fd(server_event_context(),
3149 smbd_server_connection_handler,
3151 if (!sconn->smb1.fde) {
3152 exit_server("failed to create smbd_server_connection fde");
3160 frame = talloc_stackframe_pool(8192);
3164 status = smbd_server_connection_loop_once(sconn);
3165 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3166 !NT_STATUS_IS_OK(status)) {
3167 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3168 " exiting\n", nt_errstr(status)));
3175 exit_server_cleanly(NULL);
3178 bool req_is_in_chain(struct smb_request *req)
3180 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3182 * We're right now handling a subsequent request, so we must
3188 if (!is_andx_req(req->cmd)) {
3194 * Okay, an illegal request, but definitely not chained :-)
3199 return (CVAL(req->vwv+0, 0) != 0xFF);