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_ctdb.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"
44 #include "system/threads.h"
45 #include "lib/pthreadpool/pthreadpool_tevent.h"
46 #include "util_event.h"
47 #include "libcli/smb/smbXcli_base.h"
48 #include "lib/util/time_basic.h"
50 /* Internal message queue for deferred opens. */
51 struct pending_message_list
{
52 struct pending_message_list
*next
, *prev
;
53 struct timeval request_time
; /* When was this first issued? */
54 struct smbd_server_connection
*sconn
;
55 struct smbXsrv_connection
*xconn
;
56 struct tevent_timer
*te
;
57 struct smb_perfcount_data pcd
;
62 struct deferred_open_record
*open_rec
;
65 static void construct_reply_common(uint8_t cmd
, const uint8_t *inbuf
,
67 static struct pending_message_list
*get_deferred_open_message_smb(
68 struct smbd_server_connection
*sconn
, uint64_t mid
);
69 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
);
71 static void smbd_echo_init(struct smbXsrv_connection
*xconn
)
73 xconn
->smb1
.echo_handler
.trusted_fd
= -1;
74 xconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
75 #ifdef HAVE_ROBUST_MUTEXES
76 xconn
->smb1
.echo_handler
.socket_mutex
= NULL
;
80 static bool smbd_echo_active(struct smbXsrv_connection
*xconn
)
82 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
86 #ifdef HAVE_ROBUST_MUTEXES
87 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
95 static bool smbd_lock_socket_internal(struct smbXsrv_connection
*xconn
)
97 if (!smbd_echo_active(xconn
)) {
101 xconn
->smb1
.echo_handler
.ref_count
++;
103 if (xconn
->smb1
.echo_handler
.ref_count
> 1) {
107 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
109 #ifdef HAVE_ROBUST_MUTEXES
110 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
113 while (ret
== EINTR
) {
114 ret
= pthread_mutex_lock(
115 xconn
->smb1
.echo_handler
.socket_mutex
);
121 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
128 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
133 xconn
->smb1
.echo_handler
.socket_lock_fd
,
134 F_SETLKW
, 0, 0, F_WRLCK
);
135 } while (!ok
&& (errno
== EINTR
));
138 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
143 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
148 void smbd_lock_socket(struct smbXsrv_connection
*xconn
)
150 if (!smbd_lock_socket_internal(xconn
)) {
151 exit_server_cleanly("failed to lock socket");
155 static bool smbd_unlock_socket_internal(struct smbXsrv_connection
*xconn
)
157 if (!smbd_echo_active(xconn
)) {
161 xconn
->smb1
.echo_handler
.ref_count
--;
163 if (xconn
->smb1
.echo_handler
.ref_count
> 0) {
167 #ifdef HAVE_ROBUST_MUTEXES
168 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
170 ret
= pthread_mutex_unlock(
171 xconn
->smb1
.echo_handler
.socket_mutex
);
173 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
180 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
185 xconn
->smb1
.echo_handler
.socket_lock_fd
,
186 F_SETLKW
, 0, 0, F_UNLCK
);
187 } while (!ok
&& (errno
== EINTR
));
190 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
195 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
200 void smbd_unlock_socket(struct smbXsrv_connection
*xconn
)
202 if (!smbd_unlock_socket_internal(xconn
)) {
203 exit_server_cleanly("failed to unlock socket");
207 /* Accessor function for smb_read_error for smbd functions. */
209 /****************************************************************************
211 ****************************************************************************/
213 bool srv_send_smb(struct smbXsrv_connection
*xconn
, char *buffer
,
214 bool do_signing
, uint32_t seqnum
,
216 struct smb_perfcount_data
*pcd
)
220 char *buf_out
= buffer
;
222 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
224 * we're not supposed to do any io
229 smbd_lock_socket(xconn
);
234 /* Sign the outgoing packet if required. */
235 status
= srv_calculate_sign_mac(xconn
, buf_out
, seqnum
);
236 if (!NT_STATUS_IS_OK(status
)) {
237 DBG_ERR("Failed to calculate signing mac: %s\n",
244 NTSTATUS status
= srv_encrypt_buffer(xconn
, buffer
, &buf_out
);
245 if (!NT_STATUS_IS_OK(status
)) {
246 DEBUG(0, ("send_smb: SMB encryption failed "
247 "on outgoing packet! Error %s\n",
248 nt_errstr(status
) ));
254 len
= smb_len_large(buf_out
) + 4;
256 ret
= write_data(xconn
->transport
.sock
, buf_out
, len
);
258 int saved_errno
= errno
;
260 * Try and give an error message saying what
263 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
264 (int)getpid(), (int)len
,
265 smbXsrv_connection_dbg(xconn
),
266 (int)ret
, strerror(saved_errno
)));
269 srv_free_enc_buffer(xconn
, buf_out
);
273 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
274 srv_free_enc_buffer(xconn
, buf_out
);
276 SMB_PERFCOUNT_END(pcd
);
278 smbd_unlock_socket(xconn
);
282 /*******************************************************************
283 Setup the word count and byte count for a smb message.
284 ********************************************************************/
286 size_t srv_set_message(char *buf
,
291 if (zero
&& (num_words
|| num_bytes
)) {
292 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
294 SCVAL(buf
,smb_wct
,num_words
);
295 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
296 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
297 return (smb_size
+ num_words
*2 + num_bytes
);
300 static bool valid_smb_header(const uint8_t *inbuf
)
302 if (is_encrypted_packet(inbuf
)) {
306 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
307 * but it just looks weird to call strncmp for this one.
309 return (IVAL(smb_base(inbuf
), 0) == 0x424D53FF);
312 /* Socket functions for smbd packet processing. */
314 static bool valid_packet_size(size_t len
)
317 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
318 * of header. Don't print the error if this fits.... JRA.
321 if (len
> (LARGE_WRITEX_BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
322 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
323 (unsigned long)len
));
329 static NTSTATUS
read_packet_remainder(int fd
, char *buffer
,
330 unsigned int timeout
, ssize_t len
)
338 status
= read_fd_with_timeout(fd
, buffer
, len
, len
, timeout
, NULL
);
339 if (!NT_STATUS_IS_OK(status
)) {
340 char addr
[INET6_ADDRSTRLEN
];
341 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
343 get_peer_addr(fd
, addr
, sizeof(addr
)),
349 /****************************************************************************
350 Attempt a zerocopy writeX read. We know here that len > smb_size-4
351 ****************************************************************************/
354 * Unfortunately, earlier versions of smbclient/libsmbclient
355 * don't send this "standard" writeX header. I've fixed this
356 * for 3.2 but we'll use the old method with earlier versions.
357 * Windows and CIFSFS at least use this standard size. Not
361 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
362 (2*14) + /* word count (including bcc) */ \
365 static NTSTATUS
receive_smb_raw_talloc_partial_read(TALLOC_CTX
*mem_ctx
,
366 const char lenbuf
[4],
367 struct smbXsrv_connection
*xconn
,
370 unsigned int timeout
,
374 /* Size of a WRITEX call (+4 byte len). */
375 char writeX_header
[4 + STANDARD_WRITE_AND_X_HEADER_SIZE
];
376 ssize_t len
= smb_len_large(lenbuf
); /* Could be a UNIX large writeX. */
380 memcpy(writeX_header
, lenbuf
, 4);
382 status
= read_fd_with_timeout(
383 sock
, writeX_header
+ 4,
384 STANDARD_WRITE_AND_X_HEADER_SIZE
,
385 STANDARD_WRITE_AND_X_HEADER_SIZE
,
388 if (!NT_STATUS_IS_OK(status
)) {
389 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
391 smbXsrv_connection_dbg(xconn
),
397 * Ok - now try and see if this is a possible
401 if (is_valid_writeX_buffer(xconn
, (uint8_t *)writeX_header
)) {
403 * If the data offset is beyond what
404 * we've read, drain the extra bytes.
406 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
409 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
410 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
411 if (drain_socket(sock
, drain
) != drain
) {
412 smb_panic("receive_smb_raw_talloc_partial_read:"
413 " failed to drain pending bytes");
416 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
419 /* Spoof down the length and null out the bcc. */
420 set_message_bcc(writeX_header
, 0);
421 newlen
= smb_len(writeX_header
);
423 /* Copy the header we've written. */
425 *buffer
= (char *)talloc_memdup(mem_ctx
,
427 sizeof(writeX_header
));
429 if (*buffer
== NULL
) {
430 DEBUG(0, ("Could not allocate inbuf of length %d\n",
431 (int)sizeof(writeX_header
)));
432 return NT_STATUS_NO_MEMORY
;
435 /* Work out the remaining bytes. */
436 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
437 *len_ret
= newlen
+ 4;
441 if (!valid_packet_size(len
)) {
442 return NT_STATUS_INVALID_PARAMETER
;
446 * Not a valid writeX call. Just do the standard
450 *buffer
= talloc_array(mem_ctx
, char, len
+4);
452 if (*buffer
== NULL
) {
453 DEBUG(0, ("Could not allocate inbuf of length %d\n",
455 return NT_STATUS_NO_MEMORY
;
458 /* Copy in what we already read. */
461 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
462 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
465 status
= read_packet_remainder(
467 (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
470 if (!NT_STATUS_IS_OK(status
)) {
471 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
481 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
,
482 struct smbXsrv_connection
*xconn
,
484 char **buffer
, unsigned int timeout
,
485 size_t *p_unread
, size_t *plen
)
489 int min_recv_size
= lp_min_receive_file_size();
494 status
= read_smb_length_return_keepalive(sock
, lenbuf
, timeout
,
496 if (!NT_STATUS_IS_OK(status
)) {
500 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
501 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
502 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
503 !srv_is_signing_active(xconn
) &&
504 xconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
506 return receive_smb_raw_talloc_partial_read(
507 mem_ctx
, lenbuf
, xconn
, sock
, buffer
, timeout
,
511 if (!valid_packet_size(len
)) {
512 return NT_STATUS_INVALID_PARAMETER
;
516 * The +4 here can't wrap, we've checked the length above already.
519 *buffer
= talloc_array(mem_ctx
, char, len
+4);
521 if (*buffer
== NULL
) {
522 DEBUG(0, ("Could not allocate inbuf of length %d\n",
524 return NT_STATUS_NO_MEMORY
;
527 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
529 status
= read_packet_remainder(sock
, (*buffer
)+4, timeout
, len
);
530 if (!NT_STATUS_IS_OK(status
)) {
538 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
,
539 struct smbXsrv_connection
*xconn
,
541 char **buffer
, unsigned int timeout
,
542 size_t *p_unread
, bool *p_encrypted
,
545 bool trusted_channel
)
550 *p_encrypted
= false;
552 status
= receive_smb_raw_talloc(mem_ctx
, xconn
, sock
, buffer
, timeout
,
554 if (!NT_STATUS_IS_OK(status
)) {
555 DEBUG(NT_STATUS_EQUAL(status
, NT_STATUS_END_OF_FILE
)?5:1,
556 ("receive_smb_raw_talloc failed for client %s "
557 "read error = %s.\n",
558 smbXsrv_connection_dbg(xconn
),
559 nt_errstr(status
)) );
563 if (is_encrypted_packet((uint8_t *)*buffer
)) {
564 status
= srv_decrypt_buffer(xconn
, *buffer
);
565 if (!NT_STATUS_IS_OK(status
)) {
566 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
567 "incoming packet! Error %s\n",
568 nt_errstr(status
) ));
574 /* Check the incoming SMB signature. */
575 if (!srv_check_sign_mac(xconn
, *buffer
, seqnum
, trusted_channel
)) {
576 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
577 "incoming packet!\n"));
578 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
586 * Initialize a struct smb_request from an inbuf
589 static bool init_smb_request(struct smb_request
*req
,
590 struct smbd_server_connection
*sconn
,
591 struct smbXsrv_connection
*xconn
,
592 const uint8_t *inbuf
,
593 size_t unread_bytes
, bool encrypted
,
596 struct smbXsrv_tcon
*tcon
;
599 size_t req_size
= smb_len(inbuf
) + 4;
601 /* Ensure we have at least smb_size bytes. */
602 if (req_size
< smb_size
) {
603 DEBUG(0,("init_smb_request: invalid request size %u\n",
604 (unsigned int)req_size
));
608 req
->request_time
= timeval_current();
609 now
= timeval_to_nttime(&req
->request_time
);
611 req
->cmd
= CVAL(inbuf
, smb_com
);
612 req
->flags2
= SVAL(inbuf
, smb_flg2
);
613 req
->smbpid
= SVAL(inbuf
, smb_pid
);
614 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
615 req
->seqnum
= seqnum
;
616 req
->vuid
= SVAL(inbuf
, smb_uid
);
617 req
->tid
= SVAL(inbuf
, smb_tid
);
618 req
->wct
= CVAL(inbuf
, smb_wct
);
619 req
->vwv
= (const uint16_t *)(inbuf
+smb_vwv
);
620 req
->buflen
= smb_buflen(inbuf
);
621 req
->buf
= (const uint8_t *)smb_buf_const(inbuf
);
622 req
->unread_bytes
= unread_bytes
;
623 req
->encrypted
= encrypted
;
628 status
= smb1srv_tcon_lookup(xconn
, req
->tid
, now
, &tcon
);
629 if (NT_STATUS_IS_OK(status
)) {
630 req
->conn
= tcon
->compat
;
633 req
->chain_fsp
= NULL
;
635 req
->priv_paths
= NULL
;
637 req
->posix_pathnames
= lp_posix_pathnames();
638 smb_init_perfcount_data(&req
->pcd
);
640 /* Ensure we have at least wct words and 2 bytes of bcc. */
641 if (smb_size
+ req
->wct
*2 > req_size
) {
642 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
643 (unsigned int)req
->wct
,
644 (unsigned int)req_size
));
647 /* Ensure bcc is correct. */
648 if (((const uint8_t *)smb_buf_const(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
649 DEBUG(0,("init_smb_request: invalid bcc number %u "
650 "(wct = %u, size %u)\n",
651 (unsigned int)req
->buflen
,
652 (unsigned int)req
->wct
,
653 (unsigned int)req_size
));
661 static void process_smb(struct smbXsrv_connection
*xconn
,
662 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
663 uint32_t seqnum
, bool encrypted
,
664 struct smb_perfcount_data
*deferred_pcd
);
666 static void smbd_deferred_open_timer(struct tevent_context
*ev
,
667 struct tevent_timer
*te
,
668 struct timeval _tval
,
671 struct pending_message_list
*msg
= talloc_get_type(private_data
,
672 struct pending_message_list
);
673 struct smbd_server_connection
*sconn
= msg
->sconn
;
674 struct smbXsrv_connection
*xconn
= msg
->xconn
;
675 TALLOC_CTX
*mem_ctx
= talloc_tos();
676 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
679 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
682 exit_server("smbd_deferred_open_timer: talloc failed\n");
686 /* We leave this message on the queue so the open code can
687 know this is a retry. */
688 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
689 (unsigned long long)mid
));
691 /* Mark the message as processed so this is not
692 * re-processed in error. */
693 msg
->processed
= true;
695 process_smb(xconn
, inbuf
,
697 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
699 /* If it's still there and was processed, remove it. */
700 msg
= get_deferred_open_message_smb(sconn
, mid
);
701 if (msg
&& msg
->processed
) {
702 remove_deferred_open_message_smb(xconn
, mid
);
706 /****************************************************************************
707 Function to push a message onto the tail of a linked list of smb messages ready
709 ****************************************************************************/
711 static bool push_queued_message(struct smb_request
*req
,
712 struct timeval request_time
,
713 struct timeval end_time
,
714 struct deferred_open_record
*open_rec
)
716 int msg_len
= smb_len(req
->inbuf
) + 4;
717 struct pending_message_list
*msg
;
719 msg
= talloc_zero(NULL
, struct pending_message_list
);
722 DEBUG(0,("push_message: malloc fail (1)\n"));
725 msg
->sconn
= req
->sconn
;
726 msg
->xconn
= req
->xconn
;
728 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
729 if(msg
->buf
.data
== NULL
) {
730 DEBUG(0,("push_message: malloc fail (2)\n"));
735 msg
->request_time
= request_time
;
736 msg
->seqnum
= req
->seqnum
;
737 msg
->encrypted
= req
->encrypted
;
738 msg
->processed
= false;
739 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
742 msg
->open_rec
= talloc_move(msg
, &open_rec
);
746 msg
->te
= tevent_add_timer(msg
->sconn
->ev_ctx
,
749 smbd_deferred_open_timer
,
752 DEBUG(0,("push_message: event_add_timed failed\n"));
758 DLIST_ADD_END(req
->sconn
->deferred_open_queue
, msg
);
760 DEBUG(10,("push_message: pushed message length %u on "
761 "deferred_open_queue\n", (unsigned int)msg_len
));
766 /****************************************************************************
767 Function to delete a sharing violation open message by mid.
768 ****************************************************************************/
770 void remove_deferred_open_message_smb(struct smbXsrv_connection
*xconn
,
773 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
774 struct pending_message_list
*pml
;
776 if (sconn
->using_smb2
) {
777 remove_deferred_open_message_smb2(xconn
, mid
);
781 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
782 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
783 DEBUG(10,("remove_deferred_open_message_smb: "
784 "deleting mid %llu len %u\n",
785 (unsigned long long)mid
,
786 (unsigned int)pml
->buf
.length
));
787 DLIST_REMOVE(sconn
->deferred_open_queue
, pml
);
794 /****************************************************************************
795 Move a sharing violation open retry message to the front of the list and
796 schedule it for immediate processing.
797 ****************************************************************************/
799 bool schedule_deferred_open_message_smb(struct smbXsrv_connection
*xconn
,
802 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
803 struct pending_message_list
*pml
;
806 if (sconn
->using_smb2
) {
807 return schedule_deferred_open_message_smb2(xconn
, mid
);
810 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
811 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
813 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
816 (unsigned long long)msg_mid
));
818 if (mid
== msg_mid
) {
819 struct tevent_timer
*te
;
821 if (pml
->processed
) {
822 /* A processed message should not be
824 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
825 "message mid %llu was already processed\n",
826 (unsigned long long)msg_mid
));
830 DEBUG(10,("schedule_deferred_open_message_smb: "
831 "scheduling mid %llu\n",
832 (unsigned long long)mid
));
835 * smbd_deferred_open_timer() calls
836 * process_smb() to redispatch the request
837 * including the required impersonation.
839 * So we can just use the raw tevent_context.
841 te
= tevent_add_timer(xconn
->client
->raw_ev_ctx
,
844 smbd_deferred_open_timer
,
847 DEBUG(10,("schedule_deferred_open_message_smb: "
848 "event_add_timed() failed, "
849 "skipping mid %llu\n",
850 (unsigned long long)msg_mid
));
853 TALLOC_FREE(pml
->te
);
855 DLIST_PROMOTE(sconn
->deferred_open_queue
, pml
);
860 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
861 "find message mid %llu\n",
862 (unsigned long long)mid
));
867 /****************************************************************************
868 Return true if this mid is on the deferred queue and was not yet processed.
869 ****************************************************************************/
871 bool open_was_deferred(struct smbXsrv_connection
*xconn
, uint64_t mid
)
873 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
874 struct pending_message_list
*pml
;
876 if (sconn
->using_smb2
) {
877 return open_was_deferred_smb2(xconn
, mid
);
880 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
881 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
888 /****************************************************************************
889 Return the message queued by this mid.
890 ****************************************************************************/
892 static struct pending_message_list
*get_deferred_open_message_smb(
893 struct smbd_server_connection
*sconn
, uint64_t mid
)
895 struct pending_message_list
*pml
;
897 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
898 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
905 /****************************************************************************
906 Get the state data queued by this mid.
907 ****************************************************************************/
909 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
910 struct timeval
*p_request_time
,
911 struct deferred_open_record
**open_rec
)
913 struct pending_message_list
*pml
;
915 if (smbreq
->sconn
->using_smb2
) {
916 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
921 pml
= get_deferred_open_message_smb(smbreq
->sconn
, smbreq
->mid
);
925 if (p_request_time
) {
926 *p_request_time
= pml
->request_time
;
928 if (open_rec
!= NULL
) {
929 *open_rec
= pml
->open_rec
;
934 /****************************************************************************
935 Function to push a deferred open smb message onto a linked list of local smb
936 messages ready for processing.
937 ****************************************************************************/
939 bool push_deferred_open_message_smb(struct smb_request
*req
,
940 struct timeval timeout
,
942 struct deferred_open_record
*open_rec
)
944 struct timeval_buf tvbuf
;
945 struct timeval end_time
;
948 return push_deferred_open_message_smb2(req
->smb2req
,
955 if (req
->unread_bytes
) {
956 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
957 "unread_bytes = %u\n",
958 (unsigned int)req
->unread_bytes
));
959 smb_panic("push_deferred_open_message_smb: "
960 "logic error unread_bytes != 0" );
963 end_time
= timeval_sum(&req
->request_time
, &timeout
);
965 DBG_DEBUG("pushing message len %u mid %"PRIu64
" timeout time [%s]\n",
966 (unsigned int) smb_len(req
->inbuf
)+4,
968 timeval_str_buf(&end_time
, false, true, &tvbuf
));
970 return push_queued_message(req
, req
->request_time
, end_time
, open_rec
);
973 static void smbd_sig_term_handler(struct tevent_context
*ev
,
974 struct tevent_signal
*se
,
980 exit_server_cleanly("termination signal");
983 static void smbd_setup_sig_term_handler(struct smbd_server_connection
*sconn
)
985 struct tevent_signal
*se
;
987 se
= tevent_add_signal(sconn
->ev_ctx
,
990 smbd_sig_term_handler
,
993 exit_server("failed to setup SIGTERM handler");
997 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
998 struct tevent_signal
*se
,
1004 struct smbd_server_connection
*sconn
=
1005 talloc_get_type_abort(private_data
,
1006 struct smbd_server_connection
);
1008 change_to_root_user();
1009 DEBUG(1,("Reloading services after SIGHUP\n"));
1010 reload_services(sconn
, conn_snum_used
, false);
1013 static void smbd_setup_sig_hup_handler(struct smbd_server_connection
*sconn
)
1015 struct tevent_signal
*se
;
1017 se
= tevent_add_signal(sconn
->ev_ctx
,
1020 smbd_sig_hup_handler
,
1023 exit_server("failed to setup SIGHUP handler");
1027 static void smbd_conf_updated(struct messaging_context
*msg
,
1030 struct server_id server_id
,
1033 struct smbd_server_connection
*sconn
=
1034 talloc_get_type_abort(private_data
,
1035 struct smbd_server_connection
);
1037 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1038 "updated. Reloading.\n"));
1039 change_to_root_user();
1040 reload_services(sconn
, conn_snum_used
, false);
1044 * Only allow 5 outstanding trans requests. We're allocating memory, so
1048 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
1051 for (; list
!= NULL
; list
= list
->next
) {
1053 if (list
->mid
== mid
) {
1054 return NT_STATUS_INVALID_PARAMETER
;
1060 return NT_STATUS_INSUFFICIENT_RESOURCES
;
1063 return NT_STATUS_OK
;
1067 These flags determine some of the permissions required to do an operation
1069 Note that I don't set NEED_WRITE on some write operations because they
1070 are used by some brain-dead clients when printing, and I don't want to
1071 force write permissions on print services.
1073 #define AS_USER (1<<0)
1074 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1075 #define TIME_INIT (1<<2)
1076 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1077 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1078 #define DO_CHDIR (1<<6)
1081 define a list of possible SMB messages and their corresponding
1082 functions. Any message that has a NULL function is unimplemented -
1083 please feel free to contribute implementations!
1085 static const struct smb_message_struct
{
1087 void (*fn
)(struct smb_request
*req
);
1089 } smb_messages
[256] = {
1091 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1092 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1093 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1094 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1095 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1096 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1097 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1098 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1099 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1100 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1101 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1102 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1103 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1104 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1105 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1106 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1107 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1108 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1109 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1110 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1111 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1112 /* 0x15 */ { NULL
, NULL
, 0 },
1113 /* 0x16 */ { NULL
, NULL
, 0 },
1114 /* 0x17 */ { NULL
, NULL
, 0 },
1115 /* 0x18 */ { NULL
, NULL
, 0 },
1116 /* 0x19 */ { NULL
, NULL
, 0 },
1117 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1118 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1119 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1120 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1121 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1122 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1123 /* 0x20 */ { "SMBwritec", NULL
,0},
1124 /* 0x21 */ { NULL
, NULL
, 0 },
1125 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1126 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1127 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1128 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1129 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1130 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1131 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1132 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1133 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1134 /* 0x2b */ { "SMBecho",reply_echo
,0},
1135 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1136 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1137 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1138 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1139 /* 0x30 */ { NULL
, NULL
, 0 },
1140 /* 0x31 */ { NULL
, NULL
, 0 },
1141 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1142 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1143 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1144 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1145 /* 0x36 */ { NULL
, NULL
, 0 },
1146 /* 0x37 */ { NULL
, NULL
, 0 },
1147 /* 0x38 */ { NULL
, NULL
, 0 },
1148 /* 0x39 */ { NULL
, NULL
, 0 },
1149 /* 0x3a */ { NULL
, NULL
, 0 },
1150 /* 0x3b */ { NULL
, NULL
, 0 },
1151 /* 0x3c */ { NULL
, NULL
, 0 },
1152 /* 0x3d */ { NULL
, NULL
, 0 },
1153 /* 0x3e */ { NULL
, NULL
, 0 },
1154 /* 0x3f */ { NULL
, NULL
, 0 },
1155 /* 0x40 */ { NULL
, NULL
, 0 },
1156 /* 0x41 */ { NULL
, NULL
, 0 },
1157 /* 0x42 */ { NULL
, NULL
, 0 },
1158 /* 0x43 */ { NULL
, NULL
, 0 },
1159 /* 0x44 */ { NULL
, NULL
, 0 },
1160 /* 0x45 */ { NULL
, NULL
, 0 },
1161 /* 0x46 */ { NULL
, NULL
, 0 },
1162 /* 0x47 */ { NULL
, NULL
, 0 },
1163 /* 0x48 */ { NULL
, NULL
, 0 },
1164 /* 0x49 */ { NULL
, NULL
, 0 },
1165 /* 0x4a */ { NULL
, NULL
, 0 },
1166 /* 0x4b */ { NULL
, NULL
, 0 },
1167 /* 0x4c */ { NULL
, NULL
, 0 },
1168 /* 0x4d */ { NULL
, NULL
, 0 },
1169 /* 0x4e */ { NULL
, NULL
, 0 },
1170 /* 0x4f */ { NULL
, NULL
, 0 },
1171 /* 0x50 */ { NULL
, NULL
, 0 },
1172 /* 0x51 */ { NULL
, NULL
, 0 },
1173 /* 0x52 */ { NULL
, NULL
, 0 },
1174 /* 0x53 */ { NULL
, NULL
, 0 },
1175 /* 0x54 */ { NULL
, NULL
, 0 },
1176 /* 0x55 */ { NULL
, NULL
, 0 },
1177 /* 0x56 */ { NULL
, NULL
, 0 },
1178 /* 0x57 */ { NULL
, NULL
, 0 },
1179 /* 0x58 */ { NULL
, NULL
, 0 },
1180 /* 0x59 */ { NULL
, NULL
, 0 },
1181 /* 0x5a */ { NULL
, NULL
, 0 },
1182 /* 0x5b */ { NULL
, NULL
, 0 },
1183 /* 0x5c */ { NULL
, NULL
, 0 },
1184 /* 0x5d */ { NULL
, NULL
, 0 },
1185 /* 0x5e */ { NULL
, NULL
, 0 },
1186 /* 0x5f */ { NULL
, NULL
, 0 },
1187 /* 0x60 */ { NULL
, NULL
, 0 },
1188 /* 0x61 */ { NULL
, NULL
, 0 },
1189 /* 0x62 */ { NULL
, NULL
, 0 },
1190 /* 0x63 */ { NULL
, NULL
, 0 },
1191 /* 0x64 */ { NULL
, NULL
, 0 },
1192 /* 0x65 */ { NULL
, NULL
, 0 },
1193 /* 0x66 */ { NULL
, NULL
, 0 },
1194 /* 0x67 */ { NULL
, NULL
, 0 },
1195 /* 0x68 */ { NULL
, NULL
, 0 },
1196 /* 0x69 */ { NULL
, NULL
, 0 },
1197 /* 0x6a */ { NULL
, NULL
, 0 },
1198 /* 0x6b */ { NULL
, NULL
, 0 },
1199 /* 0x6c */ { NULL
, NULL
, 0 },
1200 /* 0x6d */ { NULL
, NULL
, 0 },
1201 /* 0x6e */ { NULL
, NULL
, 0 },
1202 /* 0x6f */ { NULL
, NULL
, 0 },
1203 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1204 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1205 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1206 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1207 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1208 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1209 /* 0x76 */ { NULL
, NULL
, 0 },
1210 /* 0x77 */ { NULL
, NULL
, 0 },
1211 /* 0x78 */ { NULL
, NULL
, 0 },
1212 /* 0x79 */ { NULL
, NULL
, 0 },
1213 /* 0x7a */ { NULL
, NULL
, 0 },
1214 /* 0x7b */ { NULL
, NULL
, 0 },
1215 /* 0x7c */ { NULL
, NULL
, 0 },
1216 /* 0x7d */ { NULL
, NULL
, 0 },
1217 /* 0x7e */ { NULL
, NULL
, 0 },
1218 /* 0x7f */ { NULL
, NULL
, 0 },
1219 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1220 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1221 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1222 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1223 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1224 /* 0x85 */ { NULL
, NULL
, 0 },
1225 /* 0x86 */ { NULL
, NULL
, 0 },
1226 /* 0x87 */ { NULL
, NULL
, 0 },
1227 /* 0x88 */ { NULL
, NULL
, 0 },
1228 /* 0x89 */ { NULL
, NULL
, 0 },
1229 /* 0x8a */ { NULL
, NULL
, 0 },
1230 /* 0x8b */ { NULL
, NULL
, 0 },
1231 /* 0x8c */ { NULL
, NULL
, 0 },
1232 /* 0x8d */ { NULL
, NULL
, 0 },
1233 /* 0x8e */ { NULL
, NULL
, 0 },
1234 /* 0x8f */ { NULL
, NULL
, 0 },
1235 /* 0x90 */ { NULL
, NULL
, 0 },
1236 /* 0x91 */ { NULL
, NULL
, 0 },
1237 /* 0x92 */ { NULL
, NULL
, 0 },
1238 /* 0x93 */ { NULL
, NULL
, 0 },
1239 /* 0x94 */ { NULL
, NULL
, 0 },
1240 /* 0x95 */ { NULL
, NULL
, 0 },
1241 /* 0x96 */ { NULL
, NULL
, 0 },
1242 /* 0x97 */ { NULL
, NULL
, 0 },
1243 /* 0x98 */ { NULL
, NULL
, 0 },
1244 /* 0x99 */ { NULL
, NULL
, 0 },
1245 /* 0x9a */ { NULL
, NULL
, 0 },
1246 /* 0x9b */ { NULL
, NULL
, 0 },
1247 /* 0x9c */ { NULL
, NULL
, 0 },
1248 /* 0x9d */ { NULL
, NULL
, 0 },
1249 /* 0x9e */ { NULL
, NULL
, 0 },
1250 /* 0x9f */ { NULL
, NULL
, 0 },
1251 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1252 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1253 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1254 /* 0xa3 */ { NULL
, NULL
, 0 },
1255 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1256 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1257 /* 0xa6 */ { NULL
, NULL
, 0 },
1258 /* 0xa7 */ { NULL
, NULL
, 0 },
1259 /* 0xa8 */ { NULL
, NULL
, 0 },
1260 /* 0xa9 */ { NULL
, NULL
, 0 },
1261 /* 0xaa */ { NULL
, NULL
, 0 },
1262 /* 0xab */ { NULL
, NULL
, 0 },
1263 /* 0xac */ { NULL
, NULL
, 0 },
1264 /* 0xad */ { NULL
, NULL
, 0 },
1265 /* 0xae */ { NULL
, NULL
, 0 },
1266 /* 0xaf */ { NULL
, NULL
, 0 },
1267 /* 0xb0 */ { NULL
, NULL
, 0 },
1268 /* 0xb1 */ { NULL
, NULL
, 0 },
1269 /* 0xb2 */ { NULL
, NULL
, 0 },
1270 /* 0xb3 */ { NULL
, NULL
, 0 },
1271 /* 0xb4 */ { NULL
, NULL
, 0 },
1272 /* 0xb5 */ { NULL
, NULL
, 0 },
1273 /* 0xb6 */ { NULL
, NULL
, 0 },
1274 /* 0xb7 */ { NULL
, NULL
, 0 },
1275 /* 0xb8 */ { NULL
, NULL
, 0 },
1276 /* 0xb9 */ { NULL
, NULL
, 0 },
1277 /* 0xba */ { NULL
, NULL
, 0 },
1278 /* 0xbb */ { NULL
, NULL
, 0 },
1279 /* 0xbc */ { NULL
, NULL
, 0 },
1280 /* 0xbd */ { NULL
, NULL
, 0 },
1281 /* 0xbe */ { NULL
, NULL
, 0 },
1282 /* 0xbf */ { NULL
, NULL
, 0 },
1283 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1284 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1285 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1286 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1287 /* 0xc4 */ { NULL
, NULL
, 0 },
1288 /* 0xc5 */ { NULL
, NULL
, 0 },
1289 /* 0xc6 */ { NULL
, NULL
, 0 },
1290 /* 0xc7 */ { NULL
, NULL
, 0 },
1291 /* 0xc8 */ { NULL
, NULL
, 0 },
1292 /* 0xc9 */ { NULL
, NULL
, 0 },
1293 /* 0xca */ { NULL
, NULL
, 0 },
1294 /* 0xcb */ { NULL
, NULL
, 0 },
1295 /* 0xcc */ { NULL
, NULL
, 0 },
1296 /* 0xcd */ { NULL
, NULL
, 0 },
1297 /* 0xce */ { NULL
, NULL
, 0 },
1298 /* 0xcf */ { NULL
, NULL
, 0 },
1299 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1300 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1301 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1302 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1303 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1304 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1305 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1306 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1307 /* 0xd8 */ { NULL
, NULL
, 0 },
1308 /* 0xd9 */ { NULL
, NULL
, 0 },
1309 /* 0xda */ { NULL
, NULL
, 0 },
1310 /* 0xdb */ { NULL
, NULL
, 0 },
1311 /* 0xdc */ { NULL
, NULL
, 0 },
1312 /* 0xdd */ { NULL
, NULL
, 0 },
1313 /* 0xde */ { NULL
, NULL
, 0 },
1314 /* 0xdf */ { NULL
, NULL
, 0 },
1315 /* 0xe0 */ { NULL
, NULL
, 0 },
1316 /* 0xe1 */ { NULL
, NULL
, 0 },
1317 /* 0xe2 */ { NULL
, NULL
, 0 },
1318 /* 0xe3 */ { NULL
, NULL
, 0 },
1319 /* 0xe4 */ { NULL
, NULL
, 0 },
1320 /* 0xe5 */ { NULL
, NULL
, 0 },
1321 /* 0xe6 */ { NULL
, NULL
, 0 },
1322 /* 0xe7 */ { NULL
, NULL
, 0 },
1323 /* 0xe8 */ { NULL
, NULL
, 0 },
1324 /* 0xe9 */ { NULL
, NULL
, 0 },
1325 /* 0xea */ { NULL
, NULL
, 0 },
1326 /* 0xeb */ { NULL
, NULL
, 0 },
1327 /* 0xec */ { NULL
, NULL
, 0 },
1328 /* 0xed */ { NULL
, NULL
, 0 },
1329 /* 0xee */ { NULL
, NULL
, 0 },
1330 /* 0xef */ { NULL
, NULL
, 0 },
1331 /* 0xf0 */ { NULL
, NULL
, 0 },
1332 /* 0xf1 */ { NULL
, NULL
, 0 },
1333 /* 0xf2 */ { NULL
, NULL
, 0 },
1334 /* 0xf3 */ { NULL
, NULL
, 0 },
1335 /* 0xf4 */ { NULL
, NULL
, 0 },
1336 /* 0xf5 */ { NULL
, NULL
, 0 },
1337 /* 0xf6 */ { NULL
, NULL
, 0 },
1338 /* 0xf7 */ { NULL
, NULL
, 0 },
1339 /* 0xf8 */ { NULL
, NULL
, 0 },
1340 /* 0xf9 */ { NULL
, NULL
, 0 },
1341 /* 0xfa */ { NULL
, NULL
, 0 },
1342 /* 0xfb */ { NULL
, NULL
, 0 },
1343 /* 0xfc */ { NULL
, NULL
, 0 },
1344 /* 0xfd */ { NULL
, NULL
, 0 },
1345 /* 0xfe */ { NULL
, NULL
, 0 },
1346 /* 0xff */ { NULL
, NULL
, 0 }
1350 /*******************************************************************
1351 allocate and initialize a reply packet
1352 ********************************************************************/
1354 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1355 const uint8_t *inbuf
, char **outbuf
,
1356 uint8_t num_words
, uint32_t num_bytes
)
1358 size_t smb_len
= MIN_SMB_SIZE
+ VWV(num_words
) + num_bytes
;
1361 * Protect against integer wrap.
1362 * The SMB layer reply can be up to 0xFFFFFF bytes.
1364 if ((num_bytes
> 0xffffff) || (smb_len
> 0xffffff)) {
1366 if (asprintf(&msg
, "num_bytes too large: %u",
1367 (unsigned)num_bytes
) == -1) {
1368 msg
= discard_const_p(char, "num_bytes too large");
1374 * Here we include the NBT header for now.
1376 *outbuf
= talloc_array(mem_ctx
, char,
1377 NBT_HDR_SIZE
+ smb_len
);
1378 if (*outbuf
== NULL
) {
1382 construct_reply_common(req
->cmd
, inbuf
, *outbuf
);
1383 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1385 * Zero out the word area, the caller has to take care of the bcc area
1388 if (num_words
!= 0) {
1389 memset(*outbuf
+ (NBT_HDR_SIZE
+ HDR_VWV
), 0, VWV(num_words
));
1395 void reply_outbuf(struct smb_request
*req
, uint8_t num_words
, uint32_t num_bytes
)
1398 if (!create_outbuf(req
, req
, req
->inbuf
, &outbuf
, num_words
,
1400 smb_panic("could not allocate output buffer\n");
1402 req
->outbuf
= (uint8_t *)outbuf
;
1406 /*******************************************************************
1407 Dump a packet to a file.
1408 ********************************************************************/
1410 static void smb_dump(const char *name
, int type
, const char *data
)
1415 if (DEBUGLEVEL
< 50) {
1419 len
= smb_len_tcp(data
)+4;
1420 for (i
=1;i
<100;i
++) {
1421 fname
= talloc_asprintf(talloc_tos(),
1425 type
? "req" : "resp");
1426 if (fname
== NULL
) {
1429 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1430 if (fd
!= -1 || errno
!= EEXIST
) break;
1434 ssize_t ret
= write(fd
, data
, len
);
1436 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1438 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1443 static void smb1srv_update_crypto_flags(struct smbXsrv_session
*session
,
1444 struct smb_request
*req
,
1446 bool *update_session_globalp
,
1447 bool *update_tcon_globalp
)
1449 connection_struct
*conn
= req
->conn
;
1450 struct smbXsrv_tcon
*tcon
= conn
? conn
->tcon
: NULL
;
1451 uint8_t encrypt_flag
= SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
;
1452 uint8_t sign_flag
= SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
1453 bool update_session
= false;
1454 bool update_tcon
= false;
1456 if (req
->encrypted
) {
1457 encrypt_flag
= SMBXSRV_PROCESSED_ENCRYPTED_PACKET
;
1460 if (srv_is_signing_active(req
->xconn
)) {
1461 sign_flag
= SMBXSRV_PROCESSED_SIGNED_PACKET
;
1462 } else if ((type
== SMBecho
) || (type
== SMBsesssetupX
)) {
1464 * echo can be unsigned. Sesssion setup except final
1465 * session setup response too
1467 sign_flag
&= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
1470 update_session
|= smbXsrv_set_crypto_flag(
1471 &session
->global
->encryption_flags
, encrypt_flag
);
1472 update_session
|= smbXsrv_set_crypto_flag(
1473 &session
->global
->signing_flags
, sign_flag
);
1476 update_tcon
|= smbXsrv_set_crypto_flag(
1477 &tcon
->global
->encryption_flags
, encrypt_flag
);
1478 update_tcon
|= smbXsrv_set_crypto_flag(
1479 &tcon
->global
->signing_flags
, sign_flag
);
1482 if (update_session
) {
1483 session
->global
->channels
[0].encryption_cipher
= SMB_ENCRYPTION_GSSAPI
;
1486 *update_session_globalp
= update_session
;
1487 *update_tcon_globalp
= update_tcon
;
1491 /****************************************************************************
1492 Prepare everything for calling the actual request function, and potentially
1493 call the request function via the "new" interface.
1495 Return False if the "legacy" function needs to be called, everything is
1498 Return True if we're done.
1500 I know this API sucks, but it is the one with the least code change I could
1502 ****************************************************************************/
1504 static connection_struct
*switch_message(uint8_t type
, struct smb_request
*req
)
1506 const struct loadparm_substitution
*lp_sub
=
1507 loadparm_s3_global_substitution();
1509 uint64_t session_tag
;
1510 connection_struct
*conn
= NULL
;
1511 struct smbXsrv_connection
*xconn
= req
->xconn
;
1512 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1513 struct smbXsrv_session
*session
= NULL
;
1518 if (!xconn
->smb1
.negprot
.done
) {
1521 * Without a negprot the request must
1522 * either be a negprot, or one of the
1523 * evil old SMB mailslot messaging types.
1531 exit_server_cleanly("The first request "
1532 "should be a negprot");
1536 if (smb_messages
[type
].fn
== NULL
) {
1537 DEBUG(0,("Unknown message type %d!\n",type
));
1538 smb_dump("Unknown", 1, (const char *)req
->inbuf
);
1539 reply_unknown_new(req
, type
);
1543 flags
= smb_messages
[type
].flags
;
1545 /* In share mode security we must ignore the vuid. */
1546 session_tag
= req
->vuid
;
1549 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1550 (int)getpid(), (unsigned long)conn
));
1552 smb_dump(smb_fn_name(type
), 1, (const char *)req
->inbuf
);
1554 /* Ensure this value is replaced in the incoming packet. */
1555 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_uid
,session_tag
);
1558 * Ensure the correct username is in current_user_info. This is a
1559 * really ugly bugfix for problems with multiple session_setup_and_X's
1560 * being done and allowing %U and %G substitutions to work correctly.
1561 * There is a reason this code is done here, don't move it unless you
1562 * know what you're doing... :-).
1567 * lookup an existing session
1569 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1570 * here, the main check is still in change_to_user()
1572 status
= smb1srv_session_lookup(xconn
,
1576 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
1579 status
= NT_STATUS_OK
;
1582 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1583 (unsigned long long)session_tag
,
1584 (unsigned long long)req
->mid
));
1585 reply_nterror(req
, NT_STATUS_NETWORK_SESSION_EXPIRED
);
1590 if (session
!= NULL
&& !(flags
& AS_USER
)) {
1591 struct user_struct
*vuser
= session
->compat
;
1594 * change_to_user() implies set_current_user_info()
1595 * and chdir_connect_service().
1597 * So we only call set_current_user_info if
1598 * we don't have AS_USER specified.
1601 set_current_user_info(
1602 vuser
->session_info
->unix_info
->sanitized_username
,
1603 vuser
->session_info
->unix_info
->unix_name
,
1604 vuser
->session_info
->info
->domain_name
);
1608 /* Does this call need to be run as the connected user? */
1609 if (flags
& AS_USER
) {
1611 /* Does this call need a valid tree connection? */
1614 * Amazingly, the error code depends on the command
1617 if (type
== SMBntcreateX
) {
1618 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1620 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1625 set_current_case_sensitive(conn
, SVAL(req
->inbuf
,smb_flg
));
1628 * change_to_user() implies set_current_user_info()
1629 * and chdir_connect_service().
1631 if (!change_to_user_and_service(conn
,session_tag
)) {
1632 DEBUG(0, ("Error: Could not change to user. Removing "
1633 "deferred open, mid=%llu.\n",
1634 (unsigned long long)req
->mid
));
1635 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1639 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1641 /* Does it need write permission? */
1642 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1643 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1647 /* IPC services are limited */
1648 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1649 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1652 } else if (flags
& AS_GUEST
) {
1654 * Does this protocol need to be run as guest? (Only archane
1655 * messenger service requests have this...)
1657 if (!change_to_guest()) {
1658 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1662 /* This call needs to be run as root */
1663 change_to_root_user();
1666 /* load service specific parameters */
1668 if (req
->encrypted
) {
1669 conn
->encrypted_tid
= true;
1670 /* encrypted required from now on. */
1671 conn
->encrypt_level
= SMB_SIGNING_REQUIRED
;
1672 } else if (ENCRYPTION_REQUIRED(conn
)) {
1673 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1674 DEBUG(1,("service[%s] requires encryption"
1675 "%s ACCESS_DENIED. mid=%llu\n",
1676 lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
)),
1678 (unsigned long long)req
->mid
));
1679 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1684 if (flags
& DO_CHDIR
) {
1687 ok
= chdir_current_service(conn
);
1689 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1693 conn
->num_smb_operations
++;
1697 * Update encryption and signing state tracking flags that are
1698 * used by smbstatus to display signing and encryption status.
1700 if (session
!= NULL
) {
1701 bool update_session_global
= false;
1702 bool update_tcon_global
= false;
1704 smb1srv_update_crypto_flags(session
, req
, type
,
1705 &update_session_global
,
1706 &update_tcon_global
);
1708 if (update_session_global
) {
1709 status
= smbXsrv_session_update(session
);
1710 if (!NT_STATUS_IS_OK(status
)) {
1711 reply_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1716 if (update_tcon_global
) {
1717 status
= smbXsrv_tcon_update(req
->conn
->tcon
);
1718 if (!NT_STATUS_IS_OK(status
)) {
1719 reply_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1725 smb_messages
[type
].fn(req
);
1729 /****************************************************************************
1730 Construct a reply to the incoming packet.
1731 ****************************************************************************/
1733 static void construct_reply(struct smbXsrv_connection
*xconn
,
1734 char *inbuf
, int size
, size_t unread_bytes
,
1735 uint32_t seqnum
, bool encrypted
,
1736 struct smb_perfcount_data
*deferred_pcd
)
1738 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
1739 struct smb_request
*req
;
1741 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1742 smb_panic("could not allocate smb_request");
1745 if (!init_smb_request(req
, sconn
, xconn
, (uint8_t *)inbuf
, unread_bytes
,
1746 encrypted
, seqnum
)) {
1747 exit_server_cleanly("Invalid SMB request");
1750 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1752 /* we popped this message off the queue - keep original perf data */
1754 req
->pcd
= *deferred_pcd
;
1756 SMB_PERFCOUNT_START(&req
->pcd
);
1757 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1758 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1761 req
->conn
= switch_message(req
->cmd
, req
);
1763 if (req
->outbuf
== NULL
) {
1765 * Request has suspended itself, will come
1770 if (CVAL(req
->outbuf
,0) == 0) {
1771 show_msg((char *)req
->outbuf
);
1773 smb_request_done(req
);
1776 static void construct_reply_chain(struct smbXsrv_connection
*xconn
,
1777 char *inbuf
, int size
, uint32_t seqnum
,
1779 struct smb_perfcount_data
*deferred_pcd
)
1781 struct smb_request
**reqs
= NULL
;
1782 struct smb_request
*req
;
1786 ok
= smb1_parse_chain(xconn
, (uint8_t *)inbuf
, xconn
, encrypted
,
1787 seqnum
, &reqs
, &num_reqs
);
1789 char errbuf
[smb_size
];
1790 error_packet(errbuf
, 0, 0, NT_STATUS_INVALID_PARAMETER
,
1791 __LINE__
, __FILE__
);
1792 if (!srv_send_smb(xconn
, errbuf
, true, seqnum
, encrypted
,
1794 exit_server_cleanly("construct_reply_chain: "
1795 "srv_send_smb failed.");
1801 req
->inbuf
= (uint8_t *)talloc_move(reqs
, &inbuf
);
1803 req
->conn
= switch_message(req
->cmd
, req
);
1805 if (req
->outbuf
== NULL
) {
1807 * Request has suspended itself, will come
1812 smb_request_done(req
);
1816 * To be called from an async SMB handler that is potentially chained
1817 * when it is finished for shipping.
1820 void smb_request_done(struct smb_request
*req
)
1822 struct smb_request
**reqs
= NULL
;
1823 struct smb_request
*first_req
;
1824 size_t i
, num_reqs
, next_index
;
1827 if (req
->chain
== NULL
) {
1833 num_reqs
= talloc_array_length(reqs
);
1835 for (i
=0; i
<num_reqs
; i
++) {
1836 if (reqs
[i
] == req
) {
1840 if (i
== num_reqs
) {
1842 * Invalid chain, should not happen
1844 status
= NT_STATUS_INTERNAL_ERROR
;
1849 while ((next_index
< num_reqs
) && (IVAL(req
->outbuf
, smb_rcls
) == 0)) {
1850 struct smb_request
*next
= reqs
[next_index
];
1851 struct smbXsrv_tcon
*tcon
;
1852 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1854 next
->vuid
= SVAL(req
->outbuf
, smb_uid
);
1855 next
->tid
= SVAL(req
->outbuf
, smb_tid
);
1856 status
= smb1srv_tcon_lookup(req
->xconn
, next
->tid
,
1859 if (NT_STATUS_IS_OK(status
)) {
1860 next
->conn
= tcon
->compat
;
1864 next
->chain_fsp
= req
->chain_fsp
;
1865 next
->inbuf
= req
->inbuf
;
1868 req
->conn
= switch_message(req
->cmd
, req
);
1870 if (req
->outbuf
== NULL
) {
1872 * Request has suspended itself, will come
1880 first_req
= reqs
[0];
1882 for (i
=1; i
<next_index
; i
++) {
1885 ok
= smb_splice_chain(&first_req
->outbuf
, reqs
[i
]->outbuf
);
1887 status
= NT_STATUS_INTERNAL_ERROR
;
1892 SSVAL(first_req
->outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
1893 SSVAL(first_req
->outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
1896 * This scary statement intends to set the
1897 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1898 * to the value last_req->outbuf carries
1900 SSVAL(first_req
->outbuf
, smb_flg2
,
1901 (SVAL(first_req
->outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
1902 |(SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
1905 * Transfer the error codes from the subrequest to the main one
1907 SSVAL(first_req
->outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
1908 SSVAL(first_req
->outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
1911 first_req
->outbuf
, talloc_get_size(first_req
->outbuf
) - 4);
1914 if (!srv_send_smb(first_req
->xconn
,
1915 (char *)first_req
->outbuf
,
1916 true, first_req
->seqnum
+1,
1917 IS_CONN_ENCRYPTED(req
->conn
)||first_req
->encrypted
,
1919 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1922 TALLOC_FREE(req
); /* non-chained case */
1923 TALLOC_FREE(reqs
); /* chained case */
1928 char errbuf
[smb_size
];
1929 error_packet(errbuf
, 0, 0, status
, __LINE__
, __FILE__
);
1930 if (!srv_send_smb(req
->xconn
, errbuf
, true,
1931 req
->seqnum
+1, req
->encrypted
,
1933 exit_server_cleanly("construct_reply_chain: "
1934 "srv_send_smb failed.");
1937 TALLOC_FREE(req
); /* non-chained case */
1938 TALLOC_FREE(reqs
); /* chained case */
1941 /****************************************************************************
1942 Process an smb from the client
1943 ****************************************************************************/
1944 static void process_smb(struct smbXsrv_connection
*xconn
,
1945 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1946 uint32_t seqnum
, bool encrypted
,
1947 struct smb_perfcount_data
*deferred_pcd
)
1949 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
1950 int msg_type
= CVAL(inbuf
,0);
1952 DO_PROFILE_INC(request
);
1954 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1956 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1957 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1959 if (msg_type
!= NBSSmessage
) {
1961 * NetBIOS session request, keepalive, etc.
1963 reply_special(xconn
, (char *)inbuf
, nread
);
1967 if (sconn
->using_smb2
) {
1968 /* At this point we're not really using smb2,
1969 * we make the decision here.. */
1970 if (smbd_is_smb2_header(inbuf
, nread
)) {
1971 const uint8_t *inpdu
= inbuf
+ NBT_HDR_SIZE
;
1972 size_t pdulen
= nread
- NBT_HDR_SIZE
;
1973 smbd_smb2_process_negprot(xconn
, 0, inpdu
, pdulen
);
1976 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) == SMB_SUICIDE_PACKET
) &&
1993 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1994 uint8_t exitcode
= CVAL(inbuf
, 8);
1995 DBG_WARNING("SUICIDE: 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 (!smb1cli_is_andx_req(cmd
)) {
2114 while (CVAL(buf
, ofs
) != 0xff) {
2116 if (!smb1cli_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 (!smb1cli_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 (!smb1cli_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 (smb1cli_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 (!smb1cli_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(struct tevent_context
*ev
,
2699 uint32_t src_vnn
, uint32_t dst_vnn
,
2701 const uint8_t *msg
, size_t msglen
,
2704 struct smbd_release_ip_state
*state
=
2705 talloc_get_type_abort(private_data
,
2706 struct smbd_release_ip_state
);
2707 struct smbXsrv_connection
*xconn
= state
->xconn
;
2709 const char *addr
= state
->addr
;
2710 const char *p
= addr
;
2715 if (msg
[msglen
-1] != '\0') {
2719 ip
= (const char *)msg
;
2721 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2722 /* avoid recursion */
2726 if (strncmp("::ffff:", addr
, 7) == 0) {
2730 DEBUG(10, ("Got release IP message for %s, "
2731 "our address is %s\n", ip
, p
));
2733 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2734 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2737 * With SMB2 we should do a clean disconnect,
2738 * the previous_session_id in the session setup
2739 * will cleanup the old session, tcons and opens.
2741 * A clean disconnect is needed in order to support
2744 * Note: typically this is never triggered
2745 * as we got a TCP RST (triggered by ctdb event scripts)
2746 * before we get CTDB_SRVID_RELEASE_IP.
2748 * We used to call _exit(1) here, but as this was mostly never
2749 * triggered and has implication on our process model,
2750 * we can just use smbd_server_connection_terminate()
2753 * We don't call smbd_server_connection_terminate() directly
2754 * as we might be called from within ctdbd_migrate(),
2755 * we need to defer our action to the next event loop
2757 tevent_schedule_immediate(state
->im
,
2758 xconn
->client
->raw_ev_ctx
,
2759 smbd_release_ip_immediate
,
2763 * Make sure we don't get any io on the connection.
2765 xconn
->transport
.status
= NT_STATUS_ADDRESS_CLOSED
;
2766 return EADDRNOTAVAIL
;
2772 static NTSTATUS
smbd_register_ips(struct smbXsrv_connection
*xconn
,
2773 struct sockaddr_storage
*srv
,
2774 struct sockaddr_storage
*clnt
)
2776 struct smbd_release_ip_state
*state
;
2777 struct ctdbd_connection
*cconn
;
2780 cconn
= messaging_ctdb_connection();
2781 if (cconn
== NULL
) {
2782 return NT_STATUS_NO_MEMORY
;
2785 state
= talloc_zero(xconn
, struct smbd_release_ip_state
);
2786 if (state
== NULL
) {
2787 return NT_STATUS_NO_MEMORY
;
2789 state
->xconn
= xconn
;
2790 state
->im
= tevent_create_immediate(state
);
2791 if (state
->im
== NULL
) {
2792 return NT_STATUS_NO_MEMORY
;
2794 if (print_sockaddr(state
->addr
, sizeof(state
->addr
), srv
) == NULL
) {
2795 return NT_STATUS_NO_MEMORY
;
2798 ret
= ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, state
);
2800 return map_nt_error_from_unix(ret
);
2802 return NT_STATUS_OK
;
2805 static void msg_kill_client_ip(struct messaging_context
*msg_ctx
,
2806 void *private_data
, uint32_t msg_type
,
2807 struct server_id server_id
, DATA_BLOB
*data
)
2809 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2810 private_data
, struct smbd_server_connection
);
2811 const char *ip
= (char *) data
->data
;
2814 DBG_DEBUG("Got kill request for client IP %s\n", ip
);
2816 client_ip
= tsocket_address_inet_addr_string(sconn
->remote_address
,
2818 if (client_ip
== NULL
) {
2822 if (strequal(ip
, client_ip
)) {
2823 DBG_WARNING("Got kill client message for %s - "
2824 "exiting immediately\n", ip
);
2825 exit_server_cleanly("Forced disconnect for client");
2828 TALLOC_FREE(client_ip
);
2832 * Send keepalive packets to our client
2834 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2836 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2837 private_data
, struct smbd_server_connection
);
2838 struct smbXsrv_connection
*xconn
= NULL
;
2841 if (sconn
->using_smb2
) {
2842 /* Don't do keepalives on an SMB2 connection. */
2847 * With SMB1 we only have 1 connection
2849 xconn
= sconn
->client
->connections
;
2850 smbd_lock_socket(xconn
);
2851 ret
= send_keepalive(xconn
->transport
.sock
);
2852 smbd_unlock_socket(xconn
);
2855 int saved_errno
= errno
;
2857 * Try and give an error message saying what
2860 DEBUG(0, ("send_keepalive failed for client %s. "
2861 "Error %s - exiting\n",
2862 smbXsrv_connection_dbg(xconn
),
2863 strerror(saved_errno
)));
2864 errno
= saved_errno
;
2871 * Do the recurring check if we're idle
2873 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2875 struct smbd_server_connection
*sconn
=
2876 (struct smbd_server_connection
*)private_data
;
2878 if ((conn_num_open(sconn
) == 0)
2879 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2880 DEBUG( 2, ( "Closing idle connection\n" ) );
2881 messaging_send(sconn
->msg_ctx
,
2882 messaging_server_id(sconn
->msg_ctx
),
2883 MSG_SHUTDOWN
, &data_blob_null
);
2891 * Do the recurring log file and smb.conf reload checks.
2894 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2896 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2897 private_data
, struct smbd_server_connection
);
2899 DEBUG(5, ("housekeeping\n"));
2901 change_to_root_user();
2903 /* update printer queue caches if necessary */
2904 update_monitored_printq_cache(sconn
->msg_ctx
);
2906 /* check if we need to reload services */
2907 check_reload(sconn
, time_mono(NULL
));
2910 * Force a log file check.
2912 force_check_log_size();
2918 * Read an smb packet in the echo handler child, giving the parent
2919 * smbd one second to react once the socket becomes readable.
2922 struct smbd_echo_read_state
{
2923 struct tevent_context
*ev
;
2924 struct smbXsrv_connection
*xconn
;
2931 static void smbd_echo_read_readable(struct tevent_req
*subreq
);
2932 static void smbd_echo_read_waited(struct tevent_req
*subreq
);
2934 static struct tevent_req
*smbd_echo_read_send(
2935 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2936 struct smbXsrv_connection
*xconn
)
2938 struct tevent_req
*req
, *subreq
;
2939 struct smbd_echo_read_state
*state
;
2941 req
= tevent_req_create(mem_ctx
, &state
,
2942 struct smbd_echo_read_state
);
2947 state
->xconn
= xconn
;
2949 subreq
= wait_for_read_send(state
, ev
, xconn
->transport
.sock
, false);
2950 if (tevent_req_nomem(subreq
, req
)) {
2951 return tevent_req_post(req
, ev
);
2953 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2957 static void smbd_echo_read_readable(struct tevent_req
*subreq
)
2959 struct tevent_req
*req
= tevent_req_callback_data(
2960 subreq
, struct tevent_req
);
2961 struct smbd_echo_read_state
*state
= tevent_req_data(
2962 req
, struct smbd_echo_read_state
);
2966 ok
= wait_for_read_recv(subreq
, &err
);
2967 TALLOC_FREE(subreq
);
2969 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
2974 * Give the parent smbd one second to step in
2977 subreq
= tevent_wakeup_send(
2978 state
, state
->ev
, timeval_current_ofs(1, 0));
2979 if (tevent_req_nomem(subreq
, req
)) {
2982 tevent_req_set_callback(subreq
, smbd_echo_read_waited
, req
);
2985 static void smbd_echo_read_waited(struct tevent_req
*subreq
)
2987 struct tevent_req
*req
= tevent_req_callback_data(
2988 subreq
, struct tevent_req
);
2989 struct smbd_echo_read_state
*state
= tevent_req_data(
2990 req
, struct smbd_echo_read_state
);
2991 struct smbXsrv_connection
*xconn
= state
->xconn
;
2997 ok
= tevent_wakeup_recv(subreq
);
2998 TALLOC_FREE(subreq
);
3000 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
3004 ok
= smbd_lock_socket_internal(xconn
);
3006 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
3007 DEBUG(0, ("%s: failed to lock socket\n", __location__
));
3011 if (!fd_is_readable(xconn
->transport
.sock
)) {
3012 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3015 ok
= smbd_unlock_socket_internal(xconn
);
3017 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
3018 DEBUG(1, ("%s: failed to unlock socket\n",
3023 subreq
= wait_for_read_send(state
, state
->ev
,
3024 xconn
->transport
.sock
, false);
3025 if (tevent_req_nomem(subreq
, req
)) {
3028 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
3032 status
= receive_smb_talloc(state
, xconn
,
3033 xconn
->transport
.sock
,
3040 false /* trusted_channel*/);
3042 if (tevent_req_nterror(req
, status
)) {
3043 tevent_req_nterror(req
, status
);
3044 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3045 (int)getpid(), nt_errstr(status
)));
3049 ok
= smbd_unlock_socket_internal(xconn
);
3051 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
3052 DEBUG(1, ("%s: failed to unlock socket\n", __location__
));
3055 tevent_req_done(req
);
3058 static NTSTATUS
smbd_echo_read_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
3059 char **pbuf
, size_t *pbuflen
, uint32_t *pseqnum
)
3061 struct smbd_echo_read_state
*state
= tevent_req_data(
3062 req
, struct smbd_echo_read_state
);
3065 if (tevent_req_is_nterror(req
, &status
)) {
3068 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
3069 *pbuflen
= state
->buflen
;
3070 *pseqnum
= state
->seqnum
;
3071 return NT_STATUS_OK
;
3074 struct smbd_echo_state
{
3075 struct tevent_context
*ev
;
3076 struct iovec
*pending
;
3077 struct smbd_server_connection
*sconn
;
3078 struct smbXsrv_connection
*xconn
;
3081 struct tevent_fd
*parent_fde
;
3083 struct tevent_req
*write_req
;
3086 static void smbd_echo_writer_done(struct tevent_req
*req
);
3088 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
3092 if (state
->write_req
!= NULL
) {
3096 num_pending
= talloc_array_length(state
->pending
);
3097 if (num_pending
== 0) {
3101 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
3102 state
->parent_pipe
, false,
3103 state
->pending
, num_pending
);
3104 if (state
->write_req
== NULL
) {
3105 DEBUG(1, ("writev_send failed\n"));
3109 talloc_steal(state
->write_req
, state
->pending
);
3110 state
->pending
= NULL
;
3112 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
3116 static void smbd_echo_writer_done(struct tevent_req
*req
)
3118 struct smbd_echo_state
*state
= tevent_req_callback_data(
3119 req
, struct smbd_echo_state
);
3123 written
= writev_recv(req
, &err
);
3125 state
->write_req
= NULL
;
3126 if (written
== -1) {
3127 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
3130 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3131 smbd_echo_activate_writer(state
);
3134 static bool smbd_echo_reply(struct smbd_echo_state
*state
,
3135 uint8_t *inbuf
, size_t inbuf_len
,
3138 struct smb_request req
;
3139 uint16_t num_replies
;
3143 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == NBSSkeepalive
)) {
3144 DEBUG(10, ("Got netbios keepalive\n"));
3151 if (inbuf_len
< smb_size
) {
3152 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
3155 if (!valid_smb_header(inbuf
)) {
3156 DEBUG(10, ("Got invalid SMB header\n"));
3160 if (!init_smb_request(&req
, state
->sconn
, state
->xconn
, inbuf
, 0, false,
3166 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
3167 smb_messages
[req
.cmd
].name
3168 ? smb_messages
[req
.cmd
].name
: "unknown"));
3170 if (req
.cmd
!= SMBecho
) {
3177 num_replies
= SVAL(req
.vwv
+0, 0);
3178 if (num_replies
!= 1) {
3179 /* Not a Windows "Hey, you're still there?" request */
3183 if (!create_outbuf(talloc_tos(), &req
, req
.inbuf
, &outbuf
,
3185 DEBUG(10, ("create_outbuf failed\n"));
3188 req
.outbuf
= (uint8_t *)outbuf
;
3190 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
3192 if (req
.buflen
> 0) {
3193 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
3196 ok
= srv_send_smb(req
.xconn
,
3200 TALLOC_FREE(outbuf
);
3208 static void smbd_echo_exit(struct tevent_context
*ev
,
3209 struct tevent_fd
*fde
, uint16_t flags
,
3212 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3216 static void smbd_echo_got_packet(struct tevent_req
*req
);
3218 static void smbd_echo_loop(struct smbXsrv_connection
*xconn
,
3221 struct smbd_echo_state
*state
;
3222 struct tevent_req
*read_req
;
3224 state
= talloc_zero(xconn
, struct smbd_echo_state
);
3225 if (state
== NULL
) {
3226 DEBUG(1, ("talloc failed\n"));
3229 state
->xconn
= xconn
;
3230 state
->parent_pipe
= parent_pipe
;
3231 state
->ev
= samba_tevent_context_init(state
);
3232 if (state
->ev
== NULL
) {
3233 DEBUG(1, ("samba_tevent_context_init failed\n"));
3237 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
3238 TEVENT_FD_READ
, smbd_echo_exit
,
3240 if (state
->parent_fde
== NULL
) {
3241 DEBUG(1, ("tevent_add_fd failed\n"));
3246 read_req
= smbd_echo_read_send(state
, state
->ev
, xconn
);
3247 if (read_req
== NULL
) {
3248 DEBUG(1, ("smbd_echo_read_send failed\n"));
3252 tevent_req_set_callback(read_req
, smbd_echo_got_packet
, state
);
3255 if (tevent_loop_once(state
->ev
) == -1) {
3256 DEBUG(1, ("tevent_loop_once failed: %s\n",
3264 static void smbd_echo_got_packet(struct tevent_req
*req
)
3266 struct smbd_echo_state
*state
= tevent_req_callback_data(
3267 req
, struct smbd_echo_state
);
3271 uint32_t seqnum
= 0;
3274 status
= smbd_echo_read_recv(req
, state
, &buf
, &buflen
, &seqnum
);
3276 if (!NT_STATUS_IS_OK(status
)) {
3277 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3278 nt_errstr(status
)));
3282 reply
= smbd_echo_reply(state
, (uint8_t *)buf
, buflen
, seqnum
);
3288 num_pending
= talloc_array_length(state
->pending
);
3289 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
3292 DEBUG(1, ("talloc_realloc failed\n"));
3295 state
->pending
= tmp
;
3297 if (buflen
>= smb_size
) {
3299 * place the seqnum in the packet so that the main process
3300 * can reply with signing
3302 SIVAL(buf
, smb_ss_field
, seqnum
);
3303 SIVAL(buf
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
3306 iov
= &state
->pending
[num_pending
];
3307 iov
->iov_base
= talloc_move(state
->pending
, &buf
);
3308 iov
->iov_len
= buflen
;
3310 DEBUG(10,("echo_handler[%d]: forward to main\n",
3312 smbd_echo_activate_writer(state
);
3315 req
= smbd_echo_read_send(state
, state
->ev
, state
->xconn
);
3317 DEBUG(1, ("smbd_echo_read_send failed\n"));
3320 tevent_req_set_callback(req
, smbd_echo_got_packet
, state
);
3325 * Handle SMBecho requests in a forked child process
3327 bool fork_echo_handler(struct smbXsrv_connection
*xconn
)
3329 int listener_pipe
[2];
3332 bool use_mutex
= false;
3334 res
= pipe(listener_pipe
);
3336 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
3340 #ifdef HAVE_ROBUST_MUTEXES
3341 use_mutex
= tdb_runtime_check_for_robust_mutexes();
3344 pthread_mutexattr_t a
;
3346 xconn
->smb1
.echo_handler
.socket_mutex
=
3347 anonymous_shared_allocate(sizeof(pthread_mutex_t
));
3348 if (xconn
->smb1
.echo_handler
.socket_mutex
== NULL
) {
3349 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3354 res
= pthread_mutexattr_init(&a
);
3356 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3360 res
= pthread_mutexattr_settype(&a
, PTHREAD_MUTEX_ERRORCHECK
);
3362 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3364 pthread_mutexattr_destroy(&a
);
3367 res
= pthread_mutexattr_setpshared(&a
, PTHREAD_PROCESS_SHARED
);
3369 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3371 pthread_mutexattr_destroy(&a
);
3374 res
= pthread_mutexattr_setrobust(&a
, PTHREAD_MUTEX_ROBUST
);
3376 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3377 "%s\n", strerror(res
)));
3378 pthread_mutexattr_destroy(&a
);
3381 res
= pthread_mutex_init(xconn
->smb1
.echo_handler
.socket_mutex
,
3383 pthread_mutexattr_destroy(&a
);
3385 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3393 xconn
->smb1
.echo_handler
.socket_lock_fd
=
3394 create_unlink_tmp(lp_lock_directory());
3395 if (xconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
3396 DEBUG(1, ("Could not create lock fd: %s\n",
3406 close(listener_pipe
[0]);
3407 set_blocking(listener_pipe
[1], false);
3409 status
= smbd_reinit_after_fork(xconn
->client
->msg_ctx
,
3410 xconn
->client
->raw_ev_ctx
,
3413 if (!NT_STATUS_IS_OK(status
)) {
3414 DEBUG(1, ("reinit_after_fork failed: %s\n",
3415 nt_errstr(status
)));
3418 initialize_password_db(true, xconn
->client
->raw_ev_ctx
);
3419 smbd_echo_loop(xconn
, listener_pipe
[1]);
3422 close(listener_pipe
[1]);
3423 listener_pipe
[1] = -1;
3424 xconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
3426 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child
));
3429 * Without smb signing this is the same as the normal smbd
3430 * listener. This needs to change once signing comes in.
3432 xconn
->smb1
.echo_handler
.trusted_fde
= tevent_add_fd(
3433 xconn
->client
->raw_ev_ctx
,
3435 xconn
->smb1
.echo_handler
.trusted_fd
,
3437 smbd_server_echo_handler
,
3439 if (xconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
3440 DEBUG(1, ("event_add_fd failed\n"));
3447 if (listener_pipe
[0] != -1) {
3448 close(listener_pipe
[0]);
3450 if (listener_pipe
[1] != -1) {
3451 close(listener_pipe
[1]);
3453 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
3454 close(xconn
->smb1
.echo_handler
.socket_lock_fd
);
3456 #ifdef HAVE_ROBUST_MUTEXES
3457 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
3458 pthread_mutex_destroy(xconn
->smb1
.echo_handler
.socket_mutex
);
3459 anonymous_shared_free(xconn
->smb1
.echo_handler
.socket_mutex
);
3462 smbd_echo_init(xconn
);
3467 static bool uid_in_use(const struct user_struct
*user
, uid_t uid
)
3470 if (user
->session_info
&&
3471 (user
->session_info
->unix_token
->uid
== uid
)) {
3479 static bool gid_in_use(const struct user_struct
*user
, gid_t gid
)
3482 if (user
->session_info
!= NULL
) {
3484 struct security_unix_token
*utok
;
3486 utok
= user
->session_info
->unix_token
;
3487 if (utok
->gid
== gid
) {
3490 for(i
=0; i
<utok
->ngroups
; i
++) {
3491 if (utok
->groups
[i
] == gid
) {
3501 static bool sid_in_use(const struct user_struct
*user
,
3502 const struct dom_sid
*psid
)
3505 struct security_token
*tok
;
3507 if (user
->session_info
== NULL
) {
3510 tok
= user
->session_info
->security_token
;
3513 * Not sure session_info->security_token can
3514 * ever be NULL. This check might be not
3519 if (security_token_has_sid(tok
, psid
)) {
3527 static bool id_in_use(const struct user_struct
*user
,
3528 const struct id_cache_ref
*id
)
3532 return uid_in_use(user
, id
->id
.uid
);
3534 return gid_in_use(user
, id
->id
.gid
);
3536 return sid_in_use(user
, &id
->id
.sid
);
3543 static void smbd_id_cache_kill(struct messaging_context
*msg_ctx
,
3546 struct server_id server_id
,
3549 const char *msg
= (data
&& data
->data
)
3550 ? (const char *)data
->data
: "<NULL>";
3551 struct id_cache_ref id
;
3552 struct smbd_server_connection
*sconn
=
3553 talloc_get_type_abort(private_data
,
3554 struct smbd_server_connection
);
3556 if (!id_cache_ref_parse(msg
, &id
)) {
3557 DEBUG(0, ("Invalid ?ID: %s\n", msg
));
3561 if (id_in_use(sconn
->users
, &id
)) {
3562 exit_server_cleanly(msg
);
3564 id_cache_delete_from_cache(&id
);
3567 NTSTATUS
smbXsrv_connection_init_tables(struct smbXsrv_connection
*conn
,
3568 enum protocol_types protocol
)
3572 conn
->protocol
= protocol
;
3574 if (conn
->client
->session_table
!= NULL
) {
3575 return NT_STATUS_OK
;
3578 if (protocol
>= PROTOCOL_SMB2_02
) {
3579 status
= smb2srv_session_table_init(conn
);
3580 if (!NT_STATUS_IS_OK(status
)) {
3581 conn
->protocol
= PROTOCOL_NONE
;
3585 status
= smb2srv_open_table_init(conn
);
3586 if (!NT_STATUS_IS_OK(status
)) {
3587 conn
->protocol
= PROTOCOL_NONE
;
3591 status
= smb1srv_session_table_init(conn
);
3592 if (!NT_STATUS_IS_OK(status
)) {
3593 conn
->protocol
= PROTOCOL_NONE
;
3597 status
= smb1srv_tcon_table_init(conn
);
3598 if (!NT_STATUS_IS_OK(status
)) {
3599 conn
->protocol
= PROTOCOL_NONE
;
3603 status
= smb1srv_open_table_init(conn
);
3604 if (!NT_STATUS_IS_OK(status
)) {
3605 conn
->protocol
= PROTOCOL_NONE
;
3610 set_Protocol(protocol
);
3611 return NT_STATUS_OK
;
3614 struct smbd_tevent_trace_state
{
3615 struct tevent_context
*ev
;
3617 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle
);
3620 static void smbd_tevent_trace_callback(enum tevent_trace_point point
,
3623 struct smbd_tevent_trace_state
*state
=
3624 (struct smbd_tevent_trace_state
*)private_data
;
3627 case TEVENT_TRACE_BEFORE_WAIT
:
3628 if (!smbprofile_dump_pending()) {
3630 * If there's no dump pending
3631 * we don't want to schedule a new 1 sec timer.
3633 * Instead we want to sleep as long as nothing happens.
3635 smbprofile_dump_setup(NULL
);
3637 SMBPROFILE_BASIC_ASYNC_START(idle
, profile_p
, state
->profile_idle
);
3639 case TEVENT_TRACE_AFTER_WAIT
:
3640 SMBPROFILE_BASIC_ASYNC_END(state
->profile_idle
);
3641 if (!smbprofile_dump_pending()) {
3643 * We need to flush our state after sleeping
3644 * (hopefully a long time).
3648 * future profiling events should trigger timers
3649 * on our main event context.
3651 smbprofile_dump_setup(state
->ev
);
3654 case TEVENT_TRACE_BEFORE_LOOP_ONCE
:
3655 TALLOC_FREE(state
->frame
);
3656 state
->frame
= talloc_stackframe_pool(8192);
3658 case TEVENT_TRACE_AFTER_LOOP_ONCE
:
3659 TALLOC_FREE(state
->frame
);
3667 * Create a debug string for the connection
3669 * This is allocated to talloc_tos() or a string constant
3670 * in certain corner cases. The returned string should
3671 * hence not be free'd directly but only via the talloc stack.
3673 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection
*xconn
)
3678 * TODO: this can be improved later
3679 * maybe including the client guid or more
3681 ret
= tsocket_address_string(xconn
->remote_address
, talloc_tos());
3683 return "<tsocket_address_string() failed>";
3689 NTSTATUS
smbd_add_connection(struct smbXsrv_client
*client
, int sock_fd
,
3690 struct smbXsrv_connection
**_xconn
)
3692 TALLOC_CTX
*frame
= talloc_stackframe();
3693 struct smbXsrv_connection
*xconn
;
3694 struct sockaddr_storage ss_srv
;
3695 void *sp_srv
= (void *)&ss_srv
;
3696 struct sockaddr
*sa_srv
= (struct sockaddr
*)sp_srv
;
3697 struct sockaddr_storage ss_clnt
;
3698 void *sp_clnt
= (void *)&ss_clnt
;
3699 struct sockaddr
*sa_clnt
= (struct sockaddr
*)sp_clnt
;
3700 socklen_t sa_socklen
;
3701 struct tsocket_address
*local_address
= NULL
;
3702 struct tsocket_address
*remote_address
= NULL
;
3703 const char *remaddr
= NULL
;
3705 const char *rhost
= NULL
;
3711 DO_PROFILE_INC(connect
);
3713 xconn
= talloc_zero(client
, struct smbXsrv_connection
);
3714 if (xconn
== NULL
) {
3715 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3717 return NT_STATUS_NO_MEMORY
;
3719 talloc_steal(frame
, xconn
);
3721 xconn
->transport
.sock
= sock_fd
;
3722 smbd_echo_init(xconn
);
3723 xconn
->protocol
= PROTOCOL_NONE
;
3725 /* Ensure child is set to blocking mode */
3726 set_blocking(sock_fd
,True
);
3728 set_socket_options(sock_fd
, "SO_KEEPALIVE");
3729 set_socket_options(sock_fd
, lp_socket_options());
3731 sa_socklen
= sizeof(ss_clnt
);
3732 ret
= getpeername(sock_fd
, sa_clnt
, &sa_socklen
);
3734 int saved_errno
= errno
;
3735 int level
= (errno
== ENOTCONN
)?2:0;
3736 DEBUG(level
,("getpeername() failed - %s\n",
3737 strerror(saved_errno
)));
3739 return map_nt_error_from_unix_common(saved_errno
);
3741 ret
= tsocket_address_bsd_from_sockaddr(xconn
,
3742 sa_clnt
, sa_socklen
,
3745 int saved_errno
= errno
;
3746 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3747 __location__
, strerror(saved_errno
)));
3749 return map_nt_error_from_unix_common(saved_errno
);
3752 sa_socklen
= sizeof(ss_srv
);
3753 ret
= getsockname(sock_fd
, sa_srv
, &sa_socklen
);
3755 int saved_errno
= errno
;
3756 int level
= (errno
== ENOTCONN
)?2:0;
3757 DEBUG(level
,("getsockname() failed - %s\n",
3758 strerror(saved_errno
)));
3760 return map_nt_error_from_unix_common(saved_errno
);
3762 ret
= tsocket_address_bsd_from_sockaddr(xconn
,
3766 int saved_errno
= errno
;
3767 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3768 __location__
, strerror(saved_errno
)));
3770 return map_nt_error_from_unix_common(saved_errno
);
3773 if (tsocket_address_is_inet(remote_address
, "ip")) {
3774 remaddr
= tsocket_address_inet_addr_string(remote_address
,
3776 if (remaddr
== NULL
) {
3777 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3778 __location__
, strerror(errno
)));
3780 return NT_STATUS_NO_MEMORY
;
3783 remaddr
= "0.0.0.0";
3787 * Before the first packet, check the global hosts allow/ hosts deny
3788 * parameters before doing any parsing of packets passed to us by the
3789 * client. This prevents attacks on our parsing code from hosts not in
3790 * the hosts allow list.
3793 ret
= get_remote_hostname(remote_address
,
3796 int saved_errno
= errno
;
3797 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3798 __location__
, strerror(saved_errno
)));
3800 return map_nt_error_from_unix_common(saved_errno
);
3803 if (strequal(rhost
, "UNKNOWN")) {
3807 xconn
->local_address
= local_address
;
3808 xconn
->remote_address
= remote_address
;
3809 xconn
->remote_hostname
= talloc_strdup(xconn
, rhost
);
3810 if (xconn
->remote_hostname
== NULL
) {
3811 return NT_STATUS_NO_MEMORY
;
3814 if (!srv_init_signing(xconn
)) {
3815 DEBUG(0, ("Failed to init smb_signing\n"));
3817 return NT_STATUS_INTERNAL_ERROR
;
3820 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3821 xconn
->remote_hostname
,
3823 DEBUG( 1, ("Connection denied from %s to %s\n",
3824 tsocket_address_string(remote_address
, talloc_tos()),
3825 tsocket_address_string(local_address
, talloc_tos())));
3828 * We return a valid xconn
3829 * so that the caller can return an error message
3832 client
->connections
= xconn
;
3833 xconn
->client
= client
;
3834 talloc_steal(client
, xconn
);
3838 return NT_STATUS_NETWORK_ACCESS_DENIED
;
3841 DEBUG(10, ("Connection allowed from %s to %s\n",
3842 tsocket_address_string(remote_address
, talloc_tos()),
3843 tsocket_address_string(local_address
, talloc_tos())));
3845 if (lp_clustering()) {
3847 * We need to tell ctdb about our client's TCP
3848 * connection, so that for failover ctdbd can send
3849 * tickle acks, triggering a reconnection by the
3854 status
= smbd_register_ips(xconn
, &ss_srv
, &ss_clnt
);
3855 if (!NT_STATUS_IS_OK(status
)) {
3856 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3857 nt_errstr(status
)));
3861 tmp
= lp_max_xmit();
3862 tmp
= MAX(tmp
, SMB_BUFFER_SIZE_MIN
);
3863 tmp
= MIN(tmp
, SMB_BUFFER_SIZE_MAX
);
3865 xconn
->smb1
.negprot
.max_recv
= tmp
;
3867 xconn
->smb1
.sessions
.done_sesssetup
= false;
3868 xconn
->smb1
.sessions
.max_send
= SMB_BUFFER_SIZE_MAX
;
3870 xconn
->transport
.fde
= tevent_add_fd(client
->raw_ev_ctx
,
3874 smbd_server_connection_handler
,
3876 if (!xconn
->transport
.fde
) {
3878 return NT_STATUS_NO_MEMORY
;
3881 /* for now we only have one connection */
3882 DLIST_ADD_END(client
->connections
, xconn
);
3883 xconn
->client
= client
;
3884 talloc_steal(client
, xconn
);
3888 return NT_STATUS_OK
;
3891 /****************************************************************************
3892 Process commands from the client
3893 ****************************************************************************/
3895 void smbd_process(struct tevent_context
*ev_ctx
,
3896 struct messaging_context
*msg_ctx
,
3900 struct smbd_tevent_trace_state trace_state
= {
3902 .frame
= talloc_stackframe(),
3904 const struct loadparm_substitution
*lp_sub
=
3905 loadparm_s3_global_substitution();
3906 struct smbXsrv_client
*client
= NULL
;
3907 struct smbd_server_connection
*sconn
= NULL
;
3908 struct smbXsrv_connection
*xconn
= NULL
;
3909 const char *locaddr
= NULL
;
3910 const char *remaddr
= NULL
;
3913 struct timeval tv
= timeval_current();
3914 NTTIME now
= timeval_to_nttime(&tv
);
3915 char *chroot_dir
= NULL
;
3918 status
= smbXsrv_client_create(ev_ctx
, ev_ctx
, msg_ctx
, now
, &client
);
3919 if (!NT_STATUS_IS_OK(status
)) {
3920 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status
));
3921 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3925 * TODO: remove this...:-)
3927 global_smbXsrv_client
= client
;
3929 sconn
= talloc_zero(client
, struct smbd_server_connection
);
3930 if (sconn
== NULL
) {
3931 exit_server("failed to create smbd_server_connection");
3934 client
->sconn
= sconn
;
3935 sconn
->client
= client
;
3937 sconn
->ev_ctx
= ev_ctx
;
3938 sconn
->msg_ctx
= msg_ctx
;
3940 ret
= pthreadpool_tevent_init(sconn
, lp_aio_max_threads(),
3943 exit_server("pthreadpool_tevent_init() failed.");
3946 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02
) {
3948 * We're not making the decision here,
3949 * we're just allowing the client
3950 * to decide between SMB1 and SMB2
3951 * with the first negprot
3954 sconn
->using_smb2
= true;
3958 smbd_setup_sig_term_handler(sconn
);
3959 smbd_setup_sig_hup_handler(sconn
);
3962 status
= smbd_add_connection(client
, sock_fd
, &xconn
);
3963 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3965 * send a negative session response "not listening on calling
3968 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3969 (void)srv_send_smb(xconn
,(char *)buf
, false,
3971 exit_server_cleanly("connection denied");
3972 } else if (!NT_STATUS_IS_OK(status
)) {
3973 exit_server_cleanly(nt_errstr(status
));
3976 sconn
->local_address
=
3977 tsocket_address_copy(xconn
->local_address
, sconn
);
3978 if (sconn
->local_address
== NULL
) {
3979 exit_server_cleanly("tsocket_address_copy() failed");
3981 sconn
->remote_address
=
3982 tsocket_address_copy(xconn
->remote_address
, sconn
);
3983 if (sconn
->remote_address
== NULL
) {
3984 exit_server_cleanly("tsocket_address_copy() failed");
3986 sconn
->remote_hostname
=
3987 talloc_strdup(sconn
, xconn
->remote_hostname
);
3988 if (sconn
->remote_hostname
== NULL
) {
3989 exit_server_cleanly("tsocket_strdup() failed");
3992 if (tsocket_address_is_inet(sconn
->local_address
, "ip")) {
3993 locaddr
= tsocket_address_inet_addr_string(
3994 sconn
->local_address
,
3996 if (locaddr
== NULL
) {
3997 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3998 __location__
, strerror(errno
)));
3999 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4002 locaddr
= "0.0.0.0";
4005 if (tsocket_address_is_inet(sconn
->remote_address
, "ip")) {
4006 remaddr
= tsocket_address_inet_addr_string(
4007 sconn
->remote_address
,
4009 if (remaddr
== NULL
) {
4010 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4011 __location__
, strerror(errno
)));
4012 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4015 remaddr
= "0.0.0.0";
4018 /* this is needed so that we get decent entries
4019 in smbstatus for port 445 connects */
4020 set_remote_machine_name(remaddr
, false);
4021 reload_services(sconn
, conn_snum_used
, true);
4022 sub_set_socket_ids(remaddr
,
4023 sconn
->remote_hostname
,
4026 if (lp_preload_modules()) {
4027 smb_load_all_modules_absoute_path(lp_preload_modules());
4030 smb_perfcount_init();
4032 if (!init_account_policy()) {
4033 exit_server("Could not open account policy tdb.\n");
4036 chroot_dir
= lp_root_directory(talloc_tos(), lp_sub
);
4037 if (chroot_dir
[0] != '\0') {
4038 rc
= chdir(chroot_dir
);
4040 DBG_ERR("Failed to chdir to %s\n", chroot_dir
);
4041 exit_server("Failed to chdir()");
4044 rc
= chroot(chroot_dir
);
4046 DBG_ERR("Failed to change root to %s\n", chroot_dir
);
4047 exit_server("Failed to chroot()");
4049 DBG_WARNING("Changed root to %s\n", chroot_dir
);
4051 TALLOC_FREE(chroot_dir
);
4054 if (!file_init(sconn
)) {
4055 exit_server("file_init() failed");
4059 if (!init_oplocks(sconn
))
4060 exit_server("Failed to init oplocks");
4062 /* register our message handlers */
4063 messaging_register(sconn
->msg_ctx
, sconn
,
4064 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
4065 messaging_register(sconn
->msg_ctx
, sconn
,
4066 MSG_SMB_CLOSE_FILE
, msg_close_file
);
4067 messaging_register(sconn
->msg_ctx
, sconn
,
4068 MSG_SMB_FILE_RENAME
, msg_file_was_renamed
);
4070 id_cache_register_msgs(sconn
->msg_ctx
);
4071 messaging_deregister(sconn
->msg_ctx
, ID_CACHE_KILL
, NULL
);
4072 messaging_register(sconn
->msg_ctx
, sconn
,
4073 ID_CACHE_KILL
, smbd_id_cache_kill
);
4075 messaging_deregister(sconn
->msg_ctx
,
4076 MSG_SMB_CONF_UPDATED
, sconn
->ev_ctx
);
4077 messaging_register(sconn
->msg_ctx
, sconn
,
4078 MSG_SMB_CONF_UPDATED
, smbd_conf_updated
);
4080 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_KILL_CLIENT_IP
,
4082 messaging_register(sconn
->msg_ctx
, sconn
,
4083 MSG_SMB_KILL_CLIENT_IP
,
4084 msg_kill_client_ip
);
4086 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_TELL_NUM_CHILDREN
, NULL
);
4089 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4090 * MSGs to all child processes
4092 messaging_deregister(sconn
->msg_ctx
,
4094 messaging_register(sconn
->msg_ctx
, NULL
,
4095 MSG_DEBUG
, debug_message
);
4097 if ((lp_keepalive() != 0)
4098 && !(event_add_idle(ev_ctx
, NULL
,
4099 timeval_set(lp_keepalive(), 0),
4100 "keepalive", keepalive_fn
,
4102 DEBUG(0, ("Could not add keepalive event\n"));
4106 if (!(event_add_idle(ev_ctx
, NULL
,
4107 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
4108 "deadtime", deadtime_fn
, sconn
))) {
4109 DEBUG(0, ("Could not add deadtime event\n"));
4113 if (!(event_add_idle(ev_ctx
, NULL
,
4114 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
4115 "housekeeping", housekeeping_fn
, sconn
))) {
4116 DEBUG(0, ("Could not add housekeeping event\n"));
4120 smbprofile_dump_setup(ev_ctx
);
4122 if (!init_dptrs(sconn
)) {
4123 exit_server("init_dptrs() failed");
4126 TALLOC_FREE(trace_state
.frame
);
4128 tevent_set_trace_callback(ev_ctx
, smbd_tevent_trace_callback
,
4131 ret
= tevent_loop_wait(ev_ctx
);
4133 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4134 " exiting\n", ret
, strerror(errno
)));
4137 TALLOC_FREE(trace_state
.frame
);
4139 exit_server_cleanly(NULL
);
4142 bool req_is_in_chain(const struct smb_request
*req
)
4144 if (req
->vwv
!= (const uint16_t *)(req
->inbuf
+smb_vwv
)) {
4146 * We're right now handling a subsequent request, so we must
4152 if (!smb1cli_is_andx_req(req
->cmd
)) {
4158 * Okay, an illegal request, but definitely not chained :-)
4163 return (CVAL(req
->vwv
+0, 0) != 0xFF);