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 smbXsrv_connection
*xconn
;
51 struct tevent_timer
*te
;
52 struct smb_perfcount_data pcd
;
57 struct deferred_open_record
*open_rec
;
60 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
62 static struct pending_message_list
*get_deferred_open_message_smb(
63 struct smbd_server_connection
*sconn
, uint64_t mid
);
64 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
);
66 static void smbd_echo_init(struct smbXsrv_connection
*xconn
)
68 xconn
->smb1
.echo_handler
.trusted_fd
= -1;
69 xconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
70 #ifdef HAVE_ROBUST_MUTEXES
71 xconn
->smb1
.echo_handler
.socket_mutex
= NULL
;
75 static bool smbd_echo_active(struct smbXsrv_connection
*xconn
)
77 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
81 #ifdef HAVE_ROBUST_MUTEXES
82 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
90 static bool smbd_lock_socket_internal(struct smbXsrv_connection
*xconn
)
92 if (!smbd_echo_active(xconn
)) {
96 xconn
->smb1
.echo_handler
.ref_count
++;
98 if (xconn
->smb1
.echo_handler
.ref_count
> 1) {
102 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
104 #ifdef HAVE_ROBUST_MUTEXES
105 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
108 while (ret
== EINTR
) {
109 ret
= pthread_mutex_lock(
110 xconn
->smb1
.echo_handler
.socket_mutex
);
116 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
123 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
128 xconn
->smb1
.echo_handler
.socket_lock_fd
,
129 F_SETLKW
, 0, 0, F_WRLCK
);
130 } while (!ok
&& (errno
== EINTR
));
133 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
138 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
143 void smbd_lock_socket(struct smbXsrv_connection
*xconn
)
145 if (!smbd_lock_socket_internal(xconn
)) {
146 exit_server_cleanly("failed to lock socket");
150 static bool smbd_unlock_socket_internal(struct smbXsrv_connection
*xconn
)
152 if (!smbd_echo_active(xconn
)) {
156 xconn
->smb1
.echo_handler
.ref_count
--;
158 if (xconn
->smb1
.echo_handler
.ref_count
> 0) {
162 #ifdef HAVE_ROBUST_MUTEXES
163 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
166 while (ret
== EINTR
) {
167 ret
= pthread_mutex_unlock(
168 xconn
->smb1
.echo_handler
.socket_mutex
);
174 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
181 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
186 xconn
->smb1
.echo_handler
.socket_lock_fd
,
187 F_SETLKW
, 0, 0, F_UNLCK
);
188 } while (!ok
&& (errno
== EINTR
));
191 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
196 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
201 void smbd_unlock_socket(struct smbXsrv_connection
*xconn
)
203 if (!smbd_unlock_socket_internal(xconn
)) {
204 exit_server_cleanly("failed to unlock socket");
208 /* Accessor function for smb_read_error for smbd functions. */
210 /****************************************************************************
212 ****************************************************************************/
214 bool srv_send_smb(struct smbXsrv_connection
*xconn
, char *buffer
,
215 bool do_signing
, uint32_t seqnum
,
217 struct smb_perfcount_data
*pcd
)
221 char *buf_out
= buffer
;
223 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
225 * we're not supposed to do any io
230 smbd_lock_socket(xconn
);
233 /* Sign the outgoing packet if required. */
234 srv_calculate_sign_mac(xconn
, buf_out
, seqnum
);
238 NTSTATUS status
= srv_encrypt_buffer(xconn
, buffer
, &buf_out
);
239 if (!NT_STATUS_IS_OK(status
)) {
240 DEBUG(0, ("send_smb: SMB encryption failed "
241 "on outgoing packet! Error %s\n",
242 nt_errstr(status
) ));
248 len
= smb_len_large(buf_out
) + 4;
250 ret
= write_data(xconn
->transport
.sock
, buf_out
, len
);
252 int saved_errno
= errno
;
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 smbXsrv_connection_dbg(xconn
),
260 (int)ret
, strerror(saved_errno
)));
263 srv_free_enc_buffer(xconn
, buf_out
);
267 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
268 srv_free_enc_buffer(xconn
, buf_out
);
270 SMB_PERFCOUNT_END(pcd
);
272 smbd_unlock_socket(xconn
);
276 /*******************************************************************
277 Setup the word count and byte count for a smb message.
278 ********************************************************************/
280 int srv_set_message(char *buf
,
285 if (zero
&& (num_words
|| num_bytes
)) {
286 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
288 SCVAL(buf
,smb_wct
,num_words
);
289 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
290 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
291 return (smb_size
+ num_words
*2 + num_bytes
);
294 static bool valid_smb_header(const uint8_t *inbuf
)
296 if (is_encrypted_packet(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 smbXsrv_connection
*xconn
,
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 smbXsrv_connection_dbg(xconn
),
391 * Ok - now try and see if this is a possible
395 if (is_valid_writeX_buffer(xconn
, (uint8_t *)writeX_header
)) {
397 * If the data offset is beyond what
398 * we've read, drain the extra bytes.
400 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
403 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
404 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
405 if (drain_socket(sock
, drain
) != drain
) {
406 smb_panic("receive_smb_raw_talloc_partial_read:"
407 " failed to drain pending bytes");
410 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
413 /* Spoof down the length and null out the bcc. */
414 set_message_bcc(writeX_header
, 0);
415 newlen
= smb_len(writeX_header
);
417 /* Copy the header we've written. */
419 *buffer
= (char *)talloc_memdup(mem_ctx
,
421 sizeof(writeX_header
));
423 if (*buffer
== NULL
) {
424 DEBUG(0, ("Could not allocate inbuf of length %d\n",
425 (int)sizeof(writeX_header
)));
426 return NT_STATUS_NO_MEMORY
;
429 /* Work out the remaining bytes. */
430 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
431 *len_ret
= newlen
+ 4;
435 if (!valid_packet_size(len
)) {
436 return NT_STATUS_INVALID_PARAMETER
;
440 * Not a valid writeX call. Just do the standard
444 *buffer
= talloc_array(mem_ctx
, char, len
+4);
446 if (*buffer
== NULL
) {
447 DEBUG(0, ("Could not allocate inbuf of length %d\n",
449 return NT_STATUS_NO_MEMORY
;
452 /* Copy in what we already read. */
455 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
456 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
459 status
= read_packet_remainder(
461 (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
464 if (!NT_STATUS_IS_OK(status
)) {
465 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
475 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
,
476 struct smbXsrv_connection
*xconn
,
478 char **buffer
, unsigned int timeout
,
479 size_t *p_unread
, size_t *plen
)
483 int min_recv_size
= lp_min_receive_file_size();
488 status
= read_smb_length_return_keepalive(sock
, lenbuf
, timeout
,
490 if (!NT_STATUS_IS_OK(status
)) {
494 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
495 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
496 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
497 !srv_is_signing_active(xconn
) &&
498 xconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
500 return receive_smb_raw_talloc_partial_read(
501 mem_ctx
, lenbuf
, xconn
, sock
, buffer
, timeout
,
505 if (!valid_packet_size(len
)) {
506 return NT_STATUS_INVALID_PARAMETER
;
510 * The +4 here can't wrap, we've checked the length above already.
513 *buffer
= talloc_array(mem_ctx
, char, len
+4);
515 if (*buffer
== NULL
) {
516 DEBUG(0, ("Could not allocate inbuf of length %d\n",
518 return NT_STATUS_NO_MEMORY
;
521 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
523 status
= read_packet_remainder(sock
, (*buffer
)+4, timeout
, len
);
524 if (!NT_STATUS_IS_OK(status
)) {
532 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
,
533 struct smbXsrv_connection
*xconn
,
535 char **buffer
, unsigned int timeout
,
536 size_t *p_unread
, bool *p_encrypted
,
539 bool trusted_channel
)
544 *p_encrypted
= false;
546 status
= receive_smb_raw_talloc(mem_ctx
, xconn
, sock
, buffer
, timeout
,
548 if (!NT_STATUS_IS_OK(status
)) {
549 DEBUG(NT_STATUS_EQUAL(status
, NT_STATUS_END_OF_FILE
)?5:1,
550 ("receive_smb_raw_talloc failed for client %s "
551 "read error = %s.\n",
552 smbXsrv_connection_dbg(xconn
),
553 nt_errstr(status
)) );
557 if (is_encrypted_packet((uint8_t *)*buffer
)) {
558 status
= srv_decrypt_buffer(xconn
, *buffer
);
559 if (!NT_STATUS_IS_OK(status
)) {
560 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
561 "incoming packet! Error %s\n",
562 nt_errstr(status
) ));
568 /* Check the incoming SMB signature. */
569 if (!srv_check_sign_mac(xconn
, *buffer
, seqnum
, trusted_channel
)) {
570 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
571 "incoming packet!\n"));
572 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
580 * Initialize a struct smb_request from an inbuf
583 static bool init_smb_request(struct smb_request
*req
,
584 struct smbd_server_connection
*sconn
,
585 struct smbXsrv_connection
*xconn
,
587 size_t unread_bytes
, bool encrypted
,
590 struct smbXsrv_tcon
*tcon
;
593 size_t req_size
= smb_len(inbuf
) + 4;
595 /* Ensure we have at least smb_size bytes. */
596 if (req_size
< smb_size
) {
597 DEBUG(0,("init_smb_request: invalid request size %u\n",
598 (unsigned int)req_size
));
602 req
->request_time
= timeval_current();
603 now
= timeval_to_nttime(&req
->request_time
);
605 req
->cmd
= CVAL(inbuf
, smb_com
);
606 req
->flags2
= SVAL(inbuf
, smb_flg2
);
607 req
->smbpid
= SVAL(inbuf
, smb_pid
);
608 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
609 req
->seqnum
= seqnum
;
610 req
->vuid
= SVAL(inbuf
, smb_uid
);
611 req
->tid
= SVAL(inbuf
, smb_tid
);
612 req
->wct
= CVAL(inbuf
, smb_wct
);
613 req
->vwv
= (const uint16_t *)(inbuf
+smb_vwv
);
614 req
->buflen
= smb_buflen(inbuf
);
615 req
->buf
= (const uint8_t *)smb_buf_const(inbuf
);
616 req
->unread_bytes
= unread_bytes
;
617 req
->encrypted
= encrypted
;
622 status
= smb1srv_tcon_lookup(xconn
, req
->tid
, now
, &tcon
);
623 if (NT_STATUS_IS_OK(status
)) {
624 req
->conn
= tcon
->compat
;
627 req
->chain_fsp
= NULL
;
629 req
->priv_paths
= NULL
;
631 smb_init_perfcount_data(&req
->pcd
);
633 /* Ensure we have at least wct words and 2 bytes of bcc. */
634 if (smb_size
+ req
->wct
*2 > req_size
) {
635 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
636 (unsigned int)req
->wct
,
637 (unsigned int)req_size
));
640 /* Ensure bcc is correct. */
641 if (((const uint8_t *)smb_buf_const(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
642 DEBUG(0,("init_smb_request: invalid bcc number %u "
643 "(wct = %u, size %u)\n",
644 (unsigned int)req
->buflen
,
645 (unsigned int)req
->wct
,
646 (unsigned int)req_size
));
654 static void process_smb(struct smbXsrv_connection
*xconn
,
655 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
656 uint32_t seqnum
, bool encrypted
,
657 struct smb_perfcount_data
*deferred_pcd
);
659 static void smbd_deferred_open_timer(struct tevent_context
*ev
,
660 struct tevent_timer
*te
,
661 struct timeval _tval
,
664 struct pending_message_list
*msg
= talloc_get_type(private_data
,
665 struct pending_message_list
);
666 struct smbd_server_connection
*sconn
= msg
->sconn
;
667 struct smbXsrv_connection
*xconn
= msg
->xconn
;
668 TALLOC_CTX
*mem_ctx
= talloc_tos();
669 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
672 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
675 exit_server("smbd_deferred_open_timer: talloc failed\n");
679 /* We leave this message on the queue so the open code can
680 know this is a retry. */
681 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
682 (unsigned long long)mid
));
684 /* Mark the message as processed so this is not
685 * re-processed in error. */
686 msg
->processed
= true;
688 process_smb(xconn
, inbuf
,
690 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
692 /* If it's still there and was processed, remove it. */
693 msg
= get_deferred_open_message_smb(sconn
, mid
);
694 if (msg
&& msg
->processed
) {
695 remove_deferred_open_message_smb(xconn
, mid
);
699 /****************************************************************************
700 Function to push a message onto the tail of a linked list of smb messages ready
702 ****************************************************************************/
704 static bool push_queued_message(struct smb_request
*req
,
705 struct timeval request_time
,
706 struct timeval end_time
,
707 struct deferred_open_record
*open_rec
)
709 int msg_len
= smb_len(req
->inbuf
) + 4;
710 struct pending_message_list
*msg
;
712 msg
= talloc_zero(NULL
, struct pending_message_list
);
715 DEBUG(0,("push_message: malloc fail (1)\n"));
718 msg
->sconn
= req
->sconn
;
719 msg
->xconn
= req
->xconn
;
721 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
722 if(msg
->buf
.data
== NULL
) {
723 DEBUG(0,("push_message: malloc fail (2)\n"));
728 msg
->request_time
= request_time
;
729 msg
->seqnum
= req
->seqnum
;
730 msg
->encrypted
= req
->encrypted
;
731 msg
->processed
= false;
732 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
735 msg
->open_rec
= talloc_move(msg
, &open_rec
);
739 msg
->te
= tevent_add_timer(msg
->sconn
->ev_ctx
,
742 smbd_deferred_open_timer
,
745 DEBUG(0,("push_message: event_add_timed failed\n"));
751 DLIST_ADD_END(req
->sconn
->deferred_open_queue
, msg
,
752 struct pending_message_list
*);
754 DEBUG(10,("push_message: pushed message length %u on "
755 "deferred_open_queue\n", (unsigned int)msg_len
));
760 /****************************************************************************
761 Function to delete a sharing violation open message by mid.
762 ****************************************************************************/
764 void remove_deferred_open_message_smb(struct smbXsrv_connection
*xconn
,
767 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
768 struct pending_message_list
*pml
;
770 if (sconn
->using_smb2
) {
771 remove_deferred_open_message_smb2(xconn
, mid
);
775 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
776 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
777 DEBUG(10,("remove_deferred_open_message_smb: "
778 "deleting mid %llu len %u\n",
779 (unsigned long long)mid
,
780 (unsigned int)pml
->buf
.length
));
781 DLIST_REMOVE(sconn
->deferred_open_queue
, pml
);
788 /****************************************************************************
789 Move a sharing violation open retry message to the front of the list and
790 schedule it for immediate processing.
791 ****************************************************************************/
793 bool schedule_deferred_open_message_smb(struct smbXsrv_connection
*xconn
,
796 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
797 struct pending_message_list
*pml
;
800 if (sconn
->using_smb2
) {
801 return schedule_deferred_open_message_smb2(xconn
, mid
);
804 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
805 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
807 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
810 (unsigned long long)msg_mid
));
812 if (mid
== msg_mid
) {
813 struct tevent_timer
*te
;
815 if (pml
->processed
) {
816 /* A processed message should not be
818 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
819 "message mid %llu was already processed\n",
820 (unsigned long long)msg_mid
));
824 DEBUG(10,("schedule_deferred_open_message_smb: "
825 "scheduling mid %llu\n",
826 (unsigned long long)mid
));
828 te
= tevent_add_timer(pml
->sconn
->ev_ctx
,
831 smbd_deferred_open_timer
,
834 DEBUG(10,("schedule_deferred_open_message_smb: "
835 "event_add_timed() failed, "
836 "skipping mid %llu\n",
837 (unsigned long long)msg_mid
));
840 TALLOC_FREE(pml
->te
);
842 DLIST_PROMOTE(sconn
->deferred_open_queue
, pml
);
847 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
848 "find message mid %llu\n",
849 (unsigned long long)mid
));
854 /****************************************************************************
855 Return true if this mid is on the deferred queue and was not yet processed.
856 ****************************************************************************/
858 bool open_was_deferred(struct smbXsrv_connection
*xconn
, uint64_t mid
)
860 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
861 struct pending_message_list
*pml
;
863 if (sconn
->using_smb2
) {
864 return open_was_deferred_smb2(xconn
, mid
);
867 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
868 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
875 /****************************************************************************
876 Return the message queued by this mid.
877 ****************************************************************************/
879 static struct pending_message_list
*get_deferred_open_message_smb(
880 struct smbd_server_connection
*sconn
, uint64_t mid
)
882 struct pending_message_list
*pml
;
884 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
885 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
892 /****************************************************************************
893 Get the state data queued by this mid.
894 ****************************************************************************/
896 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
897 struct timeval
*p_request_time
,
898 struct deferred_open_record
**open_rec
)
900 struct pending_message_list
*pml
;
902 if (smbreq
->sconn
->using_smb2
) {
903 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
908 pml
= get_deferred_open_message_smb(smbreq
->sconn
, smbreq
->mid
);
912 if (p_request_time
) {
913 *p_request_time
= pml
->request_time
;
915 if (open_rec
!= NULL
) {
916 *open_rec
= pml
->open_rec
;
921 /****************************************************************************
922 Function to push a deferred open smb message onto a linked list of local smb
923 messages ready for processing.
924 ****************************************************************************/
926 bool push_deferred_open_message_smb(struct smb_request
*req
,
927 struct timeval request_time
,
928 struct timeval timeout
,
930 struct deferred_open_record
*open_rec
)
932 struct timeval end_time
;
935 return push_deferred_open_message_smb2(req
->smb2req
,
942 if (req
->unread_bytes
) {
943 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
944 "unread_bytes = %u\n",
945 (unsigned int)req
->unread_bytes
));
946 smb_panic("push_deferred_open_message_smb: "
947 "logic error unread_bytes != 0" );
950 end_time
= timeval_sum(&request_time
, &timeout
);
952 DEBUG(10,("push_deferred_open_message_smb: pushing message "
953 "len %u mid %llu timeout time [%u.%06u]\n",
954 (unsigned int) smb_len(req
->inbuf
)+4,
955 (unsigned long long)req
->mid
,
956 (unsigned int)end_time
.tv_sec
,
957 (unsigned int)end_time
.tv_usec
));
959 return push_queued_message(req
, request_time
, end_time
, open_rec
);
962 static void smbd_sig_term_handler(struct tevent_context
*ev
,
963 struct tevent_signal
*se
,
969 exit_server_cleanly("termination signal");
972 void smbd_setup_sig_term_handler(struct smbd_server_connection
*sconn
)
974 struct tevent_signal
*se
;
976 se
= tevent_add_signal(sconn
->ev_ctx
,
979 smbd_sig_term_handler
,
982 exit_server("failed to setup SIGTERM handler");
986 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
987 struct tevent_signal
*se
,
993 struct smbd_server_connection
*sconn
=
994 talloc_get_type_abort(private_data
,
995 struct smbd_server_connection
);
997 change_to_root_user();
998 DEBUG(1,("Reloading services after SIGHUP\n"));
999 reload_services(sconn
, conn_snum_used
, false);
1002 void smbd_setup_sig_hup_handler(struct smbd_server_connection
*sconn
)
1004 struct tevent_signal
*se
;
1006 se
= tevent_add_signal(sconn
->ev_ctx
,
1009 smbd_sig_hup_handler
,
1012 exit_server("failed to setup SIGHUP handler");
1016 static void smbd_conf_updated(struct messaging_context
*msg
,
1019 struct server_id server_id
,
1022 struct smbd_server_connection
*sconn
=
1023 talloc_get_type_abort(private_data
,
1024 struct smbd_server_connection
);
1026 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1027 "updated. Reloading.\n"));
1028 change_to_root_user();
1029 reload_services(sconn
, conn_snum_used
, false);
1033 * Only allow 5 outstanding trans requests. We're allocating memory, so
1037 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
1040 for (; list
!= NULL
; list
= list
->next
) {
1042 if (list
->mid
== mid
) {
1043 return NT_STATUS_INVALID_PARAMETER
;
1049 return NT_STATUS_INSUFFICIENT_RESOURCES
;
1052 return NT_STATUS_OK
;
1056 These flags determine some of the permissions required to do an operation
1058 Note that I don't set NEED_WRITE on some write operations because they
1059 are used by some brain-dead clients when printing, and I don't want to
1060 force write permissions on print services.
1062 #define AS_USER (1<<0)
1063 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1064 #define TIME_INIT (1<<2)
1065 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1066 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1067 #define DO_CHDIR (1<<6)
1070 define a list of possible SMB messages and their corresponding
1071 functions. Any message that has a NULL function is unimplemented -
1072 please feel free to contribute implementations!
1074 static const struct smb_message_struct
{
1076 void (*fn
)(struct smb_request
*req
);
1078 } smb_messages
[256] = {
1080 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1081 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1082 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1083 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1084 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1085 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1086 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1087 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1088 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1089 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1090 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1091 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1092 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1093 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1094 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1095 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1096 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1097 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1098 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1099 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1100 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1101 /* 0x15 */ { NULL
, NULL
, 0 },
1102 /* 0x16 */ { NULL
, NULL
, 0 },
1103 /* 0x17 */ { NULL
, NULL
, 0 },
1104 /* 0x18 */ { NULL
, NULL
, 0 },
1105 /* 0x19 */ { NULL
, NULL
, 0 },
1106 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1107 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1108 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1109 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1110 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1111 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1112 /* 0x20 */ { "SMBwritec", NULL
,0},
1113 /* 0x21 */ { NULL
, NULL
, 0 },
1114 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1115 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1116 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1117 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1118 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1119 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1120 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1121 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1122 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1123 /* 0x2b */ { "SMBecho",reply_echo
,0},
1124 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1125 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1126 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1127 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1128 /* 0x30 */ { NULL
, NULL
, 0 },
1129 /* 0x31 */ { NULL
, NULL
, 0 },
1130 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1131 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1132 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1133 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1134 /* 0x36 */ { NULL
, NULL
, 0 },
1135 /* 0x37 */ { NULL
, NULL
, 0 },
1136 /* 0x38 */ { NULL
, NULL
, 0 },
1137 /* 0x39 */ { NULL
, NULL
, 0 },
1138 /* 0x3a */ { NULL
, NULL
, 0 },
1139 /* 0x3b */ { NULL
, NULL
, 0 },
1140 /* 0x3c */ { NULL
, NULL
, 0 },
1141 /* 0x3d */ { NULL
, NULL
, 0 },
1142 /* 0x3e */ { NULL
, NULL
, 0 },
1143 /* 0x3f */ { NULL
, NULL
, 0 },
1144 /* 0x40 */ { NULL
, NULL
, 0 },
1145 /* 0x41 */ { NULL
, NULL
, 0 },
1146 /* 0x42 */ { NULL
, NULL
, 0 },
1147 /* 0x43 */ { NULL
, NULL
, 0 },
1148 /* 0x44 */ { NULL
, NULL
, 0 },
1149 /* 0x45 */ { NULL
, NULL
, 0 },
1150 /* 0x46 */ { NULL
, NULL
, 0 },
1151 /* 0x47 */ { NULL
, NULL
, 0 },
1152 /* 0x48 */ { NULL
, NULL
, 0 },
1153 /* 0x49 */ { NULL
, NULL
, 0 },
1154 /* 0x4a */ { NULL
, NULL
, 0 },
1155 /* 0x4b */ { NULL
, NULL
, 0 },
1156 /* 0x4c */ { NULL
, NULL
, 0 },
1157 /* 0x4d */ { NULL
, NULL
, 0 },
1158 /* 0x4e */ { NULL
, NULL
, 0 },
1159 /* 0x4f */ { NULL
, NULL
, 0 },
1160 /* 0x50 */ { NULL
, NULL
, 0 },
1161 /* 0x51 */ { NULL
, NULL
, 0 },
1162 /* 0x52 */ { NULL
, NULL
, 0 },
1163 /* 0x53 */ { NULL
, NULL
, 0 },
1164 /* 0x54 */ { NULL
, NULL
, 0 },
1165 /* 0x55 */ { NULL
, NULL
, 0 },
1166 /* 0x56 */ { NULL
, NULL
, 0 },
1167 /* 0x57 */ { NULL
, NULL
, 0 },
1168 /* 0x58 */ { NULL
, NULL
, 0 },
1169 /* 0x59 */ { NULL
, NULL
, 0 },
1170 /* 0x5a */ { NULL
, NULL
, 0 },
1171 /* 0x5b */ { NULL
, NULL
, 0 },
1172 /* 0x5c */ { NULL
, NULL
, 0 },
1173 /* 0x5d */ { NULL
, NULL
, 0 },
1174 /* 0x5e */ { NULL
, NULL
, 0 },
1175 /* 0x5f */ { NULL
, NULL
, 0 },
1176 /* 0x60 */ { NULL
, NULL
, 0 },
1177 /* 0x61 */ { NULL
, NULL
, 0 },
1178 /* 0x62 */ { NULL
, NULL
, 0 },
1179 /* 0x63 */ { NULL
, NULL
, 0 },
1180 /* 0x64 */ { NULL
, NULL
, 0 },
1181 /* 0x65 */ { NULL
, NULL
, 0 },
1182 /* 0x66 */ { NULL
, NULL
, 0 },
1183 /* 0x67 */ { NULL
, NULL
, 0 },
1184 /* 0x68 */ { NULL
, NULL
, 0 },
1185 /* 0x69 */ { NULL
, NULL
, 0 },
1186 /* 0x6a */ { NULL
, NULL
, 0 },
1187 /* 0x6b */ { NULL
, NULL
, 0 },
1188 /* 0x6c */ { NULL
, NULL
, 0 },
1189 /* 0x6d */ { NULL
, NULL
, 0 },
1190 /* 0x6e */ { NULL
, NULL
, 0 },
1191 /* 0x6f */ { NULL
, NULL
, 0 },
1192 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1193 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1194 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1195 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1196 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1197 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1198 /* 0x76 */ { NULL
, NULL
, 0 },
1199 /* 0x77 */ { NULL
, NULL
, 0 },
1200 /* 0x78 */ { NULL
, NULL
, 0 },
1201 /* 0x79 */ { NULL
, NULL
, 0 },
1202 /* 0x7a */ { NULL
, NULL
, 0 },
1203 /* 0x7b */ { NULL
, NULL
, 0 },
1204 /* 0x7c */ { NULL
, NULL
, 0 },
1205 /* 0x7d */ { NULL
, NULL
, 0 },
1206 /* 0x7e */ { NULL
, NULL
, 0 },
1207 /* 0x7f */ { NULL
, NULL
, 0 },
1208 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1209 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1210 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1211 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1212 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1213 /* 0x85 */ { NULL
, NULL
, 0 },
1214 /* 0x86 */ { NULL
, NULL
, 0 },
1215 /* 0x87 */ { NULL
, NULL
, 0 },
1216 /* 0x88 */ { NULL
, NULL
, 0 },
1217 /* 0x89 */ { NULL
, NULL
, 0 },
1218 /* 0x8a */ { NULL
, NULL
, 0 },
1219 /* 0x8b */ { NULL
, NULL
, 0 },
1220 /* 0x8c */ { NULL
, NULL
, 0 },
1221 /* 0x8d */ { NULL
, NULL
, 0 },
1222 /* 0x8e */ { NULL
, NULL
, 0 },
1223 /* 0x8f */ { NULL
, NULL
, 0 },
1224 /* 0x90 */ { NULL
, NULL
, 0 },
1225 /* 0x91 */ { NULL
, NULL
, 0 },
1226 /* 0x92 */ { NULL
, NULL
, 0 },
1227 /* 0x93 */ { NULL
, NULL
, 0 },
1228 /* 0x94 */ { NULL
, NULL
, 0 },
1229 /* 0x95 */ { NULL
, NULL
, 0 },
1230 /* 0x96 */ { NULL
, NULL
, 0 },
1231 /* 0x97 */ { NULL
, NULL
, 0 },
1232 /* 0x98 */ { NULL
, NULL
, 0 },
1233 /* 0x99 */ { NULL
, NULL
, 0 },
1234 /* 0x9a */ { NULL
, NULL
, 0 },
1235 /* 0x9b */ { NULL
, NULL
, 0 },
1236 /* 0x9c */ { NULL
, NULL
, 0 },
1237 /* 0x9d */ { NULL
, NULL
, 0 },
1238 /* 0x9e */ { NULL
, NULL
, 0 },
1239 /* 0x9f */ { NULL
, NULL
, 0 },
1240 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1241 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1242 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1243 /* 0xa3 */ { NULL
, NULL
, 0 },
1244 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1245 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1246 /* 0xa6 */ { NULL
, NULL
, 0 },
1247 /* 0xa7 */ { NULL
, NULL
, 0 },
1248 /* 0xa8 */ { NULL
, NULL
, 0 },
1249 /* 0xa9 */ { NULL
, NULL
, 0 },
1250 /* 0xaa */ { NULL
, NULL
, 0 },
1251 /* 0xab */ { NULL
, NULL
, 0 },
1252 /* 0xac */ { NULL
, NULL
, 0 },
1253 /* 0xad */ { NULL
, NULL
, 0 },
1254 /* 0xae */ { NULL
, NULL
, 0 },
1255 /* 0xaf */ { NULL
, NULL
, 0 },
1256 /* 0xb0 */ { NULL
, NULL
, 0 },
1257 /* 0xb1 */ { NULL
, NULL
, 0 },
1258 /* 0xb2 */ { NULL
, NULL
, 0 },
1259 /* 0xb3 */ { NULL
, NULL
, 0 },
1260 /* 0xb4 */ { NULL
, NULL
, 0 },
1261 /* 0xb5 */ { NULL
, NULL
, 0 },
1262 /* 0xb6 */ { NULL
, NULL
, 0 },
1263 /* 0xb7 */ { NULL
, NULL
, 0 },
1264 /* 0xb8 */ { NULL
, NULL
, 0 },
1265 /* 0xb9 */ { NULL
, NULL
, 0 },
1266 /* 0xba */ { NULL
, NULL
, 0 },
1267 /* 0xbb */ { NULL
, NULL
, 0 },
1268 /* 0xbc */ { NULL
, NULL
, 0 },
1269 /* 0xbd */ { NULL
, NULL
, 0 },
1270 /* 0xbe */ { NULL
, NULL
, 0 },
1271 /* 0xbf */ { NULL
, NULL
, 0 },
1272 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1273 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1274 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1275 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1276 /* 0xc4 */ { NULL
, NULL
, 0 },
1277 /* 0xc5 */ { NULL
, NULL
, 0 },
1278 /* 0xc6 */ { NULL
, NULL
, 0 },
1279 /* 0xc7 */ { NULL
, NULL
, 0 },
1280 /* 0xc8 */ { NULL
, NULL
, 0 },
1281 /* 0xc9 */ { NULL
, NULL
, 0 },
1282 /* 0xca */ { NULL
, NULL
, 0 },
1283 /* 0xcb */ { NULL
, NULL
, 0 },
1284 /* 0xcc */ { NULL
, NULL
, 0 },
1285 /* 0xcd */ { NULL
, NULL
, 0 },
1286 /* 0xce */ { NULL
, NULL
, 0 },
1287 /* 0xcf */ { NULL
, NULL
, 0 },
1288 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1289 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1290 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1291 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1292 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1293 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1294 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1295 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1296 /* 0xd8 */ { NULL
, NULL
, 0 },
1297 /* 0xd9 */ { NULL
, NULL
, 0 },
1298 /* 0xda */ { NULL
, NULL
, 0 },
1299 /* 0xdb */ { NULL
, NULL
, 0 },
1300 /* 0xdc */ { NULL
, NULL
, 0 },
1301 /* 0xdd */ { NULL
, NULL
, 0 },
1302 /* 0xde */ { NULL
, NULL
, 0 },
1303 /* 0xdf */ { NULL
, NULL
, 0 },
1304 /* 0xe0 */ { NULL
, NULL
, 0 },
1305 /* 0xe1 */ { NULL
, NULL
, 0 },
1306 /* 0xe2 */ { NULL
, NULL
, 0 },
1307 /* 0xe3 */ { NULL
, NULL
, 0 },
1308 /* 0xe4 */ { NULL
, NULL
, 0 },
1309 /* 0xe5 */ { NULL
, NULL
, 0 },
1310 /* 0xe6 */ { NULL
, NULL
, 0 },
1311 /* 0xe7 */ { NULL
, NULL
, 0 },
1312 /* 0xe8 */ { NULL
, NULL
, 0 },
1313 /* 0xe9 */ { NULL
, NULL
, 0 },
1314 /* 0xea */ { NULL
, NULL
, 0 },
1315 /* 0xeb */ { NULL
, NULL
, 0 },
1316 /* 0xec */ { NULL
, NULL
, 0 },
1317 /* 0xed */ { NULL
, NULL
, 0 },
1318 /* 0xee */ { NULL
, NULL
, 0 },
1319 /* 0xef */ { NULL
, NULL
, 0 },
1320 /* 0xf0 */ { NULL
, NULL
, 0 },
1321 /* 0xf1 */ { NULL
, NULL
, 0 },
1322 /* 0xf2 */ { NULL
, NULL
, 0 },
1323 /* 0xf3 */ { NULL
, NULL
, 0 },
1324 /* 0xf4 */ { NULL
, NULL
, 0 },
1325 /* 0xf5 */ { NULL
, NULL
, 0 },
1326 /* 0xf6 */ { NULL
, NULL
, 0 },
1327 /* 0xf7 */ { NULL
, NULL
, 0 },
1328 /* 0xf8 */ { NULL
, NULL
, 0 },
1329 /* 0xf9 */ { NULL
, NULL
, 0 },
1330 /* 0xfa */ { NULL
, NULL
, 0 },
1331 /* 0xfb */ { NULL
, NULL
, 0 },
1332 /* 0xfc */ { NULL
, NULL
, 0 },
1333 /* 0xfd */ { NULL
, NULL
, 0 },
1334 /* 0xfe */ { NULL
, NULL
, 0 },
1335 /* 0xff */ { NULL
, NULL
, 0 }
1339 /*******************************************************************
1340 allocate and initialize a reply packet
1341 ********************************************************************/
1343 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1344 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1347 size_t smb_len
= MIN_SMB_SIZE
+ VWV(num_words
) + num_bytes
;
1350 * Protect against integer wrap.
1351 * The SMB layer reply can be up to 0xFFFFFF bytes.
1353 if ((num_bytes
> 0xffffff) || (smb_len
> 0xffffff)) {
1355 if (asprintf(&msg
, "num_bytes too large: %u",
1356 (unsigned)num_bytes
) == -1) {
1357 msg
= discard_const_p(char, "num_bytes too large");
1363 * Here we include the NBT header for now.
1365 *outbuf
= talloc_array(mem_ctx
, char,
1366 NBT_HDR_SIZE
+ smb_len
);
1367 if (*outbuf
== NULL
) {
1371 construct_reply_common(req
, inbuf
, *outbuf
);
1372 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1374 * Zero out the word area, the caller has to take care of the bcc area
1377 if (num_words
!= 0) {
1378 memset(*outbuf
+ (NBT_HDR_SIZE
+ HDR_VWV
), 0, VWV(num_words
));
1384 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1387 if (!create_outbuf(req
, req
, (const char *)req
->inbuf
, &outbuf
, num_words
,
1389 smb_panic("could not allocate output buffer\n");
1391 req
->outbuf
= (uint8_t *)outbuf
;
1395 /*******************************************************************
1396 Dump a packet to a file.
1397 ********************************************************************/
1399 static void smb_dump(const char *name
, int type
, const char *data
)
1404 if (DEBUGLEVEL
< 50) {
1408 len
= smb_len_tcp(data
)+4;
1409 for (i
=1;i
<100;i
++) {
1410 fname
= talloc_asprintf(talloc_tos(),
1414 type
? "req" : "resp");
1415 if (fname
== NULL
) {
1418 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1419 if (fd
!= -1 || errno
!= EEXIST
) break;
1423 ssize_t ret
= write(fd
, data
, len
);
1425 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1427 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1432 /****************************************************************************
1433 Prepare everything for calling the actual request function, and potentially
1434 call the request function via the "new" interface.
1436 Return False if the "legacy" function needs to be called, everything is
1439 Return True if we're done.
1441 I know this API sucks, but it is the one with the least code change I could
1443 ****************************************************************************/
1445 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
)
1448 uint64_t session_tag
;
1449 connection_struct
*conn
= NULL
;
1450 struct smbXsrv_connection
*xconn
= req
->xconn
;
1451 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1452 struct smbXsrv_session
*session
= NULL
;
1457 if (!xconn
->smb1
.negprot
.done
) {
1460 * Without a negprot the request must
1461 * either be a negprot, or one of the
1462 * evil old SMB mailslot messaging types.
1470 exit_server_cleanly("The first request "
1471 "should be a negprot");
1475 if (smb_messages
[type
].fn
== NULL
) {
1476 DEBUG(0,("Unknown message type %d!\n",type
));
1477 smb_dump("Unknown", 1, (const char *)req
->inbuf
);
1478 reply_unknown_new(req
, type
);
1482 flags
= smb_messages
[type
].flags
;
1484 /* In share mode security we must ignore the vuid. */
1485 session_tag
= req
->vuid
;
1488 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1489 (int)getpid(), (unsigned long)conn
));
1491 smb_dump(smb_fn_name(type
), 1, (const char *)req
->inbuf
);
1493 /* Ensure this value is replaced in the incoming packet. */
1494 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_uid
,session_tag
);
1497 * Ensure the correct username is in current_user_info. This is a
1498 * really ugly bugfix for problems with multiple session_setup_and_X's
1499 * being done and allowing %U and %G substitutions to work correctly.
1500 * There is a reason this code is done here, don't move it unless you
1501 * know what you're doing... :-).
1506 * lookup an existing session
1508 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1509 * here, the main check is still in change_to_user()
1511 status
= smb1srv_session_lookup(xconn
,
1515 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
1518 status
= NT_STATUS_OK
;
1521 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1522 (unsigned long long)session_tag
,
1523 (unsigned long long)req
->mid
));
1524 reply_nterror(req
, NT_STATUS_NETWORK_SESSION_EXPIRED
);
1529 if (session_tag
!= xconn
->client
->last_session_id
) {
1530 struct user_struct
*vuser
= NULL
;
1532 xconn
->client
->last_session_id
= session_tag
;
1534 vuser
= session
->compat
;
1537 set_current_user_info(
1538 vuser
->session_info
->unix_info
->sanitized_username
,
1539 vuser
->session_info
->unix_info
->unix_name
,
1540 vuser
->session_info
->info
->domain_name
);
1544 /* Does this call need to be run as the connected user? */
1545 if (flags
& AS_USER
) {
1547 /* Does this call need a valid tree connection? */
1550 * Amazingly, the error code depends on the command
1553 if (type
== SMBntcreateX
) {
1554 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1556 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1561 if (!change_to_user(conn
,session_tag
)) {
1562 DEBUG(0, ("Error: Could not change to user. Removing "
1563 "deferred open, mid=%llu.\n",
1564 (unsigned long long)req
->mid
));
1565 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1569 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1571 /* Does it need write permission? */
1572 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1573 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1577 /* IPC services are limited */
1578 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1579 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1583 /* This call needs to be run as root */
1584 change_to_root_user();
1587 /* load service specific parameters */
1589 if (req
->encrypted
) {
1590 conn
->encrypted_tid
= true;
1591 /* encrypted required from now on. */
1592 conn
->encrypt_level
= SMB_SIGNING_REQUIRED
;
1593 } else if (ENCRYPTION_REQUIRED(conn
)) {
1594 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1595 DEBUG(1,("service[%s] requires encryption"
1596 "%s ACCESS_DENIED. mid=%llu\n",
1597 lp_servicename(talloc_tos(), SNUM(conn
)),
1599 (unsigned long long)req
->mid
));
1600 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1605 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1606 (flags
& (AS_USER
|DO_CHDIR
)
1608 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1611 conn
->num_smb_operations
++;
1615 * Does this protocol need to be run as guest? (Only archane
1616 * messenger service requests have this...)
1618 if (flags
& AS_GUEST
) {
1622 if (!change_to_guest()) {
1623 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1627 raddr
= tsocket_address_inet_addr_string(xconn
->remote_address
,
1629 if (raddr
== NULL
) {
1630 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1635 * Haven't we checked this in smbd_process already???
1638 ok
= allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1639 xconn
->remote_hostname
, raddr
);
1643 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1648 smb_messages
[type
].fn(req
);
1652 /****************************************************************************
1653 Construct a reply to the incoming packet.
1654 ****************************************************************************/
1656 static void construct_reply(struct smbXsrv_connection
*xconn
,
1657 char *inbuf
, int size
, size_t unread_bytes
,
1658 uint32_t seqnum
, bool encrypted
,
1659 struct smb_perfcount_data
*deferred_pcd
)
1661 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
1662 struct smb_request
*req
;
1664 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1665 smb_panic("could not allocate smb_request");
1668 if (!init_smb_request(req
, sconn
, xconn
, (uint8
*)inbuf
, unread_bytes
,
1669 encrypted
, seqnum
)) {
1670 exit_server_cleanly("Invalid SMB request");
1673 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1675 /* we popped this message off the queue - keep original perf data */
1677 req
->pcd
= *deferred_pcd
;
1679 SMB_PERFCOUNT_START(&req
->pcd
);
1680 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1681 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1684 req
->conn
= switch_message(req
->cmd
, req
);
1686 if (req
->outbuf
== NULL
) {
1688 * Request has suspended itself, will come
1693 if (CVAL(req
->outbuf
,0) == 0) {
1694 show_msg((char *)req
->outbuf
);
1696 smb_request_done(req
);
1699 static void construct_reply_chain(struct smbXsrv_connection
*xconn
,
1700 char *inbuf
, int size
, uint32_t seqnum
,
1702 struct smb_perfcount_data
*deferred_pcd
)
1704 struct smb_request
**reqs
= NULL
;
1705 struct smb_request
*req
;
1709 ok
= smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf
, xconn
, encrypted
,
1710 seqnum
, &reqs
, &num_reqs
);
1712 char errbuf
[smb_size
];
1713 error_packet(errbuf
, 0, 0, NT_STATUS_INVALID_PARAMETER
,
1714 __LINE__
, __FILE__
);
1715 if (!srv_send_smb(xconn
, errbuf
, true, seqnum
, encrypted
,
1717 exit_server_cleanly("construct_reply_chain: "
1718 "srv_send_smb failed.");
1724 req
->inbuf
= (uint8_t *)talloc_move(reqs
, &inbuf
);
1726 req
->conn
= switch_message(req
->cmd
, req
);
1728 if (req
->outbuf
== NULL
) {
1730 * Request has suspended itself, will come
1735 smb_request_done(req
);
1739 * To be called from an async SMB handler that is potentially chained
1740 * when it is finished for shipping.
1743 void smb_request_done(struct smb_request
*req
)
1745 struct smb_request
**reqs
= NULL
;
1746 struct smb_request
*first_req
;
1747 size_t i
, num_reqs
, next_index
;
1750 if (req
->chain
== NULL
) {
1756 num_reqs
= talloc_array_length(reqs
);
1758 for (i
=0; i
<num_reqs
; i
++) {
1759 if (reqs
[i
] == req
) {
1763 if (i
== num_reqs
) {
1765 * Invalid chain, should not happen
1767 status
= NT_STATUS_INTERNAL_ERROR
;
1772 while ((next_index
< num_reqs
) && (IVAL(req
->outbuf
, smb_rcls
) == 0)) {
1773 struct smb_request
*next
= reqs
[next_index
];
1774 struct smbXsrv_tcon
*tcon
;
1775 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1777 next
->vuid
= SVAL(req
->outbuf
, smb_uid
);
1778 next
->tid
= SVAL(req
->outbuf
, smb_tid
);
1779 status
= smb1srv_tcon_lookup(req
->xconn
, req
->tid
,
1781 if (NT_STATUS_IS_OK(status
)) {
1782 req
->conn
= tcon
->compat
;
1786 next
->chain_fsp
= req
->chain_fsp
;
1787 next
->inbuf
= req
->inbuf
;
1790 req
->conn
= switch_message(req
->cmd
, req
);
1792 if (req
->outbuf
== NULL
) {
1794 * Request has suspended itself, will come
1802 first_req
= reqs
[0];
1804 for (i
=1; i
<next_index
; i
++) {
1807 ok
= smb_splice_chain(&first_req
->outbuf
, reqs
[i
]->outbuf
);
1809 status
= NT_STATUS_INTERNAL_ERROR
;
1814 SSVAL(first_req
->outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
1815 SSVAL(first_req
->outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
1818 * This scary statement intends to set the
1819 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1820 * to the value last_req->outbuf carries
1822 SSVAL(first_req
->outbuf
, smb_flg2
,
1823 (SVAL(first_req
->outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
1824 |(SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
1827 * Transfer the error codes from the subrequest to the main one
1829 SSVAL(first_req
->outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
1830 SSVAL(first_req
->outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
1833 first_req
->outbuf
, talloc_get_size(first_req
->outbuf
) - 4);
1836 if (!srv_send_smb(first_req
->xconn
,
1837 (char *)first_req
->outbuf
,
1838 true, first_req
->seqnum
+1,
1839 IS_CONN_ENCRYPTED(req
->conn
)||first_req
->encrypted
,
1841 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1844 TALLOC_FREE(req
); /* non-chained case */
1845 TALLOC_FREE(reqs
); /* chained case */
1850 char errbuf
[smb_size
];
1851 error_packet(errbuf
, 0, 0, status
, __LINE__
, __FILE__
);
1852 if (!srv_send_smb(req
->xconn
, errbuf
, true,
1853 req
->seqnum
+1, req
->encrypted
,
1855 exit_server_cleanly("construct_reply_chain: "
1856 "srv_send_smb failed.");
1859 TALLOC_FREE(req
); /* non-chained case */
1860 TALLOC_FREE(reqs
); /* chained case */
1863 /****************************************************************************
1864 Process an smb from the client
1865 ****************************************************************************/
1866 static void process_smb(struct smbXsrv_connection
*xconn
,
1867 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1868 uint32_t seqnum
, bool encrypted
,
1869 struct smb_perfcount_data
*deferred_pcd
)
1871 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
1872 int msg_type
= CVAL(inbuf
,0);
1874 DO_PROFILE_INC(smb_count
);
1876 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1878 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1879 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1881 if (msg_type
!= NBSSmessage
) {
1883 * NetBIOS session request, keepalive, etc.
1885 reply_special(xconn
, (char *)inbuf
, nread
);
1889 if (sconn
->using_smb2
) {
1890 /* At this point we're not really using smb2,
1891 * we make the decision here.. */
1892 if (smbd_is_smb2_header(inbuf
, nread
)) {
1893 const uint8_t *inpdu
= inbuf
+ NBT_HDR_SIZE
;
1894 size_t pdulen
= nread
- NBT_HDR_SIZE
;
1895 smbd_smb2_first_negprot(xconn
, inpdu
, pdulen
);
1897 } else if (nread
>= smb_size
&& valid_smb_header(inbuf
)
1898 && CVAL(inbuf
, smb_com
) != 0x72) {
1899 /* This is a non-negprot SMB1 packet.
1900 Disable SMB2 from now on. */
1901 sconn
->using_smb2
= false;
1905 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1906 * so subtract 4 from it. */
1907 if ((nread
< (smb_size
- 4)) || !valid_smb_header(inbuf
)) {
1908 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1911 /* special magic for immediate exit */
1913 (IVAL(inbuf
, 4) == 0x74697865) &&
1914 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1915 uint8_t exitcode
= CVAL(inbuf
, 8);
1916 DEBUG(1, ("Exiting immediately with code %d\n",
1921 exit_server_cleanly("Non-SMB packet");
1924 show_msg((char *)inbuf
);
1926 if ((unread_bytes
== 0) && smb1_is_chain(inbuf
)) {
1927 construct_reply_chain(xconn
, (char *)inbuf
, nread
,
1928 seqnum
, encrypted
, deferred_pcd
);
1930 construct_reply(xconn
, (char *)inbuf
, nread
, unread_bytes
,
1931 seqnum
, encrypted
, deferred_pcd
);
1937 sconn
->num_requests
++;
1939 /* The timeout_processing function isn't run nearly
1940 often enough to implement 'max log size' without
1941 overrunning the size of the file by many megabytes.
1942 This is especially true if we are running at debug
1943 level 10. Checking every 50 SMBs is a nice
1944 tradeoff of performance vs log file size overrun. */
1946 if ((sconn
->num_requests
% 50) == 0 &&
1947 need_to_check_log_size()) {
1948 change_to_root_user();
1953 /****************************************************************************
1954 Return a string containing the function name of a SMB command.
1955 ****************************************************************************/
1957 const char *smb_fn_name(int type
)
1959 const char *unknown_name
= "SMBunknown";
1961 if (smb_messages
[type
].name
== NULL
)
1962 return(unknown_name
);
1964 return(smb_messages
[type
].name
);
1967 /****************************************************************************
1968 Helper functions for contruct_reply.
1969 ****************************************************************************/
1971 void add_to_common_flags2(uint32 v
)
1976 void remove_from_common_flags2(uint32 v
)
1978 common_flags2
&= ~v
;
1981 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1984 uint16_t in_flags2
= SVAL(inbuf
,smb_flg2
);
1985 uint16_t out_flags2
= common_flags2
;
1987 out_flags2
|= in_flags2
& FLAGS2_UNICODE_STRINGS
;
1988 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
;
1989 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
;
1991 srv_set_message(outbuf
,0,0,false);
1993 SCVAL(outbuf
, smb_com
, req
->cmd
);
1994 SIVAL(outbuf
,smb_rcls
,0);
1995 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1996 SSVAL(outbuf
,smb_flg2
, out_flags2
);
1997 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1998 memcpy(outbuf
+smb_ss_field
, inbuf
+smb_ss_field
, 8);
2000 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
2001 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
2002 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
2003 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
2006 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
2008 construct_reply_common(req
, (const char *)req
->inbuf
, outbuf
);
2012 * @brief Find the smb_cmd offset of the last command pushed
2013 * @param[in] buf The buffer we're building up
2014 * @retval Where can we put our next andx cmd?
2016 * While chaining requests, the "next" request we're looking at needs to put
2017 * its SMB_Command before the data the previous request already built up added
2018 * to the chain. Find the offset to the place where we have to put our cmd.
2021 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
2026 cmd
= CVAL(buf
, smb_com
);
2028 if (!is_andx_req(cmd
)) {
2034 while (CVAL(buf
, ofs
) != 0xff) {
2036 if (!is_andx_req(CVAL(buf
, ofs
))) {
2041 * ofs is from start of smb header, so add the 4 length
2042 * bytes. The next cmd is right after the wct field.
2044 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
2046 if (ofs
+4 >= talloc_get_size(buf
)) {
2056 * @brief Do the smb chaining at a buffer level
2057 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2058 * @param[in] andx_buf Buffer to be appended
2061 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
)
2063 uint8_t smb_command
= CVAL(andx_buf
, smb_com
);
2064 uint8_t wct
= CVAL(andx_buf
, smb_wct
);
2065 const uint16_t *vwv
= (const uint16_t *)(andx_buf
+ smb_vwv
);
2066 uint32_t num_bytes
= smb_buflen(andx_buf
);
2067 const uint8_t *bytes
= (const uint8_t *)smb_buf_const(andx_buf
);
2070 size_t old_size
, new_size
;
2072 size_t chain_padding
= 0;
2073 size_t andx_cmd_ofs
;
2076 old_size
= talloc_get_size(*poutbuf
);
2078 if ((old_size
% 4) != 0) {
2080 * Align the wct field of subsequent requests to a 4-byte
2083 chain_padding
= 4 - (old_size
% 4);
2087 * After the old request comes the new wct field (1 byte), the vwv's
2088 * and the num_bytes field.
2091 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
2092 new_size
+= num_bytes
;
2094 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
2095 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2096 (unsigned)new_size
));
2100 outbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, new_size
);
2101 if (outbuf
== NULL
) {
2102 DEBUG(0, ("talloc failed\n"));
2107 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
2108 DEBUG(1, ("invalid command chain\n"));
2109 *poutbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, old_size
);
2113 if (chain_padding
!= 0) {
2114 memset(outbuf
+ old_size
, 0, chain_padding
);
2115 old_size
+= chain_padding
;
2118 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
2119 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
2124 * Push the chained request:
2129 SCVAL(outbuf
, ofs
, wct
);
2136 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
2141 * Read&X has an offset into its data buffer at
2142 * vwv[6]. reply_read_andx has no idea anymore that it's
2143 * running from within a chain, so we have to fix up the
2146 * Although it looks disgusting at this place, I want to keep
2147 * it here. The alternative would be to push knowledge about
2148 * the andx chain down into read&x again.
2151 if (smb_command
== SMBreadX
) {
2152 uint8_t *bytes_addr
;
2156 * Invalid read&x response
2161 bytes_addr
= outbuf
+ ofs
/* vwv start */
2162 + sizeof(uint16_t) * wct
/* vwv array */
2163 + sizeof(uint16_t) /* bcc */
2164 + 1; /* padding byte */
2166 SSVAL(outbuf
+ ofs
, 6 * sizeof(uint16_t),
2167 bytes_addr
- outbuf
- 4);
2170 ofs
+= sizeof(uint16_t) * wct
;
2176 SSVAL(outbuf
, ofs
, num_bytes
);
2177 ofs
+= sizeof(uint16_t);
2183 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
2188 bool smb1_is_chain(const uint8_t *buf
)
2190 uint8_t cmd
, wct
, andx_cmd
;
2192 cmd
= CVAL(buf
, smb_com
);
2193 if (!is_andx_req(cmd
)) {
2196 wct
= CVAL(buf
, smb_wct
);
2200 andx_cmd
= CVAL(buf
, smb_vwv
);
2201 return (andx_cmd
!= 0xFF);
2204 bool smb1_walk_chain(const uint8_t *buf
,
2205 bool (*fn
)(uint8_t cmd
,
2206 uint8_t wct
, const uint16_t *vwv
,
2207 uint16_t num_bytes
, const uint8_t *bytes
,
2208 void *private_data
),
2211 size_t smblen
= smb_len(buf
);
2212 const char *smb_buf
= smb_base(buf
);
2213 uint8_t cmd
, chain_cmd
;
2215 const uint16_t *vwv
;
2217 const uint8_t *bytes
;
2219 cmd
= CVAL(buf
, smb_com
);
2220 wct
= CVAL(buf
, smb_wct
);
2221 vwv
= (const uint16_t *)(buf
+ smb_vwv
);
2222 num_bytes
= smb_buflen(buf
);
2223 bytes
= (const uint8_t *)smb_buf_const(buf
);
2225 if (!fn(cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2229 if (!is_andx_req(cmd
)) {
2236 chain_cmd
= CVAL(vwv
, 0);
2238 while (chain_cmd
!= 0xff) {
2239 uint32_t chain_offset
; /* uint32_t to avoid overflow */
2240 size_t length_needed
;
2241 ptrdiff_t vwv_offset
;
2243 chain_offset
= SVAL(vwv
+1, 0);
2246 * Check if the client tries to fool us. The chain
2247 * offset needs to point beyond the current request in
2248 * the chain, it needs to strictly grow. Otherwise we
2249 * might be tricked into an endless loop always
2250 * processing the same request over and over again. We
2251 * used to assume that vwv and the byte buffer array
2252 * in a chain are always attached, but OS/2 the
2253 * Write&X/Read&X chain puts the Read&X vwv array
2254 * right behind the Write&X vwv chain. The Write&X bcc
2255 * array is put behind the Read&X vwv array. So now we
2256 * check whether the chain offset points strictly
2257 * behind the previous vwv array. req->buf points
2258 * right after the vwv array of the previous
2260 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2264 vwv_offset
= ((const char *)vwv
- smb_buf
);
2265 if (chain_offset
<= vwv_offset
) {
2270 * Next check: Make sure the chain offset does not
2271 * point beyond the overall smb request length.
2274 length_needed
= chain_offset
+1; /* wct */
2275 if (length_needed
> smblen
) {
2280 * Now comes the pointer magic. Goal here is to set up
2281 * vwv and buf correctly again. The chain offset (the
2282 * former vwv[1]) points at the new wct field.
2285 wct
= CVAL(smb_buf
, chain_offset
);
2287 if (is_andx_req(chain_cmd
) && (wct
< 2)) {
2292 * Next consistency check: Make the new vwv array fits
2293 * in the overall smb request.
2296 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2297 if (length_needed
> smblen
) {
2300 vwv
= (const uint16_t *)(smb_buf
+ chain_offset
+ 1);
2303 * Now grab the new byte buffer....
2306 num_bytes
= SVAL(vwv
+wct
, 0);
2309 * .. and check that it fits.
2312 length_needed
+= num_bytes
;
2313 if (length_needed
> smblen
) {
2316 bytes
= (const uint8_t *)(vwv
+wct
+1);
2318 if (!fn(chain_cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2322 if (!is_andx_req(chain_cmd
)) {
2325 chain_cmd
= CVAL(vwv
, 0);
2330 static bool smb1_chain_length_cb(uint8_t cmd
,
2331 uint8_t wct
, const uint16_t *vwv
,
2332 uint16_t num_bytes
, const uint8_t *bytes
,
2335 unsigned *count
= (unsigned *)private_data
;
2340 unsigned smb1_chain_length(const uint8_t *buf
)
2344 if (!smb1_walk_chain(buf
, smb1_chain_length_cb
, &count
)) {
2350 struct smb1_parse_chain_state
{
2351 TALLOC_CTX
*mem_ctx
;
2353 struct smbd_server_connection
*sconn
;
2354 struct smbXsrv_connection
*xconn
;
2358 struct smb_request
**reqs
;
2362 static bool smb1_parse_chain_cb(uint8_t cmd
,
2363 uint8_t wct
, const uint16_t *vwv
,
2364 uint16_t num_bytes
, const uint8_t *bytes
,
2367 struct smb1_parse_chain_state
*state
=
2368 (struct smb1_parse_chain_state
*)private_data
;
2369 struct smb_request
**reqs
;
2370 struct smb_request
*req
;
2373 reqs
= talloc_realloc(state
->mem_ctx
, state
->reqs
,
2374 struct smb_request
*, state
->num_reqs
+1);
2380 req
= talloc(reqs
, struct smb_request
);
2385 ok
= init_smb_request(req
, state
->sconn
, state
->xconn
, state
->buf
, 0,
2386 state
->encrypted
, state
->seqnum
);
2393 req
->buflen
= num_bytes
;
2396 reqs
[state
->num_reqs
] = req
;
2397 state
->num_reqs
+= 1;
2401 bool smb1_parse_chain(TALLOC_CTX
*mem_ctx
, const uint8_t *buf
,
2402 struct smbXsrv_connection
*xconn
,
2403 bool encrypted
, uint32_t seqnum
,
2404 struct smb_request
***reqs
, unsigned *num_reqs
)
2406 struct smbd_server_connection
*sconn
= NULL
;
2407 struct smb1_parse_chain_state state
;
2410 if (xconn
!= NULL
) {
2411 sconn
= xconn
->client
->sconn
;
2414 state
.mem_ctx
= mem_ctx
;
2416 state
.sconn
= sconn
;
2417 state
.xconn
= xconn
;
2418 state
.encrypted
= encrypted
;
2419 state
.seqnum
= seqnum
;
2423 if (!smb1_walk_chain(buf
, smb1_parse_chain_cb
, &state
)) {
2424 TALLOC_FREE(state
.reqs
);
2427 for (i
=0; i
<state
.num_reqs
; i
++) {
2428 state
.reqs
[i
]->chain
= state
.reqs
;
2431 *num_reqs
= state
.num_reqs
;
2435 /****************************************************************************
2436 Check if services need reloading.
2437 ****************************************************************************/
2439 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2442 if (last_smb_conf_reload_time
== 0) {
2443 last_smb_conf_reload_time
= t
;
2446 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2447 reload_services(sconn
, conn_snum_used
, true);
2448 last_smb_conf_reload_time
= t
;
2452 static bool fd_is_readable(int fd
)
2456 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2458 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2462 static void smbd_server_connection_write_handler(
2463 struct smbXsrv_connection
*xconn
)
2465 /* TODO: make write nonblocking */
2468 static void smbd_server_connection_read_handler(
2469 struct smbXsrv_connection
*xconn
, int fd
)
2471 uint8_t *inbuf
= NULL
;
2472 size_t inbuf_len
= 0;
2473 size_t unread_bytes
= 0;
2474 bool encrypted
= false;
2475 TALLOC_CTX
*mem_ctx
= talloc_tos();
2479 bool async_echo
= lp_async_smb_echo_handler();
2480 bool from_client
= false;
2483 if (fd_is_readable(xconn
->smb1
.echo_handler
.trusted_fd
)) {
2485 * This is the super-ugly hack to prefer the packets
2486 * forwarded by the echo handler over the ones by the
2489 fd
= xconn
->smb1
.echo_handler
.trusted_fd
;
2493 from_client
= (xconn
->transport
.sock
== fd
);
2495 if (async_echo
&& from_client
) {
2496 smbd_lock_socket(xconn
);
2498 if (!fd_is_readable(fd
)) {
2499 DEBUG(10,("the echo listener was faster\n"));
2500 smbd_unlock_socket(xconn
);
2505 /* TODO: make this completely nonblocking */
2506 status
= receive_smb_talloc(mem_ctx
, xconn
, fd
,
2507 (char **)(void *)&inbuf
,
2511 &inbuf_len
, &seqnum
,
2512 !from_client
/* trusted channel */);
2514 if (async_echo
&& from_client
) {
2515 smbd_unlock_socket(xconn
);
2518 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2521 if (NT_STATUS_IS_ERR(status
)) {
2522 exit_server_cleanly("failed to receive smb request");
2524 if (!NT_STATUS_IS_OK(status
)) {
2529 process_smb(xconn
, inbuf
, inbuf_len
, unread_bytes
,
2530 seqnum
, encrypted
, NULL
);
2533 static void smbd_server_connection_handler(struct tevent_context
*ev
,
2534 struct tevent_fd
*fde
,
2538 struct smbXsrv_connection
*xconn
=
2539 talloc_get_type_abort(private_data
,
2540 struct smbXsrv_connection
);
2542 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2544 * we're not supposed to do any io
2546 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
2547 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
2551 if (flags
& TEVENT_FD_WRITE
) {
2552 smbd_server_connection_write_handler(xconn
);
2555 if (flags
& TEVENT_FD_READ
) {
2556 smbd_server_connection_read_handler(xconn
, xconn
->transport
.sock
);
2561 static void smbd_server_echo_handler(struct tevent_context
*ev
,
2562 struct tevent_fd
*fde
,
2566 struct smbXsrv_connection
*xconn
=
2567 talloc_get_type_abort(private_data
,
2568 struct smbXsrv_connection
);
2570 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2572 * we're not supposed to do any io
2574 TEVENT_FD_NOT_READABLE(xconn
->smb1
.echo_handler
.trusted_fde
);
2575 TEVENT_FD_NOT_WRITEABLE(xconn
->smb1
.echo_handler
.trusted_fde
);
2579 if (flags
& TEVENT_FD_WRITE
) {
2580 smbd_server_connection_write_handler(xconn
);
2583 if (flags
& TEVENT_FD_READ
) {
2584 smbd_server_connection_read_handler(
2585 xconn
, xconn
->smb1
.echo_handler
.trusted_fd
);
2590 struct smbd_release_ip_state
{
2591 struct smbXsrv_connection
*xconn
;
2592 struct tevent_immediate
*im
;
2593 char addr
[INET6_ADDRSTRLEN
];
2596 static void smbd_release_ip_immediate(struct tevent_context
*ctx
,
2597 struct tevent_immediate
*im
,
2600 struct smbd_release_ip_state
*state
=
2601 talloc_get_type_abort(private_data
,
2602 struct smbd_release_ip_state
);
2603 struct smbXsrv_connection
*xconn
= state
->xconn
;
2605 if (!NT_STATUS_EQUAL(xconn
->transport
.status
, NT_STATUS_ADDRESS_CLOSED
)) {
2607 * smbd_server_connection_terminate() already triggered ?
2612 smbd_server_connection_terminate(xconn
, "CTDB_SRVID_RELEASE_IP");
2615 /****************************************************************************
2616 received when we should release a specific IP
2617 ****************************************************************************/
2618 static bool release_ip(const char *ip
, void *priv
)
2620 struct smbd_release_ip_state
*state
=
2621 talloc_get_type_abort(priv
,
2622 struct smbd_release_ip_state
);
2623 struct smbXsrv_connection
*xconn
= state
->xconn
;
2624 const char *addr
= state
->addr
;
2625 const char *p
= addr
;
2627 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2628 /* avoid recursion */
2632 if (strncmp("::ffff:", addr
, 7) == 0) {
2636 DEBUG(10, ("Got release IP message for %s, "
2637 "our address is %s\n", ip
, p
));
2639 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2640 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2643 * With SMB2 we should do a clean disconnect,
2644 * the previous_session_id in the session setup
2645 * will cleanup the old session, tcons and opens.
2647 * A clean disconnect is needed in order to support
2650 * Note: typically this is never triggered
2651 * as we got a TCP RST (triggered by ctdb event scripts)
2652 * before we get CTDB_SRVID_RELEASE_IP.
2654 * We used to call _exit(1) here, but as this was mostly never
2655 * triggered and has implication on our process model,
2656 * we can just use smbd_server_connection_terminate()
2659 * We don't call smbd_server_connection_terminate() directly
2660 * as we might be called from within ctdbd_migrate(),
2661 * we need to defer our action to the next event loop
2663 tevent_schedule_immediate(state
->im
, xconn
->ev_ctx
,
2664 smbd_release_ip_immediate
, state
);
2667 * Make sure we don't get any io on the connection.
2669 xconn
->transport
.status
= NT_STATUS_ADDRESS_CLOSED
;
2676 static NTSTATUS
smbd_register_ips(struct smbXsrv_connection
*xconn
,
2677 struct sockaddr_storage
*srv
,
2678 struct sockaddr_storage
*clnt
)
2680 struct smbd_release_ip_state
*state
;
2681 struct ctdbd_connection
*cconn
;
2683 cconn
= messaging_ctdbd_connection();
2684 if (cconn
== NULL
) {
2685 return NT_STATUS_NO_MEMORY
;
2688 state
= talloc_zero(xconn
, struct smbd_release_ip_state
);
2689 if (state
== NULL
) {
2690 return NT_STATUS_NO_MEMORY
;
2692 state
->xconn
= xconn
;
2693 state
->im
= tevent_create_immediate(state
);
2694 if (state
->im
== NULL
) {
2695 return NT_STATUS_NO_MEMORY
;
2697 if (print_sockaddr(state
->addr
, sizeof(state
->addr
), srv
) == NULL
) {
2698 return NT_STATUS_NO_MEMORY
;
2701 return ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, state
);
2704 static void msg_kill_client_ip(struct messaging_context
*msg_ctx
,
2705 void *private_data
, uint32_t msg_type
,
2706 struct server_id server_id
, DATA_BLOB
*data
)
2708 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2709 private_data
, struct smbd_server_connection
);
2710 const char *ip
= (char *) data
->data
;
2713 DEBUG(10, ("Got kill request for client IP %s\n", ip
));
2715 client_ip
= tsocket_address_inet_addr_string(sconn
->remote_address
,
2717 if (client_ip
== NULL
) {
2721 if (strequal(ip
, client_ip
)) {
2722 DEBUG(1, ("Got kill client message for %s - "
2723 "exiting immediately\n", ip
));
2724 exit_server_cleanly("Forced disconnect for client");
2727 TALLOC_FREE(client_ip
);
2731 * Send keepalive packets to our client
2733 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2735 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2736 private_data
, struct smbd_server_connection
);
2737 struct smbXsrv_connection
*xconn
= NULL
;
2740 if (sconn
->using_smb2
) {
2741 /* Don't do keepalives on an SMB2 connection. */
2746 * With SMB1 we only have 1 connection
2748 xconn
= sconn
->client
->connections
;
2749 smbd_lock_socket(xconn
);
2750 ret
= send_keepalive(xconn
->transport
.sock
);
2751 smbd_unlock_socket(xconn
);
2754 int saved_errno
= errno
;
2756 * Try and give an error message saying what
2759 DEBUG(0, ("send_keepalive failed for client %s. "
2760 "Error %s - exiting\n",
2761 smbXsrv_connection_dbg(xconn
),
2762 strerror(saved_errno
)));
2763 errno
= saved_errno
;
2770 * Do the recurring check if we're idle
2772 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2774 struct smbd_server_connection
*sconn
=
2775 (struct smbd_server_connection
*)private_data
;
2777 if ((conn_num_open(sconn
) == 0)
2778 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2779 DEBUG( 2, ( "Closing idle connection\n" ) );
2780 messaging_send(sconn
->msg_ctx
,
2781 messaging_server_id(sconn
->msg_ctx
),
2782 MSG_SHUTDOWN
, &data_blob_null
);
2790 * Do the recurring log file and smb.conf reload checks.
2793 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2795 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2796 private_data
, struct smbd_server_connection
);
2798 DEBUG(5, ("housekeeping\n"));
2800 change_to_root_user();
2802 /* update printer queue caches if necessary */
2803 update_monitored_printq_cache(sconn
->msg_ctx
);
2805 /* check if we need to reload services */
2806 check_reload(sconn
, time_mono(NULL
));
2809 * Force a log file check.
2811 force_check_log_size();
2817 * Read an smb packet in the echo handler child, giving the parent
2818 * smbd one second to react once the socket becomes readable.
2821 struct smbd_echo_read_state
{
2822 struct tevent_context
*ev
;
2823 struct smbXsrv_connection
*xconn
;
2830 static void smbd_echo_read_readable(struct tevent_req
*subreq
);
2831 static void smbd_echo_read_waited(struct tevent_req
*subreq
);
2833 static struct tevent_req
*smbd_echo_read_send(
2834 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2835 struct smbXsrv_connection
*xconn
)
2837 struct tevent_req
*req
, *subreq
;
2838 struct smbd_echo_read_state
*state
;
2840 req
= tevent_req_create(mem_ctx
, &state
,
2841 struct smbd_echo_read_state
);
2846 state
->xconn
= xconn
;
2848 subreq
= wait_for_read_send(state
, ev
, xconn
->transport
.sock
);
2849 if (tevent_req_nomem(subreq
, req
)) {
2850 return tevent_req_post(req
, ev
);
2852 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2856 static void smbd_echo_read_readable(struct tevent_req
*subreq
)
2858 struct tevent_req
*req
= tevent_req_callback_data(
2859 subreq
, struct tevent_req
);
2860 struct smbd_echo_read_state
*state
= tevent_req_data(
2861 req
, struct smbd_echo_read_state
);
2865 ok
= wait_for_read_recv(subreq
, &err
);
2866 TALLOC_FREE(subreq
);
2868 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
2873 * Give the parent smbd one second to step in
2876 subreq
= tevent_wakeup_send(
2877 state
, state
->ev
, timeval_current_ofs(1, 0));
2878 if (tevent_req_nomem(subreq
, req
)) {
2881 tevent_req_set_callback(subreq
, smbd_echo_read_waited
, req
);
2884 static void smbd_echo_read_waited(struct tevent_req
*subreq
)
2886 struct tevent_req
*req
= tevent_req_callback_data(
2887 subreq
, struct tevent_req
);
2888 struct smbd_echo_read_state
*state
= tevent_req_data(
2889 req
, struct smbd_echo_read_state
);
2890 struct smbXsrv_connection
*xconn
= state
->xconn
;
2896 ok
= tevent_wakeup_recv(subreq
);
2897 TALLOC_FREE(subreq
);
2899 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2903 ok
= smbd_lock_socket_internal(xconn
);
2905 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2906 DEBUG(0, ("%s: failed to lock socket\n", __location__
));
2910 if (!fd_is_readable(xconn
->transport
.sock
)) {
2911 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2914 ok
= smbd_unlock_socket_internal(xconn
);
2916 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2917 DEBUG(1, ("%s: failed to unlock socket\n",
2922 subreq
= wait_for_read_send(state
, state
->ev
,
2923 xconn
->transport
.sock
);
2924 if (tevent_req_nomem(subreq
, req
)) {
2927 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2931 status
= receive_smb_talloc(state
, xconn
,
2932 xconn
->transport
.sock
,
2939 false /* trusted_channel*/);
2941 if (tevent_req_nterror(req
, status
)) {
2942 tevent_req_nterror(req
, status
);
2943 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2944 (int)getpid(), nt_errstr(status
)));
2948 ok
= smbd_unlock_socket_internal(xconn
);
2950 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2951 DEBUG(1, ("%s: failed to unlock socket\n", __location__
));
2954 tevent_req_done(req
);
2957 static NTSTATUS
smbd_echo_read_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2958 char **pbuf
, size_t *pbuflen
, uint32_t *pseqnum
)
2960 struct smbd_echo_read_state
*state
= tevent_req_data(
2961 req
, struct smbd_echo_read_state
);
2964 if (tevent_req_is_nterror(req
, &status
)) {
2967 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
2968 *pbuflen
= state
->buflen
;
2969 *pseqnum
= state
->seqnum
;
2970 return NT_STATUS_OK
;
2973 struct smbd_echo_state
{
2974 struct tevent_context
*ev
;
2975 struct iovec
*pending
;
2976 struct smbd_server_connection
*sconn
;
2977 struct smbXsrv_connection
*xconn
;
2980 struct tevent_fd
*parent_fde
;
2982 struct tevent_req
*write_req
;
2985 static void smbd_echo_writer_done(struct tevent_req
*req
);
2987 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2991 if (state
->write_req
!= NULL
) {
2995 num_pending
= talloc_array_length(state
->pending
);
2996 if (num_pending
== 0) {
3000 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
3001 state
->parent_pipe
, false,
3002 state
->pending
, num_pending
);
3003 if (state
->write_req
== NULL
) {
3004 DEBUG(1, ("writev_send failed\n"));
3008 talloc_steal(state
->write_req
, state
->pending
);
3009 state
->pending
= NULL
;
3011 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
3015 static void smbd_echo_writer_done(struct tevent_req
*req
)
3017 struct smbd_echo_state
*state
= tevent_req_callback_data(
3018 req
, struct smbd_echo_state
);
3022 written
= writev_recv(req
, &err
);
3024 state
->write_req
= NULL
;
3025 if (written
== -1) {
3026 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
3029 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3030 smbd_echo_activate_writer(state
);
3033 static bool smbd_echo_reply(struct smbd_echo_state
*state
,
3034 uint8_t *inbuf
, size_t inbuf_len
,
3037 struct smb_request req
;
3038 uint16_t num_replies
;
3042 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == NBSSkeepalive
)) {
3043 DEBUG(10, ("Got netbios keepalive\n"));
3050 if (inbuf_len
< smb_size
) {
3051 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
3054 if (!valid_smb_header(inbuf
)) {
3055 DEBUG(10, ("Got invalid SMB header\n"));
3059 if (!init_smb_request(&req
, state
->sconn
, state
->xconn
, inbuf
, 0, false,
3065 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
3066 smb_messages
[req
.cmd
].name
3067 ? smb_messages
[req
.cmd
].name
: "unknown"));
3069 if (req
.cmd
!= SMBecho
) {
3076 num_replies
= SVAL(req
.vwv
+0, 0);
3077 if (num_replies
!= 1) {
3078 /* Not a Windows "Hey, you're still there?" request */
3082 if (!create_outbuf(talloc_tos(), &req
, (const char *)req
.inbuf
, &outbuf
,
3084 DEBUG(10, ("create_outbuf failed\n"));
3087 req
.outbuf
= (uint8_t *)outbuf
;
3089 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
3091 if (req
.buflen
> 0) {
3092 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
3095 ok
= srv_send_smb(req
.xconn
,
3099 TALLOC_FREE(outbuf
);
3107 static void smbd_echo_exit(struct tevent_context
*ev
,
3108 struct tevent_fd
*fde
, uint16_t flags
,
3111 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3115 static void smbd_echo_got_packet(struct tevent_req
*req
);
3117 static void smbd_echo_loop(struct smbXsrv_connection
*xconn
,
3120 struct smbd_echo_state
*state
;
3121 struct tevent_req
*read_req
;
3123 state
= talloc_zero(xconn
, struct smbd_echo_state
);
3124 if (state
== NULL
) {
3125 DEBUG(1, ("talloc failed\n"));
3128 state
->xconn
= xconn
;
3129 state
->parent_pipe
= parent_pipe
;
3130 state
->ev
= s3_tevent_context_init(state
);
3131 if (state
->ev
== NULL
) {
3132 DEBUG(1, ("tevent_context_init failed\n"));
3136 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
3137 TEVENT_FD_READ
, smbd_echo_exit
,
3139 if (state
->parent_fde
== NULL
) {
3140 DEBUG(1, ("tevent_add_fd failed\n"));
3145 read_req
= smbd_echo_read_send(state
, state
->ev
, xconn
);
3146 if (read_req
== NULL
) {
3147 DEBUG(1, ("smbd_echo_read_send failed\n"));
3151 tevent_req_set_callback(read_req
, smbd_echo_got_packet
, state
);
3154 if (tevent_loop_once(state
->ev
) == -1) {
3155 DEBUG(1, ("tevent_loop_once failed: %s\n",
3163 static void smbd_echo_got_packet(struct tevent_req
*req
)
3165 struct smbd_echo_state
*state
= tevent_req_callback_data(
3166 req
, struct smbd_echo_state
);
3170 uint32_t seqnum
= 0;
3173 status
= smbd_echo_read_recv(req
, state
, &buf
, &buflen
, &seqnum
);
3175 if (!NT_STATUS_IS_OK(status
)) {
3176 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3177 nt_errstr(status
)));
3181 reply
= smbd_echo_reply(state
, (uint8_t *)buf
, buflen
, seqnum
);
3187 num_pending
= talloc_array_length(state
->pending
);
3188 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
3191 DEBUG(1, ("talloc_realloc failed\n"));
3194 state
->pending
= tmp
;
3196 if (buflen
>= smb_size
) {
3198 * place the seqnum in the packet so that the main process
3199 * can reply with signing
3201 SIVAL(buf
, smb_ss_field
, seqnum
);
3202 SIVAL(buf
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
3205 iov
= &state
->pending
[num_pending
];
3206 iov
->iov_base
= talloc_move(state
->pending
, &buf
);
3207 iov
->iov_len
= buflen
;
3209 DEBUG(10,("echo_handler[%d]: forward to main\n",
3211 smbd_echo_activate_writer(state
);
3214 req
= smbd_echo_read_send(state
, state
->ev
, state
->xconn
);
3216 DEBUG(1, ("smbd_echo_read_send failed\n"));
3219 tevent_req_set_callback(req
, smbd_echo_got_packet
, state
);
3224 * Handle SMBecho requests in a forked child process
3226 bool fork_echo_handler(struct smbXsrv_connection
*xconn
)
3228 int listener_pipe
[2];
3231 bool use_mutex
= false;
3233 res
= pipe(listener_pipe
);
3235 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
3239 #ifdef HAVE_ROBUST_MUTEXES
3240 use_mutex
= tdb_runtime_check_for_robust_mutexes();
3243 pthread_mutexattr_t a
;
3245 xconn
->smb1
.echo_handler
.socket_mutex
=
3246 anonymous_shared_allocate(sizeof(pthread_mutex_t
));
3247 if (xconn
->smb1
.echo_handler
.socket_mutex
== NULL
) {
3248 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3253 res
= pthread_mutexattr_init(&a
);
3255 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3259 res
= pthread_mutexattr_settype(&a
, PTHREAD_MUTEX_ERRORCHECK
);
3261 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3263 pthread_mutexattr_destroy(&a
);
3266 res
= pthread_mutexattr_setpshared(&a
, PTHREAD_PROCESS_SHARED
);
3268 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3270 pthread_mutexattr_destroy(&a
);
3273 res
= pthread_mutexattr_setrobust(&a
, PTHREAD_MUTEX_ROBUST
);
3275 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3276 "%s\n", strerror(res
)));
3277 pthread_mutexattr_destroy(&a
);
3280 res
= pthread_mutex_init(xconn
->smb1
.echo_handler
.socket_mutex
,
3282 pthread_mutexattr_destroy(&a
);
3284 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3292 xconn
->smb1
.echo_handler
.socket_lock_fd
=
3293 create_unlink_tmp(lp_lock_directory());
3294 if (xconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
3295 DEBUG(1, ("Could not create lock fd: %s\n",
3305 close(listener_pipe
[0]);
3306 set_blocking(listener_pipe
[1], false);
3308 status
= reinit_after_fork(xconn
->msg_ctx
,
3311 if (!NT_STATUS_IS_OK(status
)) {
3312 DEBUG(1, ("reinit_after_fork failed: %s\n",
3313 nt_errstr(status
)));
3316 smbd_echo_loop(xconn
, listener_pipe
[1]);
3319 close(listener_pipe
[1]);
3320 listener_pipe
[1] = -1;
3321 xconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
3323 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child
));
3326 * Without smb signing this is the same as the normal smbd
3327 * listener. This needs to change once signing comes in.
3329 xconn
->smb1
.echo_handler
.trusted_fde
= tevent_add_fd(xconn
->ev_ctx
,
3331 xconn
->smb1
.echo_handler
.trusted_fd
,
3333 smbd_server_echo_handler
,
3335 if (xconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
3336 DEBUG(1, ("event_add_fd failed\n"));
3343 if (listener_pipe
[0] != -1) {
3344 close(listener_pipe
[0]);
3346 if (listener_pipe
[1] != -1) {
3347 close(listener_pipe
[1]);
3349 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
3350 close(xconn
->smb1
.echo_handler
.socket_lock_fd
);
3352 #ifdef HAVE_ROBUST_MUTEXES
3353 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
3354 pthread_mutex_destroy(xconn
->smb1
.echo_handler
.socket_mutex
);
3355 anonymous_shared_free(xconn
->smb1
.echo_handler
.socket_mutex
);
3358 smbd_echo_init(xconn
);
3363 static bool uid_in_use(const struct user_struct
*user
, uid_t uid
)
3366 if (user
->session_info
&&
3367 (user
->session_info
->unix_token
->uid
== uid
)) {
3375 static bool gid_in_use(const struct user_struct
*user
, gid_t gid
)
3378 if (user
->session_info
!= NULL
) {
3380 struct security_unix_token
*utok
;
3382 utok
= user
->session_info
->unix_token
;
3383 if (utok
->gid
== gid
) {
3386 for(i
=0; i
<utok
->ngroups
; i
++) {
3387 if (utok
->groups
[i
] == gid
) {
3397 static bool sid_in_use(const struct user_struct
*user
,
3398 const struct dom_sid
*psid
)
3401 struct security_token
*tok
;
3403 if (user
->session_info
== NULL
) {
3406 tok
= user
->session_info
->security_token
;
3409 * Not sure session_info->security_token can
3410 * ever be NULL. This check might be not
3415 if (security_token_has_sid(tok
, psid
)) {
3423 static bool id_in_use(const struct user_struct
*user
,
3424 const struct id_cache_ref
*id
)
3428 return uid_in_use(user
, id
->id
.uid
);
3430 return gid_in_use(user
, id
->id
.gid
);
3432 return sid_in_use(user
, &id
->id
.sid
);
3439 static void smbd_id_cache_kill(struct messaging_context
*msg_ctx
,
3442 struct server_id server_id
,
3445 const char *msg
= (data
&& data
->data
)
3446 ? (const char *)data
->data
: "<NULL>";
3447 struct id_cache_ref id
;
3448 struct smbd_server_connection
*sconn
=
3449 talloc_get_type_abort(private_data
,
3450 struct smbd_server_connection
);
3452 if (!id_cache_ref_parse(msg
, &id
)) {
3453 DEBUG(0, ("Invalid ?ID: %s\n", msg
));
3457 if (id_in_use(sconn
->users
, &id
)) {
3458 exit_server_cleanly(msg
);
3460 id_cache_delete_from_cache(&id
);
3463 NTSTATUS
smbXsrv_connection_init_tables(struct smbXsrv_connection
*conn
,
3464 enum protocol_types protocol
)
3468 set_Protocol(protocol
);
3469 conn
->protocol
= protocol
;
3471 if (protocol
>= PROTOCOL_SMB2_02
) {
3472 status
= smb2srv_session_table_init(conn
);
3473 if (!NT_STATUS_IS_OK(status
)) {
3477 status
= smb2srv_open_table_init(conn
);
3478 if (!NT_STATUS_IS_OK(status
)) {
3482 status
= smb1srv_session_table_init(conn
);
3483 if (!NT_STATUS_IS_OK(status
)) {
3487 status
= smb1srv_tcon_table_init(conn
);
3488 if (!NT_STATUS_IS_OK(status
)) {
3492 status
= smb1srv_open_table_init(conn
);
3493 if (!NT_STATUS_IS_OK(status
)) {
3498 return NT_STATUS_OK
;
3501 struct smbd_tevent_trace_state
{
3503 uint64_t smbd_idle_profstamp
;
3506 static void smbd_tevent_trace_callback(enum tevent_trace_point point
,
3509 struct smbd_tevent_trace_state
*state
=
3510 (struct smbd_tevent_trace_state
*)private_data
;
3513 case TEVENT_TRACE_BEFORE_WAIT
:
3515 * This just removes compiler warning
3516 * without profile support
3518 state
->smbd_idle_profstamp
= 0;
3519 START_PROFILE_STAMP(smbd_idle
, state
->smbd_idle_profstamp
);
3521 case TEVENT_TRACE_AFTER_WAIT
:
3522 END_PROFILE_STAMP(smbd_idle
, state
->smbd_idle_profstamp
);
3524 case TEVENT_TRACE_BEFORE_LOOP_ONCE
:
3525 TALLOC_FREE(state
->frame
);
3526 state
->frame
= talloc_stackframe_pool(8192);
3528 case TEVENT_TRACE_AFTER_LOOP_ONCE
:
3529 TALLOC_FREE(state
->frame
);
3537 * Create a debug string for the connection
3539 * This is allocated to talloc_tos() or a string constant
3540 * in certain corner cases. The returned string should
3541 * hence not be free'd directly but only via the talloc stack.
3543 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection
*xconn
)
3548 * TODO: this can be improved later
3549 * maybe including the client guid or more
3551 ret
= tsocket_address_string(xconn
->remote_address
, talloc_tos());
3553 return "<tsocket_address_string() failed>";
3559 NTSTATUS
smbd_add_connection(struct smbXsrv_client
*client
, int sock_fd
,
3560 struct smbXsrv_connection
**_xconn
)
3562 TALLOC_CTX
*frame
= talloc_stackframe();
3563 struct smbXsrv_connection
*xconn
;
3564 struct sockaddr_storage ss_srv
;
3565 void *sp_srv
= (void *)&ss_srv
;
3566 struct sockaddr
*sa_srv
= (struct sockaddr
*)sp_srv
;
3567 struct sockaddr_storage ss_clnt
;
3568 void *sp_clnt
= (void *)&ss_clnt
;
3569 struct sockaddr
*sa_clnt
= (struct sockaddr
*)sp_clnt
;
3570 socklen_t sa_socklen
;
3571 struct tsocket_address
*local_address
= NULL
;
3572 struct tsocket_address
*remote_address
= NULL
;
3573 const char *remaddr
= NULL
;
3575 const char *rhost
= NULL
;
3581 xconn
= talloc_zero(client
, struct smbXsrv_connection
);
3582 if (xconn
== NULL
) {
3583 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3585 return NT_STATUS_NO_MEMORY
;
3587 talloc_steal(frame
, xconn
);
3589 xconn
->ev_ctx
= client
->ev_ctx
;
3590 xconn
->msg_ctx
= client
->msg_ctx
;
3591 xconn
->transport
.sock
= sock_fd
;
3592 smbd_echo_init(xconn
);
3593 xconn
->protocol
= PROTOCOL_NONE
;
3595 /* Ensure child is set to blocking mode */
3596 set_blocking(sock_fd
,True
);
3598 set_socket_options(sock_fd
, "SO_KEEPALIVE");
3599 set_socket_options(sock_fd
, lp_socket_options());
3601 sa_socklen
= sizeof(ss_clnt
);
3602 ret
= getpeername(sock_fd
, sa_clnt
, &sa_socklen
);
3604 int saved_errno
= errno
;
3605 int level
= (errno
== ENOTCONN
)?2:0;
3606 DEBUG(level
,("getpeername() failed - %s\n",
3607 strerror(saved_errno
)));
3609 return map_nt_error_from_unix_common(saved_errno
);
3611 ret
= tsocket_address_bsd_from_sockaddr(xconn
,
3612 sa_clnt
, sa_socklen
,
3615 int saved_errno
= errno
;
3616 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3617 __location__
, strerror(saved_errno
)));
3619 return map_nt_error_from_unix_common(saved_errno
);
3622 sa_socklen
= sizeof(ss_srv
);
3623 ret
= getsockname(sock_fd
, sa_srv
, &sa_socklen
);
3625 int saved_errno
= errno
;
3626 int level
= (errno
== ENOTCONN
)?2:0;
3627 DEBUG(level
,("getsockname() failed - %s\n",
3628 strerror(saved_errno
)));
3630 return map_nt_error_from_unix_common(saved_errno
);
3632 ret
= tsocket_address_bsd_from_sockaddr(xconn
,
3636 int saved_errno
= errno
;
3637 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3638 __location__
, strerror(saved_errno
)));
3640 return map_nt_error_from_unix_common(saved_errno
);
3643 if (tsocket_address_is_inet(remote_address
, "ip")) {
3644 remaddr
= tsocket_address_inet_addr_string(remote_address
,
3646 if (remaddr
== NULL
) {
3647 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3648 __location__
, strerror(errno
)));
3650 return NT_STATUS_NO_MEMORY
;
3653 remaddr
= "0.0.0.0";
3657 * Before the first packet, check the global hosts allow/ hosts deny
3658 * parameters before doing any parsing of packets passed to us by the
3659 * client. This prevents attacks on our parsing code from hosts not in
3660 * the hosts allow list.
3663 ret
= get_remote_hostname(remote_address
,
3666 int saved_errno
= errno
;
3667 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3668 __location__
, strerror(saved_errno
)));
3670 return map_nt_error_from_unix_common(saved_errno
);
3673 if (strequal(rhost
, "UNKNOWN")) {
3677 xconn
->local_address
= local_address
;
3678 xconn
->remote_address
= remote_address
;
3679 xconn
->remote_hostname
= talloc_strdup(xconn
, rhost
);
3680 if (xconn
->remote_hostname
== NULL
) {
3681 return NT_STATUS_NO_MEMORY
;
3684 if (!srv_init_signing(xconn
)) {
3685 DEBUG(0, ("Failed to init smb_signing\n"));
3687 return NT_STATUS_INTERNAL_ERROR
;
3690 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3691 xconn
->remote_hostname
,
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())));
3698 * We return a valid xconn
3699 * so that the caller can return an error message
3702 client
->connections
= xconn
;
3703 xconn
->client
= client
;
3704 talloc_steal(client
, xconn
);
3708 return NT_STATUS_NETWORK_ACCESS_DENIED
;
3711 DEBUG(10, ("Connection allowed from %s to %s\n",
3712 tsocket_address_string(remote_address
, talloc_tos()),
3713 tsocket_address_string(local_address
, talloc_tos())));
3715 if (lp_clustering()) {
3717 * We need to tell ctdb about our client's TCP
3718 * connection, so that for failover ctdbd can send
3719 * tickle acks, triggering a reconnection by the
3724 status
= smbd_register_ips(xconn
, &ss_srv
, &ss_clnt
);
3725 if (!NT_STATUS_IS_OK(status
)) {
3726 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3727 nt_errstr(status
)));
3731 tmp
= lp_max_xmit();
3732 tmp
= MAX(tmp
, SMB_BUFFER_SIZE_MIN
);
3733 tmp
= MIN(tmp
, SMB_BUFFER_SIZE_MAX
);
3735 xconn
->smb1
.negprot
.max_recv
= tmp
;
3737 xconn
->smb1
.sessions
.done_sesssetup
= false;
3738 xconn
->smb1
.sessions
.max_send
= SMB_BUFFER_SIZE_MAX
;
3740 xconn
->transport
.fde
= tevent_add_fd(client
->ev_ctx
,
3744 smbd_server_connection_handler
,
3746 if (!xconn
->transport
.fde
) {
3748 return NT_STATUS_NO_MEMORY
;
3751 /* for now we only have one connection */
3752 DLIST_ADD_END(client
->connections
, xconn
, NULL
);
3753 xconn
->client
= client
;
3754 talloc_steal(client
, xconn
);
3758 return NT_STATUS_OK
;
3761 /****************************************************************************
3762 Process commands from the client
3763 ****************************************************************************/
3765 void smbd_process(struct tevent_context
*ev_ctx
,
3766 struct messaging_context
*msg_ctx
,
3770 struct smbd_tevent_trace_state trace_state
= {
3771 .frame
= talloc_stackframe(),
3773 struct smbXsrv_client
*client
= NULL
;
3774 struct smbd_server_connection
*sconn
= NULL
;
3775 struct smbXsrv_connection
*xconn
= NULL
;
3776 const char *locaddr
= NULL
;
3777 const char *remaddr
= NULL
;
3781 client
= talloc_zero(ev_ctx
, struct smbXsrv_client
);
3782 if (client
== NULL
) {
3783 DEBUG(0,("talloc_zero(struct smbXsrv_client)\n"));
3784 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3788 * TODO: remove this...:-)
3790 global_smbXsrv_client
= client
;
3792 client
->ev_ctx
= ev_ctx
;
3793 client
->msg_ctx
= msg_ctx
;
3795 sconn
= talloc_zero(client
, struct smbd_server_connection
);
3796 if (sconn
== NULL
) {
3797 exit_server("failed to create smbd_server_connection");
3800 client
->sconn
= sconn
;
3801 sconn
->client
= client
;
3803 sconn
->ev_ctx
= ev_ctx
;
3804 sconn
->msg_ctx
= msg_ctx
;
3806 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02
) {
3808 * We're not making the decision here,
3809 * we're just allowing the client
3810 * to decide between SMB1 and SMB2
3811 * with the first negprot
3814 sconn
->using_smb2
= true;
3818 smbd_setup_sig_term_handler(sconn
);
3819 smbd_setup_sig_hup_handler(sconn
);
3821 if (!serverid_register(messaging_server_id(msg_ctx
),
3822 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
3824 |FLAG_MSG_PRINT_GENERAL
)) {
3825 exit_server_cleanly("Could not register myself in "
3830 status
= smbd_add_connection(client
, sock_fd
, &xconn
);
3831 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3833 * send a negative session response "not listening on calling
3836 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3837 (void)srv_send_smb(xconn
,(char *)buf
, false,
3839 exit_server_cleanly("connection denied");
3840 } else if (!NT_STATUS_IS_OK(status
)) {
3841 exit_server_cleanly(nt_errstr(status
));
3844 sconn
->local_address
=
3845 tsocket_address_copy(xconn
->local_address
, sconn
);
3846 if (sconn
->local_address
== NULL
) {
3847 exit_server_cleanly("tsocket_address_copy() failed");
3849 sconn
->remote_address
=
3850 tsocket_address_copy(xconn
->remote_address
, sconn
);
3851 if (sconn
->remote_address
== NULL
) {
3852 exit_server_cleanly("tsocket_address_copy() failed");
3854 sconn
->remote_hostname
=
3855 talloc_strdup(sconn
, xconn
->remote_hostname
);
3856 if (sconn
->remote_hostname
== NULL
) {
3857 exit_server_cleanly("tsocket_strdup() failed");
3860 if (tsocket_address_is_inet(sconn
->local_address
, "ip")) {
3861 locaddr
= tsocket_address_inet_addr_string(
3862 sconn
->local_address
,
3864 if (locaddr
== NULL
) {
3865 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3866 __location__
, strerror(errno
)));
3867 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3870 locaddr
= "0.0.0.0";
3873 if (tsocket_address_is_inet(sconn
->remote_address
, "ip")) {
3874 remaddr
= tsocket_address_inet_addr_string(
3875 sconn
->remote_address
,
3877 if (remaddr
== NULL
) {
3878 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3879 __location__
, strerror(errno
)));
3880 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3883 remaddr
= "0.0.0.0";
3886 /* this is needed so that we get decent entries
3887 in smbstatus for port 445 connects */
3888 set_remote_machine_name(remaddr
, false);
3889 reload_services(sconn
, conn_snum_used
, true);
3890 sub_set_socket_ids(remaddr
,
3891 sconn
->remote_hostname
,
3894 if (lp_preload_modules()) {
3895 smb_load_modules(lp_preload_modules());
3898 smb_perfcount_init();
3900 if (!init_account_policy()) {
3901 exit_server("Could not open account policy tdb.\n");
3904 if (*lp_root_directory(talloc_tos())) {
3905 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3906 DEBUG(0,("Failed to change root to %s\n",
3907 lp_root_directory(talloc_tos())));
3908 exit_server("Failed to chroot()");
3910 if (chdir("/") == -1) {
3911 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3912 exit_server("Failed to chroot()");
3914 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3917 if (!file_init(sconn
)) {
3918 exit_server("file_init() failed");
3922 if (!init_oplocks(sconn
))
3923 exit_server("Failed to init oplocks");
3925 /* register our message handlers */
3926 messaging_register(sconn
->msg_ctx
, sconn
,
3927 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3928 messaging_register(sconn
->msg_ctx
, sconn
,
3929 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3930 messaging_register(sconn
->msg_ctx
, sconn
,
3931 MSG_SMB_FILE_RENAME
, msg_file_was_renamed
);
3933 id_cache_register_msgs(sconn
->msg_ctx
);
3934 messaging_deregister(sconn
->msg_ctx
, ID_CACHE_KILL
, NULL
);
3935 messaging_register(sconn
->msg_ctx
, sconn
,
3936 ID_CACHE_KILL
, smbd_id_cache_kill
);
3938 messaging_deregister(sconn
->msg_ctx
,
3939 MSG_SMB_CONF_UPDATED
, sconn
->ev_ctx
);
3940 messaging_register(sconn
->msg_ctx
, sconn
,
3941 MSG_SMB_CONF_UPDATED
, smbd_conf_updated
);
3943 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_KILL_CLIENT_IP
,
3945 messaging_register(sconn
->msg_ctx
, sconn
,
3946 MSG_SMB_KILL_CLIENT_IP
,
3947 msg_kill_client_ip
);
3949 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_TELL_NUM_CHILDREN
, NULL
);
3952 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3953 * MSGs to all child processes
3955 messaging_deregister(sconn
->msg_ctx
,
3957 messaging_register(sconn
->msg_ctx
, NULL
,
3958 MSG_DEBUG
, debug_message
);
3960 if ((lp_keepalive() != 0)
3961 && !(event_add_idle(ev_ctx
, NULL
,
3962 timeval_set(lp_keepalive(), 0),
3963 "keepalive", keepalive_fn
,
3965 DEBUG(0, ("Could not add keepalive event\n"));
3969 if (!(event_add_idle(ev_ctx
, NULL
,
3970 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3971 "deadtime", deadtime_fn
, sconn
))) {
3972 DEBUG(0, ("Could not add deadtime event\n"));
3976 if (!(event_add_idle(ev_ctx
, NULL
,
3977 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
3978 "housekeeping", housekeeping_fn
, sconn
))) {
3979 DEBUG(0, ("Could not add housekeeping event\n"));
3983 if (!init_dptrs(sconn
)) {
3984 exit_server("init_dptrs() failed");
3987 TALLOC_FREE(trace_state
.frame
);
3989 tevent_set_trace_callback(ev_ctx
, smbd_tevent_trace_callback
,
3992 ret
= tevent_loop_wait(ev_ctx
);
3994 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
3995 " exiting\n", ret
, strerror(errno
)));
3998 TALLOC_FREE(trace_state
.frame
);
4000 exit_server_cleanly(NULL
);
4003 bool req_is_in_chain(const struct smb_request
*req
)
4005 if (req
->vwv
!= (const uint16_t *)(req
->inbuf
+smb_vwv
)) {
4007 * We're right now handling a subsequent request, so we must
4013 if (!is_andx_req(req
->cmd
)) {
4019 * Okay, an illegal request, but definitely not chained :-)
4024 return (CVAL(req
->vwv
+0, 0) != 0xFF);