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 "lib/messages_ctdbd.h"
36 #include "smbprofile.h"
37 #include "rpc_server/spoolss/srv_spoolss_nt.h"
38 #include "libsmb/libsmb.h"
39 #include "../lib/util/tevent_ntstatus.h"
40 #include "../libcli/security/dom_sid.h"
41 #include "../libcli/security/security_token.h"
42 #include "lib/id_cache.h"
43 #include "lib/util/sys_rw_data.h"
45 #include "system/threads.h"
47 /* Internal message queue for deferred opens. */
48 struct pending_message_list
{
49 struct pending_message_list
*next
, *prev
;
50 struct timeval request_time
; /* When was this first issued? */
51 struct smbd_server_connection
*sconn
;
52 struct smbXsrv_connection
*xconn
;
53 struct tevent_timer
*te
;
54 struct smb_perfcount_data pcd
;
59 struct deferred_open_record
*open_rec
;
62 static void construct_reply_common(uint8_t cmd
, const uint8_t *inbuf
,
64 static struct pending_message_list
*get_deferred_open_message_smb(
65 struct smbd_server_connection
*sconn
, uint64_t mid
);
66 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
);
68 static void smbd_echo_init(struct smbXsrv_connection
*xconn
)
70 xconn
->smb1
.echo_handler
.trusted_fd
= -1;
71 xconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
72 #ifdef HAVE_ROBUST_MUTEXES
73 xconn
->smb1
.echo_handler
.socket_mutex
= NULL
;
77 static bool smbd_echo_active(struct smbXsrv_connection
*xconn
)
79 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
83 #ifdef HAVE_ROBUST_MUTEXES
84 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
92 static bool smbd_lock_socket_internal(struct smbXsrv_connection
*xconn
)
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 smbXsrv_connection
*xconn
)
147 if (!smbd_lock_socket_internal(xconn
)) {
148 exit_server_cleanly("failed to lock socket");
152 static bool smbd_unlock_socket_internal(struct smbXsrv_connection
*xconn
)
154 if (!smbd_echo_active(xconn
)) {
158 xconn
->smb1
.echo_handler
.ref_count
--;
160 if (xconn
->smb1
.echo_handler
.ref_count
> 0) {
164 #ifdef HAVE_ROBUST_MUTEXES
165 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
168 while (ret
== EINTR
) {
169 ret
= pthread_mutex_unlock(
170 xconn
->smb1
.echo_handler
.socket_mutex
);
176 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
183 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
188 xconn
->smb1
.echo_handler
.socket_lock_fd
,
189 F_SETLKW
, 0, 0, F_UNLCK
);
190 } while (!ok
&& (errno
== EINTR
));
193 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
198 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
203 void smbd_unlock_socket(struct smbXsrv_connection
*xconn
)
205 if (!smbd_unlock_socket_internal(xconn
)) {
206 exit_server_cleanly("failed to unlock socket");
210 /* Accessor function for smb_read_error for smbd functions. */
212 /****************************************************************************
214 ****************************************************************************/
216 bool srv_send_smb(struct smbXsrv_connection
*xconn
, char *buffer
,
217 bool do_signing
, uint32_t seqnum
,
219 struct smb_perfcount_data
*pcd
)
223 char *buf_out
= buffer
;
225 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
227 * we're not supposed to do any io
232 smbd_lock_socket(xconn
);
235 /* Sign the outgoing packet if required. */
236 srv_calculate_sign_mac(xconn
, buf_out
, seqnum
);
240 NTSTATUS status
= srv_encrypt_buffer(xconn
, buffer
, &buf_out
);
241 if (!NT_STATUS_IS_OK(status
)) {
242 DEBUG(0, ("send_smb: SMB encryption failed "
243 "on outgoing packet! Error %s\n",
244 nt_errstr(status
) ));
250 len
= smb_len_large(buf_out
) + 4;
252 ret
= write_data(xconn
->transport
.sock
, buf_out
, len
);
254 int saved_errno
= errno
;
256 * Try and give an error message saying what
259 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
260 (int)getpid(), (int)len
,
261 smbXsrv_connection_dbg(xconn
),
262 (int)ret
, strerror(saved_errno
)));
265 srv_free_enc_buffer(xconn
, buf_out
);
269 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
270 srv_free_enc_buffer(xconn
, buf_out
);
272 SMB_PERFCOUNT_END(pcd
);
274 smbd_unlock_socket(xconn
);
278 /*******************************************************************
279 Setup the word count and byte count for a smb message.
280 ********************************************************************/
282 int srv_set_message(char *buf
,
287 if (zero
&& (num_words
|| num_bytes
)) {
288 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
290 SCVAL(buf
,smb_wct
,num_words
);
291 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
292 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
293 return (smb_size
+ num_words
*2 + num_bytes
);
296 static bool valid_smb_header(const uint8_t *inbuf
)
298 if (is_encrypted_packet(inbuf
)) {
302 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
303 * but it just looks weird to call strncmp for this one.
305 return (IVAL(smb_base(inbuf
), 0) == 0x424D53FF);
308 /* Socket functions for smbd packet processing. */
310 static bool valid_packet_size(size_t len
)
313 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
314 * of header. Don't print the error if this fits.... JRA.
317 if (len
> (LARGE_WRITEX_BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
318 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
319 (unsigned long)len
));
325 static NTSTATUS
read_packet_remainder(int fd
, char *buffer
,
326 unsigned int timeout
, ssize_t len
)
334 status
= read_fd_with_timeout(fd
, buffer
, len
, len
, timeout
, NULL
);
335 if (!NT_STATUS_IS_OK(status
)) {
336 char addr
[INET6_ADDRSTRLEN
];
337 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
339 get_peer_addr(fd
, addr
, sizeof(addr
)),
345 /****************************************************************************
346 Attempt a zerocopy writeX read. We know here that len > smb_size-4
347 ****************************************************************************/
350 * Unfortunately, earlier versions of smbclient/libsmbclient
351 * don't send this "standard" writeX header. I've fixed this
352 * for 3.2 but we'll use the old method with earlier versions.
353 * Windows and CIFSFS at least use this standard size. Not
357 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
358 (2*14) + /* word count (including bcc) */ \
361 static NTSTATUS
receive_smb_raw_talloc_partial_read(TALLOC_CTX
*mem_ctx
,
362 const char lenbuf
[4],
363 struct smbXsrv_connection
*xconn
,
366 unsigned int timeout
,
370 /* Size of a WRITEX call (+4 byte len). */
371 char writeX_header
[4 + STANDARD_WRITE_AND_X_HEADER_SIZE
];
372 ssize_t len
= smb_len_large(lenbuf
); /* Could be a UNIX large writeX. */
376 memcpy(writeX_header
, lenbuf
, 4);
378 status
= read_fd_with_timeout(
379 sock
, writeX_header
+ 4,
380 STANDARD_WRITE_AND_X_HEADER_SIZE
,
381 STANDARD_WRITE_AND_X_HEADER_SIZE
,
384 if (!NT_STATUS_IS_OK(status
)) {
385 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
387 smbXsrv_connection_dbg(xconn
),
393 * Ok - now try and see if this is a possible
397 if (is_valid_writeX_buffer(xconn
, (uint8_t *)writeX_header
)) {
399 * If the data offset is beyond what
400 * we've read, drain the extra bytes.
402 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
405 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
406 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
407 if (drain_socket(sock
, drain
) != drain
) {
408 smb_panic("receive_smb_raw_talloc_partial_read:"
409 " failed to drain pending bytes");
412 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
415 /* Spoof down the length and null out the bcc. */
416 set_message_bcc(writeX_header
, 0);
417 newlen
= smb_len(writeX_header
);
419 /* Copy the header we've written. */
421 *buffer
= (char *)talloc_memdup(mem_ctx
,
423 sizeof(writeX_header
));
425 if (*buffer
== NULL
) {
426 DEBUG(0, ("Could not allocate inbuf of length %d\n",
427 (int)sizeof(writeX_header
)));
428 return NT_STATUS_NO_MEMORY
;
431 /* Work out the remaining bytes. */
432 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
433 *len_ret
= newlen
+ 4;
437 if (!valid_packet_size(len
)) {
438 return NT_STATUS_INVALID_PARAMETER
;
442 * Not a valid writeX call. Just do the standard
446 *buffer
= talloc_array(mem_ctx
, char, len
+4);
448 if (*buffer
== NULL
) {
449 DEBUG(0, ("Could not allocate inbuf of length %d\n",
451 return NT_STATUS_NO_MEMORY
;
454 /* Copy in what we already read. */
457 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
458 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
461 status
= read_packet_remainder(
463 (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
466 if (!NT_STATUS_IS_OK(status
)) {
467 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
477 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
,
478 struct smbXsrv_connection
*xconn
,
480 char **buffer
, unsigned int timeout
,
481 size_t *p_unread
, size_t *plen
)
485 int min_recv_size
= lp_min_receive_file_size();
490 status
= read_smb_length_return_keepalive(sock
, lenbuf
, timeout
,
492 if (!NT_STATUS_IS_OK(status
)) {
496 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
497 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
498 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
499 !srv_is_signing_active(xconn
) &&
500 xconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
502 return receive_smb_raw_talloc_partial_read(
503 mem_ctx
, lenbuf
, xconn
, sock
, buffer
, timeout
,
507 if (!valid_packet_size(len
)) {
508 return NT_STATUS_INVALID_PARAMETER
;
512 * The +4 here can't wrap, we've checked the length above already.
515 *buffer
= talloc_array(mem_ctx
, char, len
+4);
517 if (*buffer
== NULL
) {
518 DEBUG(0, ("Could not allocate inbuf of length %d\n",
520 return NT_STATUS_NO_MEMORY
;
523 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
525 status
= read_packet_remainder(sock
, (*buffer
)+4, timeout
, len
);
526 if (!NT_STATUS_IS_OK(status
)) {
534 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
,
535 struct smbXsrv_connection
*xconn
,
537 char **buffer
, unsigned int timeout
,
538 size_t *p_unread
, bool *p_encrypted
,
541 bool trusted_channel
)
546 *p_encrypted
= false;
548 status
= receive_smb_raw_talloc(mem_ctx
, xconn
, sock
, buffer
, timeout
,
550 if (!NT_STATUS_IS_OK(status
)) {
551 DEBUG(NT_STATUS_EQUAL(status
, NT_STATUS_END_OF_FILE
)?5:1,
552 ("receive_smb_raw_talloc failed for client %s "
553 "read error = %s.\n",
554 smbXsrv_connection_dbg(xconn
),
555 nt_errstr(status
)) );
559 if (is_encrypted_packet((uint8_t *)*buffer
)) {
560 status
= srv_decrypt_buffer(xconn
, *buffer
);
561 if (!NT_STATUS_IS_OK(status
)) {
562 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
563 "incoming packet! Error %s\n",
564 nt_errstr(status
) ));
570 /* Check the incoming SMB signature. */
571 if (!srv_check_sign_mac(xconn
, *buffer
, seqnum
, trusted_channel
)) {
572 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
573 "incoming packet!\n"));
574 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
582 * Initialize a struct smb_request from an inbuf
585 static bool init_smb_request(struct smb_request
*req
,
586 struct smbd_server_connection
*sconn
,
587 struct smbXsrv_connection
*xconn
,
588 const uint8_t *inbuf
,
589 size_t unread_bytes
, bool encrypted
,
592 struct smbXsrv_tcon
*tcon
;
595 size_t req_size
= smb_len(inbuf
) + 4;
597 /* Ensure we have at least smb_size bytes. */
598 if (req_size
< smb_size
) {
599 DEBUG(0,("init_smb_request: invalid request size %u\n",
600 (unsigned int)req_size
));
604 req
->request_time
= timeval_current();
605 now
= timeval_to_nttime(&req
->request_time
);
607 req
->cmd
= CVAL(inbuf
, smb_com
);
608 req
->flags2
= SVAL(inbuf
, smb_flg2
);
609 req
->smbpid
= SVAL(inbuf
, smb_pid
);
610 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
611 req
->seqnum
= seqnum
;
612 req
->vuid
= SVAL(inbuf
, smb_uid
);
613 req
->tid
= SVAL(inbuf
, smb_tid
);
614 req
->wct
= CVAL(inbuf
, smb_wct
);
615 req
->vwv
= (const uint16_t *)(inbuf
+smb_vwv
);
616 req
->buflen
= smb_buflen(inbuf
);
617 req
->buf
= (const uint8_t *)smb_buf_const(inbuf
);
618 req
->unread_bytes
= unread_bytes
;
619 req
->encrypted
= encrypted
;
624 status
= smb1srv_tcon_lookup(xconn
, req
->tid
, now
, &tcon
);
625 if (NT_STATUS_IS_OK(status
)) {
626 req
->conn
= tcon
->compat
;
629 req
->chain_fsp
= NULL
;
631 req
->priv_paths
= NULL
;
633 req
->posix_pathnames
= lp_posix_pathnames();
634 smb_init_perfcount_data(&req
->pcd
);
636 /* Ensure we have at least wct words and 2 bytes of bcc. */
637 if (smb_size
+ req
->wct
*2 > req_size
) {
638 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
639 (unsigned int)req
->wct
,
640 (unsigned int)req_size
));
643 /* Ensure bcc is correct. */
644 if (((const uint8_t *)smb_buf_const(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
645 DEBUG(0,("init_smb_request: invalid bcc number %u "
646 "(wct = %u, size %u)\n",
647 (unsigned int)req
->buflen
,
648 (unsigned int)req
->wct
,
649 (unsigned int)req_size
));
657 static void process_smb(struct smbXsrv_connection
*xconn
,
658 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
659 uint32_t seqnum
, bool encrypted
,
660 struct smb_perfcount_data
*deferred_pcd
);
662 static void smbd_deferred_open_timer(struct tevent_context
*ev
,
663 struct tevent_timer
*te
,
664 struct timeval _tval
,
667 struct pending_message_list
*msg
= talloc_get_type(private_data
,
668 struct pending_message_list
);
669 struct smbd_server_connection
*sconn
= msg
->sconn
;
670 struct smbXsrv_connection
*xconn
= msg
->xconn
;
671 TALLOC_CTX
*mem_ctx
= talloc_tos();
672 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
675 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
678 exit_server("smbd_deferred_open_timer: talloc failed\n");
682 /* We leave this message on the queue so the open code can
683 know this is a retry. */
684 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
685 (unsigned long long)mid
));
687 /* Mark the message as processed so this is not
688 * re-processed in error. */
689 msg
->processed
= true;
691 process_smb(xconn
, inbuf
,
693 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
695 /* If it's still there and was processed, remove it. */
696 msg
= get_deferred_open_message_smb(sconn
, mid
);
697 if (msg
&& msg
->processed
) {
698 remove_deferred_open_message_smb(xconn
, mid
);
702 /****************************************************************************
703 Function to push a message onto the tail of a linked list of smb messages ready
705 ****************************************************************************/
707 static bool push_queued_message(struct smb_request
*req
,
708 struct timeval request_time
,
709 struct timeval end_time
,
710 struct deferred_open_record
*open_rec
)
712 int msg_len
= smb_len(req
->inbuf
) + 4;
713 struct pending_message_list
*msg
;
715 msg
= talloc_zero(NULL
, struct pending_message_list
);
718 DEBUG(0,("push_message: malloc fail (1)\n"));
721 msg
->sconn
= req
->sconn
;
722 msg
->xconn
= req
->xconn
;
724 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
725 if(msg
->buf
.data
== NULL
) {
726 DEBUG(0,("push_message: malloc fail (2)\n"));
731 msg
->request_time
= request_time
;
732 msg
->seqnum
= req
->seqnum
;
733 msg
->encrypted
= req
->encrypted
;
734 msg
->processed
= false;
735 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
738 msg
->open_rec
= talloc_move(msg
, &open_rec
);
742 msg
->te
= tevent_add_timer(msg
->sconn
->ev_ctx
,
745 smbd_deferred_open_timer
,
748 DEBUG(0,("push_message: event_add_timed failed\n"));
754 DLIST_ADD_END(req
->sconn
->deferred_open_queue
, msg
);
756 DEBUG(10,("push_message: pushed message length %u on "
757 "deferred_open_queue\n", (unsigned int)msg_len
));
762 /****************************************************************************
763 Function to delete a sharing violation open message by mid.
764 ****************************************************************************/
766 void remove_deferred_open_message_smb(struct smbXsrv_connection
*xconn
,
769 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
770 struct pending_message_list
*pml
;
772 if (sconn
->using_smb2
) {
773 remove_deferred_open_message_smb2(xconn
, mid
);
777 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
778 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
779 DEBUG(10,("remove_deferred_open_message_smb: "
780 "deleting mid %llu len %u\n",
781 (unsigned long long)mid
,
782 (unsigned int)pml
->buf
.length
));
783 DLIST_REMOVE(sconn
->deferred_open_queue
, pml
);
790 /****************************************************************************
791 Move a sharing violation open retry message to the front of the list and
792 schedule it for immediate processing.
793 ****************************************************************************/
795 bool schedule_deferred_open_message_smb(struct smbXsrv_connection
*xconn
,
798 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
799 struct pending_message_list
*pml
;
802 if (sconn
->using_smb2
) {
803 return schedule_deferred_open_message_smb2(xconn
, mid
);
806 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
807 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
809 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
812 (unsigned long long)msg_mid
));
814 if (mid
== msg_mid
) {
815 struct tevent_timer
*te
;
817 if (pml
->processed
) {
818 /* A processed message should not be
820 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
821 "message mid %llu was already processed\n",
822 (unsigned long long)msg_mid
));
826 DEBUG(10,("schedule_deferred_open_message_smb: "
827 "scheduling mid %llu\n",
828 (unsigned long long)mid
));
830 te
= tevent_add_timer(pml
->sconn
->ev_ctx
,
833 smbd_deferred_open_timer
,
836 DEBUG(10,("schedule_deferred_open_message_smb: "
837 "event_add_timed() failed, "
838 "skipping mid %llu\n",
839 (unsigned long long)msg_mid
));
842 TALLOC_FREE(pml
->te
);
844 DLIST_PROMOTE(sconn
->deferred_open_queue
, pml
);
849 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
850 "find message mid %llu\n",
851 (unsigned long long)mid
));
856 /****************************************************************************
857 Return true if this mid is on the deferred queue and was not yet processed.
858 ****************************************************************************/
860 bool open_was_deferred(struct smbXsrv_connection
*xconn
, uint64_t mid
)
862 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
863 struct pending_message_list
*pml
;
865 if (sconn
->using_smb2
) {
866 return open_was_deferred_smb2(xconn
, mid
);
869 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
870 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
877 /****************************************************************************
878 Return the message queued by this mid.
879 ****************************************************************************/
881 static struct pending_message_list
*get_deferred_open_message_smb(
882 struct smbd_server_connection
*sconn
, uint64_t mid
)
884 struct pending_message_list
*pml
;
886 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
887 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
894 /****************************************************************************
895 Get the state data queued by this mid.
896 ****************************************************************************/
898 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
899 struct timeval
*p_request_time
,
900 struct deferred_open_record
**open_rec
)
902 struct pending_message_list
*pml
;
904 if (smbreq
->sconn
->using_smb2
) {
905 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
910 pml
= get_deferred_open_message_smb(smbreq
->sconn
, smbreq
->mid
);
914 if (p_request_time
) {
915 *p_request_time
= pml
->request_time
;
917 if (open_rec
!= NULL
) {
918 *open_rec
= pml
->open_rec
;
923 /****************************************************************************
924 Function to push a deferred open smb message onto a linked list of local smb
925 messages ready for processing.
926 ****************************************************************************/
928 bool push_deferred_open_message_smb(struct smb_request
*req
,
929 struct timeval request_time
,
930 struct timeval timeout
,
932 struct deferred_open_record
*open_rec
)
934 struct timeval end_time
;
937 return push_deferred_open_message_smb2(req
->smb2req
,
944 if (req
->unread_bytes
) {
945 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
946 "unread_bytes = %u\n",
947 (unsigned int)req
->unread_bytes
));
948 smb_panic("push_deferred_open_message_smb: "
949 "logic error unread_bytes != 0" );
952 end_time
= timeval_sum(&request_time
, &timeout
);
954 DEBUG(10,("push_deferred_open_message_smb: pushing message "
955 "len %u mid %llu timeout time [%u.%06u]\n",
956 (unsigned int) smb_len(req
->inbuf
)+4,
957 (unsigned long long)req
->mid
,
958 (unsigned int)end_time
.tv_sec
,
959 (unsigned int)end_time
.tv_usec
));
961 return push_queued_message(req
, request_time
, end_time
, open_rec
);
964 static void smbd_sig_term_handler(struct tevent_context
*ev
,
965 struct tevent_signal
*se
,
971 exit_server_cleanly("termination signal");
974 void smbd_setup_sig_term_handler(struct smbd_server_connection
*sconn
)
976 struct tevent_signal
*se
;
978 se
= tevent_add_signal(sconn
->ev_ctx
,
981 smbd_sig_term_handler
,
984 exit_server("failed to setup SIGTERM handler");
988 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
989 struct tevent_signal
*se
,
995 struct smbd_server_connection
*sconn
=
996 talloc_get_type_abort(private_data
,
997 struct smbd_server_connection
);
999 change_to_root_user();
1000 DEBUG(1,("Reloading services after SIGHUP\n"));
1001 reload_services(sconn
, conn_snum_used
, false);
1004 void smbd_setup_sig_hup_handler(struct smbd_server_connection
*sconn
)
1006 struct tevent_signal
*se
;
1008 se
= tevent_add_signal(sconn
->ev_ctx
,
1011 smbd_sig_hup_handler
,
1014 exit_server("failed to setup SIGHUP handler");
1018 static void smbd_conf_updated(struct messaging_context
*msg
,
1021 struct server_id server_id
,
1024 struct smbd_server_connection
*sconn
=
1025 talloc_get_type_abort(private_data
,
1026 struct smbd_server_connection
);
1028 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1029 "updated. Reloading.\n"));
1030 change_to_root_user();
1031 reload_services(sconn
, conn_snum_used
, false);
1035 * Only allow 5 outstanding trans requests. We're allocating memory, so
1039 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
1042 for (; list
!= NULL
; list
= list
->next
) {
1044 if (list
->mid
== mid
) {
1045 return NT_STATUS_INVALID_PARAMETER
;
1051 return NT_STATUS_INSUFFICIENT_RESOURCES
;
1054 return NT_STATUS_OK
;
1058 These flags determine some of the permissions required to do an operation
1060 Note that I don't set NEED_WRITE on some write operations because they
1061 are used by some brain-dead clients when printing, and I don't want to
1062 force write permissions on print services.
1064 #define AS_USER (1<<0)
1065 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1066 #define TIME_INIT (1<<2)
1067 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1068 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1069 #define DO_CHDIR (1<<6)
1072 define a list of possible SMB messages and their corresponding
1073 functions. Any message that has a NULL function is unimplemented -
1074 please feel free to contribute implementations!
1076 static const struct smb_message_struct
{
1078 void (*fn
)(struct smb_request
*req
);
1080 } smb_messages
[256] = {
1082 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1083 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1084 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1085 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1086 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1087 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1088 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1089 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1090 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1091 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1092 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1093 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1094 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1095 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1096 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1097 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1098 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1099 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1100 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1101 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1102 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1103 /* 0x15 */ { NULL
, NULL
, 0 },
1104 /* 0x16 */ { NULL
, NULL
, 0 },
1105 /* 0x17 */ { NULL
, NULL
, 0 },
1106 /* 0x18 */ { NULL
, NULL
, 0 },
1107 /* 0x19 */ { NULL
, NULL
, 0 },
1108 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1109 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1110 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1111 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1112 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1113 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1114 /* 0x20 */ { "SMBwritec", NULL
,0},
1115 /* 0x21 */ { NULL
, NULL
, 0 },
1116 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1117 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1118 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1119 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1120 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1121 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1122 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1123 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1124 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1125 /* 0x2b */ { "SMBecho",reply_echo
,0},
1126 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1127 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1128 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1129 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1130 /* 0x30 */ { NULL
, NULL
, 0 },
1131 /* 0x31 */ { NULL
, NULL
, 0 },
1132 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1133 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1134 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1135 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1136 /* 0x36 */ { NULL
, NULL
, 0 },
1137 /* 0x37 */ { NULL
, NULL
, 0 },
1138 /* 0x38 */ { NULL
, NULL
, 0 },
1139 /* 0x39 */ { NULL
, NULL
, 0 },
1140 /* 0x3a */ { NULL
, NULL
, 0 },
1141 /* 0x3b */ { NULL
, NULL
, 0 },
1142 /* 0x3c */ { NULL
, NULL
, 0 },
1143 /* 0x3d */ { NULL
, NULL
, 0 },
1144 /* 0x3e */ { NULL
, NULL
, 0 },
1145 /* 0x3f */ { NULL
, NULL
, 0 },
1146 /* 0x40 */ { NULL
, NULL
, 0 },
1147 /* 0x41 */ { NULL
, NULL
, 0 },
1148 /* 0x42 */ { NULL
, NULL
, 0 },
1149 /* 0x43 */ { NULL
, NULL
, 0 },
1150 /* 0x44 */ { NULL
, NULL
, 0 },
1151 /* 0x45 */ { NULL
, NULL
, 0 },
1152 /* 0x46 */ { NULL
, NULL
, 0 },
1153 /* 0x47 */ { NULL
, NULL
, 0 },
1154 /* 0x48 */ { NULL
, NULL
, 0 },
1155 /* 0x49 */ { NULL
, NULL
, 0 },
1156 /* 0x4a */ { NULL
, NULL
, 0 },
1157 /* 0x4b */ { NULL
, NULL
, 0 },
1158 /* 0x4c */ { NULL
, NULL
, 0 },
1159 /* 0x4d */ { NULL
, NULL
, 0 },
1160 /* 0x4e */ { NULL
, NULL
, 0 },
1161 /* 0x4f */ { NULL
, NULL
, 0 },
1162 /* 0x50 */ { NULL
, NULL
, 0 },
1163 /* 0x51 */ { NULL
, NULL
, 0 },
1164 /* 0x52 */ { NULL
, NULL
, 0 },
1165 /* 0x53 */ { NULL
, NULL
, 0 },
1166 /* 0x54 */ { NULL
, NULL
, 0 },
1167 /* 0x55 */ { NULL
, NULL
, 0 },
1168 /* 0x56 */ { NULL
, NULL
, 0 },
1169 /* 0x57 */ { NULL
, NULL
, 0 },
1170 /* 0x58 */ { NULL
, NULL
, 0 },
1171 /* 0x59 */ { NULL
, NULL
, 0 },
1172 /* 0x5a */ { NULL
, NULL
, 0 },
1173 /* 0x5b */ { NULL
, NULL
, 0 },
1174 /* 0x5c */ { NULL
, NULL
, 0 },
1175 /* 0x5d */ { NULL
, NULL
, 0 },
1176 /* 0x5e */ { NULL
, NULL
, 0 },
1177 /* 0x5f */ { NULL
, NULL
, 0 },
1178 /* 0x60 */ { NULL
, NULL
, 0 },
1179 /* 0x61 */ { NULL
, NULL
, 0 },
1180 /* 0x62 */ { NULL
, NULL
, 0 },
1181 /* 0x63 */ { NULL
, NULL
, 0 },
1182 /* 0x64 */ { NULL
, NULL
, 0 },
1183 /* 0x65 */ { NULL
, NULL
, 0 },
1184 /* 0x66 */ { NULL
, NULL
, 0 },
1185 /* 0x67 */ { NULL
, NULL
, 0 },
1186 /* 0x68 */ { NULL
, NULL
, 0 },
1187 /* 0x69 */ { NULL
, NULL
, 0 },
1188 /* 0x6a */ { NULL
, NULL
, 0 },
1189 /* 0x6b */ { NULL
, NULL
, 0 },
1190 /* 0x6c */ { NULL
, NULL
, 0 },
1191 /* 0x6d */ { NULL
, NULL
, 0 },
1192 /* 0x6e */ { NULL
, NULL
, 0 },
1193 /* 0x6f */ { NULL
, NULL
, 0 },
1194 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1195 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1196 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1197 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1198 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1199 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1200 /* 0x76 */ { NULL
, NULL
, 0 },
1201 /* 0x77 */ { NULL
, NULL
, 0 },
1202 /* 0x78 */ { NULL
, NULL
, 0 },
1203 /* 0x79 */ { NULL
, NULL
, 0 },
1204 /* 0x7a */ { NULL
, NULL
, 0 },
1205 /* 0x7b */ { NULL
, NULL
, 0 },
1206 /* 0x7c */ { NULL
, NULL
, 0 },
1207 /* 0x7d */ { NULL
, NULL
, 0 },
1208 /* 0x7e */ { NULL
, NULL
, 0 },
1209 /* 0x7f */ { NULL
, NULL
, 0 },
1210 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1211 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1212 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1213 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1214 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1215 /* 0x85 */ { NULL
, NULL
, 0 },
1216 /* 0x86 */ { NULL
, NULL
, 0 },
1217 /* 0x87 */ { NULL
, NULL
, 0 },
1218 /* 0x88 */ { NULL
, NULL
, 0 },
1219 /* 0x89 */ { NULL
, NULL
, 0 },
1220 /* 0x8a */ { NULL
, NULL
, 0 },
1221 /* 0x8b */ { NULL
, NULL
, 0 },
1222 /* 0x8c */ { NULL
, NULL
, 0 },
1223 /* 0x8d */ { NULL
, NULL
, 0 },
1224 /* 0x8e */ { NULL
, NULL
, 0 },
1225 /* 0x8f */ { NULL
, NULL
, 0 },
1226 /* 0x90 */ { NULL
, NULL
, 0 },
1227 /* 0x91 */ { NULL
, NULL
, 0 },
1228 /* 0x92 */ { NULL
, NULL
, 0 },
1229 /* 0x93 */ { NULL
, NULL
, 0 },
1230 /* 0x94 */ { NULL
, NULL
, 0 },
1231 /* 0x95 */ { NULL
, NULL
, 0 },
1232 /* 0x96 */ { NULL
, NULL
, 0 },
1233 /* 0x97 */ { NULL
, NULL
, 0 },
1234 /* 0x98 */ { NULL
, NULL
, 0 },
1235 /* 0x99 */ { NULL
, NULL
, 0 },
1236 /* 0x9a */ { NULL
, NULL
, 0 },
1237 /* 0x9b */ { NULL
, NULL
, 0 },
1238 /* 0x9c */ { NULL
, NULL
, 0 },
1239 /* 0x9d */ { NULL
, NULL
, 0 },
1240 /* 0x9e */ { NULL
, NULL
, 0 },
1241 /* 0x9f */ { NULL
, NULL
, 0 },
1242 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1243 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1244 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1245 /* 0xa3 */ { NULL
, NULL
, 0 },
1246 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1247 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1248 /* 0xa6 */ { NULL
, NULL
, 0 },
1249 /* 0xa7 */ { NULL
, NULL
, 0 },
1250 /* 0xa8 */ { NULL
, NULL
, 0 },
1251 /* 0xa9 */ { NULL
, NULL
, 0 },
1252 /* 0xaa */ { NULL
, NULL
, 0 },
1253 /* 0xab */ { NULL
, NULL
, 0 },
1254 /* 0xac */ { NULL
, NULL
, 0 },
1255 /* 0xad */ { NULL
, NULL
, 0 },
1256 /* 0xae */ { NULL
, NULL
, 0 },
1257 /* 0xaf */ { NULL
, NULL
, 0 },
1258 /* 0xb0 */ { NULL
, NULL
, 0 },
1259 /* 0xb1 */ { NULL
, NULL
, 0 },
1260 /* 0xb2 */ { NULL
, NULL
, 0 },
1261 /* 0xb3 */ { NULL
, NULL
, 0 },
1262 /* 0xb4 */ { NULL
, NULL
, 0 },
1263 /* 0xb5 */ { NULL
, NULL
, 0 },
1264 /* 0xb6 */ { NULL
, NULL
, 0 },
1265 /* 0xb7 */ { NULL
, NULL
, 0 },
1266 /* 0xb8 */ { NULL
, NULL
, 0 },
1267 /* 0xb9 */ { NULL
, NULL
, 0 },
1268 /* 0xba */ { NULL
, NULL
, 0 },
1269 /* 0xbb */ { NULL
, NULL
, 0 },
1270 /* 0xbc */ { NULL
, NULL
, 0 },
1271 /* 0xbd */ { NULL
, NULL
, 0 },
1272 /* 0xbe */ { NULL
, NULL
, 0 },
1273 /* 0xbf */ { NULL
, NULL
, 0 },
1274 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1275 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1276 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1277 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1278 /* 0xc4 */ { NULL
, NULL
, 0 },
1279 /* 0xc5 */ { NULL
, NULL
, 0 },
1280 /* 0xc6 */ { NULL
, NULL
, 0 },
1281 /* 0xc7 */ { NULL
, NULL
, 0 },
1282 /* 0xc8 */ { NULL
, NULL
, 0 },
1283 /* 0xc9 */ { NULL
, NULL
, 0 },
1284 /* 0xca */ { NULL
, NULL
, 0 },
1285 /* 0xcb */ { NULL
, NULL
, 0 },
1286 /* 0xcc */ { NULL
, NULL
, 0 },
1287 /* 0xcd */ { NULL
, NULL
, 0 },
1288 /* 0xce */ { NULL
, NULL
, 0 },
1289 /* 0xcf */ { NULL
, NULL
, 0 },
1290 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1291 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1292 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1293 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1294 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1295 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1296 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1297 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1298 /* 0xd8 */ { NULL
, NULL
, 0 },
1299 /* 0xd9 */ { NULL
, NULL
, 0 },
1300 /* 0xda */ { NULL
, NULL
, 0 },
1301 /* 0xdb */ { NULL
, NULL
, 0 },
1302 /* 0xdc */ { NULL
, NULL
, 0 },
1303 /* 0xdd */ { NULL
, NULL
, 0 },
1304 /* 0xde */ { NULL
, NULL
, 0 },
1305 /* 0xdf */ { NULL
, NULL
, 0 },
1306 /* 0xe0 */ { NULL
, NULL
, 0 },
1307 /* 0xe1 */ { NULL
, NULL
, 0 },
1308 /* 0xe2 */ { NULL
, NULL
, 0 },
1309 /* 0xe3 */ { NULL
, NULL
, 0 },
1310 /* 0xe4 */ { NULL
, NULL
, 0 },
1311 /* 0xe5 */ { NULL
, NULL
, 0 },
1312 /* 0xe6 */ { NULL
, NULL
, 0 },
1313 /* 0xe7 */ { NULL
, NULL
, 0 },
1314 /* 0xe8 */ { NULL
, NULL
, 0 },
1315 /* 0xe9 */ { NULL
, NULL
, 0 },
1316 /* 0xea */ { NULL
, NULL
, 0 },
1317 /* 0xeb */ { NULL
, NULL
, 0 },
1318 /* 0xec */ { NULL
, NULL
, 0 },
1319 /* 0xed */ { NULL
, NULL
, 0 },
1320 /* 0xee */ { NULL
, NULL
, 0 },
1321 /* 0xef */ { NULL
, NULL
, 0 },
1322 /* 0xf0 */ { NULL
, NULL
, 0 },
1323 /* 0xf1 */ { NULL
, NULL
, 0 },
1324 /* 0xf2 */ { NULL
, NULL
, 0 },
1325 /* 0xf3 */ { NULL
, NULL
, 0 },
1326 /* 0xf4 */ { NULL
, NULL
, 0 },
1327 /* 0xf5 */ { NULL
, NULL
, 0 },
1328 /* 0xf6 */ { NULL
, NULL
, 0 },
1329 /* 0xf7 */ { NULL
, NULL
, 0 },
1330 /* 0xf8 */ { NULL
, NULL
, 0 },
1331 /* 0xf9 */ { NULL
, NULL
, 0 },
1332 /* 0xfa */ { NULL
, NULL
, 0 },
1333 /* 0xfb */ { NULL
, NULL
, 0 },
1334 /* 0xfc */ { NULL
, NULL
, 0 },
1335 /* 0xfd */ { NULL
, NULL
, 0 },
1336 /* 0xfe */ { NULL
, NULL
, 0 },
1337 /* 0xff */ { NULL
, NULL
, 0 }
1341 /*******************************************************************
1342 allocate and initialize a reply packet
1343 ********************************************************************/
1345 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1346 const uint8_t *inbuf
, char **outbuf
,
1347 uint8_t num_words
, uint32_t num_bytes
)
1349 size_t smb_len
= MIN_SMB_SIZE
+ VWV(num_words
) + num_bytes
;
1352 * Protect against integer wrap.
1353 * The SMB layer reply can be up to 0xFFFFFF bytes.
1355 if ((num_bytes
> 0xffffff) || (smb_len
> 0xffffff)) {
1357 if (asprintf(&msg
, "num_bytes too large: %u",
1358 (unsigned)num_bytes
) == -1) {
1359 msg
= discard_const_p(char, "num_bytes too large");
1365 * Here we include the NBT header for now.
1367 *outbuf
= talloc_array(mem_ctx
, char,
1368 NBT_HDR_SIZE
+ smb_len
);
1369 if (*outbuf
== NULL
) {
1373 construct_reply_common(req
->cmd
, inbuf
, *outbuf
);
1374 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1376 * Zero out the word area, the caller has to take care of the bcc area
1379 if (num_words
!= 0) {
1380 memset(*outbuf
+ (NBT_HDR_SIZE
+ HDR_VWV
), 0, VWV(num_words
));
1386 void reply_outbuf(struct smb_request
*req
, uint8_t num_words
, uint32_t num_bytes
)
1389 if (!create_outbuf(req
, req
, req
->inbuf
, &outbuf
, num_words
,
1391 smb_panic("could not allocate output buffer\n");
1393 req
->outbuf
= (uint8_t *)outbuf
;
1397 /*******************************************************************
1398 Dump a packet to a file.
1399 ********************************************************************/
1401 static void smb_dump(const char *name
, int type
, const char *data
)
1406 if (DEBUGLEVEL
< 50) {
1410 len
= smb_len_tcp(data
)+4;
1411 for (i
=1;i
<100;i
++) {
1412 fname
= talloc_asprintf(talloc_tos(),
1416 type
? "req" : "resp");
1417 if (fname
== NULL
) {
1420 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1421 if (fd
!= -1 || errno
!= EEXIST
) break;
1425 ssize_t ret
= write(fd
, data
, len
);
1427 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1429 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1434 static void smb1srv_update_crypto_flags(struct smbXsrv_session
*session
,
1435 struct smb_request
*req
,
1437 bool *update_session_globalp
,
1438 bool *update_tcon_globalp
)
1440 connection_struct
*conn
= req
->conn
;
1441 struct smbXsrv_tcon
*tcon
= conn
? conn
->tcon
: NULL
;
1442 uint8_t encrypt_flag
= SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
;
1443 uint8_t sign_flag
= SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
1444 bool update_session
= false;
1445 bool update_tcon
= false;
1447 if (req
->encrypted
) {
1448 encrypt_flag
= SMBXSRV_PROCESSED_ENCRYPTED_PACKET
;
1451 if (srv_is_signing_active(req
->xconn
)) {
1452 sign_flag
= SMBXSRV_PROCESSED_SIGNED_PACKET
;
1453 } else if ((type
== SMBecho
) || (type
== SMBsesssetupX
)) {
1455 * echo can be unsigned. Sesssion setup except final
1456 * session setup response too
1458 sign_flag
&= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
1461 update_session
|= smbXsrv_set_crypto_flag(
1462 &session
->global
->encryption_flags
, encrypt_flag
);
1463 update_session
|= smbXsrv_set_crypto_flag(
1464 &session
->global
->signing_flags
, sign_flag
);
1467 update_tcon
|= smbXsrv_set_crypto_flag(
1468 &tcon
->global
->encryption_flags
, encrypt_flag
);
1469 update_tcon
|= smbXsrv_set_crypto_flag(
1470 &tcon
->global
->signing_flags
, sign_flag
);
1473 if (update_session
) {
1474 session
->global
->channels
[0].encryption_cipher
= SMB_ENCRYPTION_GSSAPI
;
1477 *update_session_globalp
= update_session
;
1478 *update_tcon_globalp
= update_tcon
;
1482 /****************************************************************************
1483 Prepare everything for calling the actual request function, and potentially
1484 call the request function via the "new" interface.
1486 Return False if the "legacy" function needs to be called, everything is
1489 Return True if we're done.
1491 I know this API sucks, but it is the one with the least code change I could
1493 ****************************************************************************/
1495 static connection_struct
*switch_message(uint8_t type
, struct smb_request
*req
)
1498 uint64_t session_tag
;
1499 connection_struct
*conn
= NULL
;
1500 struct smbXsrv_connection
*xconn
= req
->xconn
;
1501 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1502 struct smbXsrv_session
*session
= NULL
;
1507 if (!xconn
->smb1
.negprot
.done
) {
1510 * Without a negprot the request must
1511 * either be a negprot, or one of the
1512 * evil old SMB mailslot messaging types.
1520 exit_server_cleanly("The first request "
1521 "should be a negprot");
1525 if (smb_messages
[type
].fn
== NULL
) {
1526 DEBUG(0,("Unknown message type %d!\n",type
));
1527 smb_dump("Unknown", 1, (const char *)req
->inbuf
);
1528 reply_unknown_new(req
, type
);
1532 flags
= smb_messages
[type
].flags
;
1534 /* In share mode security we must ignore the vuid. */
1535 session_tag
= req
->vuid
;
1538 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1539 (int)getpid(), (unsigned long)conn
));
1541 smb_dump(smb_fn_name(type
), 1, (const char *)req
->inbuf
);
1543 /* Ensure this value is replaced in the incoming packet. */
1544 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_uid
,session_tag
);
1547 * Ensure the correct username is in current_user_info. This is a
1548 * really ugly bugfix for problems with multiple session_setup_and_X's
1549 * being done and allowing %U and %G substitutions to work correctly.
1550 * There is a reason this code is done here, don't move it unless you
1551 * know what you're doing... :-).
1556 * lookup an existing session
1558 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1559 * here, the main check is still in change_to_user()
1561 status
= smb1srv_session_lookup(xconn
,
1565 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
1568 status
= NT_STATUS_OK
;
1571 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1572 (unsigned long long)session_tag
,
1573 (unsigned long long)req
->mid
));
1574 reply_nterror(req
, NT_STATUS_NETWORK_SESSION_EXPIRED
);
1579 if (session_tag
!= xconn
->client
->last_session_id
) {
1580 struct user_struct
*vuser
= NULL
;
1582 xconn
->client
->last_session_id
= session_tag
;
1584 vuser
= session
->compat
;
1587 set_current_user_info(
1588 vuser
->session_info
->unix_info
->sanitized_username
,
1589 vuser
->session_info
->unix_info
->unix_name
,
1590 vuser
->session_info
->info
->domain_name
);
1594 /* Does this call need to be run as the connected user? */
1595 if (flags
& AS_USER
) {
1597 /* Does this call need a valid tree connection? */
1600 * Amazingly, the error code depends on the command
1603 if (type
== SMBntcreateX
) {
1604 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1606 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1611 if (!change_to_user(conn
,session_tag
)) {
1612 DEBUG(0, ("Error: Could not change to user. Removing "
1613 "deferred open, mid=%llu.\n",
1614 (unsigned long long)req
->mid
));
1615 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1619 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1621 /* Does it need write permission? */
1622 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1623 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1627 /* IPC services are limited */
1628 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1629 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1633 /* This call needs to be run as root */
1634 change_to_root_user();
1637 /* load service specific parameters */
1639 if (req
->encrypted
) {
1640 conn
->encrypted_tid
= true;
1641 /* encrypted required from now on. */
1642 conn
->encrypt_level
= SMB_SIGNING_REQUIRED
;
1643 } else if (ENCRYPTION_REQUIRED(conn
)) {
1644 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1645 DEBUG(1,("service[%s] requires encryption"
1646 "%s ACCESS_DENIED. mid=%llu\n",
1647 lp_servicename(talloc_tos(), SNUM(conn
)),
1649 (unsigned long long)req
->mid
));
1650 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1655 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1656 (flags
& (AS_USER
|DO_CHDIR
)
1658 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1661 conn
->num_smb_operations
++;
1665 * Does this protocol need to be run as guest? (Only archane
1666 * messenger service requests have this...)
1668 if (flags
& AS_GUEST
) {
1672 if (!change_to_guest()) {
1673 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1677 raddr
= tsocket_address_inet_addr_string(xconn
->remote_address
,
1679 if (raddr
== NULL
) {
1680 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1685 * Haven't we checked this in smbd_process already???
1688 ok
= allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1689 xconn
->remote_hostname
, raddr
);
1693 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1699 * Update encryption and signing state tracking flags that are
1700 * used by smbstatus to display signing and encryption status.
1702 if (session
!= NULL
) {
1703 bool update_session_global
= false;
1704 bool update_tcon_global
= false;
1706 smb1srv_update_crypto_flags(session
, req
, type
,
1707 &update_session_global
,
1708 &update_tcon_global
);
1710 if (update_session_global
) {
1711 status
= smbXsrv_session_update(session
);
1712 if (!NT_STATUS_IS_OK(status
)) {
1713 reply_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1718 if (update_tcon_global
) {
1719 status
= smbXsrv_tcon_update(req
->conn
->tcon
);
1720 if (!NT_STATUS_IS_OK(status
)) {
1721 reply_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1727 smb_messages
[type
].fn(req
);
1731 /****************************************************************************
1732 Construct a reply to the incoming packet.
1733 ****************************************************************************/
1735 static void construct_reply(struct smbXsrv_connection
*xconn
,
1736 char *inbuf
, int size
, size_t unread_bytes
,
1737 uint32_t seqnum
, bool encrypted
,
1738 struct smb_perfcount_data
*deferred_pcd
)
1740 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
1741 struct smb_request
*req
;
1743 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1744 smb_panic("could not allocate smb_request");
1747 if (!init_smb_request(req
, sconn
, xconn
, (uint8_t *)inbuf
, unread_bytes
,
1748 encrypted
, seqnum
)) {
1749 exit_server_cleanly("Invalid SMB request");
1752 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1754 /* we popped this message off the queue - keep original perf data */
1756 req
->pcd
= *deferred_pcd
;
1758 SMB_PERFCOUNT_START(&req
->pcd
);
1759 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1760 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1763 req
->conn
= switch_message(req
->cmd
, req
);
1765 if (req
->outbuf
== NULL
) {
1767 * Request has suspended itself, will come
1772 if (CVAL(req
->outbuf
,0) == 0) {
1773 show_msg((char *)req
->outbuf
);
1775 smb_request_done(req
);
1778 static void construct_reply_chain(struct smbXsrv_connection
*xconn
,
1779 char *inbuf
, int size
, uint32_t seqnum
,
1781 struct smb_perfcount_data
*deferred_pcd
)
1783 struct smb_request
**reqs
= NULL
;
1784 struct smb_request
*req
;
1788 ok
= smb1_parse_chain(xconn
, (uint8_t *)inbuf
, xconn
, encrypted
,
1789 seqnum
, &reqs
, &num_reqs
);
1791 char errbuf
[smb_size
];
1792 error_packet(errbuf
, 0, 0, NT_STATUS_INVALID_PARAMETER
,
1793 __LINE__
, __FILE__
);
1794 if (!srv_send_smb(xconn
, errbuf
, true, seqnum
, encrypted
,
1796 exit_server_cleanly("construct_reply_chain: "
1797 "srv_send_smb failed.");
1803 req
->inbuf
= (uint8_t *)talloc_move(reqs
, &inbuf
);
1805 req
->conn
= switch_message(req
->cmd
, req
);
1807 if (req
->outbuf
== NULL
) {
1809 * Request has suspended itself, will come
1814 smb_request_done(req
);
1818 * To be called from an async SMB handler that is potentially chained
1819 * when it is finished for shipping.
1822 void smb_request_done(struct smb_request
*req
)
1824 struct smb_request
**reqs
= NULL
;
1825 struct smb_request
*first_req
;
1826 size_t i
, num_reqs
, next_index
;
1829 if (req
->chain
== NULL
) {
1835 num_reqs
= talloc_array_length(reqs
);
1837 for (i
=0; i
<num_reqs
; i
++) {
1838 if (reqs
[i
] == req
) {
1842 if (i
== num_reqs
) {
1844 * Invalid chain, should not happen
1846 status
= NT_STATUS_INTERNAL_ERROR
;
1851 while ((next_index
< num_reqs
) && (IVAL(req
->outbuf
, smb_rcls
) == 0)) {
1852 struct smb_request
*next
= reqs
[next_index
];
1853 struct smbXsrv_tcon
*tcon
;
1854 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1856 next
->vuid
= SVAL(req
->outbuf
, smb_uid
);
1857 next
->tid
= SVAL(req
->outbuf
, smb_tid
);
1858 status
= smb1srv_tcon_lookup(req
->xconn
, req
->tid
,
1860 if (NT_STATUS_IS_OK(status
)) {
1861 req
->conn
= tcon
->compat
;
1865 next
->chain_fsp
= req
->chain_fsp
;
1866 next
->inbuf
= req
->inbuf
;
1869 req
->conn
= switch_message(req
->cmd
, req
);
1871 if (req
->outbuf
== NULL
) {
1873 * Request has suspended itself, will come
1881 first_req
= reqs
[0];
1883 for (i
=1; i
<next_index
; i
++) {
1886 ok
= smb_splice_chain(&first_req
->outbuf
, reqs
[i
]->outbuf
);
1888 status
= NT_STATUS_INTERNAL_ERROR
;
1893 SSVAL(first_req
->outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
1894 SSVAL(first_req
->outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
1897 * This scary statement intends to set the
1898 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1899 * to the value last_req->outbuf carries
1901 SSVAL(first_req
->outbuf
, smb_flg2
,
1902 (SVAL(first_req
->outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
1903 |(SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
1906 * Transfer the error codes from the subrequest to the main one
1908 SSVAL(first_req
->outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
1909 SSVAL(first_req
->outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
1912 first_req
->outbuf
, talloc_get_size(first_req
->outbuf
) - 4);
1915 if (!srv_send_smb(first_req
->xconn
,
1916 (char *)first_req
->outbuf
,
1917 true, first_req
->seqnum
+1,
1918 IS_CONN_ENCRYPTED(req
->conn
)||first_req
->encrypted
,
1920 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1923 TALLOC_FREE(req
); /* non-chained case */
1924 TALLOC_FREE(reqs
); /* chained case */
1929 char errbuf
[smb_size
];
1930 error_packet(errbuf
, 0, 0, status
, __LINE__
, __FILE__
);
1931 if (!srv_send_smb(req
->xconn
, errbuf
, true,
1932 req
->seqnum
+1, req
->encrypted
,
1934 exit_server_cleanly("construct_reply_chain: "
1935 "srv_send_smb failed.");
1938 TALLOC_FREE(req
); /* non-chained case */
1939 TALLOC_FREE(reqs
); /* chained case */
1942 /****************************************************************************
1943 Process an smb from the client
1944 ****************************************************************************/
1945 static void process_smb(struct smbXsrv_connection
*xconn
,
1946 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1947 uint32_t seqnum
, bool encrypted
,
1948 struct smb_perfcount_data
*deferred_pcd
)
1950 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
1951 int msg_type
= CVAL(inbuf
,0);
1953 DO_PROFILE_INC(request
);
1955 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1957 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1958 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1960 if (msg_type
!= NBSSmessage
) {
1962 * NetBIOS session request, keepalive, etc.
1964 reply_special(xconn
, (char *)inbuf
, nread
);
1968 if (sconn
->using_smb2
) {
1969 /* At this point we're not really using smb2,
1970 * we make the decision here.. */
1971 if (smbd_is_smb2_header(inbuf
, nread
)) {
1972 const uint8_t *inpdu
= inbuf
+ NBT_HDR_SIZE
;
1973 size_t pdulen
= nread
- NBT_HDR_SIZE
;
1974 smbd_smb2_process_negprot(xconn
, 0, inpdu
, pdulen
);
1976 } else if (nread
>= smb_size
&& valid_smb_header(inbuf
)
1977 && CVAL(inbuf
, smb_com
) != 0x72) {
1978 /* This is a non-negprot SMB1 packet.
1979 Disable SMB2 from now on. */
1980 sconn
->using_smb2
= false;
1984 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1985 * so subtract 4 from it. */
1986 if ((nread
< (smb_size
- 4)) || !valid_smb_header(inbuf
)) {
1987 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1990 /* special magic for immediate exit */
1992 (IVAL(inbuf
, 4) == 0x74697865) &&
1993 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1994 uint8_t exitcode
= CVAL(inbuf
, 8);
1995 DEBUG(1, ("Exiting immediately with code %d\n",
2000 exit_server_cleanly("Non-SMB packet");
2003 show_msg((char *)inbuf
);
2005 if ((unread_bytes
== 0) && smb1_is_chain(inbuf
)) {
2006 construct_reply_chain(xconn
, (char *)inbuf
, nread
,
2007 seqnum
, encrypted
, deferred_pcd
);
2009 construct_reply(xconn
, (char *)inbuf
, nread
, unread_bytes
,
2010 seqnum
, encrypted
, deferred_pcd
);
2016 sconn
->num_requests
++;
2018 /* The timeout_processing function isn't run nearly
2019 often enough to implement 'max log size' without
2020 overrunning the size of the file by many megabytes.
2021 This is especially true if we are running at debug
2022 level 10. Checking every 50 SMBs is a nice
2023 tradeoff of performance vs log file size overrun. */
2025 if ((sconn
->num_requests
% 50) == 0 &&
2026 need_to_check_log_size()) {
2027 change_to_root_user();
2032 /****************************************************************************
2033 Return a string containing the function name of a SMB command.
2034 ****************************************************************************/
2036 const char *smb_fn_name(int type
)
2038 const char *unknown_name
= "SMBunknown";
2040 if (smb_messages
[type
].name
== NULL
)
2041 return(unknown_name
);
2043 return(smb_messages
[type
].name
);
2046 /****************************************************************************
2047 Helper functions for contruct_reply.
2048 ****************************************************************************/
2050 void add_to_common_flags2(uint32_t v
)
2055 void remove_from_common_flags2(uint32_t v
)
2057 common_flags2
&= ~v
;
2060 static void construct_reply_common(uint8_t cmd
, const uint8_t *inbuf
,
2063 uint16_t in_flags2
= SVAL(inbuf
,smb_flg2
);
2064 uint16_t out_flags2
= common_flags2
;
2066 out_flags2
|= in_flags2
& FLAGS2_UNICODE_STRINGS
;
2067 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
;
2068 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
;
2070 srv_set_message(outbuf
,0,0,false);
2072 SCVAL(outbuf
, smb_com
, cmd
);
2073 SIVAL(outbuf
,smb_rcls
,0);
2074 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
2075 SSVAL(outbuf
,smb_flg2
, out_flags2
);
2076 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
2077 memcpy(outbuf
+smb_ss_field
, inbuf
+smb_ss_field
, 8);
2079 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
2080 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
2081 SSVAL(outbuf
,smb_pidhigh
,SVAL(inbuf
,smb_pidhigh
));
2082 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
2083 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
2086 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
2088 construct_reply_common(req
->cmd
, req
->inbuf
, outbuf
);
2092 * @brief Find the smb_cmd offset of the last command pushed
2093 * @param[in] buf The buffer we're building up
2094 * @retval Where can we put our next andx cmd?
2096 * While chaining requests, the "next" request we're looking at needs to put
2097 * its SMB_Command before the data the previous request already built up added
2098 * to the chain. Find the offset to the place where we have to put our cmd.
2101 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
2106 cmd
= CVAL(buf
, smb_com
);
2108 if (!is_andx_req(cmd
)) {
2114 while (CVAL(buf
, ofs
) != 0xff) {
2116 if (!is_andx_req(CVAL(buf
, ofs
))) {
2121 * ofs is from start of smb header, so add the 4 length
2122 * bytes. The next cmd is right after the wct field.
2124 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
2126 if (ofs
+4 >= talloc_get_size(buf
)) {
2136 * @brief Do the smb chaining at a buffer level
2137 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2138 * @param[in] andx_buf Buffer to be appended
2141 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
)
2143 uint8_t smb_command
= CVAL(andx_buf
, smb_com
);
2144 uint8_t wct
= CVAL(andx_buf
, smb_wct
);
2145 const uint16_t *vwv
= (const uint16_t *)(andx_buf
+ smb_vwv
);
2146 uint32_t num_bytes
= smb_buflen(andx_buf
);
2147 const uint8_t *bytes
= (const uint8_t *)smb_buf_const(andx_buf
);
2150 size_t old_size
, new_size
;
2152 size_t chain_padding
= 0;
2153 size_t andx_cmd_ofs
;
2156 old_size
= talloc_get_size(*poutbuf
);
2158 if ((old_size
% 4) != 0) {
2160 * Align the wct field of subsequent requests to a 4-byte
2163 chain_padding
= 4 - (old_size
% 4);
2167 * After the old request comes the new wct field (1 byte), the vwv's
2168 * and the num_bytes field.
2171 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
2172 new_size
+= num_bytes
;
2174 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
2175 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2176 (unsigned)new_size
));
2180 outbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, new_size
);
2181 if (outbuf
== NULL
) {
2182 DEBUG(0, ("talloc failed\n"));
2187 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
2188 DEBUG(1, ("invalid command chain\n"));
2189 *poutbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, old_size
);
2193 if (chain_padding
!= 0) {
2194 memset(outbuf
+ old_size
, 0, chain_padding
);
2195 old_size
+= chain_padding
;
2198 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
2199 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
2204 * Push the chained request:
2209 SCVAL(outbuf
, ofs
, wct
);
2216 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
2221 * Read&X has an offset into its data buffer at
2222 * vwv[6]. reply_read_andx has no idea anymore that it's
2223 * running from within a chain, so we have to fix up the
2226 * Although it looks disgusting at this place, I want to keep
2227 * it here. The alternative would be to push knowledge about
2228 * the andx chain down into read&x again.
2231 if (smb_command
== SMBreadX
) {
2232 uint8_t *bytes_addr
;
2236 * Invalid read&x response
2241 bytes_addr
= outbuf
+ ofs
/* vwv start */
2242 + sizeof(uint16_t) * wct
/* vwv array */
2243 + sizeof(uint16_t) /* bcc */
2244 + 1; /* padding byte */
2246 SSVAL(outbuf
+ ofs
, 6 * sizeof(uint16_t),
2247 bytes_addr
- outbuf
- 4);
2250 ofs
+= sizeof(uint16_t) * wct
;
2256 SSVAL(outbuf
, ofs
, num_bytes
);
2257 ofs
+= sizeof(uint16_t);
2263 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
2268 bool smb1_is_chain(const uint8_t *buf
)
2270 uint8_t cmd
, wct
, andx_cmd
;
2272 cmd
= CVAL(buf
, smb_com
);
2273 if (!is_andx_req(cmd
)) {
2276 wct
= CVAL(buf
, smb_wct
);
2280 andx_cmd
= CVAL(buf
, smb_vwv
);
2281 return (andx_cmd
!= 0xFF);
2284 bool smb1_walk_chain(const uint8_t *buf
,
2285 bool (*fn
)(uint8_t cmd
,
2286 uint8_t wct
, const uint16_t *vwv
,
2287 uint16_t num_bytes
, const uint8_t *bytes
,
2288 void *private_data
),
2291 size_t smblen
= smb_len(buf
);
2292 const char *smb_buf
= smb_base(buf
);
2293 uint8_t cmd
, chain_cmd
;
2295 const uint16_t *vwv
;
2297 const uint8_t *bytes
;
2299 cmd
= CVAL(buf
, smb_com
);
2300 wct
= CVAL(buf
, smb_wct
);
2301 vwv
= (const uint16_t *)(buf
+ smb_vwv
);
2302 num_bytes
= smb_buflen(buf
);
2303 bytes
= (const uint8_t *)smb_buf_const(buf
);
2305 if (!fn(cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2309 if (!is_andx_req(cmd
)) {
2316 chain_cmd
= CVAL(vwv
, 0);
2318 while (chain_cmd
!= 0xff) {
2319 uint32_t chain_offset
; /* uint32_t to avoid overflow */
2320 size_t length_needed
;
2321 ptrdiff_t vwv_offset
;
2323 chain_offset
= SVAL(vwv
+1, 0);
2326 * Check if the client tries to fool us. The chain
2327 * offset needs to point beyond the current request in
2328 * the chain, it needs to strictly grow. Otherwise we
2329 * might be tricked into an endless loop always
2330 * processing the same request over and over again. We
2331 * used to assume that vwv and the byte buffer array
2332 * in a chain are always attached, but OS/2 the
2333 * Write&X/Read&X chain puts the Read&X vwv array
2334 * right behind the Write&X vwv chain. The Write&X bcc
2335 * array is put behind the Read&X vwv array. So now we
2336 * check whether the chain offset points strictly
2337 * behind the previous vwv array. req->buf points
2338 * right after the vwv array of the previous
2340 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2344 vwv_offset
= ((const char *)vwv
- smb_buf
);
2345 if (chain_offset
<= vwv_offset
) {
2350 * Next check: Make sure the chain offset does not
2351 * point beyond the overall smb request length.
2354 length_needed
= chain_offset
+1; /* wct */
2355 if (length_needed
> smblen
) {
2360 * Now comes the pointer magic. Goal here is to set up
2361 * vwv and buf correctly again. The chain offset (the
2362 * former vwv[1]) points at the new wct field.
2365 wct
= CVAL(smb_buf
, chain_offset
);
2367 if (is_andx_req(chain_cmd
) && (wct
< 2)) {
2372 * Next consistency check: Make the new vwv array fits
2373 * in the overall smb request.
2376 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2377 if (length_needed
> smblen
) {
2380 vwv
= (const uint16_t *)(smb_buf
+ chain_offset
+ 1);
2383 * Now grab the new byte buffer....
2386 num_bytes
= SVAL(vwv
+wct
, 0);
2389 * .. and check that it fits.
2392 length_needed
+= num_bytes
;
2393 if (length_needed
> smblen
) {
2396 bytes
= (const uint8_t *)(vwv
+wct
+1);
2398 if (!fn(chain_cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2402 if (!is_andx_req(chain_cmd
)) {
2405 chain_cmd
= CVAL(vwv
, 0);
2410 static bool smb1_chain_length_cb(uint8_t cmd
,
2411 uint8_t wct
, const uint16_t *vwv
,
2412 uint16_t num_bytes
, const uint8_t *bytes
,
2415 unsigned *count
= (unsigned *)private_data
;
2420 unsigned smb1_chain_length(const uint8_t *buf
)
2424 if (!smb1_walk_chain(buf
, smb1_chain_length_cb
, &count
)) {
2430 struct smb1_parse_chain_state
{
2431 TALLOC_CTX
*mem_ctx
;
2433 struct smbd_server_connection
*sconn
;
2434 struct smbXsrv_connection
*xconn
;
2438 struct smb_request
**reqs
;
2442 static bool smb1_parse_chain_cb(uint8_t cmd
,
2443 uint8_t wct
, const uint16_t *vwv
,
2444 uint16_t num_bytes
, const uint8_t *bytes
,
2447 struct smb1_parse_chain_state
*state
=
2448 (struct smb1_parse_chain_state
*)private_data
;
2449 struct smb_request
**reqs
;
2450 struct smb_request
*req
;
2453 reqs
= talloc_realloc(state
->mem_ctx
, state
->reqs
,
2454 struct smb_request
*, state
->num_reqs
+1);
2460 req
= talloc(reqs
, struct smb_request
);
2465 ok
= init_smb_request(req
, state
->sconn
, state
->xconn
, state
->buf
, 0,
2466 state
->encrypted
, state
->seqnum
);
2473 req
->buflen
= num_bytes
;
2476 reqs
[state
->num_reqs
] = req
;
2477 state
->num_reqs
+= 1;
2481 bool smb1_parse_chain(TALLOC_CTX
*mem_ctx
, const uint8_t *buf
,
2482 struct smbXsrv_connection
*xconn
,
2483 bool encrypted
, uint32_t seqnum
,
2484 struct smb_request
***reqs
, unsigned *num_reqs
)
2486 struct smbd_server_connection
*sconn
= NULL
;
2487 struct smb1_parse_chain_state state
;
2490 if (xconn
!= NULL
) {
2491 sconn
= xconn
->client
->sconn
;
2494 state
.mem_ctx
= mem_ctx
;
2496 state
.sconn
= sconn
;
2497 state
.xconn
= xconn
;
2498 state
.encrypted
= encrypted
;
2499 state
.seqnum
= seqnum
;
2503 if (!smb1_walk_chain(buf
, smb1_parse_chain_cb
, &state
)) {
2504 TALLOC_FREE(state
.reqs
);
2507 for (i
=0; i
<state
.num_reqs
; i
++) {
2508 state
.reqs
[i
]->chain
= state
.reqs
;
2511 *num_reqs
= state
.num_reqs
;
2515 /****************************************************************************
2516 Check if services need reloading.
2517 ****************************************************************************/
2519 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2522 if (last_smb_conf_reload_time
== 0) {
2523 last_smb_conf_reload_time
= t
;
2526 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2527 reload_services(sconn
, conn_snum_used
, true);
2528 last_smb_conf_reload_time
= t
;
2532 static bool fd_is_readable(int fd
)
2536 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2538 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2542 static void smbd_server_connection_write_handler(
2543 struct smbXsrv_connection
*xconn
)
2545 /* TODO: make write nonblocking */
2548 static void smbd_server_connection_read_handler(
2549 struct smbXsrv_connection
*xconn
, int fd
)
2551 uint8_t *inbuf
= NULL
;
2552 size_t inbuf_len
= 0;
2553 size_t unread_bytes
= 0;
2554 bool encrypted
= false;
2555 TALLOC_CTX
*mem_ctx
= talloc_tos();
2559 bool async_echo
= lp_async_smb_echo_handler();
2560 bool from_client
= false;
2563 if (fd_is_readable(xconn
->smb1
.echo_handler
.trusted_fd
)) {
2565 * This is the super-ugly hack to prefer the packets
2566 * forwarded by the echo handler over the ones by the
2569 fd
= xconn
->smb1
.echo_handler
.trusted_fd
;
2573 from_client
= (xconn
->transport
.sock
== fd
);
2575 if (async_echo
&& from_client
) {
2576 smbd_lock_socket(xconn
);
2578 if (!fd_is_readable(fd
)) {
2579 DEBUG(10,("the echo listener was faster\n"));
2580 smbd_unlock_socket(xconn
);
2585 /* TODO: make this completely nonblocking */
2586 status
= receive_smb_talloc(mem_ctx
, xconn
, fd
,
2587 (char **)(void *)&inbuf
,
2591 &inbuf_len
, &seqnum
,
2592 !from_client
/* trusted channel */);
2594 if (async_echo
&& from_client
) {
2595 smbd_unlock_socket(xconn
);
2598 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2601 if (NT_STATUS_IS_ERR(status
)) {
2602 exit_server_cleanly("failed to receive smb request");
2604 if (!NT_STATUS_IS_OK(status
)) {
2609 process_smb(xconn
, inbuf
, inbuf_len
, unread_bytes
,
2610 seqnum
, encrypted
, NULL
);
2613 static void smbd_server_connection_handler(struct tevent_context
*ev
,
2614 struct tevent_fd
*fde
,
2618 struct smbXsrv_connection
*xconn
=
2619 talloc_get_type_abort(private_data
,
2620 struct smbXsrv_connection
);
2622 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2624 * we're not supposed to do any io
2626 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
2627 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
2631 if (flags
& TEVENT_FD_WRITE
) {
2632 smbd_server_connection_write_handler(xconn
);
2635 if (flags
& TEVENT_FD_READ
) {
2636 smbd_server_connection_read_handler(xconn
, xconn
->transport
.sock
);
2641 static void smbd_server_echo_handler(struct tevent_context
*ev
,
2642 struct tevent_fd
*fde
,
2646 struct smbXsrv_connection
*xconn
=
2647 talloc_get_type_abort(private_data
,
2648 struct smbXsrv_connection
);
2650 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2652 * we're not supposed to do any io
2654 TEVENT_FD_NOT_READABLE(xconn
->smb1
.echo_handler
.trusted_fde
);
2655 TEVENT_FD_NOT_WRITEABLE(xconn
->smb1
.echo_handler
.trusted_fde
);
2659 if (flags
& TEVENT_FD_WRITE
) {
2660 smbd_server_connection_write_handler(xconn
);
2663 if (flags
& TEVENT_FD_READ
) {
2664 smbd_server_connection_read_handler(
2665 xconn
, xconn
->smb1
.echo_handler
.trusted_fd
);
2670 struct smbd_release_ip_state
{
2671 struct smbXsrv_connection
*xconn
;
2672 struct tevent_immediate
*im
;
2673 char addr
[INET6_ADDRSTRLEN
];
2676 static void smbd_release_ip_immediate(struct tevent_context
*ctx
,
2677 struct tevent_immediate
*im
,
2680 struct smbd_release_ip_state
*state
=
2681 talloc_get_type_abort(private_data
,
2682 struct smbd_release_ip_state
);
2683 struct smbXsrv_connection
*xconn
= state
->xconn
;
2685 if (!NT_STATUS_EQUAL(xconn
->transport
.status
, NT_STATUS_ADDRESS_CLOSED
)) {
2687 * smbd_server_connection_terminate() already triggered ?
2692 smbd_server_connection_terminate(xconn
, "CTDB_SRVID_RELEASE_IP");
2695 /****************************************************************************
2696 received when we should release a specific IP
2697 ****************************************************************************/
2698 static int release_ip(uint32_t src_vnn
, uint32_t dst_vnn
,
2700 const uint8_t *msg
, size_t msglen
,
2703 struct smbd_release_ip_state
*state
=
2704 talloc_get_type_abort(private_data
,
2705 struct smbd_release_ip_state
);
2706 struct smbXsrv_connection
*xconn
= state
->xconn
;
2708 const char *addr
= state
->addr
;
2709 const char *p
= addr
;
2714 if (msg
[msglen
-1] != '\0') {
2718 ip
= (const char *)msg
;
2720 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2721 /* avoid recursion */
2725 if (strncmp("::ffff:", addr
, 7) == 0) {
2729 DEBUG(10, ("Got release IP message for %s, "
2730 "our address is %s\n", ip
, p
));
2732 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2733 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2736 * With SMB2 we should do a clean disconnect,
2737 * the previous_session_id in the session setup
2738 * will cleanup the old session, tcons and opens.
2740 * A clean disconnect is needed in order to support
2743 * Note: typically this is never triggered
2744 * as we got a TCP RST (triggered by ctdb event scripts)
2745 * before we get CTDB_SRVID_RELEASE_IP.
2747 * We used to call _exit(1) here, but as this was mostly never
2748 * triggered and has implication on our process model,
2749 * we can just use smbd_server_connection_terminate()
2752 * We don't call smbd_server_connection_terminate() directly
2753 * as we might be called from within ctdbd_migrate(),
2754 * we need to defer our action to the next event loop
2756 tevent_schedule_immediate(state
->im
, xconn
->ev_ctx
,
2757 smbd_release_ip_immediate
, state
);
2760 * Make sure we don't get any io on the connection.
2762 xconn
->transport
.status
= NT_STATUS_ADDRESS_CLOSED
;
2763 return EADDRNOTAVAIL
;
2769 static NTSTATUS
smbd_register_ips(struct smbXsrv_connection
*xconn
,
2770 struct sockaddr_storage
*srv
,
2771 struct sockaddr_storage
*clnt
)
2773 struct smbd_release_ip_state
*state
;
2774 struct ctdbd_connection
*cconn
;
2777 cconn
= messaging_ctdbd_connection();
2778 if (cconn
== NULL
) {
2779 return NT_STATUS_NO_MEMORY
;
2782 state
= talloc_zero(xconn
, struct smbd_release_ip_state
);
2783 if (state
== NULL
) {
2784 return NT_STATUS_NO_MEMORY
;
2786 state
->xconn
= xconn
;
2787 state
->im
= tevent_create_immediate(state
);
2788 if (state
->im
== NULL
) {
2789 return NT_STATUS_NO_MEMORY
;
2791 if (print_sockaddr(state
->addr
, sizeof(state
->addr
), srv
) == NULL
) {
2792 return NT_STATUS_NO_MEMORY
;
2795 ret
= ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, state
);
2797 return map_nt_error_from_unix(ret
);
2799 return NT_STATUS_OK
;
2802 static void msg_kill_client_ip(struct messaging_context
*msg_ctx
,
2803 void *private_data
, uint32_t msg_type
,
2804 struct server_id server_id
, DATA_BLOB
*data
)
2806 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2807 private_data
, struct smbd_server_connection
);
2808 const char *ip
= (char *) data
->data
;
2811 DBG_DEBUG("Got kill request for client IP %s\n", ip
);
2813 client_ip
= tsocket_address_inet_addr_string(sconn
->remote_address
,
2815 if (client_ip
== NULL
) {
2819 if (strequal(ip
, client_ip
)) {
2820 DBG_WARNING("Got kill client message for %s - "
2821 "exiting immediately\n", ip
);
2822 exit_server_cleanly("Forced disconnect for client");
2825 TALLOC_FREE(client_ip
);
2829 * Send keepalive packets to our client
2831 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2833 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2834 private_data
, struct smbd_server_connection
);
2835 struct smbXsrv_connection
*xconn
= NULL
;
2838 if (sconn
->using_smb2
) {
2839 /* Don't do keepalives on an SMB2 connection. */
2844 * With SMB1 we only have 1 connection
2846 xconn
= sconn
->client
->connections
;
2847 smbd_lock_socket(xconn
);
2848 ret
= send_keepalive(xconn
->transport
.sock
);
2849 smbd_unlock_socket(xconn
);
2852 int saved_errno
= errno
;
2854 * Try and give an error message saying what
2857 DEBUG(0, ("send_keepalive failed for client %s. "
2858 "Error %s - exiting\n",
2859 smbXsrv_connection_dbg(xconn
),
2860 strerror(saved_errno
)));
2861 errno
= saved_errno
;
2868 * Do the recurring check if we're idle
2870 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2872 struct smbd_server_connection
*sconn
=
2873 (struct smbd_server_connection
*)private_data
;
2875 if ((conn_num_open(sconn
) == 0)
2876 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2877 DEBUG( 2, ( "Closing idle connection\n" ) );
2878 messaging_send(sconn
->msg_ctx
,
2879 messaging_server_id(sconn
->msg_ctx
),
2880 MSG_SHUTDOWN
, &data_blob_null
);
2888 * Do the recurring log file and smb.conf reload checks.
2891 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2893 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2894 private_data
, struct smbd_server_connection
);
2896 DEBUG(5, ("housekeeping\n"));
2898 change_to_root_user();
2900 /* update printer queue caches if necessary */
2901 update_monitored_printq_cache(sconn
->msg_ctx
);
2903 /* check if we need to reload services */
2904 check_reload(sconn
, time_mono(NULL
));
2907 * Force a log file check.
2909 force_check_log_size();
2915 * Read an smb packet in the echo handler child, giving the parent
2916 * smbd one second to react once the socket becomes readable.
2919 struct smbd_echo_read_state
{
2920 struct tevent_context
*ev
;
2921 struct smbXsrv_connection
*xconn
;
2928 static void smbd_echo_read_readable(struct tevent_req
*subreq
);
2929 static void smbd_echo_read_waited(struct tevent_req
*subreq
);
2931 static struct tevent_req
*smbd_echo_read_send(
2932 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2933 struct smbXsrv_connection
*xconn
)
2935 struct tevent_req
*req
, *subreq
;
2936 struct smbd_echo_read_state
*state
;
2938 req
= tevent_req_create(mem_ctx
, &state
,
2939 struct smbd_echo_read_state
);
2944 state
->xconn
= xconn
;
2946 subreq
= wait_for_read_send(state
, ev
, xconn
->transport
.sock
, false);
2947 if (tevent_req_nomem(subreq
, req
)) {
2948 return tevent_req_post(req
, ev
);
2950 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2954 static void smbd_echo_read_readable(struct tevent_req
*subreq
)
2956 struct tevent_req
*req
= tevent_req_callback_data(
2957 subreq
, struct tevent_req
);
2958 struct smbd_echo_read_state
*state
= tevent_req_data(
2959 req
, struct smbd_echo_read_state
);
2963 ok
= wait_for_read_recv(subreq
, &err
);
2964 TALLOC_FREE(subreq
);
2966 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
2971 * Give the parent smbd one second to step in
2974 subreq
= tevent_wakeup_send(
2975 state
, state
->ev
, timeval_current_ofs(1, 0));
2976 if (tevent_req_nomem(subreq
, req
)) {
2979 tevent_req_set_callback(subreq
, smbd_echo_read_waited
, req
);
2982 static void smbd_echo_read_waited(struct tevent_req
*subreq
)
2984 struct tevent_req
*req
= tevent_req_callback_data(
2985 subreq
, struct tevent_req
);
2986 struct smbd_echo_read_state
*state
= tevent_req_data(
2987 req
, struct smbd_echo_read_state
);
2988 struct smbXsrv_connection
*xconn
= state
->xconn
;
2994 ok
= tevent_wakeup_recv(subreq
);
2995 TALLOC_FREE(subreq
);
2997 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
3001 ok
= smbd_lock_socket_internal(xconn
);
3003 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
3004 DEBUG(0, ("%s: failed to lock socket\n", __location__
));
3008 if (!fd_is_readable(xconn
->transport
.sock
)) {
3009 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3012 ok
= smbd_unlock_socket_internal(xconn
);
3014 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
3015 DEBUG(1, ("%s: failed to unlock socket\n",
3020 subreq
= wait_for_read_send(state
, state
->ev
,
3021 xconn
->transport
.sock
, false);
3022 if (tevent_req_nomem(subreq
, req
)) {
3025 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
3029 status
= receive_smb_talloc(state
, xconn
,
3030 xconn
->transport
.sock
,
3037 false /* trusted_channel*/);
3039 if (tevent_req_nterror(req
, status
)) {
3040 tevent_req_nterror(req
, status
);
3041 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3042 (int)getpid(), nt_errstr(status
)));
3046 ok
= smbd_unlock_socket_internal(xconn
);
3048 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
3049 DEBUG(1, ("%s: failed to unlock socket\n", __location__
));
3052 tevent_req_done(req
);
3055 static NTSTATUS
smbd_echo_read_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
3056 char **pbuf
, size_t *pbuflen
, uint32_t *pseqnum
)
3058 struct smbd_echo_read_state
*state
= tevent_req_data(
3059 req
, struct smbd_echo_read_state
);
3062 if (tevent_req_is_nterror(req
, &status
)) {
3065 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
3066 *pbuflen
= state
->buflen
;
3067 *pseqnum
= state
->seqnum
;
3068 return NT_STATUS_OK
;
3071 struct smbd_echo_state
{
3072 struct tevent_context
*ev
;
3073 struct iovec
*pending
;
3074 struct smbd_server_connection
*sconn
;
3075 struct smbXsrv_connection
*xconn
;
3078 struct tevent_fd
*parent_fde
;
3080 struct tevent_req
*write_req
;
3083 static void smbd_echo_writer_done(struct tevent_req
*req
);
3085 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
3089 if (state
->write_req
!= NULL
) {
3093 num_pending
= talloc_array_length(state
->pending
);
3094 if (num_pending
== 0) {
3098 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
3099 state
->parent_pipe
, false,
3100 state
->pending
, num_pending
);
3101 if (state
->write_req
== NULL
) {
3102 DEBUG(1, ("writev_send failed\n"));
3106 talloc_steal(state
->write_req
, state
->pending
);
3107 state
->pending
= NULL
;
3109 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
3113 static void smbd_echo_writer_done(struct tevent_req
*req
)
3115 struct smbd_echo_state
*state
= tevent_req_callback_data(
3116 req
, struct smbd_echo_state
);
3120 written
= writev_recv(req
, &err
);
3122 state
->write_req
= NULL
;
3123 if (written
== -1) {
3124 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
3127 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3128 smbd_echo_activate_writer(state
);
3131 static bool smbd_echo_reply(struct smbd_echo_state
*state
,
3132 uint8_t *inbuf
, size_t inbuf_len
,
3135 struct smb_request req
;
3136 uint16_t num_replies
;
3140 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == NBSSkeepalive
)) {
3141 DEBUG(10, ("Got netbios keepalive\n"));
3148 if (inbuf_len
< smb_size
) {
3149 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
3152 if (!valid_smb_header(inbuf
)) {
3153 DEBUG(10, ("Got invalid SMB header\n"));
3157 if (!init_smb_request(&req
, state
->sconn
, state
->xconn
, inbuf
, 0, false,
3163 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
3164 smb_messages
[req
.cmd
].name
3165 ? smb_messages
[req
.cmd
].name
: "unknown"));
3167 if (req
.cmd
!= SMBecho
) {
3174 num_replies
= SVAL(req
.vwv
+0, 0);
3175 if (num_replies
!= 1) {
3176 /* Not a Windows "Hey, you're still there?" request */
3180 if (!create_outbuf(talloc_tos(), &req
, req
.inbuf
, &outbuf
,
3182 DEBUG(10, ("create_outbuf failed\n"));
3185 req
.outbuf
= (uint8_t *)outbuf
;
3187 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
3189 if (req
.buflen
> 0) {
3190 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
3193 ok
= srv_send_smb(req
.xconn
,
3197 TALLOC_FREE(outbuf
);
3205 static void smbd_echo_exit(struct tevent_context
*ev
,
3206 struct tevent_fd
*fde
, uint16_t flags
,
3209 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3213 static void smbd_echo_got_packet(struct tevent_req
*req
);
3215 static void smbd_echo_loop(struct smbXsrv_connection
*xconn
,
3218 struct smbd_echo_state
*state
;
3219 struct tevent_req
*read_req
;
3221 state
= talloc_zero(xconn
, struct smbd_echo_state
);
3222 if (state
== NULL
) {
3223 DEBUG(1, ("talloc failed\n"));
3226 state
->xconn
= xconn
;
3227 state
->parent_pipe
= parent_pipe
;
3228 state
->ev
= samba_tevent_context_init(state
);
3229 if (state
->ev
== NULL
) {
3230 DEBUG(1, ("samba_tevent_context_init failed\n"));
3234 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
3235 TEVENT_FD_READ
, smbd_echo_exit
,
3237 if (state
->parent_fde
== NULL
) {
3238 DEBUG(1, ("tevent_add_fd failed\n"));
3243 read_req
= smbd_echo_read_send(state
, state
->ev
, xconn
);
3244 if (read_req
== NULL
) {
3245 DEBUG(1, ("smbd_echo_read_send failed\n"));
3249 tevent_req_set_callback(read_req
, smbd_echo_got_packet
, state
);
3252 if (tevent_loop_once(state
->ev
) == -1) {
3253 DEBUG(1, ("tevent_loop_once failed: %s\n",
3261 static void smbd_echo_got_packet(struct tevent_req
*req
)
3263 struct smbd_echo_state
*state
= tevent_req_callback_data(
3264 req
, struct smbd_echo_state
);
3268 uint32_t seqnum
= 0;
3271 status
= smbd_echo_read_recv(req
, state
, &buf
, &buflen
, &seqnum
);
3273 if (!NT_STATUS_IS_OK(status
)) {
3274 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3275 nt_errstr(status
)));
3279 reply
= smbd_echo_reply(state
, (uint8_t *)buf
, buflen
, seqnum
);
3285 num_pending
= talloc_array_length(state
->pending
);
3286 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
3289 DEBUG(1, ("talloc_realloc failed\n"));
3292 state
->pending
= tmp
;
3294 if (buflen
>= smb_size
) {
3296 * place the seqnum in the packet so that the main process
3297 * can reply with signing
3299 SIVAL(buf
, smb_ss_field
, seqnum
);
3300 SIVAL(buf
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
3303 iov
= &state
->pending
[num_pending
];
3304 iov
->iov_base
= talloc_move(state
->pending
, &buf
);
3305 iov
->iov_len
= buflen
;
3307 DEBUG(10,("echo_handler[%d]: forward to main\n",
3309 smbd_echo_activate_writer(state
);
3312 req
= smbd_echo_read_send(state
, state
->ev
, state
->xconn
);
3314 DEBUG(1, ("smbd_echo_read_send failed\n"));
3317 tevent_req_set_callback(req
, smbd_echo_got_packet
, state
);
3322 * Handle SMBecho requests in a forked child process
3324 bool fork_echo_handler(struct smbXsrv_connection
*xconn
)
3326 int listener_pipe
[2];
3329 bool use_mutex
= false;
3331 res
= pipe(listener_pipe
);
3333 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
3337 #ifdef HAVE_ROBUST_MUTEXES
3338 use_mutex
= tdb_runtime_check_for_robust_mutexes();
3341 pthread_mutexattr_t a
;
3343 xconn
->smb1
.echo_handler
.socket_mutex
=
3344 anonymous_shared_allocate(sizeof(pthread_mutex_t
));
3345 if (xconn
->smb1
.echo_handler
.socket_mutex
== NULL
) {
3346 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3351 res
= pthread_mutexattr_init(&a
);
3353 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3357 res
= pthread_mutexattr_settype(&a
, PTHREAD_MUTEX_ERRORCHECK
);
3359 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3361 pthread_mutexattr_destroy(&a
);
3364 res
= pthread_mutexattr_setpshared(&a
, PTHREAD_PROCESS_SHARED
);
3366 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3368 pthread_mutexattr_destroy(&a
);
3371 res
= pthread_mutexattr_setrobust(&a
, PTHREAD_MUTEX_ROBUST
);
3373 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3374 "%s\n", strerror(res
)));
3375 pthread_mutexattr_destroy(&a
);
3378 res
= pthread_mutex_init(xconn
->smb1
.echo_handler
.socket_mutex
,
3380 pthread_mutexattr_destroy(&a
);
3382 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3390 xconn
->smb1
.echo_handler
.socket_lock_fd
=
3391 create_unlink_tmp(lp_lock_directory());
3392 if (xconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
3393 DEBUG(1, ("Could not create lock fd: %s\n",
3403 close(listener_pipe
[0]);
3404 set_blocking(listener_pipe
[1], false);
3406 status
= smbd_reinit_after_fork(xconn
->msg_ctx
, xconn
->ev_ctx
,
3408 if (!NT_STATUS_IS_OK(status
)) {
3409 DEBUG(1, ("reinit_after_fork failed: %s\n",
3410 nt_errstr(status
)));
3413 smbd_echo_loop(xconn
, listener_pipe
[1]);
3416 close(listener_pipe
[1]);
3417 listener_pipe
[1] = -1;
3418 xconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
3420 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child
));
3423 * Without smb signing this is the same as the normal smbd
3424 * listener. This needs to change once signing comes in.
3426 xconn
->smb1
.echo_handler
.trusted_fde
= tevent_add_fd(xconn
->ev_ctx
,
3428 xconn
->smb1
.echo_handler
.trusted_fd
,
3430 smbd_server_echo_handler
,
3432 if (xconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
3433 DEBUG(1, ("event_add_fd failed\n"));
3440 if (listener_pipe
[0] != -1) {
3441 close(listener_pipe
[0]);
3443 if (listener_pipe
[1] != -1) {
3444 close(listener_pipe
[1]);
3446 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
3447 close(xconn
->smb1
.echo_handler
.socket_lock_fd
);
3449 #ifdef HAVE_ROBUST_MUTEXES
3450 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
3451 pthread_mutex_destroy(xconn
->smb1
.echo_handler
.socket_mutex
);
3452 anonymous_shared_free(xconn
->smb1
.echo_handler
.socket_mutex
);
3455 smbd_echo_init(xconn
);
3460 static bool uid_in_use(const struct user_struct
*user
, uid_t uid
)
3463 if (user
->session_info
&&
3464 (user
->session_info
->unix_token
->uid
== uid
)) {
3472 static bool gid_in_use(const struct user_struct
*user
, gid_t gid
)
3475 if (user
->session_info
!= NULL
) {
3477 struct security_unix_token
*utok
;
3479 utok
= user
->session_info
->unix_token
;
3480 if (utok
->gid
== gid
) {
3483 for(i
=0; i
<utok
->ngroups
; i
++) {
3484 if (utok
->groups
[i
] == gid
) {
3494 static bool sid_in_use(const struct user_struct
*user
,
3495 const struct dom_sid
*psid
)
3498 struct security_token
*tok
;
3500 if (user
->session_info
== NULL
) {
3503 tok
= user
->session_info
->security_token
;
3506 * Not sure session_info->security_token can
3507 * ever be NULL. This check might be not
3512 if (security_token_has_sid(tok
, psid
)) {
3520 static bool id_in_use(const struct user_struct
*user
,
3521 const struct id_cache_ref
*id
)
3525 return uid_in_use(user
, id
->id
.uid
);
3527 return gid_in_use(user
, id
->id
.gid
);
3529 return sid_in_use(user
, &id
->id
.sid
);
3536 static void smbd_id_cache_kill(struct messaging_context
*msg_ctx
,
3539 struct server_id server_id
,
3542 const char *msg
= (data
&& data
->data
)
3543 ? (const char *)data
->data
: "<NULL>";
3544 struct id_cache_ref id
;
3545 struct smbd_server_connection
*sconn
=
3546 talloc_get_type_abort(private_data
,
3547 struct smbd_server_connection
);
3549 if (!id_cache_ref_parse(msg
, &id
)) {
3550 DEBUG(0, ("Invalid ?ID: %s\n", msg
));
3554 if (id_in_use(sconn
->users
, &id
)) {
3555 exit_server_cleanly(msg
);
3557 id_cache_delete_from_cache(&id
);
3560 NTSTATUS
smbXsrv_connection_init_tables(struct smbXsrv_connection
*conn
,
3561 enum protocol_types protocol
)
3565 conn
->protocol
= protocol
;
3567 if (conn
->client
->session_table
!= NULL
) {
3568 return NT_STATUS_OK
;
3571 if (protocol
>= PROTOCOL_SMB2_02
) {
3572 status
= smb2srv_session_table_init(conn
);
3573 if (!NT_STATUS_IS_OK(status
)) {
3574 conn
->protocol
= PROTOCOL_NONE
;
3578 status
= smb2srv_open_table_init(conn
);
3579 if (!NT_STATUS_IS_OK(status
)) {
3580 conn
->protocol
= PROTOCOL_NONE
;
3584 status
= smb1srv_session_table_init(conn
);
3585 if (!NT_STATUS_IS_OK(status
)) {
3586 conn
->protocol
= PROTOCOL_NONE
;
3590 status
= smb1srv_tcon_table_init(conn
);
3591 if (!NT_STATUS_IS_OK(status
)) {
3592 conn
->protocol
= PROTOCOL_NONE
;
3596 status
= smb1srv_open_table_init(conn
);
3597 if (!NT_STATUS_IS_OK(status
)) {
3598 conn
->protocol
= PROTOCOL_NONE
;
3603 set_Protocol(protocol
);
3604 return NT_STATUS_OK
;
3607 struct smbd_tevent_trace_state
{
3608 struct tevent_context
*ev
;
3610 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle
);
3613 static void smbd_tevent_trace_callback(enum tevent_trace_point point
,
3616 struct smbd_tevent_trace_state
*state
=
3617 (struct smbd_tevent_trace_state
*)private_data
;
3620 case TEVENT_TRACE_BEFORE_WAIT
:
3621 if (!smbprofile_dump_pending()) {
3623 * If there's no dump pending
3624 * we don't want to schedule a new 1 sec timer.
3626 * Instead we want to sleep as long as nothing happens.
3628 smbprofile_dump_setup(NULL
);
3630 SMBPROFILE_BASIC_ASYNC_START(idle
, profile_p
, state
->profile_idle
);
3632 case TEVENT_TRACE_AFTER_WAIT
:
3633 SMBPROFILE_BASIC_ASYNC_END(state
->profile_idle
);
3634 if (!smbprofile_dump_pending()) {
3636 * We need to flush our state after sleeping
3637 * (hopefully a long time).
3641 * future profiling events should trigger timers
3642 * on our main event context.
3644 smbprofile_dump_setup(state
->ev
);
3647 case TEVENT_TRACE_BEFORE_LOOP_ONCE
:
3648 TALLOC_FREE(state
->frame
);
3649 state
->frame
= talloc_stackframe_pool(8192);
3651 case TEVENT_TRACE_AFTER_LOOP_ONCE
:
3652 TALLOC_FREE(state
->frame
);
3660 * Create a debug string for the connection
3662 * This is allocated to talloc_tos() or a string constant
3663 * in certain corner cases. The returned string should
3664 * hence not be free'd directly but only via the talloc stack.
3666 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection
*xconn
)
3671 * TODO: this can be improved later
3672 * maybe including the client guid or more
3674 ret
= tsocket_address_string(xconn
->remote_address
, talloc_tos());
3676 return "<tsocket_address_string() failed>";
3682 NTSTATUS
smbd_add_connection(struct smbXsrv_client
*client
, int sock_fd
,
3683 struct smbXsrv_connection
**_xconn
)
3685 TALLOC_CTX
*frame
= talloc_stackframe();
3686 struct smbXsrv_connection
*xconn
;
3687 struct sockaddr_storage ss_srv
;
3688 void *sp_srv
= (void *)&ss_srv
;
3689 struct sockaddr
*sa_srv
= (struct sockaddr
*)sp_srv
;
3690 struct sockaddr_storage ss_clnt
;
3691 void *sp_clnt
= (void *)&ss_clnt
;
3692 struct sockaddr
*sa_clnt
= (struct sockaddr
*)sp_clnt
;
3693 socklen_t sa_socklen
;
3694 struct tsocket_address
*local_address
= NULL
;
3695 struct tsocket_address
*remote_address
= NULL
;
3696 const char *remaddr
= NULL
;
3698 const char *rhost
= NULL
;
3704 DO_PROFILE_INC(connect
);
3706 xconn
= talloc_zero(client
, struct smbXsrv_connection
);
3707 if (xconn
== NULL
) {
3708 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3710 return NT_STATUS_NO_MEMORY
;
3712 talloc_steal(frame
, xconn
);
3714 xconn
->ev_ctx
= client
->ev_ctx
;
3715 xconn
->msg_ctx
= client
->msg_ctx
;
3716 xconn
->transport
.sock
= sock_fd
;
3717 smbd_echo_init(xconn
);
3718 xconn
->protocol
= PROTOCOL_NONE
;
3720 /* Ensure child is set to blocking mode */
3721 set_blocking(sock_fd
,True
);
3723 set_socket_options(sock_fd
, "SO_KEEPALIVE");
3724 set_socket_options(sock_fd
, lp_socket_options());
3726 sa_socklen
= sizeof(ss_clnt
);
3727 ret
= getpeername(sock_fd
, sa_clnt
, &sa_socklen
);
3729 int saved_errno
= errno
;
3730 int level
= (errno
== ENOTCONN
)?2:0;
3731 DEBUG(level
,("getpeername() failed - %s\n",
3732 strerror(saved_errno
)));
3734 return map_nt_error_from_unix_common(saved_errno
);
3736 ret
= tsocket_address_bsd_from_sockaddr(xconn
,
3737 sa_clnt
, sa_socklen
,
3740 int saved_errno
= errno
;
3741 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3742 __location__
, strerror(saved_errno
)));
3744 return map_nt_error_from_unix_common(saved_errno
);
3747 sa_socklen
= sizeof(ss_srv
);
3748 ret
= getsockname(sock_fd
, sa_srv
, &sa_socklen
);
3750 int saved_errno
= errno
;
3751 int level
= (errno
== ENOTCONN
)?2:0;
3752 DEBUG(level
,("getsockname() failed - %s\n",
3753 strerror(saved_errno
)));
3755 return map_nt_error_from_unix_common(saved_errno
);
3757 ret
= tsocket_address_bsd_from_sockaddr(xconn
,
3761 int saved_errno
= errno
;
3762 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3763 __location__
, strerror(saved_errno
)));
3765 return map_nt_error_from_unix_common(saved_errno
);
3768 if (tsocket_address_is_inet(remote_address
, "ip")) {
3769 remaddr
= tsocket_address_inet_addr_string(remote_address
,
3771 if (remaddr
== NULL
) {
3772 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3773 __location__
, strerror(errno
)));
3775 return NT_STATUS_NO_MEMORY
;
3778 remaddr
= "0.0.0.0";
3782 * Before the first packet, check the global hosts allow/ hosts deny
3783 * parameters before doing any parsing of packets passed to us by the
3784 * client. This prevents attacks on our parsing code from hosts not in
3785 * the hosts allow list.
3788 ret
= get_remote_hostname(remote_address
,
3791 int saved_errno
= errno
;
3792 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3793 __location__
, strerror(saved_errno
)));
3795 return map_nt_error_from_unix_common(saved_errno
);
3798 if (strequal(rhost
, "UNKNOWN")) {
3802 xconn
->local_address
= local_address
;
3803 xconn
->remote_address
= remote_address
;
3804 xconn
->remote_hostname
= talloc_strdup(xconn
, rhost
);
3805 if (xconn
->remote_hostname
== NULL
) {
3806 return NT_STATUS_NO_MEMORY
;
3809 if (!srv_init_signing(xconn
)) {
3810 DEBUG(0, ("Failed to init smb_signing\n"));
3812 return NT_STATUS_INTERNAL_ERROR
;
3815 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3816 xconn
->remote_hostname
,
3818 DEBUG( 1, ("Connection denied from %s to %s\n",
3819 tsocket_address_string(remote_address
, talloc_tos()),
3820 tsocket_address_string(local_address
, talloc_tos())));
3823 * We return a valid xconn
3824 * so that the caller can return an error message
3827 client
->connections
= xconn
;
3828 xconn
->client
= client
;
3829 talloc_steal(client
, xconn
);
3833 return NT_STATUS_NETWORK_ACCESS_DENIED
;
3836 DEBUG(10, ("Connection allowed from %s to %s\n",
3837 tsocket_address_string(remote_address
, talloc_tos()),
3838 tsocket_address_string(local_address
, talloc_tos())));
3840 if (lp_clustering()) {
3842 * We need to tell ctdb about our client's TCP
3843 * connection, so that for failover ctdbd can send
3844 * tickle acks, triggering a reconnection by the
3849 status
= smbd_register_ips(xconn
, &ss_srv
, &ss_clnt
);
3850 if (!NT_STATUS_IS_OK(status
)) {
3851 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3852 nt_errstr(status
)));
3856 tmp
= lp_max_xmit();
3857 tmp
= MAX(tmp
, SMB_BUFFER_SIZE_MIN
);
3858 tmp
= MIN(tmp
, SMB_BUFFER_SIZE_MAX
);
3860 xconn
->smb1
.negprot
.max_recv
= tmp
;
3862 xconn
->smb1
.sessions
.done_sesssetup
= false;
3863 xconn
->smb1
.sessions
.max_send
= SMB_BUFFER_SIZE_MAX
;
3865 xconn
->transport
.fde
= tevent_add_fd(client
->ev_ctx
,
3869 smbd_server_connection_handler
,
3871 if (!xconn
->transport
.fde
) {
3873 return NT_STATUS_NO_MEMORY
;
3876 /* for now we only have one connection */
3877 DLIST_ADD_END(client
->connections
, xconn
);
3878 xconn
->client
= client
;
3879 talloc_steal(client
, xconn
);
3883 return NT_STATUS_OK
;
3886 /****************************************************************************
3887 Process commands from the client
3888 ****************************************************************************/
3890 void smbd_process(struct tevent_context
*ev_ctx
,
3891 struct messaging_context
*msg_ctx
,
3895 struct smbd_tevent_trace_state trace_state
= {
3897 .frame
= talloc_stackframe(),
3899 struct smbXsrv_client
*client
= NULL
;
3900 struct smbd_server_connection
*sconn
= NULL
;
3901 struct smbXsrv_connection
*xconn
= NULL
;
3902 const char *locaddr
= NULL
;
3903 const char *remaddr
= NULL
;
3906 struct timeval tv
= timeval_current();
3907 NTTIME now
= timeval_to_nttime(&tv
);
3908 char *chroot_dir
= NULL
;
3911 status
= smbXsrv_client_create(ev_ctx
, ev_ctx
, msg_ctx
, now
, &client
);
3912 if (!NT_STATUS_IS_OK(status
)) {
3913 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status
));
3914 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3918 * TODO: remove this...:-)
3920 global_smbXsrv_client
= client
;
3922 sconn
= talloc_zero(client
, struct smbd_server_connection
);
3923 if (sconn
== NULL
) {
3924 exit_server("failed to create smbd_server_connection");
3927 client
->sconn
= sconn
;
3928 sconn
->client
= client
;
3930 sconn
->ev_ctx
= ev_ctx
;
3931 sconn
->msg_ctx
= msg_ctx
;
3933 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02
) {
3935 * We're not making the decision here,
3936 * we're just allowing the client
3937 * to decide between SMB1 and SMB2
3938 * with the first negprot
3941 sconn
->using_smb2
= true;
3945 smbd_setup_sig_term_handler(sconn
);
3946 smbd_setup_sig_hup_handler(sconn
);
3948 if (!serverid_register(messaging_server_id(msg_ctx
),
3949 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
3951 |FLAG_MSG_PRINT_GENERAL
)) {
3952 exit_server_cleanly("Could not register myself in "
3957 status
= smbd_add_connection(client
, sock_fd
, &xconn
);
3958 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3960 * send a negative session response "not listening on calling
3963 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3964 (void)srv_send_smb(xconn
,(char *)buf
, false,
3966 exit_server_cleanly("connection denied");
3967 } else if (!NT_STATUS_IS_OK(status
)) {
3968 exit_server_cleanly(nt_errstr(status
));
3971 sconn
->local_address
=
3972 tsocket_address_copy(xconn
->local_address
, sconn
);
3973 if (sconn
->local_address
== NULL
) {
3974 exit_server_cleanly("tsocket_address_copy() failed");
3976 sconn
->remote_address
=
3977 tsocket_address_copy(xconn
->remote_address
, sconn
);
3978 if (sconn
->remote_address
== NULL
) {
3979 exit_server_cleanly("tsocket_address_copy() failed");
3981 sconn
->remote_hostname
=
3982 talloc_strdup(sconn
, xconn
->remote_hostname
);
3983 if (sconn
->remote_hostname
== NULL
) {
3984 exit_server_cleanly("tsocket_strdup() failed");
3987 if (tsocket_address_is_inet(sconn
->local_address
, "ip")) {
3988 locaddr
= tsocket_address_inet_addr_string(
3989 sconn
->local_address
,
3991 if (locaddr
== NULL
) {
3992 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3993 __location__
, strerror(errno
)));
3994 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3997 locaddr
= "0.0.0.0";
4000 if (tsocket_address_is_inet(sconn
->remote_address
, "ip")) {
4001 remaddr
= tsocket_address_inet_addr_string(
4002 sconn
->remote_address
,
4004 if (remaddr
== NULL
) {
4005 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4006 __location__
, strerror(errno
)));
4007 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4010 remaddr
= "0.0.0.0";
4013 /* this is needed so that we get decent entries
4014 in smbstatus for port 445 connects */
4015 set_remote_machine_name(remaddr
, false);
4016 reload_services(sconn
, conn_snum_used
, true);
4017 sub_set_socket_ids(remaddr
,
4018 sconn
->remote_hostname
,
4021 if (lp_preload_modules()) {
4022 smb_load_all_modules_absoute_path(lp_preload_modules());
4025 smb_perfcount_init();
4027 if (!init_account_policy()) {
4028 exit_server("Could not open account policy tdb.\n");
4031 chroot_dir
= lp_root_directory(talloc_tos());
4032 if (chroot_dir
[0] != '\0') {
4033 rc
= chdir(chroot_dir
);
4035 DBG_ERR("Failed to chdir to %s\n", chroot_dir
);
4036 exit_server("Failed to chdir()");
4039 rc
= chroot(chroot_dir
);
4041 DBG_ERR("Failed to change root to %s\n", chroot_dir
);
4042 exit_server("Failed to chroot()");
4044 DBG_WARNING("Changed root to %s\n", chroot_dir
);
4046 TALLOC_FREE(chroot_dir
);
4049 if (!file_init(sconn
)) {
4050 exit_server("file_init() failed");
4054 if (!init_oplocks(sconn
))
4055 exit_server("Failed to init oplocks");
4057 /* register our message handlers */
4058 messaging_register(sconn
->msg_ctx
, sconn
,
4059 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
4060 messaging_register(sconn
->msg_ctx
, sconn
,
4061 MSG_SMB_CLOSE_FILE
, msg_close_file
);
4062 messaging_register(sconn
->msg_ctx
, sconn
,
4063 MSG_SMB_FILE_RENAME
, msg_file_was_renamed
);
4065 id_cache_register_msgs(sconn
->msg_ctx
);
4066 messaging_deregister(sconn
->msg_ctx
, ID_CACHE_KILL
, NULL
);
4067 messaging_register(sconn
->msg_ctx
, sconn
,
4068 ID_CACHE_KILL
, smbd_id_cache_kill
);
4070 messaging_deregister(sconn
->msg_ctx
,
4071 MSG_SMB_CONF_UPDATED
, sconn
->ev_ctx
);
4072 messaging_register(sconn
->msg_ctx
, sconn
,
4073 MSG_SMB_CONF_UPDATED
, smbd_conf_updated
);
4075 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_KILL_CLIENT_IP
,
4077 messaging_register(sconn
->msg_ctx
, sconn
,
4078 MSG_SMB_KILL_CLIENT_IP
,
4079 msg_kill_client_ip
);
4081 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_TELL_NUM_CHILDREN
, NULL
);
4084 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4085 * MSGs to all child processes
4087 messaging_deregister(sconn
->msg_ctx
,
4089 messaging_register(sconn
->msg_ctx
, NULL
,
4090 MSG_DEBUG
, debug_message
);
4092 if ((lp_keepalive() != 0)
4093 && !(event_add_idle(ev_ctx
, NULL
,
4094 timeval_set(lp_keepalive(), 0),
4095 "keepalive", keepalive_fn
,
4097 DEBUG(0, ("Could not add keepalive event\n"));
4101 if (!(event_add_idle(ev_ctx
, NULL
,
4102 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
4103 "deadtime", deadtime_fn
, sconn
))) {
4104 DEBUG(0, ("Could not add deadtime event\n"));
4108 if (!(event_add_idle(ev_ctx
, NULL
,
4109 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
4110 "housekeeping", housekeeping_fn
, sconn
))) {
4111 DEBUG(0, ("Could not add housekeeping event\n"));
4115 smbprofile_dump_setup(ev_ctx
);
4117 if (!init_dptrs(sconn
)) {
4118 exit_server("init_dptrs() failed");
4121 TALLOC_FREE(trace_state
.frame
);
4123 tevent_set_trace_callback(ev_ctx
, smbd_tevent_trace_callback
,
4126 ret
= tevent_loop_wait(ev_ctx
);
4128 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4129 " exiting\n", ret
, strerror(errno
)));
4132 TALLOC_FREE(trace_state
.frame
);
4134 exit_server_cleanly(NULL
);
4137 bool req_is_in_chain(const struct smb_request
*req
)
4139 if (req
->vwv
!= (const uint16_t *)(req
->inbuf
+smb_vwv
)) {
4141 * We're right now handling a subsequent request, so we must
4147 if (!is_andx_req(req
->cmd
)) {
4153 * Okay, an illegal request, but definitely not chained :-)
4158 return (CVAL(req
->vwv
+0, 0) != 0xFF);