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 smbd_server_connection
*sconn
)
92 struct smbXsrv_connection
*xconn
= sconn
->conn
;
94 if (!smbd_echo_active(xconn
)) {
98 xconn
->smb1
.echo_handler
.ref_count
++;
100 if (xconn
->smb1
.echo_handler
.ref_count
> 1) {
104 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
106 #ifdef HAVE_ROBUST_MUTEXES
107 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
110 while (ret
== EINTR
) {
111 ret
= pthread_mutex_lock(
112 xconn
->smb1
.echo_handler
.socket_mutex
);
118 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
125 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
130 xconn
->smb1
.echo_handler
.socket_lock_fd
,
131 F_SETLKW
, 0, 0, F_WRLCK
);
132 } while (!ok
&& (errno
== EINTR
));
135 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
140 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
145 void smbd_lock_socket(struct smbd_server_connection
*sconn
)
147 if (!smbd_lock_socket_internal(sconn
)) {
148 exit_server_cleanly("failed to lock socket");
152 static bool smbd_unlock_socket_internal(struct smbd_server_connection
*sconn
)
154 struct smbXsrv_connection
*xconn
= sconn
->conn
;
156 if (!smbd_echo_active(xconn
)) {
160 xconn
->smb1
.echo_handler
.ref_count
--;
162 if (xconn
->smb1
.echo_handler
.ref_count
> 0) {
166 #ifdef HAVE_ROBUST_MUTEXES
167 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
170 while (ret
== EINTR
) {
171 ret
= pthread_mutex_unlock(
172 xconn
->smb1
.echo_handler
.socket_mutex
);
178 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
185 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
190 xconn
->smb1
.echo_handler
.socket_lock_fd
,
191 F_SETLKW
, 0, 0, F_UNLCK
);
192 } while (!ok
&& (errno
== EINTR
));
195 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
200 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
205 void smbd_unlock_socket(struct smbd_server_connection
*sconn
)
207 if (!smbd_unlock_socket_internal(sconn
)) {
208 exit_server_cleanly("failed to unlock socket");
212 /* Accessor function for smb_read_error for smbd functions. */
214 /****************************************************************************
216 ****************************************************************************/
218 bool srv_send_smb(struct smbd_server_connection
*sconn
, char *buffer
,
219 bool do_signing
, uint32_t seqnum
,
221 struct smb_perfcount_data
*pcd
)
223 struct smbXsrv_connection
*xconn
= sconn
->conn
;
226 char *buf_out
= buffer
;
228 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
230 * we're not supposed to do any io
235 smbd_lock_socket(sconn
);
238 /* Sign the outgoing packet if required. */
239 srv_calculate_sign_mac(xconn
, buf_out
, seqnum
);
243 NTSTATUS status
= srv_encrypt_buffer(sconn
, buffer
, &buf_out
);
244 if (!NT_STATUS_IS_OK(status
)) {
245 DEBUG(0, ("send_smb: SMB encryption failed "
246 "on outgoing packet! Error %s\n",
247 nt_errstr(status
) ));
253 len
= smb_len_large(buf_out
) + 4;
255 ret
= write_data(xconn
->transport
.sock
, buf_out
, len
);
257 int saved_errno
= errno
;
259 * Try and give an error message saying what
262 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
263 (int)getpid(), (int)len
,
264 smbXsrv_connection_dbg(xconn
),
265 (int)ret
, strerror(saved_errno
)));
268 srv_free_enc_buffer(sconn
, buf_out
);
272 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
273 srv_free_enc_buffer(sconn
, buf_out
);
275 SMB_PERFCOUNT_END(pcd
);
277 smbd_unlock_socket(sconn
);
281 /*******************************************************************
282 Setup the word count and byte count for a smb message.
283 ********************************************************************/
285 int srv_set_message(char *buf
,
290 if (zero
&& (num_words
|| num_bytes
)) {
291 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
293 SCVAL(buf
,smb_wct
,num_words
);
294 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
295 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
296 return (smb_size
+ num_words
*2 + num_bytes
);
299 static bool valid_smb_header(struct smbd_server_connection
*sconn
,
300 const uint8_t *inbuf
)
302 if (is_encrypted_packet(sconn
, inbuf
)) {
306 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
307 * but it just looks weird to call strncmp for this one.
309 return (IVAL(smb_base(inbuf
), 0) == 0x424D53FF);
312 /* Socket functions for smbd packet processing. */
314 static bool valid_packet_size(size_t len
)
317 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
318 * of header. Don't print the error if this fits.... JRA.
321 if (len
> (LARGE_WRITEX_BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
322 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
323 (unsigned long)len
));
329 static NTSTATUS
read_packet_remainder(int fd
, char *buffer
,
330 unsigned int timeout
, ssize_t len
)
338 status
= read_fd_with_timeout(fd
, buffer
, len
, len
, timeout
, NULL
);
339 if (!NT_STATUS_IS_OK(status
)) {
340 char addr
[INET6_ADDRSTRLEN
];
341 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
343 get_peer_addr(fd
, addr
, sizeof(addr
)),
349 /****************************************************************************
350 Attempt a zerocopy writeX read. We know here that len > smb_size-4
351 ****************************************************************************/
354 * Unfortunately, earlier versions of smbclient/libsmbclient
355 * don't send this "standard" writeX header. I've fixed this
356 * for 3.2 but we'll use the old method with earlier versions.
357 * Windows and CIFSFS at least use this standard size. Not
361 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
362 (2*14) + /* word count (including bcc) */ \
365 static NTSTATUS
receive_smb_raw_talloc_partial_read(TALLOC_CTX
*mem_ctx
,
366 const char lenbuf
[4],
367 struct smbd_server_connection
*sconn
,
370 unsigned int timeout
,
374 /* Size of a WRITEX call (+4 byte len). */
375 char writeX_header
[4 + STANDARD_WRITE_AND_X_HEADER_SIZE
];
376 ssize_t len
= smb_len_large(lenbuf
); /* Could be a UNIX large writeX. */
380 memcpy(writeX_header
, lenbuf
, 4);
382 status
= read_fd_with_timeout(
383 sock
, writeX_header
+ 4,
384 STANDARD_WRITE_AND_X_HEADER_SIZE
,
385 STANDARD_WRITE_AND_X_HEADER_SIZE
,
388 if (!NT_STATUS_IS_OK(status
)) {
389 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
391 tsocket_address_string(sconn
->remote_address
,
398 * Ok - now try and see if this is a possible
402 if (is_valid_writeX_buffer(sconn
, (uint8_t *)writeX_header
)) {
404 * If the data offset is beyond what
405 * we've read, drain the extra bytes.
407 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
410 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
411 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
412 if (drain_socket(sock
, drain
) != drain
) {
413 smb_panic("receive_smb_raw_talloc_partial_read:"
414 " failed to drain pending bytes");
417 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
420 /* Spoof down the length and null out the bcc. */
421 set_message_bcc(writeX_header
, 0);
422 newlen
= smb_len(writeX_header
);
424 /* Copy the header we've written. */
426 *buffer
= (char *)talloc_memdup(mem_ctx
,
428 sizeof(writeX_header
));
430 if (*buffer
== NULL
) {
431 DEBUG(0, ("Could not allocate inbuf of length %d\n",
432 (int)sizeof(writeX_header
)));
433 return NT_STATUS_NO_MEMORY
;
436 /* Work out the remaining bytes. */
437 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
438 *len_ret
= newlen
+ 4;
442 if (!valid_packet_size(len
)) {
443 return NT_STATUS_INVALID_PARAMETER
;
447 * Not a valid writeX call. Just do the standard
451 *buffer
= talloc_array(mem_ctx
, char, len
+4);
453 if (*buffer
== NULL
) {
454 DEBUG(0, ("Could not allocate inbuf of length %d\n",
456 return NT_STATUS_NO_MEMORY
;
459 /* Copy in what we already read. */
462 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
463 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
466 status
= read_packet_remainder(
468 (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
471 if (!NT_STATUS_IS_OK(status
)) {
472 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
482 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
,
483 struct smbd_server_connection
*sconn
,
485 char **buffer
, unsigned int timeout
,
486 size_t *p_unread
, size_t *plen
)
488 struct smbXsrv_connection
*xconn
= sconn
->conn
;
491 int min_recv_size
= lp_min_receive_file_size();
496 status
= read_smb_length_return_keepalive(sock
, lenbuf
, timeout
,
498 if (!NT_STATUS_IS_OK(status
)) {
502 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
503 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
504 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
505 !srv_is_signing_active(xconn
) &&
506 xconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
508 return receive_smb_raw_talloc_partial_read(
509 mem_ctx
, lenbuf
, sconn
, sock
, buffer
, timeout
,
513 if (!valid_packet_size(len
)) {
514 return NT_STATUS_INVALID_PARAMETER
;
518 * The +4 here can't wrap, we've checked the length above already.
521 *buffer
= talloc_array(mem_ctx
, char, len
+4);
523 if (*buffer
== NULL
) {
524 DEBUG(0, ("Could not allocate inbuf of length %d\n",
526 return NT_STATUS_NO_MEMORY
;
529 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
531 status
= read_packet_remainder(sock
, (*buffer
)+4, timeout
, len
);
532 if (!NT_STATUS_IS_OK(status
)) {
540 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
,
541 struct smbd_server_connection
*sconn
,
543 char **buffer
, unsigned int timeout
,
544 size_t *p_unread
, bool *p_encrypted
,
547 bool trusted_channel
)
549 struct smbXsrv_connection
*xconn
= sconn
->conn
;
553 *p_encrypted
= false;
555 status
= receive_smb_raw_talloc(mem_ctx
, sconn
, sock
, buffer
, timeout
,
557 if (!NT_STATUS_IS_OK(status
)) {
558 DEBUG(NT_STATUS_EQUAL(status
, NT_STATUS_END_OF_FILE
)?5:1,
559 ("receive_smb_raw_talloc failed for client %s "
560 "read error = %s.\n",
561 tsocket_address_string(sconn
->remote_address
,
563 nt_errstr(status
)) );
567 if (is_encrypted_packet(sconn
, (uint8_t *)*buffer
)) {
568 status
= srv_decrypt_buffer(sconn
, *buffer
);
569 if (!NT_STATUS_IS_OK(status
)) {
570 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
571 "incoming packet! Error %s\n",
572 nt_errstr(status
) ));
578 /* Check the incoming SMB signature. */
579 if (!srv_check_sign_mac(xconn
, *buffer
, seqnum
, trusted_channel
)) {
580 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
581 "incoming packet!\n"));
582 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
590 * Initialize a struct smb_request from an inbuf
593 static bool init_smb_request(struct smb_request
*req
,
594 struct smbd_server_connection
*sconn
,
595 struct smbXsrv_connection
*xconn
,
597 size_t unread_bytes
, bool encrypted
,
600 struct smbXsrv_tcon
*tcon
;
603 size_t req_size
= smb_len(inbuf
) + 4;
605 /* Ensure we have at least smb_size bytes. */
606 if (req_size
< smb_size
) {
607 DEBUG(0,("init_smb_request: invalid request size %u\n",
608 (unsigned int)req_size
));
612 req
->request_time
= timeval_current();
613 now
= timeval_to_nttime(&req
->request_time
);
615 req
->cmd
= CVAL(inbuf
, smb_com
);
616 req
->flags2
= SVAL(inbuf
, smb_flg2
);
617 req
->smbpid
= SVAL(inbuf
, smb_pid
);
618 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
619 req
->seqnum
= seqnum
;
620 req
->vuid
= SVAL(inbuf
, smb_uid
);
621 req
->tid
= SVAL(inbuf
, smb_tid
);
622 req
->wct
= CVAL(inbuf
, smb_wct
);
623 req
->vwv
= (const uint16_t *)(inbuf
+smb_vwv
);
624 req
->buflen
= smb_buflen(inbuf
);
625 req
->buf
= (const uint8_t *)smb_buf_const(inbuf
);
626 req
->unread_bytes
= unread_bytes
;
627 req
->encrypted
= encrypted
;
630 status
= smb1srv_tcon_lookup(xconn
, req
->tid
, now
, &tcon
);
631 if (NT_STATUS_IS_OK(status
)) {
632 req
->conn
= tcon
->compat
;
636 req
->chain_fsp
= NULL
;
638 req
->priv_paths
= NULL
;
640 smb_init_perfcount_data(&req
->pcd
);
642 /* Ensure we have at least wct words and 2 bytes of bcc. */
643 if (smb_size
+ req
->wct
*2 > req_size
) {
644 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
645 (unsigned int)req
->wct
,
646 (unsigned int)req_size
));
649 /* Ensure bcc is correct. */
650 if (((const uint8_t *)smb_buf_const(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
651 DEBUG(0,("init_smb_request: invalid bcc number %u "
652 "(wct = %u, size %u)\n",
653 (unsigned int)req
->buflen
,
654 (unsigned int)req
->wct
,
655 (unsigned int)req_size
));
663 static void process_smb(struct smbXsrv_connection
*xconn
,
664 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
665 uint32_t seqnum
, bool encrypted
,
666 struct smb_perfcount_data
*deferred_pcd
);
668 static void smbd_deferred_open_timer(struct tevent_context
*ev
,
669 struct tevent_timer
*te
,
670 struct timeval _tval
,
673 struct pending_message_list
*msg
= talloc_get_type(private_data
,
674 struct pending_message_list
);
675 struct smbd_server_connection
*sconn
= msg
->sconn
;
676 struct smbXsrv_connection
*xconn
= msg
->xconn
;
677 TALLOC_CTX
*mem_ctx
= talloc_tos();
678 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
681 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
684 exit_server("smbd_deferred_open_timer: talloc failed\n");
688 /* We leave this message on the queue so the open code can
689 know this is a retry. */
690 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
691 (unsigned long long)mid
));
693 /* Mark the message as processed so this is not
694 * re-processed in error. */
695 msg
->processed
= true;
697 process_smb(xconn
, inbuf
,
699 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
701 /* If it's still there and was processed, remove it. */
702 msg
= get_deferred_open_message_smb(sconn
, mid
);
703 if (msg
&& msg
->processed
) {
704 remove_deferred_open_message_smb(sconn
, mid
);
708 /****************************************************************************
709 Function to push a message onto the tail of a linked list of smb messages ready
711 ****************************************************************************/
713 static bool push_queued_message(struct smb_request
*req
,
714 struct timeval request_time
,
715 struct timeval end_time
,
716 struct deferred_open_record
*open_rec
)
718 int msg_len
= smb_len(req
->inbuf
) + 4;
719 struct pending_message_list
*msg
;
721 msg
= talloc_zero(NULL
, struct pending_message_list
);
724 DEBUG(0,("push_message: malloc fail (1)\n"));
727 msg
->sconn
= req
->sconn
;
728 msg
->xconn
= req
->xconn
;
730 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
731 if(msg
->buf
.data
== NULL
) {
732 DEBUG(0,("push_message: malloc fail (2)\n"));
737 msg
->request_time
= request_time
;
738 msg
->seqnum
= req
->seqnum
;
739 msg
->encrypted
= req
->encrypted
;
740 msg
->processed
= false;
741 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
744 msg
->open_rec
= talloc_move(msg
, &open_rec
);
748 msg
->te
= tevent_add_timer(msg
->sconn
->ev_ctx
,
751 smbd_deferred_open_timer
,
754 DEBUG(0,("push_message: event_add_timed failed\n"));
760 DLIST_ADD_END(req
->sconn
->deferred_open_queue
, msg
,
761 struct pending_message_list
*);
763 DEBUG(10,("push_message: pushed message length %u on "
764 "deferred_open_queue\n", (unsigned int)msg_len
));
769 /****************************************************************************
770 Function to delete a sharing violation open message by mid.
771 ****************************************************************************/
773 void remove_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
776 struct pending_message_list
*pml
;
778 if (sconn
->using_smb2
) {
779 remove_deferred_open_message_smb2(sconn
, mid
);
783 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
784 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
785 DEBUG(10,("remove_deferred_open_message_smb: "
786 "deleting mid %llu len %u\n",
787 (unsigned long long)mid
,
788 (unsigned int)pml
->buf
.length
));
789 DLIST_REMOVE(sconn
->deferred_open_queue
, pml
);
796 /****************************************************************************
797 Move a sharing violation open retry message to the front of the list and
798 schedule it for immediate processing.
799 ****************************************************************************/
801 bool schedule_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
804 struct pending_message_list
*pml
;
807 if (sconn
->using_smb2
) {
808 return schedule_deferred_open_message_smb2(sconn
, mid
);
811 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
812 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
814 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
817 (unsigned long long)msg_mid
));
819 if (mid
== msg_mid
) {
820 struct tevent_timer
*te
;
822 if (pml
->processed
) {
823 /* A processed message should not be
825 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
826 "message mid %llu was already processed\n",
827 (unsigned long long)msg_mid
));
831 DEBUG(10,("schedule_deferred_open_message_smb: "
832 "scheduling mid %llu\n",
833 (unsigned long long)mid
));
835 te
= tevent_add_timer(pml
->sconn
->ev_ctx
,
838 smbd_deferred_open_timer
,
841 DEBUG(10,("schedule_deferred_open_message_smb: "
842 "event_add_timed() failed, "
843 "skipping mid %llu\n",
844 (unsigned long long)msg_mid
));
847 TALLOC_FREE(pml
->te
);
849 DLIST_PROMOTE(sconn
->deferred_open_queue
, pml
);
854 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
855 "find message mid %llu\n",
856 (unsigned long long)mid
));
861 /****************************************************************************
862 Return true if this mid is on the deferred queue and was not yet processed.
863 ****************************************************************************/
865 bool open_was_deferred(struct smbd_server_connection
*sconn
, uint64_t mid
)
867 struct pending_message_list
*pml
;
869 if (sconn
->using_smb2
) {
870 return open_was_deferred_smb2(sconn
, mid
);
873 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
874 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
881 /****************************************************************************
882 Return the message queued by this mid.
883 ****************************************************************************/
885 static struct pending_message_list
*get_deferred_open_message_smb(
886 struct smbd_server_connection
*sconn
, uint64_t mid
)
888 struct pending_message_list
*pml
;
890 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
891 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
898 /****************************************************************************
899 Get the state data queued by this mid.
900 ****************************************************************************/
902 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
903 struct timeval
*p_request_time
,
904 struct deferred_open_record
**open_rec
)
906 struct pending_message_list
*pml
;
908 if (smbreq
->sconn
->using_smb2
) {
909 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
914 pml
= get_deferred_open_message_smb(smbreq
->sconn
, smbreq
->mid
);
918 if (p_request_time
) {
919 *p_request_time
= pml
->request_time
;
921 if (open_rec
!= NULL
) {
922 *open_rec
= pml
->open_rec
;
927 /****************************************************************************
928 Function to push a deferred open smb message onto a linked list of local smb
929 messages ready for processing.
930 ****************************************************************************/
932 bool push_deferred_open_message_smb(struct smb_request
*req
,
933 struct timeval request_time
,
934 struct timeval timeout
,
936 struct deferred_open_record
*open_rec
)
938 struct timeval end_time
;
941 return push_deferred_open_message_smb2(req
->smb2req
,
948 if (req
->unread_bytes
) {
949 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
950 "unread_bytes = %u\n",
951 (unsigned int)req
->unread_bytes
));
952 smb_panic("push_deferred_open_message_smb: "
953 "logic error unread_bytes != 0" );
956 end_time
= timeval_sum(&request_time
, &timeout
);
958 DEBUG(10,("push_deferred_open_message_smb: pushing message "
959 "len %u mid %llu timeout time [%u.%06u]\n",
960 (unsigned int) smb_len(req
->inbuf
)+4,
961 (unsigned long long)req
->mid
,
962 (unsigned int)end_time
.tv_sec
,
963 (unsigned int)end_time
.tv_usec
));
965 return push_queued_message(req
, request_time
, end_time
, open_rec
);
968 static void smbd_sig_term_handler(struct tevent_context
*ev
,
969 struct tevent_signal
*se
,
975 exit_server_cleanly("termination signal");
978 void smbd_setup_sig_term_handler(struct smbd_server_connection
*sconn
)
980 struct tevent_signal
*se
;
982 se
= tevent_add_signal(sconn
->ev_ctx
,
985 smbd_sig_term_handler
,
988 exit_server("failed to setup SIGTERM handler");
992 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
993 struct tevent_signal
*se
,
999 struct smbd_server_connection
*sconn
=
1000 talloc_get_type_abort(private_data
,
1001 struct smbd_server_connection
);
1003 change_to_root_user();
1004 DEBUG(1,("Reloading services after SIGHUP\n"));
1005 reload_services(sconn
, conn_snum_used
, false);
1008 void smbd_setup_sig_hup_handler(struct smbd_server_connection
*sconn
)
1010 struct tevent_signal
*se
;
1012 se
= tevent_add_signal(sconn
->ev_ctx
,
1015 smbd_sig_hup_handler
,
1018 exit_server("failed to setup SIGHUP handler");
1022 static void smbd_conf_updated(struct messaging_context
*msg
,
1025 struct server_id server_id
,
1028 struct smbd_server_connection
*sconn
=
1029 talloc_get_type_abort(private_data
,
1030 struct smbd_server_connection
);
1032 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1033 "updated. Reloading.\n"));
1034 change_to_root_user();
1035 reload_services(sconn
, conn_snum_used
, false);
1039 * Only allow 5 outstanding trans requests. We're allocating memory, so
1043 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
1046 for (; list
!= NULL
; list
= list
->next
) {
1048 if (list
->mid
== mid
) {
1049 return NT_STATUS_INVALID_PARAMETER
;
1055 return NT_STATUS_INSUFFICIENT_RESOURCES
;
1058 return NT_STATUS_OK
;
1062 These flags determine some of the permissions required to do an operation
1064 Note that I don't set NEED_WRITE on some write operations because they
1065 are used by some brain-dead clients when printing, and I don't want to
1066 force write permissions on print services.
1068 #define AS_USER (1<<0)
1069 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1070 #define TIME_INIT (1<<2)
1071 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1072 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1073 #define DO_CHDIR (1<<6)
1076 define a list of possible SMB messages and their corresponding
1077 functions. Any message that has a NULL function is unimplemented -
1078 please feel free to contribute implementations!
1080 static const struct smb_message_struct
{
1082 void (*fn
)(struct smb_request
*req
);
1084 } smb_messages
[256] = {
1086 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1087 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1088 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1089 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1090 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1091 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1092 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1093 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1094 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1095 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1096 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1097 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1098 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1099 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1100 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1101 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1102 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1103 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1104 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1105 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1106 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1107 /* 0x15 */ { NULL
, NULL
, 0 },
1108 /* 0x16 */ { NULL
, NULL
, 0 },
1109 /* 0x17 */ { NULL
, NULL
, 0 },
1110 /* 0x18 */ { NULL
, NULL
, 0 },
1111 /* 0x19 */ { NULL
, NULL
, 0 },
1112 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1113 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1114 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1115 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1116 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1117 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1118 /* 0x20 */ { "SMBwritec", NULL
,0},
1119 /* 0x21 */ { NULL
, NULL
, 0 },
1120 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1121 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1122 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1123 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1124 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1125 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1126 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1127 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1128 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1129 /* 0x2b */ { "SMBecho",reply_echo
,0},
1130 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1131 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1132 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1133 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1134 /* 0x30 */ { NULL
, NULL
, 0 },
1135 /* 0x31 */ { NULL
, NULL
, 0 },
1136 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1137 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1138 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1139 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1140 /* 0x36 */ { NULL
, NULL
, 0 },
1141 /* 0x37 */ { NULL
, NULL
, 0 },
1142 /* 0x38 */ { NULL
, NULL
, 0 },
1143 /* 0x39 */ { NULL
, NULL
, 0 },
1144 /* 0x3a */ { NULL
, NULL
, 0 },
1145 /* 0x3b */ { NULL
, NULL
, 0 },
1146 /* 0x3c */ { NULL
, NULL
, 0 },
1147 /* 0x3d */ { NULL
, NULL
, 0 },
1148 /* 0x3e */ { NULL
, NULL
, 0 },
1149 /* 0x3f */ { NULL
, NULL
, 0 },
1150 /* 0x40 */ { NULL
, NULL
, 0 },
1151 /* 0x41 */ { NULL
, NULL
, 0 },
1152 /* 0x42 */ { NULL
, NULL
, 0 },
1153 /* 0x43 */ { NULL
, NULL
, 0 },
1154 /* 0x44 */ { NULL
, NULL
, 0 },
1155 /* 0x45 */ { NULL
, NULL
, 0 },
1156 /* 0x46 */ { NULL
, NULL
, 0 },
1157 /* 0x47 */ { NULL
, NULL
, 0 },
1158 /* 0x48 */ { NULL
, NULL
, 0 },
1159 /* 0x49 */ { NULL
, NULL
, 0 },
1160 /* 0x4a */ { NULL
, NULL
, 0 },
1161 /* 0x4b */ { NULL
, NULL
, 0 },
1162 /* 0x4c */ { NULL
, NULL
, 0 },
1163 /* 0x4d */ { NULL
, NULL
, 0 },
1164 /* 0x4e */ { NULL
, NULL
, 0 },
1165 /* 0x4f */ { NULL
, NULL
, 0 },
1166 /* 0x50 */ { NULL
, NULL
, 0 },
1167 /* 0x51 */ { NULL
, NULL
, 0 },
1168 /* 0x52 */ { NULL
, NULL
, 0 },
1169 /* 0x53 */ { NULL
, NULL
, 0 },
1170 /* 0x54 */ { NULL
, NULL
, 0 },
1171 /* 0x55 */ { NULL
, NULL
, 0 },
1172 /* 0x56 */ { NULL
, NULL
, 0 },
1173 /* 0x57 */ { NULL
, NULL
, 0 },
1174 /* 0x58 */ { NULL
, NULL
, 0 },
1175 /* 0x59 */ { NULL
, NULL
, 0 },
1176 /* 0x5a */ { NULL
, NULL
, 0 },
1177 /* 0x5b */ { NULL
, NULL
, 0 },
1178 /* 0x5c */ { NULL
, NULL
, 0 },
1179 /* 0x5d */ { NULL
, NULL
, 0 },
1180 /* 0x5e */ { NULL
, NULL
, 0 },
1181 /* 0x5f */ { NULL
, NULL
, 0 },
1182 /* 0x60 */ { NULL
, NULL
, 0 },
1183 /* 0x61 */ { NULL
, NULL
, 0 },
1184 /* 0x62 */ { NULL
, NULL
, 0 },
1185 /* 0x63 */ { NULL
, NULL
, 0 },
1186 /* 0x64 */ { NULL
, NULL
, 0 },
1187 /* 0x65 */ { NULL
, NULL
, 0 },
1188 /* 0x66 */ { NULL
, NULL
, 0 },
1189 /* 0x67 */ { NULL
, NULL
, 0 },
1190 /* 0x68 */ { NULL
, NULL
, 0 },
1191 /* 0x69 */ { NULL
, NULL
, 0 },
1192 /* 0x6a */ { NULL
, NULL
, 0 },
1193 /* 0x6b */ { NULL
, NULL
, 0 },
1194 /* 0x6c */ { NULL
, NULL
, 0 },
1195 /* 0x6d */ { NULL
, NULL
, 0 },
1196 /* 0x6e */ { NULL
, NULL
, 0 },
1197 /* 0x6f */ { NULL
, NULL
, 0 },
1198 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1199 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1200 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1201 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1202 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1203 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1204 /* 0x76 */ { NULL
, NULL
, 0 },
1205 /* 0x77 */ { NULL
, NULL
, 0 },
1206 /* 0x78 */ { NULL
, NULL
, 0 },
1207 /* 0x79 */ { NULL
, NULL
, 0 },
1208 /* 0x7a */ { NULL
, NULL
, 0 },
1209 /* 0x7b */ { NULL
, NULL
, 0 },
1210 /* 0x7c */ { NULL
, NULL
, 0 },
1211 /* 0x7d */ { NULL
, NULL
, 0 },
1212 /* 0x7e */ { NULL
, NULL
, 0 },
1213 /* 0x7f */ { NULL
, NULL
, 0 },
1214 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1215 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1216 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1217 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1218 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1219 /* 0x85 */ { NULL
, NULL
, 0 },
1220 /* 0x86 */ { NULL
, NULL
, 0 },
1221 /* 0x87 */ { NULL
, NULL
, 0 },
1222 /* 0x88 */ { NULL
, NULL
, 0 },
1223 /* 0x89 */ { NULL
, NULL
, 0 },
1224 /* 0x8a */ { NULL
, NULL
, 0 },
1225 /* 0x8b */ { NULL
, NULL
, 0 },
1226 /* 0x8c */ { NULL
, NULL
, 0 },
1227 /* 0x8d */ { NULL
, NULL
, 0 },
1228 /* 0x8e */ { NULL
, NULL
, 0 },
1229 /* 0x8f */ { NULL
, NULL
, 0 },
1230 /* 0x90 */ { NULL
, NULL
, 0 },
1231 /* 0x91 */ { NULL
, NULL
, 0 },
1232 /* 0x92 */ { NULL
, NULL
, 0 },
1233 /* 0x93 */ { NULL
, NULL
, 0 },
1234 /* 0x94 */ { NULL
, NULL
, 0 },
1235 /* 0x95 */ { NULL
, NULL
, 0 },
1236 /* 0x96 */ { NULL
, NULL
, 0 },
1237 /* 0x97 */ { NULL
, NULL
, 0 },
1238 /* 0x98 */ { NULL
, NULL
, 0 },
1239 /* 0x99 */ { NULL
, NULL
, 0 },
1240 /* 0x9a */ { NULL
, NULL
, 0 },
1241 /* 0x9b */ { NULL
, NULL
, 0 },
1242 /* 0x9c */ { NULL
, NULL
, 0 },
1243 /* 0x9d */ { NULL
, NULL
, 0 },
1244 /* 0x9e */ { NULL
, NULL
, 0 },
1245 /* 0x9f */ { NULL
, NULL
, 0 },
1246 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1247 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1248 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1249 /* 0xa3 */ { NULL
, NULL
, 0 },
1250 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1251 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1252 /* 0xa6 */ { NULL
, NULL
, 0 },
1253 /* 0xa7 */ { NULL
, NULL
, 0 },
1254 /* 0xa8 */ { NULL
, NULL
, 0 },
1255 /* 0xa9 */ { NULL
, NULL
, 0 },
1256 /* 0xaa */ { NULL
, NULL
, 0 },
1257 /* 0xab */ { NULL
, NULL
, 0 },
1258 /* 0xac */ { NULL
, NULL
, 0 },
1259 /* 0xad */ { NULL
, NULL
, 0 },
1260 /* 0xae */ { NULL
, NULL
, 0 },
1261 /* 0xaf */ { NULL
, NULL
, 0 },
1262 /* 0xb0 */ { NULL
, NULL
, 0 },
1263 /* 0xb1 */ { NULL
, NULL
, 0 },
1264 /* 0xb2 */ { NULL
, NULL
, 0 },
1265 /* 0xb3 */ { NULL
, NULL
, 0 },
1266 /* 0xb4 */ { NULL
, NULL
, 0 },
1267 /* 0xb5 */ { NULL
, NULL
, 0 },
1268 /* 0xb6 */ { NULL
, NULL
, 0 },
1269 /* 0xb7 */ { NULL
, NULL
, 0 },
1270 /* 0xb8 */ { NULL
, NULL
, 0 },
1271 /* 0xb9 */ { NULL
, NULL
, 0 },
1272 /* 0xba */ { NULL
, NULL
, 0 },
1273 /* 0xbb */ { NULL
, NULL
, 0 },
1274 /* 0xbc */ { NULL
, NULL
, 0 },
1275 /* 0xbd */ { NULL
, NULL
, 0 },
1276 /* 0xbe */ { NULL
, NULL
, 0 },
1277 /* 0xbf */ { NULL
, NULL
, 0 },
1278 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1279 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1280 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1281 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1282 /* 0xc4 */ { NULL
, NULL
, 0 },
1283 /* 0xc5 */ { NULL
, NULL
, 0 },
1284 /* 0xc6 */ { NULL
, NULL
, 0 },
1285 /* 0xc7 */ { NULL
, NULL
, 0 },
1286 /* 0xc8 */ { NULL
, NULL
, 0 },
1287 /* 0xc9 */ { NULL
, NULL
, 0 },
1288 /* 0xca */ { NULL
, NULL
, 0 },
1289 /* 0xcb */ { NULL
, NULL
, 0 },
1290 /* 0xcc */ { NULL
, NULL
, 0 },
1291 /* 0xcd */ { NULL
, NULL
, 0 },
1292 /* 0xce */ { NULL
, NULL
, 0 },
1293 /* 0xcf */ { NULL
, NULL
, 0 },
1294 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1295 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1296 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1297 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1298 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1299 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1300 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1301 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1302 /* 0xd8 */ { NULL
, NULL
, 0 },
1303 /* 0xd9 */ { NULL
, NULL
, 0 },
1304 /* 0xda */ { NULL
, NULL
, 0 },
1305 /* 0xdb */ { NULL
, NULL
, 0 },
1306 /* 0xdc */ { NULL
, NULL
, 0 },
1307 /* 0xdd */ { NULL
, NULL
, 0 },
1308 /* 0xde */ { NULL
, NULL
, 0 },
1309 /* 0xdf */ { NULL
, NULL
, 0 },
1310 /* 0xe0 */ { NULL
, NULL
, 0 },
1311 /* 0xe1 */ { NULL
, NULL
, 0 },
1312 /* 0xe2 */ { NULL
, NULL
, 0 },
1313 /* 0xe3 */ { NULL
, NULL
, 0 },
1314 /* 0xe4 */ { NULL
, NULL
, 0 },
1315 /* 0xe5 */ { NULL
, NULL
, 0 },
1316 /* 0xe6 */ { NULL
, NULL
, 0 },
1317 /* 0xe7 */ { NULL
, NULL
, 0 },
1318 /* 0xe8 */ { NULL
, NULL
, 0 },
1319 /* 0xe9 */ { NULL
, NULL
, 0 },
1320 /* 0xea */ { NULL
, NULL
, 0 },
1321 /* 0xeb */ { NULL
, NULL
, 0 },
1322 /* 0xec */ { NULL
, NULL
, 0 },
1323 /* 0xed */ { NULL
, NULL
, 0 },
1324 /* 0xee */ { NULL
, NULL
, 0 },
1325 /* 0xef */ { NULL
, NULL
, 0 },
1326 /* 0xf0 */ { NULL
, NULL
, 0 },
1327 /* 0xf1 */ { NULL
, NULL
, 0 },
1328 /* 0xf2 */ { NULL
, NULL
, 0 },
1329 /* 0xf3 */ { NULL
, NULL
, 0 },
1330 /* 0xf4 */ { NULL
, NULL
, 0 },
1331 /* 0xf5 */ { NULL
, NULL
, 0 },
1332 /* 0xf6 */ { NULL
, NULL
, 0 },
1333 /* 0xf7 */ { NULL
, NULL
, 0 },
1334 /* 0xf8 */ { NULL
, NULL
, 0 },
1335 /* 0xf9 */ { NULL
, NULL
, 0 },
1336 /* 0xfa */ { NULL
, NULL
, 0 },
1337 /* 0xfb */ { NULL
, NULL
, 0 },
1338 /* 0xfc */ { NULL
, NULL
, 0 },
1339 /* 0xfd */ { NULL
, NULL
, 0 },
1340 /* 0xfe */ { NULL
, NULL
, 0 },
1341 /* 0xff */ { NULL
, NULL
, 0 }
1345 /*******************************************************************
1346 allocate and initialize a reply packet
1347 ********************************************************************/
1349 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1350 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1353 size_t smb_len
= MIN_SMB_SIZE
+ VWV(num_words
) + num_bytes
;
1356 * Protect against integer wrap.
1357 * The SMB layer reply can be up to 0xFFFFFF bytes.
1359 if ((num_bytes
> 0xffffff) || (smb_len
> 0xffffff)) {
1361 if (asprintf(&msg
, "num_bytes too large: %u",
1362 (unsigned)num_bytes
) == -1) {
1363 msg
= discard_const_p(char, "num_bytes too large");
1369 * Here we include the NBT header for now.
1371 *outbuf
= talloc_array(mem_ctx
, char,
1372 NBT_HDR_SIZE
+ smb_len
);
1373 if (*outbuf
== NULL
) {
1377 construct_reply_common(req
, inbuf
, *outbuf
);
1378 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1380 * Zero out the word area, the caller has to take care of the bcc area
1383 if (num_words
!= 0) {
1384 memset(*outbuf
+ (NBT_HDR_SIZE
+ HDR_VWV
), 0, VWV(num_words
));
1390 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1393 if (!create_outbuf(req
, req
, (const char *)req
->inbuf
, &outbuf
, num_words
,
1395 smb_panic("could not allocate output buffer\n");
1397 req
->outbuf
= (uint8_t *)outbuf
;
1401 /*******************************************************************
1402 Dump a packet to a file.
1403 ********************************************************************/
1405 static void smb_dump(const char *name
, int type
, const char *data
)
1410 if (DEBUGLEVEL
< 50) {
1414 len
= smb_len_tcp(data
)+4;
1415 for (i
=1;i
<100;i
++) {
1416 fname
= talloc_asprintf(talloc_tos(),
1420 type
? "req" : "resp");
1421 if (fname
== NULL
) {
1424 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1425 if (fd
!= -1 || errno
!= EEXIST
) break;
1429 ssize_t ret
= write(fd
, data
, len
);
1431 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1433 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1438 /****************************************************************************
1439 Prepare everything for calling the actual request function, and potentially
1440 call the request function via the "new" interface.
1442 Return False if the "legacy" function needs to be called, everything is
1445 Return True if we're done.
1447 I know this API sucks, but it is the one with the least code change I could
1449 ****************************************************************************/
1451 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
)
1454 uint64_t session_tag
;
1455 connection_struct
*conn
= NULL
;
1456 struct smbXsrv_connection
*xconn
= req
->xconn
;
1457 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1458 struct smbXsrv_session
*session
= NULL
;
1463 if (smb_messages
[type
].fn
== NULL
) {
1464 DEBUG(0,("Unknown message type %d!\n",type
));
1465 smb_dump("Unknown", 1, (const char *)req
->inbuf
);
1466 reply_unknown_new(req
, type
);
1470 flags
= smb_messages
[type
].flags
;
1472 /* In share mode security we must ignore the vuid. */
1473 session_tag
= req
->vuid
;
1476 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1477 (int)getpid(), (unsigned long)conn
));
1479 smb_dump(smb_fn_name(type
), 1, (const char *)req
->inbuf
);
1481 /* Ensure this value is replaced in the incoming packet. */
1482 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_uid
,session_tag
);
1485 * Ensure the correct username is in current_user_info. This is a
1486 * really ugly bugfix for problems with multiple session_setup_and_X's
1487 * being done and allowing %U and %G substitutions to work correctly.
1488 * There is a reason this code is done here, don't move it unless you
1489 * know what you're doing... :-).
1494 * lookup an existing session
1496 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1497 * here, the main check is still in change_to_user()
1499 status
= smb1srv_session_lookup(xconn
,
1503 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
1506 status
= NT_STATUS_OK
;
1509 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1510 (unsigned long long)session_tag
,
1511 (unsigned long long)req
->mid
));
1512 reply_nterror(req
, NT_STATUS_NETWORK_SESSION_EXPIRED
);
1517 if (session_tag
!= xconn
->last_session_id
) {
1518 struct user_struct
*vuser
= NULL
;
1520 xconn
->last_session_id
= session_tag
;
1522 vuser
= session
->compat
;
1525 set_current_user_info(
1526 vuser
->session_info
->unix_info
->sanitized_username
,
1527 vuser
->session_info
->unix_info
->unix_name
,
1528 vuser
->session_info
->info
->domain_name
);
1532 /* Does this call need to be run as the connected user? */
1533 if (flags
& AS_USER
) {
1535 /* Does this call need a valid tree connection? */
1538 * Amazingly, the error code depends on the command
1541 if (type
== SMBntcreateX
) {
1542 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1544 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1549 if (!change_to_user(conn
,session_tag
)) {
1550 DEBUG(0, ("Error: Could not change to user. Removing "
1551 "deferred open, mid=%llu.\n",
1552 (unsigned long long)req
->mid
));
1553 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1557 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1559 /* Does it need write permission? */
1560 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1561 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1565 /* IPC services are limited */
1566 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1567 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1571 /* This call needs to be run as root */
1572 change_to_root_user();
1575 /* load service specific parameters */
1577 if (req
->encrypted
) {
1578 conn
->encrypted_tid
= true;
1579 /* encrypted required from now on. */
1580 conn
->encrypt_level
= SMB_SIGNING_REQUIRED
;
1581 } else if (ENCRYPTION_REQUIRED(conn
)) {
1582 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1583 DEBUG(1,("service[%s] requires encryption"
1584 "%s ACCESS_DENIED. mid=%llu\n",
1585 lp_servicename(talloc_tos(), SNUM(conn
)),
1587 (unsigned long long)req
->mid
));
1588 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1593 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1594 (flags
& (AS_USER
|DO_CHDIR
)
1596 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1599 conn
->num_smb_operations
++;
1603 * Does this protocol need to be run as guest? (Only archane
1604 * messenger service requests have this...)
1606 if (flags
& AS_GUEST
) {
1610 if (!change_to_guest()) {
1611 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1615 raddr
= tsocket_address_inet_addr_string(xconn
->remote_address
,
1617 if (raddr
== NULL
) {
1618 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1623 * Haven't we checked this in smbd_process already???
1626 ok
= allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1627 xconn
->remote_hostname
, raddr
);
1631 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1636 smb_messages
[type
].fn(req
);
1640 /****************************************************************************
1641 Construct a reply to the incoming packet.
1642 ****************************************************************************/
1644 static void construct_reply(struct smbd_server_connection
*sconn
,
1645 char *inbuf
, int size
, size_t unread_bytes
,
1646 uint32_t seqnum
, bool encrypted
,
1647 struct smb_perfcount_data
*deferred_pcd
)
1649 struct smbXsrv_connection
*xconn
= sconn
->conn
;
1650 struct smb_request
*req
;
1652 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1653 smb_panic("could not allocate smb_request");
1656 if (!init_smb_request(req
, sconn
, xconn
, (uint8
*)inbuf
, unread_bytes
,
1657 encrypted
, seqnum
)) {
1658 exit_server_cleanly("Invalid SMB request");
1661 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1663 /* we popped this message off the queue - keep original perf data */
1665 req
->pcd
= *deferred_pcd
;
1667 SMB_PERFCOUNT_START(&req
->pcd
);
1668 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1669 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1672 req
->conn
= switch_message(req
->cmd
, req
);
1674 if (req
->outbuf
== NULL
) {
1676 * Request has suspended itself, will come
1681 if (CVAL(req
->outbuf
,0) == 0) {
1682 show_msg((char *)req
->outbuf
);
1684 smb_request_done(req
);
1687 static void construct_reply_chain(struct smbd_server_connection
*sconn
,
1688 char *inbuf
, int size
, uint32_t seqnum
,
1690 struct smb_perfcount_data
*deferred_pcd
)
1692 struct smb_request
**reqs
= NULL
;
1693 struct smb_request
*req
;
1697 ok
= smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf
, sconn
, encrypted
,
1698 seqnum
, &reqs
, &num_reqs
);
1700 char errbuf
[smb_size
];
1701 error_packet(errbuf
, 0, 0, NT_STATUS_INVALID_PARAMETER
,
1702 __LINE__
, __FILE__
);
1703 if (!srv_send_smb(sconn
, errbuf
, true, seqnum
, encrypted
,
1705 exit_server_cleanly("construct_reply_chain: "
1706 "srv_send_smb failed.");
1712 req
->inbuf
= (uint8_t *)talloc_move(reqs
, &inbuf
);
1714 req
->conn
= switch_message(req
->cmd
, req
);
1716 if (req
->outbuf
== NULL
) {
1718 * Request has suspended itself, will come
1723 smb_request_done(req
);
1727 * To be called from an async SMB handler that is potentially chained
1728 * when it is finished for shipping.
1731 void smb_request_done(struct smb_request
*req
)
1733 struct smb_request
**reqs
= NULL
;
1734 struct smb_request
*first_req
;
1735 size_t i
, num_reqs
, next_index
;
1738 if (req
->chain
== NULL
) {
1744 num_reqs
= talloc_array_length(reqs
);
1746 for (i
=0; i
<num_reqs
; i
++) {
1747 if (reqs
[i
] == req
) {
1751 if (i
== num_reqs
) {
1753 * Invalid chain, should not happen
1755 status
= NT_STATUS_INTERNAL_ERROR
;
1760 while ((next_index
< num_reqs
) && (IVAL(req
->outbuf
, smb_rcls
) == 0)) {
1761 struct smb_request
*next
= reqs
[next_index
];
1762 struct smbXsrv_tcon
*tcon
;
1763 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1765 next
->vuid
= SVAL(req
->outbuf
, smb_uid
);
1766 next
->tid
= SVAL(req
->outbuf
, smb_tid
);
1767 status
= smb1srv_tcon_lookup(req
->sconn
->conn
, req
->tid
,
1769 if (NT_STATUS_IS_OK(status
)) {
1770 req
->conn
= tcon
->compat
;
1774 next
->chain_fsp
= req
->chain_fsp
;
1775 next
->inbuf
= req
->inbuf
;
1778 req
->conn
= switch_message(req
->cmd
, req
);
1780 if (req
->outbuf
== NULL
) {
1782 * Request has suspended itself, will come
1790 first_req
= reqs
[0];
1792 for (i
=1; i
<next_index
; i
++) {
1795 ok
= smb_splice_chain(&first_req
->outbuf
, reqs
[i
]->outbuf
);
1797 status
= NT_STATUS_INTERNAL_ERROR
;
1802 SSVAL(first_req
->outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
1803 SSVAL(first_req
->outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
1806 * This scary statement intends to set the
1807 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1808 * to the value last_req->outbuf carries
1810 SSVAL(first_req
->outbuf
, smb_flg2
,
1811 (SVAL(first_req
->outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
1812 |(SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
1815 * Transfer the error codes from the subrequest to the main one
1817 SSVAL(first_req
->outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
1818 SSVAL(first_req
->outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
1821 first_req
->outbuf
, talloc_get_size(first_req
->outbuf
) - 4);
1824 if (!srv_send_smb(first_req
->sconn
,
1825 (char *)first_req
->outbuf
,
1826 true, first_req
->seqnum
+1,
1827 IS_CONN_ENCRYPTED(req
->conn
)||first_req
->encrypted
,
1829 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1832 TALLOC_FREE(req
); /* non-chained case */
1833 TALLOC_FREE(reqs
); /* chained case */
1838 char errbuf
[smb_size
];
1839 error_packet(errbuf
, 0, 0, status
, __LINE__
, __FILE__
);
1840 if (!srv_send_smb(req
->sconn
, errbuf
, true,
1841 req
->seqnum
+1, req
->encrypted
,
1843 exit_server_cleanly("construct_reply_chain: "
1844 "srv_send_smb failed.");
1847 TALLOC_FREE(req
); /* non-chained case */
1848 TALLOC_FREE(reqs
); /* chained case */
1851 /****************************************************************************
1852 Process an smb from the client
1853 ****************************************************************************/
1854 static void process_smb(struct smbXsrv_connection
*xconn
,
1855 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1856 uint32_t seqnum
, bool encrypted
,
1857 struct smb_perfcount_data
*deferred_pcd
)
1859 struct smbd_server_connection
*sconn
= xconn
->sconn
;
1860 int msg_type
= CVAL(inbuf
,0);
1862 DO_PROFILE_INC(smb_count
);
1864 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1866 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1867 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1869 if (msg_type
!= NBSSmessage
) {
1871 * NetBIOS session request, keepalive, etc.
1873 reply_special(sconn
, (char *)inbuf
, nread
);
1877 if (sconn
->using_smb2
) {
1878 /* At this point we're not really using smb2,
1879 * we make the decision here.. */
1880 if (smbd_is_smb2_header(inbuf
, nread
)) {
1881 const uint8_t *inpdu
= inbuf
+ NBT_HDR_SIZE
;
1882 size_t pdulen
= nread
- NBT_HDR_SIZE
;
1883 smbd_smb2_first_negprot(xconn
, inpdu
, pdulen
);
1885 } else if (nread
>= smb_size
&& valid_smb_header(sconn
, inbuf
)
1886 && CVAL(inbuf
, smb_com
) != 0x72) {
1887 /* This is a non-negprot SMB1 packet.
1888 Disable SMB2 from now on. */
1889 sconn
->using_smb2
= false;
1893 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1894 * so subtract 4 from it. */
1895 if ((nread
< (smb_size
- 4)) || !valid_smb_header(sconn
, inbuf
)) {
1896 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1899 /* special magic for immediate exit */
1901 (IVAL(inbuf
, 4) == 0x74697865) &&
1902 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1903 uint8_t exitcode
= CVAL(inbuf
, 8);
1904 DEBUG(1, ("Exiting immediately with code %d\n",
1909 exit_server_cleanly("Non-SMB packet");
1912 show_msg((char *)inbuf
);
1914 if ((unread_bytes
== 0) && smb1_is_chain(inbuf
)) {
1915 construct_reply_chain(sconn
, (char *)inbuf
, nread
,
1916 seqnum
, encrypted
, deferred_pcd
);
1918 construct_reply(sconn
, (char *)inbuf
, nread
, unread_bytes
,
1919 seqnum
, encrypted
, deferred_pcd
);
1925 sconn
->num_requests
++;
1927 /* The timeout_processing function isn't run nearly
1928 often enough to implement 'max log size' without
1929 overrunning the size of the file by many megabytes.
1930 This is especially true if we are running at debug
1931 level 10. Checking every 50 SMBs is a nice
1932 tradeoff of performance vs log file size overrun. */
1934 if ((sconn
->num_requests
% 50) == 0 &&
1935 need_to_check_log_size()) {
1936 change_to_root_user();
1941 /****************************************************************************
1942 Return a string containing the function name of a SMB command.
1943 ****************************************************************************/
1945 const char *smb_fn_name(int type
)
1947 const char *unknown_name
= "SMBunknown";
1949 if (smb_messages
[type
].name
== NULL
)
1950 return(unknown_name
);
1952 return(smb_messages
[type
].name
);
1955 /****************************************************************************
1956 Helper functions for contruct_reply.
1957 ****************************************************************************/
1959 void add_to_common_flags2(uint32 v
)
1964 void remove_from_common_flags2(uint32 v
)
1966 common_flags2
&= ~v
;
1969 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1972 uint16_t in_flags2
= SVAL(inbuf
,smb_flg2
);
1973 uint16_t out_flags2
= common_flags2
;
1975 out_flags2
|= in_flags2
& FLAGS2_UNICODE_STRINGS
;
1976 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
;
1977 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
;
1979 srv_set_message(outbuf
,0,0,false);
1981 SCVAL(outbuf
, smb_com
, req
->cmd
);
1982 SIVAL(outbuf
,smb_rcls
,0);
1983 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1984 SSVAL(outbuf
,smb_flg2
, out_flags2
);
1985 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1986 memcpy(outbuf
+smb_ss_field
, inbuf
+smb_ss_field
, 8);
1988 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
1989 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
1990 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
1991 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
1994 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
1996 construct_reply_common(req
, (const char *)req
->inbuf
, outbuf
);
2000 * @brief Find the smb_cmd offset of the last command pushed
2001 * @param[in] buf The buffer we're building up
2002 * @retval Where can we put our next andx cmd?
2004 * While chaining requests, the "next" request we're looking at needs to put
2005 * its SMB_Command before the data the previous request already built up added
2006 * to the chain. Find the offset to the place where we have to put our cmd.
2009 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
2014 cmd
= CVAL(buf
, smb_com
);
2016 if (!is_andx_req(cmd
)) {
2022 while (CVAL(buf
, ofs
) != 0xff) {
2024 if (!is_andx_req(CVAL(buf
, ofs
))) {
2029 * ofs is from start of smb header, so add the 4 length
2030 * bytes. The next cmd is right after the wct field.
2032 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
2034 if (ofs
+4 >= talloc_get_size(buf
)) {
2044 * @brief Do the smb chaining at a buffer level
2045 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2046 * @param[in] andx_buf Buffer to be appended
2049 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
)
2051 uint8_t smb_command
= CVAL(andx_buf
, smb_com
);
2052 uint8_t wct
= CVAL(andx_buf
, smb_wct
);
2053 const uint16_t *vwv
= (const uint16_t *)(andx_buf
+ smb_vwv
);
2054 uint32_t num_bytes
= smb_buflen(andx_buf
);
2055 const uint8_t *bytes
= (const uint8_t *)smb_buf_const(andx_buf
);
2058 size_t old_size
, new_size
;
2060 size_t chain_padding
= 0;
2061 size_t andx_cmd_ofs
;
2064 old_size
= talloc_get_size(*poutbuf
);
2066 if ((old_size
% 4) != 0) {
2068 * Align the wct field of subsequent requests to a 4-byte
2071 chain_padding
= 4 - (old_size
% 4);
2075 * After the old request comes the new wct field (1 byte), the vwv's
2076 * and the num_bytes field.
2079 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
2080 new_size
+= num_bytes
;
2082 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
2083 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2084 (unsigned)new_size
));
2088 outbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, new_size
);
2089 if (outbuf
== NULL
) {
2090 DEBUG(0, ("talloc failed\n"));
2095 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
2096 DEBUG(1, ("invalid command chain\n"));
2097 *poutbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, old_size
);
2101 if (chain_padding
!= 0) {
2102 memset(outbuf
+ old_size
, 0, chain_padding
);
2103 old_size
+= chain_padding
;
2106 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
2107 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
2112 * Push the chained request:
2117 SCVAL(outbuf
, ofs
, wct
);
2124 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
2129 * Read&X has an offset into its data buffer at
2130 * vwv[6]. reply_read_andx has no idea anymore that it's
2131 * running from within a chain, so we have to fix up the
2134 * Although it looks disgusting at this place, I want to keep
2135 * it here. The alternative would be to push knowledge about
2136 * the andx chain down into read&x again.
2139 if (smb_command
== SMBreadX
) {
2140 uint8_t *bytes_addr
;
2144 * Invalid read&x response
2149 bytes_addr
= outbuf
+ ofs
/* vwv start */
2150 + sizeof(uint16_t) * wct
/* vwv array */
2151 + sizeof(uint16_t); /* bcc */
2153 SSVAL(outbuf
+ ofs
, 6 * sizeof(uint16_t),
2154 bytes_addr
- outbuf
- 4);
2157 ofs
+= sizeof(uint16_t) * wct
;
2163 SSVAL(outbuf
, ofs
, num_bytes
);
2164 ofs
+= sizeof(uint16_t);
2170 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
2175 bool smb1_is_chain(const uint8_t *buf
)
2177 uint8_t cmd
, wct
, andx_cmd
;
2179 cmd
= CVAL(buf
, smb_com
);
2180 if (!is_andx_req(cmd
)) {
2183 wct
= CVAL(buf
, smb_wct
);
2187 andx_cmd
= CVAL(buf
, smb_vwv
);
2188 return (andx_cmd
!= 0xFF);
2191 bool smb1_walk_chain(const uint8_t *buf
,
2192 bool (*fn
)(uint8_t cmd
,
2193 uint8_t wct
, const uint16_t *vwv
,
2194 uint16_t num_bytes
, const uint8_t *bytes
,
2195 void *private_data
),
2198 size_t smblen
= smb_len(buf
);
2199 const char *smb_buf
= smb_base(buf
);
2200 uint8_t cmd
, chain_cmd
;
2202 const uint16_t *vwv
;
2204 const uint8_t *bytes
;
2206 cmd
= CVAL(buf
, smb_com
);
2207 wct
= CVAL(buf
, smb_wct
);
2208 vwv
= (const uint16_t *)(buf
+ smb_vwv
);
2209 num_bytes
= smb_buflen(buf
);
2210 bytes
= (const uint8_t *)smb_buf_const(buf
);
2212 if (!fn(cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2216 if (!is_andx_req(cmd
)) {
2223 chain_cmd
= CVAL(vwv
, 0);
2225 while (chain_cmd
!= 0xff) {
2226 uint32_t chain_offset
; /* uint32_t to avoid overflow */
2227 size_t length_needed
;
2228 ptrdiff_t vwv_offset
;
2230 chain_offset
= SVAL(vwv
+1, 0);
2233 * Check if the client tries to fool us. The chain
2234 * offset needs to point beyond the current request in
2235 * the chain, it needs to strictly grow. Otherwise we
2236 * might be tricked into an endless loop always
2237 * processing the same request over and over again. We
2238 * used to assume that vwv and the byte buffer array
2239 * in a chain are always attached, but OS/2 the
2240 * Write&X/Read&X chain puts the Read&X vwv array
2241 * right behind the Write&X vwv chain. The Write&X bcc
2242 * array is put behind the Read&X vwv array. So now we
2243 * check whether the chain offset points strictly
2244 * behind the previous vwv array. req->buf points
2245 * right after the vwv array of the previous
2247 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2251 vwv_offset
= ((const char *)vwv
- smb_buf
);
2252 if (chain_offset
<= vwv_offset
) {
2257 * Next check: Make sure the chain offset does not
2258 * point beyond the overall smb request length.
2261 length_needed
= chain_offset
+1; /* wct */
2262 if (length_needed
> smblen
) {
2267 * Now comes the pointer magic. Goal here is to set up
2268 * vwv and buf correctly again. The chain offset (the
2269 * former vwv[1]) points at the new wct field.
2272 wct
= CVAL(smb_buf
, chain_offset
);
2274 if (is_andx_req(chain_cmd
) && (wct
< 2)) {
2279 * Next consistency check: Make the new vwv array fits
2280 * in the overall smb request.
2283 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2284 if (length_needed
> smblen
) {
2287 vwv
= (const uint16_t *)(smb_buf
+ chain_offset
+ 1);
2290 * Now grab the new byte buffer....
2293 num_bytes
= SVAL(vwv
+wct
, 0);
2296 * .. and check that it fits.
2299 length_needed
+= num_bytes
;
2300 if (length_needed
> smblen
) {
2303 bytes
= (const uint8_t *)(vwv
+wct
+1);
2305 if (!fn(chain_cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2309 if (!is_andx_req(chain_cmd
)) {
2312 chain_cmd
= CVAL(vwv
, 0);
2317 static bool smb1_chain_length_cb(uint8_t cmd
,
2318 uint8_t wct
, const uint16_t *vwv
,
2319 uint16_t num_bytes
, const uint8_t *bytes
,
2322 unsigned *count
= (unsigned *)private_data
;
2327 unsigned smb1_chain_length(const uint8_t *buf
)
2331 if (!smb1_walk_chain(buf
, smb1_chain_length_cb
, &count
)) {
2337 struct smb1_parse_chain_state
{
2338 TALLOC_CTX
*mem_ctx
;
2340 struct smbd_server_connection
*sconn
;
2341 struct smbXsrv_connection
*xconn
;
2345 struct smb_request
**reqs
;
2349 static bool smb1_parse_chain_cb(uint8_t cmd
,
2350 uint8_t wct
, const uint16_t *vwv
,
2351 uint16_t num_bytes
, const uint8_t *bytes
,
2354 struct smb1_parse_chain_state
*state
=
2355 (struct smb1_parse_chain_state
*)private_data
;
2356 struct smb_request
**reqs
;
2357 struct smb_request
*req
;
2360 reqs
= talloc_realloc(state
->mem_ctx
, state
->reqs
,
2361 struct smb_request
*, state
->num_reqs
+1);
2367 req
= talloc(reqs
, struct smb_request
);
2372 ok
= init_smb_request(req
, state
->sconn
, state
->xconn
, state
->buf
, 0,
2373 state
->encrypted
, state
->seqnum
);
2380 req
->buflen
= num_bytes
;
2383 reqs
[state
->num_reqs
] = req
;
2384 state
->num_reqs
+= 1;
2388 bool smb1_parse_chain(TALLOC_CTX
*mem_ctx
, const uint8_t *buf
,
2389 struct smbd_server_connection
*sconn
,
2390 bool encrypted
, uint32_t seqnum
,
2391 struct smb_request
***reqs
, unsigned *num_reqs
)
2393 struct smbXsrv_connection
*xconn
= sconn
->conn
;
2394 struct smb1_parse_chain_state state
;
2397 state
.mem_ctx
= mem_ctx
;
2399 state
.sconn
= sconn
;
2400 state
.xconn
= xconn
;
2401 state
.encrypted
= encrypted
;
2402 state
.seqnum
= seqnum
;
2406 if (!smb1_walk_chain(buf
, smb1_parse_chain_cb
, &state
)) {
2407 TALLOC_FREE(state
.reqs
);
2410 for (i
=0; i
<state
.num_reqs
; i
++) {
2411 state
.reqs
[i
]->chain
= state
.reqs
;
2414 *num_reqs
= state
.num_reqs
;
2418 /****************************************************************************
2419 Check if services need reloading.
2420 ****************************************************************************/
2422 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2425 if (last_smb_conf_reload_time
== 0) {
2426 last_smb_conf_reload_time
= t
;
2429 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2430 reload_services(sconn
, conn_snum_used
, true);
2431 last_smb_conf_reload_time
= t
;
2435 static bool fd_is_readable(int fd
)
2439 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2441 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2445 static void smbd_server_connection_write_handler(
2446 struct smbXsrv_connection
*xconn
)
2448 /* TODO: make write nonblocking */
2451 static void smbd_server_connection_read_handler(
2452 struct smbXsrv_connection
*xconn
, int fd
)
2454 struct smbd_server_connection
*sconn
= xconn
->sconn
;
2455 uint8_t *inbuf
= NULL
;
2456 size_t inbuf_len
= 0;
2457 size_t unread_bytes
= 0;
2458 bool encrypted
= false;
2459 TALLOC_CTX
*mem_ctx
= talloc_tos();
2463 bool async_echo
= lp_async_smb_echo_handler();
2464 bool from_client
= false;
2467 if (fd_is_readable(xconn
->smb1
.echo_handler
.trusted_fd
)) {
2469 * This is the super-ugly hack to prefer the packets
2470 * forwarded by the echo handler over the ones by the
2473 fd
= xconn
->smb1
.echo_handler
.trusted_fd
;
2477 from_client
= (xconn
->transport
.sock
== fd
);
2479 if (async_echo
&& from_client
) {
2480 smbd_lock_socket(sconn
);
2482 if (!fd_is_readable(fd
)) {
2483 DEBUG(10,("the echo listener was faster\n"));
2484 smbd_unlock_socket(sconn
);
2489 /* TODO: make this completely nonblocking */
2490 status
= receive_smb_talloc(mem_ctx
, sconn
, fd
,
2491 (char **)(void *)&inbuf
,
2495 &inbuf_len
, &seqnum
,
2496 !from_client
/* trusted channel */);
2498 if (async_echo
&& from_client
) {
2499 smbd_unlock_socket(sconn
);
2502 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2505 if (NT_STATUS_IS_ERR(status
)) {
2506 exit_server_cleanly("failed to receive smb request");
2508 if (!NT_STATUS_IS_OK(status
)) {
2513 process_smb(xconn
, inbuf
, inbuf_len
, unread_bytes
,
2514 seqnum
, encrypted
, NULL
);
2517 static void smbd_server_connection_handler(struct tevent_context
*ev
,
2518 struct tevent_fd
*fde
,
2522 struct smbXsrv_connection
*xconn
=
2523 talloc_get_type_abort(private_data
,
2524 struct smbXsrv_connection
);
2526 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2528 * we're not supposed to do any io
2530 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
2531 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
2535 if (flags
& TEVENT_FD_WRITE
) {
2536 smbd_server_connection_write_handler(xconn
);
2539 if (flags
& TEVENT_FD_READ
) {
2540 smbd_server_connection_read_handler(xconn
, xconn
->transport
.sock
);
2545 static void smbd_server_echo_handler(struct tevent_context
*ev
,
2546 struct tevent_fd
*fde
,
2550 struct smbXsrv_connection
*xconn
=
2551 talloc_get_type_abort(private_data
,
2552 struct smbXsrv_connection
);
2554 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2556 * we're not supposed to do any io
2558 TEVENT_FD_NOT_READABLE(xconn
->smb1
.echo_handler
.trusted_fde
);
2559 TEVENT_FD_NOT_WRITEABLE(xconn
->smb1
.echo_handler
.trusted_fde
);
2563 if (flags
& TEVENT_FD_WRITE
) {
2564 smbd_server_connection_write_handler(xconn
);
2567 if (flags
& TEVENT_FD_READ
) {
2568 smbd_server_connection_read_handler(
2569 xconn
, xconn
->smb1
.echo_handler
.trusted_fd
);
2574 struct smbd_release_ip_state
{
2575 struct smbXsrv_connection
*xconn
;
2576 struct tevent_immediate
*im
;
2577 char addr
[INET6_ADDRSTRLEN
];
2580 static void smbd_release_ip_immediate(struct tevent_context
*ctx
,
2581 struct tevent_immediate
*im
,
2584 struct smbd_release_ip_state
*state
=
2585 talloc_get_type_abort(private_data
,
2586 struct smbd_release_ip_state
);
2587 struct smbXsrv_connection
*xconn
= state
->xconn
;
2589 if (!NT_STATUS_EQUAL(xconn
->transport
.status
, NT_STATUS_ADDRESS_CLOSED
)) {
2591 * smbd_server_connection_terminate() already triggered ?
2596 smbd_server_connection_terminate(xconn
, "CTDB_SRVID_RELEASE_IP");
2599 /****************************************************************************
2600 received when we should release a specific IP
2601 ****************************************************************************/
2602 static bool release_ip(const char *ip
, void *priv
)
2604 struct smbd_release_ip_state
*state
=
2605 talloc_get_type_abort(priv
,
2606 struct smbd_release_ip_state
);
2607 struct smbXsrv_connection
*xconn
= state
->xconn
;
2608 const char *addr
= state
->addr
;
2609 const char *p
= addr
;
2611 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2612 /* avoid recursion */
2616 if (strncmp("::ffff:", addr
, 7) == 0) {
2620 DEBUG(10, ("Got release IP message for %s, "
2621 "our address is %s\n", ip
, p
));
2623 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2624 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2627 * With SMB2 we should do a clean disconnect,
2628 * the previous_session_id in the session setup
2629 * will cleanup the old session, tcons and opens.
2631 * A clean disconnect is needed in order to support
2634 * Note: typically this is never triggered
2635 * as we got a TCP RST (triggered by ctdb event scripts)
2636 * before we get CTDB_SRVID_RELEASE_IP.
2638 * We used to call _exit(1) here, but as this was mostly never
2639 * triggered and has implication on our process model,
2640 * we can just use smbd_server_connection_terminate()
2643 * We don't call smbd_server_connection_terminate() directly
2644 * as we might be called from within ctdbd_migrate(),
2645 * we need to defer our action to the next event loop
2647 tevent_schedule_immediate(state
->im
, xconn
->ev_ctx
,
2648 smbd_release_ip_immediate
, state
);
2651 * Make sure we don't get any io on the connection.
2653 xconn
->transport
.status
= NT_STATUS_ADDRESS_CLOSED
;
2660 static NTSTATUS
smbd_register_ips(struct smbXsrv_connection
*xconn
,
2661 struct sockaddr_storage
*srv
,
2662 struct sockaddr_storage
*clnt
)
2664 struct smbd_release_ip_state
*state
;
2665 struct ctdbd_connection
*cconn
;
2667 cconn
= messaging_ctdbd_connection();
2668 if (cconn
== NULL
) {
2669 return NT_STATUS_NO_MEMORY
;
2672 state
= talloc_zero(xconn
, struct smbd_release_ip_state
);
2673 if (state
== NULL
) {
2674 return NT_STATUS_NO_MEMORY
;
2676 state
->xconn
= xconn
;
2677 state
->im
= tevent_create_immediate(state
);
2678 if (state
->im
== NULL
) {
2679 return NT_STATUS_NO_MEMORY
;
2681 if (print_sockaddr(state
->addr
, sizeof(state
->addr
), srv
) == NULL
) {
2682 return NT_STATUS_NO_MEMORY
;
2685 return ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, state
);
2688 static void msg_kill_client_ip(struct messaging_context
*msg_ctx
,
2689 void *private_data
, uint32_t msg_type
,
2690 struct server_id server_id
, DATA_BLOB
*data
)
2692 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2693 private_data
, struct smbd_server_connection
);
2694 const char *ip
= (char *) data
->data
;
2697 DEBUG(10, ("Got kill request for client IP %s\n", ip
));
2699 client_ip
= tsocket_address_inet_addr_string(sconn
->remote_address
,
2701 if (client_ip
== NULL
) {
2705 if (strequal(ip
, client_ip
)) {
2706 DEBUG(1, ("Got kill client message for %s - "
2707 "exiting immediately\n", ip
));
2708 exit_server_cleanly("Forced disconnect for client");
2711 TALLOC_FREE(client_ip
);
2715 * Send keepalive packets to our client
2717 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2719 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2720 private_data
, struct smbd_server_connection
);
2721 struct smbXsrv_connection
*xconn
= sconn
->conn
;
2724 if (sconn
->using_smb2
) {
2725 /* Don't do keepalives on an SMB2 connection. */
2729 smbd_lock_socket(sconn
);
2730 ret
= send_keepalive(xconn
->transport
.sock
);
2731 smbd_unlock_socket(sconn
);
2734 int saved_errno
= errno
;
2736 * Try and give an error message saying what
2739 DEBUG(0, ("send_keepalive failed for client %s. "
2740 "Error %s - exiting\n",
2741 smbXsrv_connection_dbg(xconn
),
2742 strerror(saved_errno
)));
2743 errno
= saved_errno
;
2750 * Do the recurring check if we're idle
2752 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2754 struct smbd_server_connection
*sconn
=
2755 (struct smbd_server_connection
*)private_data
;
2757 if ((conn_num_open(sconn
) == 0)
2758 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2759 DEBUG( 2, ( "Closing idle connection\n" ) );
2760 messaging_send(sconn
->msg_ctx
,
2761 messaging_server_id(sconn
->msg_ctx
),
2762 MSG_SHUTDOWN
, &data_blob_null
);
2770 * Do the recurring log file and smb.conf reload checks.
2773 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2775 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2776 private_data
, struct smbd_server_connection
);
2778 DEBUG(5, ("housekeeping\n"));
2780 change_to_root_user();
2782 /* update printer queue caches if necessary */
2783 update_monitored_printq_cache(sconn
->msg_ctx
);
2785 /* check if we need to reload services */
2786 check_reload(sconn
, time_mono(NULL
));
2789 * Force a log file check.
2791 force_check_log_size();
2797 * Read an smb packet in the echo handler child, giving the parent
2798 * smbd one second to react once the socket becomes readable.
2801 struct smbd_echo_read_state
{
2802 struct tevent_context
*ev
;
2803 struct smbd_server_connection
*sconn
;
2810 static void smbd_echo_read_readable(struct tevent_req
*subreq
);
2811 static void smbd_echo_read_waited(struct tevent_req
*subreq
);
2813 static struct tevent_req
*smbd_echo_read_send(
2814 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2815 struct smbd_server_connection
*sconn
)
2817 struct tevent_req
*req
, *subreq
;
2818 struct smbd_echo_read_state
*state
;
2819 struct smbXsrv_connection
*xconn
= sconn
->conn
;
2821 req
= tevent_req_create(mem_ctx
, &state
,
2822 struct smbd_echo_read_state
);
2827 state
->sconn
= sconn
;
2829 subreq
= wait_for_read_send(state
, ev
, xconn
->transport
.sock
);
2830 if (tevent_req_nomem(subreq
, req
)) {
2831 return tevent_req_post(req
, ev
);
2833 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2837 static void smbd_echo_read_readable(struct tevent_req
*subreq
)
2839 struct tevent_req
*req
= tevent_req_callback_data(
2840 subreq
, struct tevent_req
);
2841 struct smbd_echo_read_state
*state
= tevent_req_data(
2842 req
, struct smbd_echo_read_state
);
2846 ok
= wait_for_read_recv(subreq
, &err
);
2847 TALLOC_FREE(subreq
);
2849 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
2854 * Give the parent smbd one second to step in
2857 subreq
= tevent_wakeup_send(
2858 state
, state
->ev
, timeval_current_ofs(1, 0));
2859 if (tevent_req_nomem(subreq
, req
)) {
2862 tevent_req_set_callback(subreq
, smbd_echo_read_waited
, req
);
2865 static void smbd_echo_read_waited(struct tevent_req
*subreq
)
2867 struct tevent_req
*req
= tevent_req_callback_data(
2868 subreq
, struct tevent_req
);
2869 struct smbd_echo_read_state
*state
= tevent_req_data(
2870 req
, struct smbd_echo_read_state
);
2871 struct smbd_server_connection
*sconn
= state
->sconn
;
2872 struct smbXsrv_connection
*xconn
= sconn
->conn
;
2878 ok
= tevent_wakeup_recv(subreq
);
2879 TALLOC_FREE(subreq
);
2881 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2885 ok
= smbd_lock_socket_internal(sconn
);
2887 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2888 DEBUG(0, ("%s: failed to lock socket\n", __location__
));
2892 if (!fd_is_readable(xconn
->transport
.sock
)) {
2893 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2896 ok
= smbd_unlock_socket_internal(sconn
);
2898 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2899 DEBUG(1, ("%s: failed to unlock socket\n",
2904 subreq
= wait_for_read_send(state
, state
->ev
,
2905 xconn
->transport
.sock
);
2906 if (tevent_req_nomem(subreq
, req
)) {
2909 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2913 status
= receive_smb_talloc(state
, sconn
,
2914 xconn
->transport
.sock
,
2921 false /* trusted_channel*/);
2923 if (tevent_req_nterror(req
, status
)) {
2924 tevent_req_nterror(req
, status
);
2925 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2926 (int)getpid(), nt_errstr(status
)));
2930 ok
= smbd_unlock_socket_internal(sconn
);
2932 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2933 DEBUG(1, ("%s: failed to unlock socket\n", __location__
));
2936 tevent_req_done(req
);
2939 static NTSTATUS
smbd_echo_read_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2940 char **pbuf
, size_t *pbuflen
, uint32_t *pseqnum
)
2942 struct smbd_echo_read_state
*state
= tevent_req_data(
2943 req
, struct smbd_echo_read_state
);
2946 if (tevent_req_is_nterror(req
, &status
)) {
2949 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
2950 *pbuflen
= state
->buflen
;
2951 *pseqnum
= state
->seqnum
;
2952 return NT_STATUS_OK
;
2955 struct smbd_echo_state
{
2956 struct tevent_context
*ev
;
2957 struct iovec
*pending
;
2958 struct smbd_server_connection
*sconn
;
2959 struct smbXsrv_connection
*xconn
;
2962 struct tevent_fd
*parent_fde
;
2964 struct tevent_req
*write_req
;
2967 static void smbd_echo_writer_done(struct tevent_req
*req
);
2969 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2973 if (state
->write_req
!= NULL
) {
2977 num_pending
= talloc_array_length(state
->pending
);
2978 if (num_pending
== 0) {
2982 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
2983 state
->parent_pipe
, false,
2984 state
->pending
, num_pending
);
2985 if (state
->write_req
== NULL
) {
2986 DEBUG(1, ("writev_send failed\n"));
2990 talloc_steal(state
->write_req
, state
->pending
);
2991 state
->pending
= NULL
;
2993 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
2997 static void smbd_echo_writer_done(struct tevent_req
*req
)
2999 struct smbd_echo_state
*state
= tevent_req_callback_data(
3000 req
, struct smbd_echo_state
);
3004 written
= writev_recv(req
, &err
);
3006 state
->write_req
= NULL
;
3007 if (written
== -1) {
3008 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
3011 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3012 smbd_echo_activate_writer(state
);
3015 static bool smbd_echo_reply(struct smbd_echo_state
*state
,
3016 uint8_t *inbuf
, size_t inbuf_len
,
3019 struct smb_request req
;
3020 uint16_t num_replies
;
3024 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == NBSSkeepalive
)) {
3025 DEBUG(10, ("Got netbios keepalive\n"));
3032 if (inbuf_len
< smb_size
) {
3033 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
3036 if (!valid_smb_header(state
->sconn
, inbuf
)) {
3037 DEBUG(10, ("Got invalid SMB header\n"));
3041 if (!init_smb_request(&req
, state
->sconn
, state
->xconn
, inbuf
, 0, false,
3047 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
3048 smb_messages
[req
.cmd
].name
3049 ? smb_messages
[req
.cmd
].name
: "unknown"));
3051 if (req
.cmd
!= SMBecho
) {
3058 num_replies
= SVAL(req
.vwv
+0, 0);
3059 if (num_replies
!= 1) {
3060 /* Not a Windows "Hey, you're still there?" request */
3064 if (!create_outbuf(talloc_tos(), &req
, (const char *)req
.inbuf
, &outbuf
,
3066 DEBUG(10, ("create_outbuf failed\n"));
3069 req
.outbuf
= (uint8_t *)outbuf
;
3071 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
3073 if (req
.buflen
> 0) {
3074 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
3077 ok
= srv_send_smb(req
.sconn
,
3081 TALLOC_FREE(outbuf
);
3089 static void smbd_echo_exit(struct tevent_context
*ev
,
3090 struct tevent_fd
*fde
, uint16_t flags
,
3093 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3097 static void smbd_echo_got_packet(struct tevent_req
*req
);
3099 static void smbd_echo_loop(struct smbd_server_connection
*sconn
,
3102 struct smbXsrv_connection
*xconn
= sconn
->conn
;
3103 struct smbd_echo_state
*state
;
3104 struct tevent_req
*read_req
;
3106 state
= talloc_zero(sconn
, struct smbd_echo_state
);
3107 if (state
== NULL
) {
3108 DEBUG(1, ("talloc failed\n"));
3111 state
->sconn
= sconn
;
3112 state
->xconn
= xconn
;
3113 state
->parent_pipe
= parent_pipe
;
3114 state
->ev
= s3_tevent_context_init(state
);
3115 if (state
->ev
== NULL
) {
3116 DEBUG(1, ("tevent_context_init failed\n"));
3120 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
3121 TEVENT_FD_READ
, smbd_echo_exit
,
3123 if (state
->parent_fde
== NULL
) {
3124 DEBUG(1, ("tevent_add_fd failed\n"));
3129 read_req
= smbd_echo_read_send(state
, state
->ev
, sconn
);
3130 if (read_req
== NULL
) {
3131 DEBUG(1, ("smbd_echo_read_send failed\n"));
3135 tevent_req_set_callback(read_req
, smbd_echo_got_packet
, state
);
3138 if (tevent_loop_once(state
->ev
) == -1) {
3139 DEBUG(1, ("tevent_loop_once failed: %s\n",
3147 static void smbd_echo_got_packet(struct tevent_req
*req
)
3149 struct smbd_echo_state
*state
= tevent_req_callback_data(
3150 req
, struct smbd_echo_state
);
3154 uint32_t seqnum
= 0;
3157 status
= smbd_echo_read_recv(req
, state
, &buf
, &buflen
, &seqnum
);
3159 if (!NT_STATUS_IS_OK(status
)) {
3160 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3161 nt_errstr(status
)));
3165 reply
= smbd_echo_reply(state
, (uint8_t *)buf
, buflen
, seqnum
);
3171 num_pending
= talloc_array_length(state
->pending
);
3172 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
3175 DEBUG(1, ("talloc_realloc failed\n"));
3178 state
->pending
= tmp
;
3180 if (buflen
>= smb_size
) {
3182 * place the seqnum in the packet so that the main process
3183 * can reply with signing
3185 SIVAL(buf
, smb_ss_field
, seqnum
);
3186 SIVAL(buf
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
3189 iov
= &state
->pending
[num_pending
];
3190 iov
->iov_base
= talloc_move(state
->pending
, &buf
);
3191 iov
->iov_len
= buflen
;
3193 DEBUG(10,("echo_handler[%d]: forward to main\n",
3195 smbd_echo_activate_writer(state
);
3198 req
= smbd_echo_read_send(state
, state
->ev
, state
->sconn
);
3200 DEBUG(1, ("smbd_echo_read_send failed\n"));
3203 tevent_req_set_callback(req
, smbd_echo_got_packet
, state
);
3208 * Handle SMBecho requests in a forked child process
3210 bool fork_echo_handler(struct smbd_server_connection
*sconn
)
3212 struct smbXsrv_connection
*xconn
= sconn
->conn
;
3213 int listener_pipe
[2];
3216 bool use_mutex
= false;
3218 res
= pipe(listener_pipe
);
3220 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
3224 #ifdef HAVE_ROBUST_MUTEXES
3225 use_mutex
= tdb_runtime_check_for_robust_mutexes();
3228 pthread_mutexattr_t a
;
3230 xconn
->smb1
.echo_handler
.socket_mutex
=
3231 anonymous_shared_allocate(sizeof(pthread_mutex_t
));
3232 if (xconn
->smb1
.echo_handler
.socket_mutex
== NULL
) {
3233 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3238 res
= pthread_mutexattr_init(&a
);
3240 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3244 res
= pthread_mutexattr_settype(&a
, PTHREAD_MUTEX_ERRORCHECK
);
3246 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3248 pthread_mutexattr_destroy(&a
);
3251 res
= pthread_mutexattr_setpshared(&a
, PTHREAD_PROCESS_SHARED
);
3253 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3255 pthread_mutexattr_destroy(&a
);
3258 res
= pthread_mutexattr_setrobust(&a
, PTHREAD_MUTEX_ROBUST
);
3260 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3261 "%s\n", strerror(res
)));
3262 pthread_mutexattr_destroy(&a
);
3265 res
= pthread_mutex_init(xconn
->smb1
.echo_handler
.socket_mutex
,
3267 pthread_mutexattr_destroy(&a
);
3269 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3277 xconn
->smb1
.echo_handler
.socket_lock_fd
=
3278 create_unlink_tmp(lp_lock_directory());
3279 if (xconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
3280 DEBUG(1, ("Could not create lock fd: %s\n",
3290 close(listener_pipe
[0]);
3291 set_blocking(listener_pipe
[1], false);
3293 status
= reinit_after_fork(sconn
->msg_ctx
,
3296 if (!NT_STATUS_IS_OK(status
)) {
3297 DEBUG(1, ("reinit_after_fork failed: %s\n",
3298 nt_errstr(status
)));
3301 smbd_echo_loop(sconn
, listener_pipe
[1]);
3304 close(listener_pipe
[1]);
3305 listener_pipe
[1] = -1;
3306 xconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
3308 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child
));
3311 * Without smb signing this is the same as the normal smbd
3312 * listener. This needs to change once signing comes in.
3314 xconn
->smb1
.echo_handler
.trusted_fde
= tevent_add_fd(xconn
->ev_ctx
,
3316 xconn
->smb1
.echo_handler
.trusted_fd
,
3318 smbd_server_echo_handler
,
3320 if (xconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
3321 DEBUG(1, ("event_add_fd failed\n"));
3328 if (listener_pipe
[0] != -1) {
3329 close(listener_pipe
[0]);
3331 if (listener_pipe
[1] != -1) {
3332 close(listener_pipe
[1]);
3334 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
3335 close(xconn
->smb1
.echo_handler
.socket_lock_fd
);
3337 #ifdef HAVE_ROBUST_MUTEXES
3338 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
3339 pthread_mutex_destroy(xconn
->smb1
.echo_handler
.socket_mutex
);
3340 anonymous_shared_free(xconn
->smb1
.echo_handler
.socket_mutex
);
3343 smbd_echo_init(xconn
);
3348 static bool uid_in_use(const struct user_struct
*user
, uid_t uid
)
3351 if (user
->session_info
&&
3352 (user
->session_info
->unix_token
->uid
== uid
)) {
3360 static bool gid_in_use(const struct user_struct
*user
, gid_t gid
)
3363 if (user
->session_info
!= NULL
) {
3365 struct security_unix_token
*utok
;
3367 utok
= user
->session_info
->unix_token
;
3368 if (utok
->gid
== gid
) {
3371 for(i
=0; i
<utok
->ngroups
; i
++) {
3372 if (utok
->groups
[i
] == gid
) {
3382 static bool sid_in_use(const struct user_struct
*user
,
3383 const struct dom_sid
*psid
)
3386 struct security_token
*tok
;
3388 if (user
->session_info
== NULL
) {
3391 tok
= user
->session_info
->security_token
;
3394 * Not sure session_info->security_token can
3395 * ever be NULL. This check might be not
3400 if (security_token_has_sid(tok
, psid
)) {
3408 static bool id_in_use(const struct user_struct
*user
,
3409 const struct id_cache_ref
*id
)
3413 return uid_in_use(user
, id
->id
.uid
);
3415 return gid_in_use(user
, id
->id
.gid
);
3417 return sid_in_use(user
, &id
->id
.sid
);
3424 static void smbd_id_cache_kill(struct messaging_context
*msg_ctx
,
3427 struct server_id server_id
,
3430 const char *msg
= (data
&& data
->data
)
3431 ? (const char *)data
->data
: "<NULL>";
3432 struct id_cache_ref id
;
3433 struct smbd_server_connection
*sconn
=
3434 talloc_get_type_abort(private_data
,
3435 struct smbd_server_connection
);
3437 if (!id_cache_ref_parse(msg
, &id
)) {
3438 DEBUG(0, ("Invalid ?ID: %s\n", msg
));
3442 if (id_in_use(sconn
->users
, &id
)) {
3443 exit_server_cleanly(msg
);
3445 id_cache_delete_from_cache(&id
);
3448 NTSTATUS
smbXsrv_connection_init_tables(struct smbXsrv_connection
*conn
,
3449 enum protocol_types protocol
)
3453 set_Protocol(protocol
);
3454 conn
->protocol
= protocol
;
3456 if (protocol
>= PROTOCOL_SMB2_02
) {
3457 status
= smb2srv_session_table_init(conn
);
3458 if (!NT_STATUS_IS_OK(status
)) {
3462 status
= smb2srv_open_table_init(conn
);
3463 if (!NT_STATUS_IS_OK(status
)) {
3467 status
= smb1srv_session_table_init(conn
);
3468 if (!NT_STATUS_IS_OK(status
)) {
3472 status
= smb1srv_tcon_table_init(conn
);
3473 if (!NT_STATUS_IS_OK(status
)) {
3477 status
= smb1srv_open_table_init(conn
);
3478 if (!NT_STATUS_IS_OK(status
)) {
3483 return NT_STATUS_OK
;
3486 static void smbd_tevent_trace_callback(enum tevent_trace_point point
,
3489 struct smbXsrv_connection
*conn
=
3490 talloc_get_type_abort(private_data
,
3491 struct smbXsrv_connection
);
3494 case TEVENT_TRACE_BEFORE_WAIT
:
3496 * This just removes compiler warning
3497 * without profile support
3499 conn
->smbd_idle_profstamp
= 0;
3500 START_PROFILE_STAMP(smbd_idle
, conn
->smbd_idle_profstamp
);
3502 case TEVENT_TRACE_AFTER_WAIT
:
3503 END_PROFILE_STAMP(smbd_idle
, conn
->smbd_idle_profstamp
);
3505 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3506 case TEVENT_TRACE_BEFORE_LOOP_ONCE
:
3507 case TEVENT_TRACE_AFTER_LOOP_ONCE
:
3514 * Create a debug string for the connection
3516 * This is allocated to talloc_tos() or a string constant
3517 * in certain corner cases. The returned string should
3518 * hence not be free'd directly but only via the talloc stack.
3520 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection
*xconn
)
3525 * TODO: this can be improved later
3526 * maybe including the client guid or more
3528 ret
= tsocket_address_string(xconn
->remote_address
, talloc_tos());
3530 return "<tsocket_address_string() failed>";
3536 /****************************************************************************
3537 Process commands from the client
3538 ****************************************************************************/
3540 void smbd_process(struct tevent_context
*ev_ctx
,
3541 struct messaging_context
*msg_ctx
,
3545 TALLOC_CTX
*frame
= talloc_stackframe();
3546 struct smbXsrv_connection
*xconn
;
3547 struct smbd_server_connection
*sconn
;
3548 struct sockaddr_storage ss_srv
;
3549 void *sp_srv
= (void *)&ss_srv
;
3550 struct sockaddr
*sa_srv
= (struct sockaddr
*)sp_srv
;
3551 struct sockaddr_storage ss_clnt
;
3552 void *sp_clnt
= (void *)&ss_clnt
;
3553 struct sockaddr
*sa_clnt
= (struct sockaddr
*)sp_clnt
;
3554 socklen_t sa_socklen
;
3555 struct tsocket_address
*local_address
= NULL
;
3556 struct tsocket_address
*remote_address
= NULL
;
3557 const char *locaddr
= NULL
;
3558 const char *remaddr
= NULL
;
3563 xconn
= talloc_zero(ev_ctx
, struct smbXsrv_connection
);
3564 if (xconn
== NULL
) {
3565 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3566 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3569 xconn
->ev_ctx
= ev_ctx
;
3570 xconn
->msg_ctx
= msg_ctx
;
3571 xconn
->transport
.sock
= sock_fd
;
3572 smbd_echo_init(xconn
);
3574 sconn
= talloc_zero(xconn
, struct smbd_server_connection
);
3576 exit_server("failed to create smbd_server_connection");
3579 xconn
->sconn
= sconn
;
3580 sconn
->conn
= xconn
;
3583 * TODO: remove this...:-)
3585 global_smbXsrv_connection
= xconn
;
3587 sconn
->ev_ctx
= ev_ctx
;
3588 sconn
->msg_ctx
= msg_ctx
;
3591 smbd_setup_sig_term_handler(sconn
);
3592 smbd_setup_sig_hup_handler(sconn
);
3594 if (!serverid_register(messaging_server_id(msg_ctx
),
3595 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
3597 |FLAG_MSG_PRINT_GENERAL
)) {
3598 exit_server_cleanly("Could not register myself in "
3603 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02
) {
3605 * We're not making the decision here,
3606 * we're just allowing the client
3607 * to decide between SMB1 and SMB2
3608 * with the first negprot
3611 sconn
->using_smb2
= true;
3614 /* Ensure child is set to blocking mode */
3615 set_blocking(sock_fd
,True
);
3617 set_socket_options(sock_fd
, "SO_KEEPALIVE");
3618 set_socket_options(sock_fd
, lp_socket_options());
3620 sa_socklen
= sizeof(ss_clnt
);
3621 ret
= getpeername(sock_fd
, sa_clnt
, &sa_socklen
);
3623 int level
= (errno
== ENOTCONN
)?2:0;
3624 DEBUG(level
,("getpeername() failed - %s\n", strerror(errno
)));
3625 exit_server_cleanly("getpeername() failed.\n");
3627 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3628 sa_clnt
, sa_socklen
,
3631 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3632 __location__
, strerror(errno
)));
3633 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3636 sa_socklen
= sizeof(ss_srv
);
3637 ret
= getsockname(sock_fd
, sa_srv
, &sa_socklen
);
3639 int level
= (errno
== ENOTCONN
)?2:0;
3640 DEBUG(level
,("getsockname() failed - %s\n", strerror(errno
)));
3641 exit_server_cleanly("getsockname() failed.\n");
3643 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3647 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3648 __location__
, strerror(errno
)));
3649 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3652 sconn
->local_address
= local_address
;
3653 sconn
->remote_address
= remote_address
;
3655 if (tsocket_address_is_inet(local_address
, "ip")) {
3656 locaddr
= tsocket_address_inet_addr_string(
3657 sconn
->local_address
,
3659 if (locaddr
== NULL
) {
3660 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3661 __location__
, strerror(errno
)));
3662 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3665 locaddr
= "0.0.0.0";
3668 if (tsocket_address_is_inet(remote_address
, "ip")) {
3669 remaddr
= tsocket_address_inet_addr_string(
3670 sconn
->remote_address
,
3672 if (remaddr
== NULL
) {
3673 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3674 __location__
, strerror(errno
)));
3675 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3678 remaddr
= "0.0.0.0";
3681 /* this is needed so that we get decent entries
3682 in smbstatus for port 445 connects */
3683 set_remote_machine_name(remaddr
, false);
3684 reload_services(sconn
, conn_snum_used
, true);
3687 * Before the first packet, check the global hosts allow/ hosts deny
3688 * parameters before doing any parsing of packets passed to us by the
3689 * client. This prevents attacks on our parsing code from hosts not in
3690 * the hosts allow list.
3693 ret
= get_remote_hostname(remote_address
,
3697 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3698 __location__
, strerror(errno
)));
3699 exit_server_cleanly("get_remote_hostname failed.\n");
3701 if (strequal(rhost
, "UNKNOWN")) {
3702 rhost
= talloc_strdup(talloc_tos(), remaddr
);
3704 sconn
->remote_hostname
= talloc_move(sconn
, &rhost
);
3706 sub_set_socket_ids(remaddr
,
3707 sconn
->remote_hostname
,
3710 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3711 sconn
->remote_hostname
,
3714 * send a negative session response "not listening on calling
3717 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3718 DEBUG( 1, ("Connection denied from %s to %s\n",
3719 tsocket_address_string(remote_address
, talloc_tos()),
3720 tsocket_address_string(local_address
, talloc_tos())));
3721 (void)srv_send_smb(sconn
,(char *)buf
, false,
3723 exit_server_cleanly("connection denied");
3726 DEBUG(10, ("Connection allowed from %s to %s\n",
3727 tsocket_address_string(remote_address
, talloc_tos()),
3728 tsocket_address_string(local_address
, talloc_tos())));
3730 if (lp_preload_modules()) {
3731 smb_load_modules(lp_preload_modules());
3734 smb_perfcount_init();
3736 if (!init_account_policy()) {
3737 exit_server("Could not open account policy tdb.\n");
3740 if (*lp_root_directory(talloc_tos())) {
3741 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3742 DEBUG(0,("Failed to change root to %s\n",
3743 lp_root_directory(talloc_tos())));
3744 exit_server("Failed to chroot()");
3746 if (chdir("/") == -1) {
3747 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3748 exit_server("Failed to chroot()");
3750 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3753 if (!srv_init_signing(xconn
)) {
3754 exit_server("Failed to init smb_signing");
3757 if (!file_init(sconn
)) {
3758 exit_server("file_init() failed");
3762 if (!init_oplocks(sconn
))
3763 exit_server("Failed to init oplocks");
3765 /* register our message handlers */
3766 messaging_register(sconn
->msg_ctx
, sconn
,
3767 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3768 messaging_register(sconn
->msg_ctx
, sconn
,
3769 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3770 messaging_register(sconn
->msg_ctx
, sconn
,
3771 MSG_SMB_FILE_RENAME
, msg_file_was_renamed
);
3773 id_cache_register_msgs(sconn
->msg_ctx
);
3774 messaging_deregister(sconn
->msg_ctx
, ID_CACHE_KILL
, NULL
);
3775 messaging_register(sconn
->msg_ctx
, sconn
,
3776 ID_CACHE_KILL
, smbd_id_cache_kill
);
3778 messaging_deregister(sconn
->msg_ctx
,
3779 MSG_SMB_CONF_UPDATED
, sconn
->ev_ctx
);
3780 messaging_register(sconn
->msg_ctx
, sconn
,
3781 MSG_SMB_CONF_UPDATED
, smbd_conf_updated
);
3783 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_KILL_CLIENT_IP
,
3785 messaging_register(sconn
->msg_ctx
, sconn
,
3786 MSG_SMB_KILL_CLIENT_IP
,
3787 msg_kill_client_ip
);
3789 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_TELL_NUM_CHILDREN
, NULL
);
3792 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3793 * MSGs to all child processes
3795 messaging_deregister(sconn
->msg_ctx
,
3797 messaging_register(sconn
->msg_ctx
, NULL
,
3798 MSG_DEBUG
, debug_message
);
3800 if ((lp_keepalive() != 0)
3801 && !(event_add_idle(ev_ctx
, NULL
,
3802 timeval_set(lp_keepalive(), 0),
3803 "keepalive", keepalive_fn
,
3805 DEBUG(0, ("Could not add keepalive event\n"));
3809 if (!(event_add_idle(ev_ctx
, NULL
,
3810 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3811 "deadtime", deadtime_fn
, sconn
))) {
3812 DEBUG(0, ("Could not add deadtime event\n"));
3816 if (!(event_add_idle(ev_ctx
, NULL
,
3817 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
3818 "housekeeping", housekeeping_fn
, sconn
))) {
3819 DEBUG(0, ("Could not add housekeeping event\n"));
3823 if (lp_clustering()) {
3825 * We need to tell ctdb about our client's TCP
3826 * connection, so that for failover ctdbd can send
3827 * tickle acks, triggering a reconnection by the
3832 status
= smbd_register_ips(xconn
, &ss_srv
, &ss_clnt
);
3833 if (!NT_STATUS_IS_OK(status
)) {
3834 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3835 nt_errstr(status
)));
3839 tmp
= lp_max_xmit();
3840 tmp
= MAX(tmp
, SMB_BUFFER_SIZE_MIN
);
3841 tmp
= MIN(tmp
, SMB_BUFFER_SIZE_MAX
);
3843 xconn
->smb1
.negprot
.max_recv
= tmp
;
3845 xconn
->smb1
.sessions
.done_sesssetup
= false;
3846 xconn
->smb1
.sessions
.max_send
= SMB_BUFFER_SIZE_MAX
;
3848 if (!init_dptrs(sconn
)) {
3849 exit_server("init_dptrs() failed");
3852 xconn
->transport
.fde
= tevent_add_fd(ev_ctx
,
3856 smbd_server_connection_handler
,
3858 if (!xconn
->transport
.fde
) {
3859 exit_server("failed to create smbd_server_connection fde");
3862 sconn
->conn
->local_address
= sconn
->local_address
;
3863 sconn
->conn
->remote_address
= sconn
->remote_address
;
3864 sconn
->conn
->remote_hostname
= sconn
->remote_hostname
;
3865 sconn
->conn
->protocol
= PROTOCOL_NONE
;
3869 tevent_set_trace_callback(ev_ctx
, smbd_tevent_trace_callback
, xconn
);
3872 frame
= talloc_stackframe_pool(8192);
3875 if (tevent_loop_once(ev_ctx
) == -1) {
3876 if (errno
!= EINTR
) {
3877 DEBUG(3, ("tevent_loop_once failed: %s,"
3878 " exiting\n", strerror(errno
) ));
3886 exit_server_cleanly(NULL
);
3889 bool req_is_in_chain(const struct smb_request
*req
)
3891 if (req
->vwv
!= (const uint16_t *)(req
->inbuf
+smb_vwv
)) {
3893 * We're right now handling a subsequent request, so we must
3899 if (!is_andx_req(req
->cmd
)) {
3905 * Okay, an illegal request, but definitely not chained :-)
3910 return (CVAL(req
->vwv
+0, 0) != 0xFF);