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/queue_process.h"
31 #include "system/select.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
43 #include "system/threads.h"
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list {
47 struct pending_message_list *next, *prev;
48 struct timeval request_time; /* When was this first issued? */
49 struct smbd_server_connection *sconn;
50 struct tevent_timer *te;
51 struct smb_perfcount_data pcd;
56 struct deferred_open_record *open_rec;
59 static void construct_reply_common(struct smb_request *req, const char *inbuf,
61 static struct pending_message_list *get_deferred_open_message_smb(
62 struct smbd_server_connection *sconn, uint64_t mid);
63 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
65 void smbd_echo_init(struct smbd_server_connection *sconn)
67 sconn->smb1.echo_handler.trusted_fd = -1;
68 sconn->smb1.echo_handler.socket_lock_fd = -1;
69 #ifdef HAVE_ROBUST_MUTEXES
70 sconn->smb1.echo_handler.socket_mutex = NULL;
74 static bool smbd_echo_active(struct smbd_server_connection *sconn)
76 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
80 #ifdef HAVE_ROBUST_MUTEXES
81 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
89 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
91 if (!smbd_echo_active(sconn)) {
95 sconn->smb1.echo_handler.ref_count++;
97 if (sconn->smb1.echo_handler.ref_count > 1) {
101 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
103 #ifdef HAVE_ROBUST_MUTEXES
104 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
107 while (ret == EINTR) {
108 ret = pthread_mutex_lock(
109 sconn->smb1.echo_handler.socket_mutex);
115 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
122 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
127 sconn->smb1.echo_handler.socket_lock_fd,
128 F_SETLKW, 0, 0, F_WRLCK);
129 } while (!ok && (errno == EINTR));
132 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
137 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
142 void smbd_lock_socket(struct smbd_server_connection *sconn)
144 if (!smbd_lock_socket_internal(sconn)) {
145 exit_server_cleanly("failed to lock socket");
149 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
151 if (!smbd_echo_active(sconn)) {
155 sconn->smb1.echo_handler.ref_count--;
157 if (sconn->smb1.echo_handler.ref_count > 0) {
161 #ifdef HAVE_ROBUST_MUTEXES
162 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
165 while (ret == EINTR) {
166 ret = pthread_mutex_unlock(
167 sconn->smb1.echo_handler.socket_mutex);
173 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
180 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
185 sconn->smb1.echo_handler.socket_lock_fd,
186 F_SETLKW, 0, 0, F_UNLCK);
187 } while (!ok && (errno == EINTR));
190 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
195 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
200 void smbd_unlock_socket(struct smbd_server_connection *sconn)
202 if (!smbd_unlock_socket_internal(sconn)) {
203 exit_server_cleanly("failed to unlock socket");
207 /* Accessor function for smb_read_error for smbd functions. */
209 /****************************************************************************
211 ****************************************************************************/
213 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
214 bool do_signing, uint32_t seqnum,
216 struct smb_perfcount_data *pcd)
220 char *buf_out = buffer;
222 if (!NT_STATUS_IS_OK(sconn->status)) {
224 * we're not supposed to do any io
229 smbd_lock_socket(sconn);
232 /* Sign the outgoing packet if required. */
233 srv_calculate_sign_mac(sconn, buf_out, seqnum);
237 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
238 if (!NT_STATUS_IS_OK(status)) {
239 DEBUG(0, ("send_smb: SMB encryption failed "
240 "on outgoing packet! Error %s\n",
241 nt_errstr(status) ));
247 len = smb_len_large(buf_out) + 4;
249 ret = write_data(sconn->sock, buf_out, len);
252 char addr[INET6_ADDRSTRLEN];
254 * Try and give an error message saying what
257 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
258 (int)getpid(), (int)len,
259 get_peer_addr(sconn->sock, addr, sizeof(addr)),
260 (int)ret, strerror(errno) ));
262 srv_free_enc_buffer(sconn, buf_out);
266 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
267 srv_free_enc_buffer(sconn, buf_out);
269 SMB_PERFCOUNT_END(pcd);
271 smbd_unlock_socket(sconn);
275 /*******************************************************************
276 Setup the word count and byte count for a smb message.
277 ********************************************************************/
279 int srv_set_message(char *buf,
284 if (zero && (num_words || num_bytes)) {
285 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
287 SCVAL(buf,smb_wct,num_words);
288 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
289 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
290 return (smb_size + num_words*2 + num_bytes);
293 static bool valid_smb_header(struct smbd_server_connection *sconn,
294 const uint8_t *inbuf)
296 if (is_encrypted_packet(sconn, inbuf)) {
300 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
301 * but it just looks weird to call strncmp for this one.
303 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
306 /* Socket functions for smbd packet processing. */
308 static bool valid_packet_size(size_t len)
311 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
312 * of header. Don't print the error if this fits.... JRA.
315 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
316 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
317 (unsigned long)len));
323 static NTSTATUS read_packet_remainder(int fd, char *buffer,
324 unsigned int timeout, ssize_t len)
332 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
333 if (!NT_STATUS_IS_OK(status)) {
334 char addr[INET6_ADDRSTRLEN];
335 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
337 get_peer_addr(fd, addr, sizeof(addr)),
343 /****************************************************************************
344 Attempt a zerocopy writeX read. We know here that len > smb_size-4
345 ****************************************************************************/
348 * Unfortunately, earlier versions of smbclient/libsmbclient
349 * don't send this "standard" writeX header. I've fixed this
350 * for 3.2 but we'll use the old method with earlier versions.
351 * Windows and CIFSFS at least use this standard size. Not
355 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
356 (2*14) + /* word count (including bcc) */ \
359 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
360 const char lenbuf[4],
361 struct smbd_server_connection *sconn,
364 unsigned int timeout,
368 /* Size of a WRITEX call (+4 byte len). */
369 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
370 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
374 memcpy(writeX_header, lenbuf, 4);
376 status = read_fd_with_timeout(
377 sock, writeX_header + 4,
378 STANDARD_WRITE_AND_X_HEADER_SIZE,
379 STANDARD_WRITE_AND_X_HEADER_SIZE,
382 if (!NT_STATUS_IS_OK(status)) {
383 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
385 tsocket_address_string(sconn->remote_address,
392 * Ok - now try and see if this is a possible
396 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
398 * If the data offset is beyond what
399 * we've read, drain the extra bytes.
401 uint16_t doff = SVAL(writeX_header,smb_vwv11);
404 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
405 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
406 if (drain_socket(sock, drain) != drain) {
407 smb_panic("receive_smb_raw_talloc_partial_read:"
408 " failed to drain pending bytes");
411 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
414 /* Spoof down the length and null out the bcc. */
415 set_message_bcc(writeX_header, 0);
416 newlen = smb_len(writeX_header);
418 /* Copy the header we've written. */
420 *buffer = (char *)talloc_memdup(mem_ctx,
422 sizeof(writeX_header));
424 if (*buffer == NULL) {
425 DEBUG(0, ("Could not allocate inbuf of length %d\n",
426 (int)sizeof(writeX_header)));
427 return NT_STATUS_NO_MEMORY;
430 /* Work out the remaining bytes. */
431 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
432 *len_ret = newlen + 4;
436 if (!valid_packet_size(len)) {
437 return NT_STATUS_INVALID_PARAMETER;
441 * Not a valid writeX call. Just do the standard
445 *buffer = talloc_array(mem_ctx, char, len+4);
447 if (*buffer == NULL) {
448 DEBUG(0, ("Could not allocate inbuf of length %d\n",
450 return NT_STATUS_NO_MEMORY;
453 /* Copy in what we already read. */
456 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
457 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
460 status = read_packet_remainder(
462 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
465 if (!NT_STATUS_IS_OK(status)) {
466 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
476 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
477 struct smbd_server_connection *sconn,
479 char **buffer, unsigned int timeout,
480 size_t *p_unread, size_t *plen)
484 int min_recv_size = lp_min_receive_file_size();
489 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
491 if (!NT_STATUS_IS_OK(status)) {
495 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
496 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
497 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
498 !srv_is_signing_active(sconn) &&
499 sconn->smb1.echo_handler.trusted_fde == NULL) {
501 return receive_smb_raw_talloc_partial_read(
502 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
506 if (!valid_packet_size(len)) {
507 return NT_STATUS_INVALID_PARAMETER;
511 * The +4 here can't wrap, we've checked the length above already.
514 *buffer = talloc_array(mem_ctx, char, len+4);
516 if (*buffer == NULL) {
517 DEBUG(0, ("Could not allocate inbuf of length %d\n",
519 return NT_STATUS_NO_MEMORY;
522 memcpy(*buffer, lenbuf, sizeof(lenbuf));
524 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
525 if (!NT_STATUS_IS_OK(status)) {
533 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
534 struct smbd_server_connection *sconn,
536 char **buffer, unsigned int timeout,
537 size_t *p_unread, bool *p_encrypted,
540 bool trusted_channel)
545 *p_encrypted = false;
547 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
549 if (!NT_STATUS_IS_OK(status)) {
550 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
551 ("receive_smb_raw_talloc failed for client %s "
552 "read error = %s.\n",
553 tsocket_address_string(sconn->remote_address,
555 nt_errstr(status)) );
559 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
560 status = srv_decrypt_buffer(sconn, *buffer);
561 if (!NT_STATUS_IS_OK(status)) {
562 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
563 "incoming packet! Error %s\n",
564 nt_errstr(status) ));
570 /* Check the incoming SMB signature. */
571 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
572 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
573 "incoming packet!\n"));
574 return NT_STATUS_INVALID_NETWORK_RESPONSE;
582 * Initialize a struct smb_request from an inbuf
585 static bool init_smb_request(struct smb_request *req,
586 struct smbd_server_connection *sconn,
588 size_t unread_bytes, bool encrypted,
591 struct smbXsrv_tcon *tcon;
594 size_t req_size = smb_len(inbuf) + 4;
596 /* Ensure we have at least smb_size bytes. */
597 if (req_size < smb_size) {
598 DEBUG(0,("init_smb_request: invalid request size %u\n",
599 (unsigned int)req_size ));
603 req->request_time = timeval_current();
604 now = timeval_to_nttime(&req->request_time);
606 req->cmd = CVAL(inbuf, smb_com);
607 req->flags2 = SVAL(inbuf, smb_flg2);
608 req->smbpid = SVAL(inbuf, smb_pid);
609 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
610 req->seqnum = seqnum;
611 req->vuid = SVAL(inbuf, smb_uid);
612 req->tid = SVAL(inbuf, smb_tid);
613 req->wct = CVAL(inbuf, smb_wct);
614 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
615 req->buflen = smb_buflen(inbuf);
616 req->buf = (const uint8_t *)smb_buf_const(inbuf);
617 req->unread_bytes = unread_bytes;
618 req->encrypted = encrypted;
620 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
621 if (NT_STATUS_IS_OK(status)) {
622 req->conn = tcon->compat;
626 req->chain_fsp = NULL;
628 req->priv_paths = NULL;
630 smb_init_perfcount_data(&req->pcd);
632 /* Ensure we have at least wct words and 2 bytes of bcc. */
633 if (smb_size + req->wct*2 > req_size) {
634 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
635 (unsigned int)req->wct,
636 (unsigned int)req_size));
639 /* Ensure bcc is correct. */
640 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
641 DEBUG(0,("init_smb_request: invalid bcc number %u "
642 "(wct = %u, size %u)\n",
643 (unsigned int)req->buflen,
644 (unsigned int)req->wct,
645 (unsigned int)req_size));
653 static void process_smb(struct smbd_server_connection *conn,
654 uint8_t *inbuf, size_t nread, size_t unread_bytes,
655 uint32_t seqnum, bool encrypted,
656 struct smb_perfcount_data *deferred_pcd);
658 static void smbd_deferred_open_timer(struct tevent_context *ev,
659 struct tevent_timer *te,
660 struct timeval _tval,
663 struct pending_message_list *msg = talloc_get_type(private_data,
664 struct pending_message_list);
665 struct smbd_server_connection *sconn = msg->sconn;
666 TALLOC_CTX *mem_ctx = talloc_tos();
667 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
670 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
673 exit_server("smbd_deferred_open_timer: talloc failed\n");
677 /* We leave this message on the queue so the open code can
678 know this is a retry. */
679 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
680 (unsigned long long)mid ));
682 /* Mark the message as processed so this is not
683 * re-processed in error. */
684 msg->processed = true;
686 process_smb(sconn, inbuf,
688 msg->seqnum, msg->encrypted, &msg->pcd);
690 /* If it's still there and was processed, remove it. */
691 msg = get_deferred_open_message_smb(sconn, mid);
692 if (msg && msg->processed) {
693 remove_deferred_open_message_smb(sconn, mid);
697 /****************************************************************************
698 Function to push a message onto the tail of a linked list of smb messages ready
700 ****************************************************************************/
702 static bool push_queued_message(struct smb_request *req,
703 struct timeval request_time,
704 struct timeval end_time,
705 struct deferred_open_record *open_rec)
707 int msg_len = smb_len(req->inbuf) + 4;
708 struct pending_message_list *msg;
710 msg = talloc_zero(NULL, struct pending_message_list);
713 DEBUG(0,("push_message: malloc fail (1)\n"));
716 msg->sconn = req->sconn;
718 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
719 if(msg->buf.data == NULL) {
720 DEBUG(0,("push_message: malloc fail (2)\n"));
725 msg->request_time = request_time;
726 msg->seqnum = req->seqnum;
727 msg->encrypted = req->encrypted;
728 msg->processed = false;
729 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
732 msg->open_rec = talloc_move(msg, &open_rec);
736 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
739 smbd_deferred_open_timer,
742 DEBUG(0,("push_message: event_add_timed failed\n"));
748 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
749 struct pending_message_list *);
751 DEBUG(10,("push_message: pushed message length %u on "
752 "deferred_open_queue\n", (unsigned int)msg_len));
757 /****************************************************************************
758 Function to delete a sharing violation open message by mid.
759 ****************************************************************************/
761 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
764 struct pending_message_list *pml;
766 if (sconn->using_smb2) {
767 remove_deferred_open_message_smb2(sconn, mid);
771 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
772 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
773 DEBUG(10,("remove_deferred_open_message_smb: "
774 "deleting mid %llu len %u\n",
775 (unsigned long long)mid,
776 (unsigned int)pml->buf.length ));
777 DLIST_REMOVE(sconn->deferred_open_queue, pml);
784 /****************************************************************************
785 Move a sharing violation open retry message to the front of the list and
786 schedule it for immediate processing.
787 ****************************************************************************/
789 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
792 struct pending_message_list *pml;
795 if (sconn->using_smb2) {
796 return schedule_deferred_open_message_smb2(sconn, mid);
799 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
800 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
802 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
805 (unsigned long long)msg_mid ));
807 if (mid == msg_mid) {
808 struct tevent_timer *te;
810 if (pml->processed) {
811 /* A processed message should not be
813 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
814 "message mid %llu was already processed\n",
815 (unsigned long long)msg_mid ));
819 DEBUG(10,("schedule_deferred_open_message_smb: "
820 "scheduling mid %llu\n",
821 (unsigned long long)mid ));
823 te = tevent_add_timer(pml->sconn->ev_ctx,
826 smbd_deferred_open_timer,
829 DEBUG(10,("schedule_deferred_open_message_smb: "
830 "event_add_timed() failed, "
831 "skipping mid %llu\n",
832 (unsigned long long)msg_mid ));
835 TALLOC_FREE(pml->te);
837 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
842 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
843 "find message mid %llu\n",
844 (unsigned long long)mid ));
849 /****************************************************************************
850 Return true if this mid is on the deferred queue and was not yet processed.
851 ****************************************************************************/
853 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
855 struct pending_message_list *pml;
857 if (sconn->using_smb2) {
858 return open_was_deferred_smb2(sconn, mid);
861 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
862 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
869 /****************************************************************************
870 Return the message queued by this mid.
871 ****************************************************************************/
873 static struct pending_message_list *get_deferred_open_message_smb(
874 struct smbd_server_connection *sconn, uint64_t mid)
876 struct pending_message_list *pml;
878 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
879 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
886 /****************************************************************************
887 Get the state data queued by this mid.
888 ****************************************************************************/
890 bool get_deferred_open_message_state(struct smb_request *smbreq,
891 struct timeval *p_request_time,
892 struct deferred_open_record **open_rec)
894 struct pending_message_list *pml;
896 if (smbreq->sconn->using_smb2) {
897 return get_deferred_open_message_state_smb2(smbreq->smb2req,
902 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
906 if (p_request_time) {
907 *p_request_time = pml->request_time;
909 if (open_rec != NULL) {
910 *open_rec = pml->open_rec;
915 /****************************************************************************
916 Function to push a deferred open smb message onto a linked list of local smb
917 messages ready for processing.
918 ****************************************************************************/
920 bool push_deferred_open_message_smb(struct smb_request *req,
921 struct timeval request_time,
922 struct timeval timeout,
924 struct deferred_open_record *open_rec)
926 struct timeval end_time;
929 return push_deferred_open_message_smb2(req->smb2req,
936 if (req->unread_bytes) {
937 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
938 "unread_bytes = %u\n",
939 (unsigned int)req->unread_bytes ));
940 smb_panic("push_deferred_open_message_smb: "
941 "logic error unread_bytes != 0" );
944 end_time = timeval_sum(&request_time, &timeout);
946 DEBUG(10,("push_deferred_open_message_smb: pushing message "
947 "len %u mid %llu timeout time [%u.%06u]\n",
948 (unsigned int) smb_len(req->inbuf)+4,
949 (unsigned long long)req->mid,
950 (unsigned int)end_time.tv_sec,
951 (unsigned int)end_time.tv_usec));
953 return push_queued_message(req, request_time, end_time, open_rec);
956 static void smbd_sig_term_handler(struct tevent_context *ev,
957 struct tevent_signal *se,
963 exit_server_cleanly("termination signal");
966 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
968 struct tevent_signal *se;
970 se = tevent_add_signal(sconn->ev_ctx,
973 smbd_sig_term_handler,
976 exit_server("failed to setup SIGTERM handler");
980 static void smbd_sig_hup_handler(struct tevent_context *ev,
981 struct tevent_signal *se,
987 struct smbd_server_connection *sconn =
988 talloc_get_type_abort(private_data,
989 struct smbd_server_connection);
991 change_to_root_user();
992 DEBUG(1,("Reloading services after SIGHUP\n"));
993 reload_services(sconn, conn_snum_used, false);
996 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
998 struct tevent_signal *se;
1000 se = tevent_add_signal(sconn->ev_ctx,
1003 smbd_sig_hup_handler,
1006 exit_server("failed to setup SIGHUP handler");
1010 static void smbd_conf_updated(struct messaging_context *msg,
1013 struct server_id server_id,
1016 struct smbd_server_connection *sconn =
1017 talloc_get_type_abort(private_data,
1018 struct smbd_server_connection);
1020 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1021 "updated. Reloading.\n"));
1022 change_to_root_user();
1023 reload_services(sconn, conn_snum_used, false);
1027 * Only allow 5 outstanding trans requests. We're allocating memory, so
1031 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1034 for (; list != NULL; list = list->next) {
1036 if (list->mid == mid) {
1037 return NT_STATUS_INVALID_PARAMETER;
1043 return NT_STATUS_INSUFFICIENT_RESOURCES;
1046 return NT_STATUS_OK;
1050 These flags determine some of the permissions required to do an operation
1052 Note that I don't set NEED_WRITE on some write operations because they
1053 are used by some brain-dead clients when printing, and I don't want to
1054 force write permissions on print services.
1056 #define AS_USER (1<<0)
1057 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1058 #define TIME_INIT (1<<2)
1059 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1060 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1061 #define DO_CHDIR (1<<6)
1064 define a list of possible SMB messages and their corresponding
1065 functions. Any message that has a NULL function is unimplemented -
1066 please feel free to contribute implementations!
1068 static const struct smb_message_struct {
1070 void (*fn)(struct smb_request *req);
1072 } smb_messages[256] = {
1074 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1075 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1076 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1077 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1078 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1079 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1080 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1081 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1082 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1083 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1084 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1085 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1086 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1087 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1088 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1089 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1090 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1091 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1092 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1093 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1094 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1095 /* 0x15 */ { NULL, NULL, 0 },
1096 /* 0x16 */ { NULL, NULL, 0 },
1097 /* 0x17 */ { NULL, NULL, 0 },
1098 /* 0x18 */ { NULL, NULL, 0 },
1099 /* 0x19 */ { NULL, NULL, 0 },
1100 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1101 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1102 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1103 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1104 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1105 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1106 /* 0x20 */ { "SMBwritec", NULL,0},
1107 /* 0x21 */ { NULL, NULL, 0 },
1108 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1109 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1110 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1111 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1112 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1113 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1114 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1115 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1116 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1117 /* 0x2b */ { "SMBecho",reply_echo,0},
1118 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1119 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1120 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1121 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1122 /* 0x30 */ { NULL, NULL, 0 },
1123 /* 0x31 */ { NULL, NULL, 0 },
1124 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1125 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1126 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1127 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1128 /* 0x36 */ { NULL, NULL, 0 },
1129 /* 0x37 */ { NULL, NULL, 0 },
1130 /* 0x38 */ { NULL, NULL, 0 },
1131 /* 0x39 */ { NULL, NULL, 0 },
1132 /* 0x3a */ { NULL, NULL, 0 },
1133 /* 0x3b */ { NULL, NULL, 0 },
1134 /* 0x3c */ { NULL, NULL, 0 },
1135 /* 0x3d */ { NULL, NULL, 0 },
1136 /* 0x3e */ { NULL, NULL, 0 },
1137 /* 0x3f */ { NULL, NULL, 0 },
1138 /* 0x40 */ { NULL, NULL, 0 },
1139 /* 0x41 */ { NULL, NULL, 0 },
1140 /* 0x42 */ { NULL, NULL, 0 },
1141 /* 0x43 */ { NULL, NULL, 0 },
1142 /* 0x44 */ { NULL, NULL, 0 },
1143 /* 0x45 */ { NULL, NULL, 0 },
1144 /* 0x46 */ { NULL, NULL, 0 },
1145 /* 0x47 */ { NULL, NULL, 0 },
1146 /* 0x48 */ { NULL, NULL, 0 },
1147 /* 0x49 */ { NULL, NULL, 0 },
1148 /* 0x4a */ { NULL, NULL, 0 },
1149 /* 0x4b */ { NULL, NULL, 0 },
1150 /* 0x4c */ { NULL, NULL, 0 },
1151 /* 0x4d */ { NULL, NULL, 0 },
1152 /* 0x4e */ { NULL, NULL, 0 },
1153 /* 0x4f */ { NULL, NULL, 0 },
1154 /* 0x50 */ { NULL, NULL, 0 },
1155 /* 0x51 */ { NULL, NULL, 0 },
1156 /* 0x52 */ { NULL, NULL, 0 },
1157 /* 0x53 */ { NULL, NULL, 0 },
1158 /* 0x54 */ { NULL, NULL, 0 },
1159 /* 0x55 */ { NULL, NULL, 0 },
1160 /* 0x56 */ { NULL, NULL, 0 },
1161 /* 0x57 */ { NULL, NULL, 0 },
1162 /* 0x58 */ { NULL, NULL, 0 },
1163 /* 0x59 */ { NULL, NULL, 0 },
1164 /* 0x5a */ { NULL, NULL, 0 },
1165 /* 0x5b */ { NULL, NULL, 0 },
1166 /* 0x5c */ { NULL, NULL, 0 },
1167 /* 0x5d */ { NULL, NULL, 0 },
1168 /* 0x5e */ { NULL, NULL, 0 },
1169 /* 0x5f */ { NULL, NULL, 0 },
1170 /* 0x60 */ { NULL, NULL, 0 },
1171 /* 0x61 */ { NULL, NULL, 0 },
1172 /* 0x62 */ { NULL, NULL, 0 },
1173 /* 0x63 */ { NULL, NULL, 0 },
1174 /* 0x64 */ { NULL, NULL, 0 },
1175 /* 0x65 */ { NULL, NULL, 0 },
1176 /* 0x66 */ { NULL, NULL, 0 },
1177 /* 0x67 */ { NULL, NULL, 0 },
1178 /* 0x68 */ { NULL, NULL, 0 },
1179 /* 0x69 */ { NULL, NULL, 0 },
1180 /* 0x6a */ { NULL, NULL, 0 },
1181 /* 0x6b */ { NULL, NULL, 0 },
1182 /* 0x6c */ { NULL, NULL, 0 },
1183 /* 0x6d */ { NULL, NULL, 0 },
1184 /* 0x6e */ { NULL, NULL, 0 },
1185 /* 0x6f */ { NULL, NULL, 0 },
1186 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1187 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1188 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1189 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1190 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1191 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1192 /* 0x76 */ { NULL, NULL, 0 },
1193 /* 0x77 */ { NULL, NULL, 0 },
1194 /* 0x78 */ { NULL, NULL, 0 },
1195 /* 0x79 */ { NULL, NULL, 0 },
1196 /* 0x7a */ { NULL, NULL, 0 },
1197 /* 0x7b */ { NULL, NULL, 0 },
1198 /* 0x7c */ { NULL, NULL, 0 },
1199 /* 0x7d */ { NULL, NULL, 0 },
1200 /* 0x7e */ { NULL, NULL, 0 },
1201 /* 0x7f */ { NULL, NULL, 0 },
1202 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1203 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1204 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1205 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1206 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1207 /* 0x85 */ { NULL, NULL, 0 },
1208 /* 0x86 */ { NULL, NULL, 0 },
1209 /* 0x87 */ { NULL, NULL, 0 },
1210 /* 0x88 */ { NULL, NULL, 0 },
1211 /* 0x89 */ { NULL, NULL, 0 },
1212 /* 0x8a */ { NULL, NULL, 0 },
1213 /* 0x8b */ { NULL, NULL, 0 },
1214 /* 0x8c */ { NULL, NULL, 0 },
1215 /* 0x8d */ { NULL, NULL, 0 },
1216 /* 0x8e */ { NULL, NULL, 0 },
1217 /* 0x8f */ { NULL, NULL, 0 },
1218 /* 0x90 */ { NULL, NULL, 0 },
1219 /* 0x91 */ { NULL, NULL, 0 },
1220 /* 0x92 */ { NULL, NULL, 0 },
1221 /* 0x93 */ { NULL, NULL, 0 },
1222 /* 0x94 */ { NULL, NULL, 0 },
1223 /* 0x95 */ { NULL, NULL, 0 },
1224 /* 0x96 */ { NULL, NULL, 0 },
1225 /* 0x97 */ { NULL, NULL, 0 },
1226 /* 0x98 */ { NULL, NULL, 0 },
1227 /* 0x99 */ { NULL, NULL, 0 },
1228 /* 0x9a */ { NULL, NULL, 0 },
1229 /* 0x9b */ { NULL, NULL, 0 },
1230 /* 0x9c */ { NULL, NULL, 0 },
1231 /* 0x9d */ { NULL, NULL, 0 },
1232 /* 0x9e */ { NULL, NULL, 0 },
1233 /* 0x9f */ { NULL, NULL, 0 },
1234 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1235 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1236 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1237 /* 0xa3 */ { NULL, NULL, 0 },
1238 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1239 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1240 /* 0xa6 */ { NULL, NULL, 0 },
1241 /* 0xa7 */ { NULL, NULL, 0 },
1242 /* 0xa8 */ { NULL, NULL, 0 },
1243 /* 0xa9 */ { NULL, NULL, 0 },
1244 /* 0xaa */ { NULL, NULL, 0 },
1245 /* 0xab */ { NULL, NULL, 0 },
1246 /* 0xac */ { NULL, NULL, 0 },
1247 /* 0xad */ { NULL, NULL, 0 },
1248 /* 0xae */ { NULL, NULL, 0 },
1249 /* 0xaf */ { NULL, NULL, 0 },
1250 /* 0xb0 */ { NULL, NULL, 0 },
1251 /* 0xb1 */ { NULL, NULL, 0 },
1252 /* 0xb2 */ { NULL, NULL, 0 },
1253 /* 0xb3 */ { NULL, NULL, 0 },
1254 /* 0xb4 */ { NULL, NULL, 0 },
1255 /* 0xb5 */ { NULL, NULL, 0 },
1256 /* 0xb6 */ { NULL, NULL, 0 },
1257 /* 0xb7 */ { NULL, NULL, 0 },
1258 /* 0xb8 */ { NULL, NULL, 0 },
1259 /* 0xb9 */ { NULL, NULL, 0 },
1260 /* 0xba */ { NULL, NULL, 0 },
1261 /* 0xbb */ { NULL, NULL, 0 },
1262 /* 0xbc */ { NULL, NULL, 0 },
1263 /* 0xbd */ { NULL, NULL, 0 },
1264 /* 0xbe */ { NULL, NULL, 0 },
1265 /* 0xbf */ { NULL, NULL, 0 },
1266 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1267 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1268 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1269 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1270 /* 0xc4 */ { NULL, NULL, 0 },
1271 /* 0xc5 */ { NULL, NULL, 0 },
1272 /* 0xc6 */ { NULL, NULL, 0 },
1273 /* 0xc7 */ { NULL, NULL, 0 },
1274 /* 0xc8 */ { NULL, NULL, 0 },
1275 /* 0xc9 */ { NULL, NULL, 0 },
1276 /* 0xca */ { NULL, NULL, 0 },
1277 /* 0xcb */ { NULL, NULL, 0 },
1278 /* 0xcc */ { NULL, NULL, 0 },
1279 /* 0xcd */ { NULL, NULL, 0 },
1280 /* 0xce */ { NULL, NULL, 0 },
1281 /* 0xcf */ { NULL, NULL, 0 },
1282 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1283 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1284 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1285 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1286 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1287 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1288 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1289 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1290 /* 0xd8 */ { NULL, NULL, 0 },
1291 /* 0xd9 */ { NULL, NULL, 0 },
1292 /* 0xda */ { NULL, NULL, 0 },
1293 /* 0xdb */ { NULL, NULL, 0 },
1294 /* 0xdc */ { NULL, NULL, 0 },
1295 /* 0xdd */ { NULL, NULL, 0 },
1296 /* 0xde */ { NULL, NULL, 0 },
1297 /* 0xdf */ { NULL, NULL, 0 },
1298 /* 0xe0 */ { NULL, NULL, 0 },
1299 /* 0xe1 */ { NULL, NULL, 0 },
1300 /* 0xe2 */ { NULL, NULL, 0 },
1301 /* 0xe3 */ { NULL, NULL, 0 },
1302 /* 0xe4 */ { NULL, NULL, 0 },
1303 /* 0xe5 */ { NULL, NULL, 0 },
1304 /* 0xe6 */ { NULL, NULL, 0 },
1305 /* 0xe7 */ { NULL, NULL, 0 },
1306 /* 0xe8 */ { NULL, NULL, 0 },
1307 /* 0xe9 */ { NULL, NULL, 0 },
1308 /* 0xea */ { NULL, NULL, 0 },
1309 /* 0xeb */ { NULL, NULL, 0 },
1310 /* 0xec */ { NULL, NULL, 0 },
1311 /* 0xed */ { NULL, NULL, 0 },
1312 /* 0xee */ { NULL, NULL, 0 },
1313 /* 0xef */ { NULL, NULL, 0 },
1314 /* 0xf0 */ { NULL, NULL, 0 },
1315 /* 0xf1 */ { NULL, NULL, 0 },
1316 /* 0xf2 */ { NULL, NULL, 0 },
1317 /* 0xf3 */ { NULL, NULL, 0 },
1318 /* 0xf4 */ { NULL, NULL, 0 },
1319 /* 0xf5 */ { NULL, NULL, 0 },
1320 /* 0xf6 */ { NULL, NULL, 0 },
1321 /* 0xf7 */ { NULL, NULL, 0 },
1322 /* 0xf8 */ { NULL, NULL, 0 },
1323 /* 0xf9 */ { NULL, NULL, 0 },
1324 /* 0xfa */ { NULL, NULL, 0 },
1325 /* 0xfb */ { NULL, NULL, 0 },
1326 /* 0xfc */ { NULL, NULL, 0 },
1327 /* 0xfd */ { NULL, NULL, 0 },
1328 /* 0xfe */ { NULL, NULL, 0 },
1329 /* 0xff */ { NULL, NULL, 0 }
1333 /*******************************************************************
1334 allocate and initialize a reply packet
1335 ********************************************************************/
1337 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1338 const char *inbuf, char **outbuf, uint8_t num_words,
1341 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1344 * Protect against integer wrap.
1345 * The SMB layer reply can be up to 0xFFFFFF bytes.
1347 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1349 if (asprintf(&msg, "num_bytes too large: %u",
1350 (unsigned)num_bytes) == -1) {
1351 msg = discard_const_p(char, "num_bytes too large");
1357 * Here we include the NBT header for now.
1359 *outbuf = talloc_array(mem_ctx, char,
1360 NBT_HDR_SIZE + smb_len);
1361 if (*outbuf == NULL) {
1365 construct_reply_common(req, inbuf, *outbuf);
1366 srv_set_message(*outbuf, num_words, num_bytes, false);
1368 * Zero out the word area, the caller has to take care of the bcc area
1371 if (num_words != 0) {
1372 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1378 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1381 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1383 smb_panic("could not allocate output buffer\n");
1385 req->outbuf = (uint8_t *)outbuf;
1389 /*******************************************************************
1390 Dump a packet to a file.
1391 ********************************************************************/
1393 static void smb_dump(const char *name, int type, const char *data)
1398 if (DEBUGLEVEL < 50) {
1402 len = smb_len_tcp(data)+4;
1403 for (i=1;i<100;i++) {
1404 fname = talloc_asprintf(talloc_tos(),
1408 type ? "req" : "resp");
1409 if (fname == NULL) {
1412 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1413 if (fd != -1 || errno != EEXIST) break;
1417 ssize_t ret = write(fd, data, len);
1419 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1421 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1426 /****************************************************************************
1427 Prepare everything for calling the actual request function, and potentially
1428 call the request function via the "new" interface.
1430 Return False if the "legacy" function needs to be called, everything is
1433 Return True if we're done.
1435 I know this API sucks, but it is the one with the least code change I could
1437 ****************************************************************************/
1439 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1442 uint64_t session_tag;
1443 connection_struct *conn = NULL;
1444 struct smbd_server_connection *sconn = req->sconn;
1445 NTTIME now = timeval_to_nttime(&req->request_time);
1446 struct smbXsrv_session *session = NULL;
1451 if (smb_messages[type].fn == NULL) {
1452 DEBUG(0,("Unknown message type %d!\n",type));
1453 smb_dump("Unknown", 1, (const char *)req->inbuf);
1454 reply_unknown_new(req, type);
1458 flags = smb_messages[type].flags;
1460 /* In share mode security we must ignore the vuid. */
1461 session_tag = req->vuid;
1464 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1465 (int)getpid(), (unsigned long)conn));
1467 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1469 /* Ensure this value is replaced in the incoming packet. */
1470 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1473 * Ensure the correct username is in current_user_info. This is a
1474 * really ugly bugfix for problems with multiple session_setup_and_X's
1475 * being done and allowing %U and %G substitutions to work correctly.
1476 * There is a reason this code is done here, don't move it unless you
1477 * know what you're doing... :-).
1482 * lookup an existing session
1484 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1485 * here, the main check is still in change_to_user()
1487 status = smb1srv_session_lookup(sconn->conn,
1491 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1494 status = NT_STATUS_OK;
1497 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1498 (unsigned long long)session_tag,
1499 (unsigned long long)req->mid));
1500 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1505 if (session_tag != sconn->conn->last_session_id) {
1506 struct user_struct *vuser = NULL;
1508 sconn->conn->last_session_id = session_tag;
1510 vuser = session->compat;
1513 set_current_user_info(
1514 vuser->session_info->unix_info->sanitized_username,
1515 vuser->session_info->unix_info->unix_name,
1516 vuser->session_info->info->domain_name);
1520 /* Does this call need to be run as the connected user? */
1521 if (flags & AS_USER) {
1523 /* Does this call need a valid tree connection? */
1526 * Amazingly, the error code depends on the command
1529 if (type == SMBntcreateX) {
1530 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1532 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1537 if (!change_to_user(conn,session_tag)) {
1538 DEBUG(0, ("Error: Could not change to user. Removing "
1539 "deferred open, mid=%llu.\n",
1540 (unsigned long long)req->mid));
1541 reply_force_doserror(req, ERRSRV, ERRbaduid);
1545 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1547 /* Does it need write permission? */
1548 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1549 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1553 /* IPC services are limited */
1554 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1555 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1559 /* This call needs to be run as root */
1560 change_to_root_user();
1563 /* load service specific parameters */
1565 if (req->encrypted) {
1566 conn->encrypted_tid = true;
1567 /* encrypted required from now on. */
1568 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1569 } else if (ENCRYPTION_REQUIRED(conn)) {
1570 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1571 DEBUG(1,("service[%s] requires encryption"
1572 "%s ACCESS_DENIED. mid=%llu\n",
1573 lp_servicename(talloc_tos(), SNUM(conn)),
1575 (unsigned long long)req->mid));
1576 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1581 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1582 (flags & (AS_USER|DO_CHDIR)
1584 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1587 conn->num_smb_operations++;
1591 * Does this protocol need to be run as guest? (Only archane
1592 * messenger service requests have this...)
1594 if (flags & AS_GUEST) {
1598 if (!change_to_guest()) {
1599 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1603 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1605 if (raddr == NULL) {
1606 reply_nterror(req, NT_STATUS_NO_MEMORY);
1611 * Haven't we checked this in smbd_process already???
1614 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1615 sconn->remote_hostname, raddr);
1619 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1624 smb_messages[type].fn(req);
1628 /****************************************************************************
1629 Construct a reply to the incoming packet.
1630 ****************************************************************************/
1632 static void construct_reply(struct smbd_server_connection *sconn,
1633 char *inbuf, int size, size_t unread_bytes,
1634 uint32_t seqnum, bool encrypted,
1635 struct smb_perfcount_data *deferred_pcd)
1637 connection_struct *conn;
1638 struct smb_request *req;
1640 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1641 smb_panic("could not allocate smb_request");
1644 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1645 encrypted, seqnum)) {
1646 exit_server_cleanly("Invalid SMB request");
1649 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1651 /* we popped this message off the queue - keep original perf data */
1653 req->pcd = *deferred_pcd;
1655 SMB_PERFCOUNT_START(&req->pcd);
1656 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1657 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1660 conn = switch_message(req->cmd, req);
1662 if (req->outbuf == NULL) {
1666 if (CVAL(req->outbuf,0) == 0) {
1667 show_msg((char *)req->outbuf);
1670 if (!srv_send_smb(req->sconn,
1671 (char *)req->outbuf,
1672 true, req->seqnum+1,
1673 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1675 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1683 static void construct_reply_chain(struct smbd_server_connection *sconn,
1684 char *inbuf, int size, uint32_t seqnum,
1686 struct smb_perfcount_data *deferred_pcd)
1688 struct smb_request **reqs = NULL;
1689 struct smb_request *req;
1693 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1694 seqnum, &reqs, &num_reqs);
1696 char errbuf[smb_size];
1697 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1698 __LINE__, __FILE__);
1699 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1701 exit_server_cleanly("construct_reply_chain: "
1702 "srv_send_smb failed.");
1708 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1710 req->conn = switch_message(req->cmd, req);
1712 if (req->outbuf == NULL) {
1714 * Request has suspended itself, will come
1719 smb_request_done(req);
1723 * To be called from an async SMB handler that is potentially chained
1724 * when it is finished for shipping.
1727 void smb_request_done(struct smb_request *req)
1729 struct smb_request **reqs = NULL;
1730 struct smb_request *first_req;
1731 size_t i, num_reqs, next_index;
1734 if (req->chain == NULL) {
1740 num_reqs = talloc_array_length(reqs);
1742 for (i=0; i<num_reqs; i++) {
1743 if (reqs[i] == req) {
1747 if (i == num_reqs) {
1749 * Invalid chain, should not happen
1751 status = NT_STATUS_INTERNAL_ERROR;
1756 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1757 struct smb_request *next = reqs[next_index];
1758 struct smbXsrv_tcon *tcon;
1759 NTTIME now = timeval_to_nttime(&req->request_time);
1761 next->vuid = SVAL(req->outbuf, smb_uid);
1762 next->tid = SVAL(req->outbuf, smb_tid);
1763 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1765 if (NT_STATUS_IS_OK(status)) {
1766 req->conn = tcon->compat;
1770 next->chain_fsp = req->chain_fsp;
1771 next->inbuf = req->inbuf;
1774 req->conn = switch_message(req->cmd, req);
1776 if (req->outbuf == NULL) {
1778 * Request has suspended itself, will come
1786 first_req = reqs[0];
1788 for (i=1; i<next_index; i++) {
1791 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1793 status = NT_STATUS_INTERNAL_ERROR;
1798 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1799 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1802 * This scary statement intends to set the
1803 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1804 * to the value last_req->outbuf carries
1806 SSVAL(first_req->outbuf, smb_flg2,
1807 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1808 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1811 * Transfer the error codes from the subrequest to the main one
1813 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1814 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1817 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1820 if (!srv_send_smb(first_req->sconn,
1821 (char *)first_req->outbuf,
1822 true, first_req->seqnum+1,
1823 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1825 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1828 TALLOC_FREE(req); /* non-chained case */
1829 TALLOC_FREE(reqs); /* chained case */
1834 char errbuf[smb_size];
1835 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1836 if (!srv_send_smb(req->sconn, errbuf, true,
1837 req->seqnum+1, req->encrypted,
1839 exit_server_cleanly("construct_reply_chain: "
1840 "srv_send_smb failed.");
1843 TALLOC_FREE(req); /* non-chained case */
1844 TALLOC_FREE(reqs); /* chained case */
1847 /****************************************************************************
1848 Process an smb from the client
1849 ****************************************************************************/
1850 static void process_smb(struct smbd_server_connection *sconn,
1851 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1852 uint32_t seqnum, bool encrypted,
1853 struct smb_perfcount_data *deferred_pcd)
1855 int msg_type = CVAL(inbuf,0);
1857 DO_PROFILE_INC(smb_count);
1859 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1861 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1862 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1864 if (msg_type != NBSSmessage) {
1866 * NetBIOS session request, keepalive, etc.
1868 reply_special(sconn, (char *)inbuf, nread);
1872 if (sconn->using_smb2) {
1873 /* At this point we're not really using smb2,
1874 * we make the decision here.. */
1875 if (smbd_is_smb2_header(inbuf, nread)) {
1876 smbd_smb2_first_negprot(sconn, inbuf, nread);
1878 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1879 && CVAL(inbuf, smb_com) != 0x72) {
1880 /* This is a non-negprot SMB1 packet.
1881 Disable SMB2 from now on. */
1882 sconn->using_smb2 = false;
1886 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1887 * so subtract 4 from it. */
1888 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1889 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1892 /* special magic for immediate exit */
1894 (IVAL(inbuf, 4) == 0x74697865) &&
1895 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1896 uint8_t exitcode = CVAL(inbuf, 8);
1897 DEBUG(1, ("Exiting immediately with code %d\n",
1902 exit_server_cleanly("Non-SMB packet");
1905 show_msg((char *)inbuf);
1907 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1908 construct_reply_chain(sconn, (char *)inbuf, nread,
1909 seqnum, encrypted, deferred_pcd);
1911 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1912 seqnum, encrypted, deferred_pcd);
1918 sconn->num_requests++;
1920 /* The timeout_processing function isn't run nearly
1921 often enough to implement 'max log size' without
1922 overrunning the size of the file by many megabytes.
1923 This is especially true if we are running at debug
1924 level 10. Checking every 50 SMBs is a nice
1925 tradeoff of performance vs log file size overrun. */
1927 if ((sconn->num_requests % 50) == 0 &&
1928 need_to_check_log_size()) {
1929 change_to_root_user();
1934 /****************************************************************************
1935 Return a string containing the function name of a SMB command.
1936 ****************************************************************************/
1938 const char *smb_fn_name(int type)
1940 const char *unknown_name = "SMBunknown";
1942 if (smb_messages[type].name == NULL)
1943 return(unknown_name);
1945 return(smb_messages[type].name);
1948 /****************************************************************************
1949 Helper functions for contruct_reply.
1950 ****************************************************************************/
1952 void add_to_common_flags2(uint32 v)
1957 void remove_from_common_flags2(uint32 v)
1959 common_flags2 &= ~v;
1962 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1965 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1966 uint16_t out_flags2 = common_flags2;
1968 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1969 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1970 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1972 srv_set_message(outbuf,0,0,false);
1974 SCVAL(outbuf, smb_com, req->cmd);
1975 SIVAL(outbuf,smb_rcls,0);
1976 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1977 SSVAL(outbuf,smb_flg2, out_flags2);
1978 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1979 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1981 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1982 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1983 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1984 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1987 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1989 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1993 * @brief Find the smb_cmd offset of the last command pushed
1994 * @param[in] buf The buffer we're building up
1995 * @retval Where can we put our next andx cmd?
1997 * While chaining requests, the "next" request we're looking at needs to put
1998 * its SMB_Command before the data the previous request already built up added
1999 * to the chain. Find the offset to the place where we have to put our cmd.
2002 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2007 cmd = CVAL(buf, smb_com);
2009 if (!is_andx_req(cmd)) {
2015 while (CVAL(buf, ofs) != 0xff) {
2017 if (!is_andx_req(CVAL(buf, ofs))) {
2022 * ofs is from start of smb header, so add the 4 length
2023 * bytes. The next cmd is right after the wct field.
2025 ofs = SVAL(buf, ofs+2) + 4 + 1;
2027 if (ofs+4 >= talloc_get_size(buf)) {
2037 * @brief Do the smb chaining at a buffer level
2038 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2039 * @param[in] andx_buf Buffer to be appended
2042 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2044 uint8_t smb_command = CVAL(andx_buf, smb_com);
2045 uint8_t wct = CVAL(andx_buf, smb_wct);
2046 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2047 uint32_t num_bytes = smb_buflen(andx_buf);
2048 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2051 size_t old_size, new_size;
2053 size_t chain_padding = 0;
2054 size_t andx_cmd_ofs;
2057 old_size = talloc_get_size(*poutbuf);
2059 if ((old_size % 4) != 0) {
2061 * Align the wct field of subsequent requests to a 4-byte
2064 chain_padding = 4 - (old_size % 4);
2068 * After the old request comes the new wct field (1 byte), the vwv's
2069 * and the num_bytes field.
2072 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2073 new_size += num_bytes;
2075 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2076 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2077 (unsigned)new_size));
2081 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2082 if (outbuf == NULL) {
2083 DEBUG(0, ("talloc failed\n"));
2088 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2089 DEBUG(1, ("invalid command chain\n"));
2090 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2094 if (chain_padding != 0) {
2095 memset(outbuf + old_size, 0, chain_padding);
2096 old_size += chain_padding;
2099 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2100 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2105 * Push the chained request:
2110 SCVAL(outbuf, ofs, wct);
2117 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2122 * Read&X has an offset into its data buffer at
2123 * vwv[6]. reply_read_andx has no idea anymore that it's
2124 * running from within a chain, so we have to fix up the
2127 * Although it looks disgusting at this place, I want to keep
2128 * it here. The alternative would be to push knowledge about
2129 * the andx chain down into read&x again.
2132 if (smb_command == SMBreadX) {
2133 uint8_t *bytes_addr;
2137 * Invalid read&x response
2142 bytes_addr = outbuf + ofs /* vwv start */
2143 + sizeof(uint16_t) * wct /* vwv array */
2144 + sizeof(uint16_t); /* bcc */
2146 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2147 bytes_addr - outbuf - 4);
2150 ofs += sizeof(uint16_t) * wct;
2156 SSVAL(outbuf, ofs, num_bytes);
2157 ofs += sizeof(uint16_t);
2163 memcpy(outbuf + ofs, bytes, num_bytes);
2168 bool smb1_is_chain(const uint8_t *buf)
2170 uint8_t cmd, wct, andx_cmd;
2172 cmd = CVAL(buf, smb_com);
2173 if (!is_andx_req(cmd)) {
2176 wct = CVAL(buf, smb_wct);
2180 andx_cmd = CVAL(buf, smb_vwv);
2181 return (andx_cmd != 0xFF);
2184 bool smb1_walk_chain(const uint8_t *buf,
2185 bool (*fn)(uint8_t cmd,
2186 uint8_t wct, const uint16_t *vwv,
2187 uint16_t num_bytes, const uint8_t *bytes,
2188 void *private_data),
2191 size_t smblen = smb_len(buf);
2192 const char *smb_buf = smb_base(buf);
2193 uint8_t cmd, chain_cmd;
2195 const uint16_t *vwv;
2197 const uint8_t *bytes;
2199 cmd = CVAL(buf, smb_com);
2200 wct = CVAL(buf, smb_wct);
2201 vwv = (const uint16_t *)(buf + smb_vwv);
2202 num_bytes = smb_buflen(buf);
2203 bytes = (const uint8_t *)smb_buf_const(buf);
2205 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2209 if (!is_andx_req(cmd)) {
2216 chain_cmd = CVAL(vwv, 0);
2218 while (chain_cmd != 0xff) {
2219 uint32_t chain_offset; /* uint32_t to avoid overflow */
2220 size_t length_needed;
2221 ptrdiff_t vwv_offset;
2223 chain_offset = SVAL(vwv+1, 0);
2226 * Check if the client tries to fool us. The chain
2227 * offset needs to point beyond the current request in
2228 * the chain, it needs to strictly grow. Otherwise we
2229 * might be tricked into an endless loop always
2230 * processing the same request over and over again. We
2231 * used to assume that vwv and the byte buffer array
2232 * in a chain are always attached, but OS/2 the
2233 * Write&X/Read&X chain puts the Read&X vwv array
2234 * right behind the Write&X vwv chain. The Write&X bcc
2235 * array is put behind the Read&X vwv array. So now we
2236 * check whether the chain offset points strictly
2237 * behind the previous vwv array. req->buf points
2238 * right after the vwv array of the previous
2240 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2244 vwv_offset = ((const char *)vwv - smb_buf);
2245 if (chain_offset <= vwv_offset) {
2250 * Next check: Make sure the chain offset does not
2251 * point beyond the overall smb request length.
2254 length_needed = chain_offset+1; /* wct */
2255 if (length_needed > smblen) {
2260 * Now comes the pointer magic. Goal here is to set up
2261 * vwv and buf correctly again. The chain offset (the
2262 * former vwv[1]) points at the new wct field.
2265 wct = CVAL(smb_buf, chain_offset);
2267 if (is_andx_req(chain_cmd) && (wct < 2)) {
2272 * Next consistency check: Make the new vwv array fits
2273 * in the overall smb request.
2276 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2277 if (length_needed > smblen) {
2280 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2283 * Now grab the new byte buffer....
2286 num_bytes = SVAL(vwv+wct, 0);
2289 * .. and check that it fits.
2292 length_needed += num_bytes;
2293 if (length_needed > smblen) {
2296 bytes = (const uint8_t *)(vwv+wct+1);
2298 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2302 if (!is_andx_req(chain_cmd)) {
2305 chain_cmd = CVAL(vwv, 0);
2310 static bool smb1_chain_length_cb(uint8_t cmd,
2311 uint8_t wct, const uint16_t *vwv,
2312 uint16_t num_bytes, const uint8_t *bytes,
2315 unsigned *count = (unsigned *)private_data;
2320 unsigned smb1_chain_length(const uint8_t *buf)
2324 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2330 struct smb1_parse_chain_state {
2331 TALLOC_CTX *mem_ctx;
2333 struct smbd_server_connection *sconn;
2337 struct smb_request **reqs;
2341 static bool smb1_parse_chain_cb(uint8_t cmd,
2342 uint8_t wct, const uint16_t *vwv,
2343 uint16_t num_bytes, const uint8_t *bytes,
2346 struct smb1_parse_chain_state *state =
2347 (struct smb1_parse_chain_state *)private_data;
2348 struct smb_request **reqs;
2349 struct smb_request *req;
2352 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2353 struct smb_request *, state->num_reqs+1);
2359 req = talloc(reqs, struct smb_request);
2364 ok = init_smb_request(req, state->sconn, state->buf, 0,
2365 state->encrypted, state->seqnum);
2372 req->buflen = num_bytes;
2375 reqs[state->num_reqs] = req;
2376 state->num_reqs += 1;
2380 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2381 struct smbd_server_connection *sconn,
2382 bool encrypted, uint32_t seqnum,
2383 struct smb_request ***reqs, unsigned *num_reqs)
2385 struct smb1_parse_chain_state state;
2388 state.mem_ctx = mem_ctx;
2390 state.sconn = sconn;
2391 state.encrypted = encrypted;
2392 state.seqnum = seqnum;
2396 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2397 TALLOC_FREE(state.reqs);
2400 for (i=0; i<state.num_reqs; i++) {
2401 state.reqs[i]->chain = state.reqs;
2404 *num_reqs = state.num_reqs;
2408 /****************************************************************************
2409 Check if services need reloading.
2410 ****************************************************************************/
2412 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2415 if (last_smb_conf_reload_time == 0) {
2416 last_smb_conf_reload_time = t;
2419 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2420 reload_services(sconn, conn_snum_used, true);
2421 last_smb_conf_reload_time = t;
2425 static bool fd_is_readable(int fd)
2429 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2431 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2435 static void smbd_server_connection_write_handler(
2436 struct smbd_server_connection *sconn)
2438 /* TODO: make write nonblocking */
2441 static void smbd_server_connection_read_handler(
2442 struct smbd_server_connection *sconn, int fd)
2444 uint8_t *inbuf = NULL;
2445 size_t inbuf_len = 0;
2446 size_t unread_bytes = 0;
2447 bool encrypted = false;
2448 TALLOC_CTX *mem_ctx = talloc_tos();
2452 bool async_echo = lp_async_smb_echo_handler();
2453 bool from_client = false;
2456 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2458 * This is the super-ugly hack to prefer the packets
2459 * forwarded by the echo handler over the ones by the
2462 fd = sconn->smb1.echo_handler.trusted_fd;
2466 from_client = (sconn->sock == fd);
2468 if (async_echo && from_client) {
2469 smbd_lock_socket(sconn);
2471 if (!fd_is_readable(fd)) {
2472 DEBUG(10,("the echo listener was faster\n"));
2473 smbd_unlock_socket(sconn);
2478 /* TODO: make this completely nonblocking */
2479 status = receive_smb_talloc(mem_ctx, sconn, fd,
2480 (char **)(void *)&inbuf,
2484 &inbuf_len, &seqnum,
2485 !from_client /* trusted channel */);
2487 if (async_echo && from_client) {
2488 smbd_unlock_socket(sconn);
2491 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2494 if (NT_STATUS_IS_ERR(status)) {
2495 exit_server_cleanly("failed to receive smb request");
2497 if (!NT_STATUS_IS_OK(status)) {
2502 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2503 seqnum, encrypted, NULL);
2506 static void smbd_server_connection_handler(struct tevent_context *ev,
2507 struct tevent_fd *fde,
2511 struct smbd_server_connection *conn = talloc_get_type(private_data,
2512 struct smbd_server_connection);
2514 if (!NT_STATUS_IS_OK(conn->status)) {
2516 * we're not supposed to do any io
2518 TEVENT_FD_NOT_READABLE(conn->smb1.fde);
2519 TEVENT_FD_NOT_WRITEABLE(conn->smb1.fde);
2523 if (flags & TEVENT_FD_WRITE) {
2524 smbd_server_connection_write_handler(conn);
2527 if (flags & TEVENT_FD_READ) {
2528 smbd_server_connection_read_handler(conn, conn->sock);
2533 static void smbd_server_echo_handler(struct tevent_context *ev,
2534 struct tevent_fd *fde,
2538 struct smbd_server_connection *conn = talloc_get_type(private_data,
2539 struct smbd_server_connection);
2541 if (!NT_STATUS_IS_OK(conn->status)) {
2543 * we're not supposed to do any io
2545 TEVENT_FD_NOT_READABLE(conn->smb1.echo_handler.trusted_fde);
2546 TEVENT_FD_NOT_WRITEABLE(conn->smb1.echo_handler.trusted_fde);
2550 if (flags & TEVENT_FD_WRITE) {
2551 smbd_server_connection_write_handler(conn);
2554 if (flags & TEVENT_FD_READ) {
2555 smbd_server_connection_read_handler(
2556 conn, conn->smb1.echo_handler.trusted_fd);
2561 struct smbd_release_ip_state {
2562 struct smbd_server_connection *sconn;
2563 struct tevent_immediate *im;
2564 char addr[INET6_ADDRSTRLEN];
2567 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2568 struct tevent_immediate *im,
2571 struct smbd_release_ip_state *state =
2572 talloc_get_type_abort(private_data,
2573 struct smbd_release_ip_state);
2575 if (!NT_STATUS_EQUAL(state->sconn->status, NT_STATUS_ADDRESS_CLOSED)) {
2577 * smbd_server_connection_terminate() already triggered ?
2582 smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
2585 /****************************************************************************
2586 received when we should release a specific IP
2587 ****************************************************************************/
2588 static bool release_ip(const char *ip, void *priv)
2590 struct smbd_release_ip_state *state =
2591 talloc_get_type_abort(priv,
2592 struct smbd_release_ip_state);
2593 const char *addr = state->addr;
2594 const char *p = addr;
2596 if (!NT_STATUS_IS_OK(state->sconn->status)) {
2597 /* avoid recursion */
2601 if (strncmp("::ffff:", addr, 7) == 0) {
2605 DEBUG(10, ("Got release IP message for %s, "
2606 "our address is %s\n", ip, p));
2608 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2609 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2612 * With SMB2 we should do a clean disconnect,
2613 * the previous_session_id in the session setup
2614 * will cleanup the old session, tcons and opens.
2616 * A clean disconnect is needed in order to support
2619 * Note: typically this is never triggered
2620 * as we got a TCP RST (triggered by ctdb event scripts)
2621 * before we get CTDB_SRVID_RELEASE_IP.
2623 * We used to call _exit(1) here, but as this was mostly never
2624 * triggered and has implication on our process model,
2625 * we can just use smbd_server_connection_terminate()
2628 * We don't call smbd_server_connection_terminate() directly
2629 * as we might be called from within ctdbd_migrate(),
2630 * we need to defer our action to the next event loop
2632 tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
2633 smbd_release_ip_immediate, state);
2636 * Make sure we don't get any io on the connection.
2638 state->sconn->status = NT_STATUS_ADDRESS_CLOSED;
2645 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2646 struct sockaddr_storage *srv,
2647 struct sockaddr_storage *clnt)
2649 struct smbd_release_ip_state *state;
2650 struct ctdbd_connection *cconn;
2652 cconn = messaging_ctdbd_connection();
2653 if (cconn == NULL) {
2654 return NT_STATUS_NO_MEMORY;
2657 state = talloc_zero(sconn, struct smbd_release_ip_state);
2658 if (state == NULL) {
2659 return NT_STATUS_NO_MEMORY;
2661 state->sconn = sconn;
2662 state->im = tevent_create_immediate(state);
2663 if (state->im == NULL) {
2664 return NT_STATUS_NO_MEMORY;
2666 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2667 return NT_STATUS_NO_MEMORY;
2670 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2673 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2674 void *private_data, uint32_t msg_type,
2675 struct server_id server_id, DATA_BLOB *data)
2677 struct smbd_server_connection *sconn = talloc_get_type_abort(
2678 private_data, struct smbd_server_connection);
2679 const char *ip = (char *) data->data;
2682 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2684 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2686 if (client_ip == NULL) {
2690 if (strequal(ip, client_ip)) {
2691 DEBUG(1, ("Got kill client message for %s - "
2692 "exiting immediately\n", ip));
2693 exit_server_cleanly("Forced disconnect for client");
2696 TALLOC_FREE(client_ip);
2700 * Send keepalive packets to our client
2702 static bool keepalive_fn(const struct timeval *now, void *private_data)
2704 struct smbd_server_connection *sconn = talloc_get_type_abort(
2705 private_data, struct smbd_server_connection);
2708 if (sconn->using_smb2) {
2709 /* Don't do keepalives on an SMB2 connection. */
2713 smbd_lock_socket(sconn);
2714 ret = send_keepalive(sconn->sock);
2715 smbd_unlock_socket(sconn);
2718 char addr[INET6_ADDRSTRLEN];
2720 * Try and give an error message saying what
2723 DEBUG(0, ("send_keepalive failed for client %s. "
2724 "Error %s - exiting\n",
2725 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2733 * Do the recurring check if we're idle
2735 static bool deadtime_fn(const struct timeval *now, void *private_data)
2737 struct smbd_server_connection *sconn =
2738 (struct smbd_server_connection *)private_data;
2740 if ((conn_num_open(sconn) == 0)
2741 || (conn_idle_all(sconn, now->tv_sec))) {
2742 DEBUG( 2, ( "Closing idle connection\n" ) );
2743 messaging_send(sconn->msg_ctx,
2744 messaging_server_id(sconn->msg_ctx),
2745 MSG_SHUTDOWN, &data_blob_null);
2753 * Do the recurring log file and smb.conf reload checks.
2756 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2758 struct smbd_server_connection *sconn = talloc_get_type_abort(
2759 private_data, struct smbd_server_connection);
2761 DEBUG(5, ("housekeeping\n"));
2763 change_to_root_user();
2765 /* update printer queue caches if necessary */
2766 update_monitored_printq_cache(sconn->msg_ctx);
2768 /* check if we need to reload services */
2769 check_reload(sconn, time_mono(NULL));
2772 * Force a log file check.
2774 force_check_log_size();
2780 * Read an smb packet in the echo handler child, giving the parent
2781 * smbd one second to react once the socket becomes readable.
2784 struct smbd_echo_read_state {
2785 struct tevent_context *ev;
2786 struct smbd_server_connection *sconn;
2793 static void smbd_echo_read_readable(struct tevent_req *subreq);
2794 static void smbd_echo_read_waited(struct tevent_req *subreq);
2796 static struct tevent_req *smbd_echo_read_send(
2797 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2798 struct smbd_server_connection *sconn)
2800 struct tevent_req *req, *subreq;
2801 struct smbd_echo_read_state *state;
2803 req = tevent_req_create(mem_ctx, &state,
2804 struct smbd_echo_read_state);
2809 state->sconn = sconn;
2811 subreq = wait_for_read_send(state, ev, sconn->sock);
2812 if (tevent_req_nomem(subreq, req)) {
2813 return tevent_req_post(req, ev);
2815 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2819 static void smbd_echo_read_readable(struct tevent_req *subreq)
2821 struct tevent_req *req = tevent_req_callback_data(
2822 subreq, struct tevent_req);
2823 struct smbd_echo_read_state *state = tevent_req_data(
2824 req, struct smbd_echo_read_state);
2828 ok = wait_for_read_recv(subreq, &err);
2829 TALLOC_FREE(subreq);
2831 tevent_req_nterror(req, map_nt_error_from_unix(err));
2836 * Give the parent smbd one second to step in
2839 subreq = tevent_wakeup_send(
2840 state, state->ev, timeval_current_ofs(1, 0));
2841 if (tevent_req_nomem(subreq, req)) {
2844 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2847 static void smbd_echo_read_waited(struct tevent_req *subreq)
2849 struct tevent_req *req = tevent_req_callback_data(
2850 subreq, struct tevent_req);
2851 struct smbd_echo_read_state *state = tevent_req_data(
2852 req, struct smbd_echo_read_state);
2853 struct smbd_server_connection *sconn = state->sconn;
2859 ok = tevent_wakeup_recv(subreq);
2860 TALLOC_FREE(subreq);
2862 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2866 ok = smbd_lock_socket_internal(sconn);
2868 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2869 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2873 if (!fd_is_readable(sconn->sock)) {
2874 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2877 ok = smbd_unlock_socket_internal(sconn);
2879 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2880 DEBUG(1, ("%s: failed to unlock socket\n",
2885 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2886 if (tevent_req_nomem(subreq, req)) {
2889 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2893 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2899 false /* trusted_channel*/);
2901 if (tevent_req_nterror(req, status)) {
2902 tevent_req_nterror(req, status);
2903 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2904 (int)getpid(), nt_errstr(status)));
2908 ok = smbd_unlock_socket_internal(sconn);
2910 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2911 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2914 tevent_req_done(req);
2917 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2918 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2920 struct smbd_echo_read_state *state = tevent_req_data(
2921 req, struct smbd_echo_read_state);
2924 if (tevent_req_is_nterror(req, &status)) {
2927 *pbuf = talloc_move(mem_ctx, &state->buf);
2928 *pbuflen = state->buflen;
2929 *pseqnum = state->seqnum;
2930 return NT_STATUS_OK;
2933 struct smbd_echo_state {
2934 struct tevent_context *ev;
2935 struct iovec *pending;
2936 struct smbd_server_connection *sconn;
2939 struct tevent_fd *parent_fde;
2941 struct tevent_req *write_req;
2944 static void smbd_echo_writer_done(struct tevent_req *req);
2946 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2950 if (state->write_req != NULL) {
2954 num_pending = talloc_array_length(state->pending);
2955 if (num_pending == 0) {
2959 state->write_req = writev_send(state, state->ev, NULL,
2960 state->parent_pipe, false,
2961 state->pending, num_pending);
2962 if (state->write_req == NULL) {
2963 DEBUG(1, ("writev_send failed\n"));
2967 talloc_steal(state->write_req, state->pending);
2968 state->pending = NULL;
2970 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2974 static void smbd_echo_writer_done(struct tevent_req *req)
2976 struct smbd_echo_state *state = tevent_req_callback_data(
2977 req, struct smbd_echo_state);
2981 written = writev_recv(req, &err);
2983 state->write_req = NULL;
2984 if (written == -1) {
2985 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2988 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2989 smbd_echo_activate_writer(state);
2992 static bool smbd_echo_reply(struct smbd_echo_state *state,
2993 uint8_t *inbuf, size_t inbuf_len,
2996 struct smb_request req;
2997 uint16_t num_replies;
3001 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3002 DEBUG(10, ("Got netbios keepalive\n"));
3009 if (inbuf_len < smb_size) {
3010 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3013 if (!valid_smb_header(state->sconn, inbuf)) {
3014 DEBUG(10, ("Got invalid SMB header\n"));
3018 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
3024 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3025 smb_messages[req.cmd].name
3026 ? smb_messages[req.cmd].name : "unknown"));
3028 if (req.cmd != SMBecho) {
3035 num_replies = SVAL(req.vwv+0, 0);
3036 if (num_replies != 1) {
3037 /* Not a Windows "Hey, you're still there?" request */
3041 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3043 DEBUG(10, ("create_outbuf failed\n"));
3046 req.outbuf = (uint8_t *)outbuf;
3048 SSVAL(req.outbuf, smb_vwv0, num_replies);
3050 if (req.buflen > 0) {
3051 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3054 ok = srv_send_smb(req.sconn,
3058 TALLOC_FREE(outbuf);
3066 static void smbd_echo_exit(struct tevent_context *ev,
3067 struct tevent_fd *fde, uint16_t flags,
3070 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3074 static void smbd_echo_got_packet(struct tevent_req *req);
3076 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3079 struct smbd_echo_state *state;
3080 struct tevent_req *read_req;
3082 state = talloc_zero(sconn, struct smbd_echo_state);
3083 if (state == NULL) {
3084 DEBUG(1, ("talloc failed\n"));
3087 state->sconn = sconn;
3088 state->parent_pipe = parent_pipe;
3089 state->ev = s3_tevent_context_init(state);
3090 if (state->ev == NULL) {
3091 DEBUG(1, ("tevent_context_init failed\n"));
3095 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3096 TEVENT_FD_READ, smbd_echo_exit,
3098 if (state->parent_fde == NULL) {
3099 DEBUG(1, ("tevent_add_fd failed\n"));
3104 read_req = smbd_echo_read_send(state, state->ev, sconn);
3105 if (read_req == NULL) {
3106 DEBUG(1, ("smbd_echo_read_send failed\n"));
3110 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3113 if (tevent_loop_once(state->ev) == -1) {
3114 DEBUG(1, ("tevent_loop_once failed: %s\n",
3122 static void smbd_echo_got_packet(struct tevent_req *req)
3124 struct smbd_echo_state *state = tevent_req_callback_data(
3125 req, struct smbd_echo_state);
3129 uint32_t seqnum = 0;
3132 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3134 if (!NT_STATUS_IS_OK(status)) {
3135 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3136 nt_errstr(status)));
3140 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3146 num_pending = talloc_array_length(state->pending);
3147 tmp = talloc_realloc(state, state->pending, struct iovec,
3150 DEBUG(1, ("talloc_realloc failed\n"));
3153 state->pending = tmp;
3155 if (buflen >= smb_size) {
3157 * place the seqnum in the packet so that the main process
3158 * can reply with signing
3160 SIVAL(buf, smb_ss_field, seqnum);
3161 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3164 iov = &state->pending[num_pending];
3165 iov->iov_base = talloc_move(state->pending, &buf);
3166 iov->iov_len = buflen;
3168 DEBUG(10,("echo_handler[%d]: forward to main\n",
3170 smbd_echo_activate_writer(state);
3173 req = smbd_echo_read_send(state, state->ev, state->sconn);
3175 DEBUG(1, ("smbd_echo_read_send failed\n"));
3178 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3183 * Handle SMBecho requests in a forked child process
3185 bool fork_echo_handler(struct smbd_server_connection *sconn)
3187 int listener_pipe[2];
3190 bool use_mutex = false;
3192 res = pipe(listener_pipe);
3194 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3198 #ifdef HAVE_ROBUST_MUTEXES
3199 use_mutex = tdb_runtime_check_for_robust_mutexes();
3202 pthread_mutexattr_t a;
3204 sconn->smb1.echo_handler.socket_mutex =
3205 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3206 if (sconn->smb1.echo_handler.socket_mutex == NULL) {
3207 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3212 res = pthread_mutexattr_init(&a);
3214 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3218 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3220 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3222 pthread_mutexattr_destroy(&a);
3225 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3227 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3229 pthread_mutexattr_destroy(&a);
3232 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3234 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3235 "%s\n", strerror(res)));
3236 pthread_mutexattr_destroy(&a);
3239 res = pthread_mutex_init(sconn->smb1.echo_handler.socket_mutex,
3241 pthread_mutexattr_destroy(&a);
3243 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3251 sconn->smb1.echo_handler.socket_lock_fd =
3252 create_unlink_tmp(lp_lock_directory());
3253 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3254 DEBUG(1, ("Could not create lock fd: %s\n",
3264 close(listener_pipe[0]);
3265 set_blocking(listener_pipe[1], false);
3267 status = reinit_after_fork(sconn->msg_ctx,
3270 if (!NT_STATUS_IS_OK(status)) {
3271 DEBUG(1, ("reinit_after_fork failed: %s\n",
3272 nt_errstr(status)));
3275 smbd_echo_loop(sconn, listener_pipe[1]);
3278 close(listener_pipe[1]);
3279 listener_pipe[1] = -1;
3280 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3282 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3285 * Without smb signing this is the same as the normal smbd
3286 * listener. This needs to change once signing comes in.
3288 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3290 sconn->smb1.echo_handler.trusted_fd,
3292 smbd_server_echo_handler,
3294 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3295 DEBUG(1, ("event_add_fd failed\n"));
3302 if (listener_pipe[0] != -1) {
3303 close(listener_pipe[0]);
3305 if (listener_pipe[1] != -1) {
3306 close(listener_pipe[1]);
3308 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3309 close(sconn->smb1.echo_handler.socket_lock_fd);
3312 #ifdef HAVE_ROBUST_MUTEXES
3313 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
3314 pthread_mutex_destroy(sconn->smb1.echo_handler.socket_mutex);
3315 anonymous_shared_free(sconn->smb1.echo_handler.socket_mutex);
3318 smbd_echo_init(sconn);
3323 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3326 if (user->session_info &&
3327 (user->session_info->unix_token->uid == uid)) {
3335 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3338 if (user->session_info != NULL) {
3340 struct security_unix_token *utok;
3342 utok = user->session_info->unix_token;
3343 if (utok->gid == gid) {
3346 for(i=0; i<utok->ngroups; i++) {
3347 if (utok->groups[i] == gid) {
3357 static bool sid_in_use(const struct user_struct *user,
3358 const struct dom_sid *psid)
3361 struct security_token *tok;
3363 if (user->session_info == NULL) {
3366 tok = user->session_info->security_token;
3369 * Not sure session_info->security_token can
3370 * ever be NULL. This check might be not
3375 if (security_token_has_sid(tok, psid)) {
3383 static bool id_in_use(const struct user_struct *user,
3384 const struct id_cache_ref *id)
3388 return uid_in_use(user, id->id.uid);
3390 return gid_in_use(user, id->id.gid);
3392 return sid_in_use(user, &id->id.sid);
3399 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3402 struct server_id server_id,
3405 const char *msg = (data && data->data)
3406 ? (const char *)data->data : "<NULL>";
3407 struct id_cache_ref id;
3408 struct smbd_server_connection *sconn =
3409 talloc_get_type_abort(private_data,
3410 struct smbd_server_connection);
3412 if (!id_cache_ref_parse(msg, &id)) {
3413 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3417 if (id_in_use(sconn->users, &id)) {
3418 exit_server_cleanly(msg);
3420 id_cache_delete_from_cache(&id);
3423 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3424 enum protocol_types protocol)
3428 set_Protocol(protocol);
3429 conn->protocol = protocol;
3431 if (protocol >= PROTOCOL_SMB2_02) {
3432 status = smb2srv_session_table_init(conn);
3433 if (!NT_STATUS_IS_OK(status)) {
3437 status = smb2srv_open_table_init(conn);
3438 if (!NT_STATUS_IS_OK(status)) {
3442 status = smb1srv_session_table_init(conn);
3443 if (!NT_STATUS_IS_OK(status)) {
3447 status = smb1srv_tcon_table_init(conn);
3448 if (!NT_STATUS_IS_OK(status)) {
3452 status = smb1srv_open_table_init(conn);
3453 if (!NT_STATUS_IS_OK(status)) {
3458 return NT_STATUS_OK;
3461 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3464 struct smbXsrv_connection *conn =
3465 talloc_get_type_abort(private_data,
3466 struct smbXsrv_connection);
3469 case TEVENT_TRACE_BEFORE_WAIT:
3471 * This just removes compiler warning
3472 * without profile support
3474 conn->smbd_idle_profstamp = 0;
3475 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3477 case TEVENT_TRACE_AFTER_WAIT:
3478 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3480 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3481 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3482 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3489 * Create a debug string for the connection
3491 * This is allocated to talloc_tos() or a string constant
3492 * in certain corner cases. The returned string should
3493 * hence not be free'd directly but only via the talloc stack.
3495 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3500 * TODO: this can be improved later
3501 * maybe including the client guid or more
3503 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3505 return "<tsocket_address_string() failed>";
3511 /****************************************************************************
3512 Process commands from the client
3513 ****************************************************************************/
3515 void smbd_process(struct tevent_context *ev_ctx,
3516 struct messaging_context *msg_ctx,
3520 TALLOC_CTX *frame = talloc_stackframe();
3521 struct smbXsrv_connection *conn;
3522 struct smbd_server_connection *sconn;
3523 struct sockaddr_storage ss_srv;
3524 void *sp_srv = (void *)&ss_srv;
3525 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3526 struct sockaddr_storage ss_clnt;
3527 void *sp_clnt = (void *)&ss_clnt;
3528 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3529 socklen_t sa_socklen;
3530 struct tsocket_address *local_address = NULL;
3531 struct tsocket_address *remote_address = NULL;
3532 const char *locaddr = NULL;
3533 const char *remaddr = NULL;
3538 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3540 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3541 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3544 conn->ev_ctx = ev_ctx;
3545 conn->msg_ctx = msg_ctx;
3547 sconn = talloc_zero(conn, struct smbd_server_connection);
3549 exit_server("failed to create smbd_server_connection");
3552 conn->sconn = sconn;
3556 * TODO: remove this...:-)
3558 global_smbXsrv_connection = conn;
3560 sconn->ev_ctx = ev_ctx;
3561 sconn->msg_ctx = msg_ctx;
3562 sconn->sock = sock_fd;
3563 smbd_echo_init(sconn);
3566 smbd_setup_sig_term_handler(sconn);
3567 smbd_setup_sig_hup_handler(sconn);
3569 if (!serverid_register(messaging_server_id(msg_ctx),
3570 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3572 |FLAG_MSG_PRINT_GENERAL)) {
3573 exit_server_cleanly("Could not register myself in "
3578 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3580 * We're not making the decision here,
3581 * we're just allowing the client
3582 * to decide between SMB1 and SMB2
3583 * with the first negprot
3586 sconn->using_smb2 = true;
3589 /* Ensure child is set to blocking mode */
3590 set_blocking(sconn->sock,True);
3592 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3593 set_socket_options(sconn->sock, lp_socket_options());
3595 sa_socklen = sizeof(ss_clnt);
3596 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3598 int level = (errno == ENOTCONN)?2:0;
3599 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3600 exit_server_cleanly("getpeername() failed.\n");
3602 ret = tsocket_address_bsd_from_sockaddr(sconn,
3603 sa_clnt, sa_socklen,
3606 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3607 __location__, strerror(errno)));
3608 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3611 sa_socklen = sizeof(ss_srv);
3612 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3614 int level = (errno == ENOTCONN)?2:0;
3615 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3616 exit_server_cleanly("getsockname() failed.\n");
3618 ret = tsocket_address_bsd_from_sockaddr(sconn,
3622 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3623 __location__, strerror(errno)));
3624 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3627 sconn->local_address = local_address;
3628 sconn->remote_address = remote_address;
3630 if (tsocket_address_is_inet(local_address, "ip")) {
3631 locaddr = tsocket_address_inet_addr_string(
3632 sconn->local_address,
3634 if (locaddr == NULL) {
3635 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3636 __location__, strerror(errno)));
3637 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3640 locaddr = "0.0.0.0";
3643 if (tsocket_address_is_inet(remote_address, "ip")) {
3644 remaddr = tsocket_address_inet_addr_string(
3645 sconn->remote_address,
3647 if (remaddr == NULL) {
3648 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3649 __location__, strerror(errno)));
3650 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3653 remaddr = "0.0.0.0";
3656 /* this is needed so that we get decent entries
3657 in smbstatus for port 445 connects */
3658 set_remote_machine_name(remaddr, false);
3659 reload_services(sconn, conn_snum_used, true);
3662 * Before the first packet, check the global hosts allow/ hosts deny
3663 * parameters before doing any parsing of packets passed to us by the
3664 * client. This prevents attacks on our parsing code from hosts not in
3665 * the hosts allow list.
3668 ret = get_remote_hostname(remote_address,
3672 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3673 __location__, strerror(errno)));
3674 exit_server_cleanly("get_remote_hostname failed.\n");
3676 if (strequal(rhost, "UNKNOWN")) {
3677 rhost = talloc_strdup(talloc_tos(), remaddr);
3679 sconn->remote_hostname = talloc_move(sconn, &rhost);
3681 sub_set_socket_ids(remaddr,
3682 sconn->remote_hostname,
3685 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3686 sconn->remote_hostname,
3689 * send a negative session response "not listening on calling
3692 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3693 DEBUG( 1, ("Connection denied from %s to %s\n",
3694 tsocket_address_string(remote_address, talloc_tos()),
3695 tsocket_address_string(local_address, talloc_tos())));
3696 (void)srv_send_smb(sconn,(char *)buf, false,
3698 exit_server_cleanly("connection denied");
3701 DEBUG(10, ("Connection allowed from %s to %s\n",
3702 tsocket_address_string(remote_address, talloc_tos()),
3703 tsocket_address_string(local_address, talloc_tos())));
3705 if (lp_preload_modules()) {
3706 smb_load_modules(lp_preload_modules());
3709 smb_perfcount_init();
3711 if (!init_account_policy()) {
3712 exit_server("Could not open account policy tdb.\n");
3715 if (*lp_root_directory(talloc_tos())) {
3716 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3717 DEBUG(0,("Failed to change root to %s\n",
3718 lp_root_directory(talloc_tos())));
3719 exit_server("Failed to chroot()");
3721 if (chdir("/") == -1) {
3722 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3723 exit_server("Failed to chroot()");
3725 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3728 if (!srv_init_signing(sconn)) {
3729 exit_server("Failed to init smb_signing");
3732 if (!file_init(sconn)) {
3733 exit_server("file_init() failed");
3737 if (!init_oplocks(sconn))
3738 exit_server("Failed to init oplocks");
3740 /* register our message handlers */
3741 messaging_register(sconn->msg_ctx, sconn,
3742 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3743 messaging_register(sconn->msg_ctx, sconn,
3744 MSG_SMB_CLOSE_FILE, msg_close_file);
3745 messaging_register(sconn->msg_ctx, sconn,
3746 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3748 id_cache_register_msgs(sconn->msg_ctx);
3749 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3750 messaging_register(sconn->msg_ctx, sconn,
3751 ID_CACHE_KILL, smbd_id_cache_kill);
3753 messaging_deregister(sconn->msg_ctx,
3754 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3755 messaging_register(sconn->msg_ctx, sconn,
3756 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3758 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3760 messaging_register(sconn->msg_ctx, sconn,
3761 MSG_SMB_KILL_CLIENT_IP,
3762 msg_kill_client_ip);
3764 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3767 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3768 * MSGs to all child processes
3770 messaging_deregister(sconn->msg_ctx,
3772 messaging_register(sconn->msg_ctx, NULL,
3773 MSG_DEBUG, debug_message);
3775 if ((lp_keepalive() != 0)
3776 && !(event_add_idle(ev_ctx, NULL,
3777 timeval_set(lp_keepalive(), 0),
3778 "keepalive", keepalive_fn,
3780 DEBUG(0, ("Could not add keepalive event\n"));
3784 if (!(event_add_idle(ev_ctx, NULL,
3785 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3786 "deadtime", deadtime_fn, sconn))) {
3787 DEBUG(0, ("Could not add deadtime event\n"));
3791 if (!(event_add_idle(ev_ctx, NULL,
3792 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3793 "housekeeping", housekeeping_fn, sconn))) {
3794 DEBUG(0, ("Could not add housekeeping event\n"));
3798 if (lp_clustering()) {
3800 * We need to tell ctdb about our client's TCP
3801 * connection, so that for failover ctdbd can send
3802 * tickle acks, triggering a reconnection by the
3807 status = smbd_register_ips(sconn, &ss_srv, &ss_clnt);
3808 if (!NT_STATUS_IS_OK(status)) {
3809 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3810 nt_errstr(status)));
3814 sconn->nbt.got_session = false;
3816 tmp = lp_max_xmit();
3817 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3818 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3820 sconn->smb1.negprot.max_recv = tmp;
3822 sconn->smb1.sessions.done_sesssetup = false;
3823 sconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3825 if (!init_dptrs(sconn)) {
3826 exit_server("init_dptrs() failed");
3829 sconn->smb1.fde = tevent_add_fd(ev_ctx,
3833 smbd_server_connection_handler,
3835 if (!sconn->smb1.fde) {
3836 exit_server("failed to create smbd_server_connection fde");
3839 sconn->conn->local_address = sconn->local_address;
3840 sconn->conn->remote_address = sconn->remote_address;
3841 sconn->conn->remote_hostname = sconn->remote_hostname;
3842 sconn->conn->protocol = PROTOCOL_NONE;
3846 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3849 frame = talloc_stackframe_pool(8192);
3852 if (tevent_loop_once(ev_ctx) == -1) {
3853 if (errno != EINTR) {
3854 DEBUG(3, ("tevent_loop_once failed: %s,"
3855 " exiting\n", strerror(errno) ));
3863 exit_server_cleanly(NULL);
3866 bool req_is_in_chain(const struct smb_request *req)
3868 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3870 * We're right now handling a subsequent request, so we must
3876 if (!is_andx_req(req->cmd)) {
3882 * Okay, an illegal request, but definitely not chained :-)
3887 return (CVAL(req->vwv+0, 0) != 0xFF);