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"
47 /* Internal message queue for deferred opens. */
48 struct pending_message_list
{
49 struct pending_message_list
*next
, *prev
;
50 struct timeval request_time
; /* When was this first issued? */
51 struct smbd_server_connection
*sconn
;
52 struct smbXsrv_connection
*xconn
;
53 struct tevent_timer
*te
;
54 struct smb_perfcount_data pcd
;
59 struct deferred_open_record
*open_rec
;
62 static void construct_reply_common(uint8_t cmd
, const uint8_t *inbuf
,
64 static struct pending_message_list
*get_deferred_open_message_smb(
65 struct smbd_server_connection
*sconn
, uint64_t mid
);
66 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
);
68 static void smbd_echo_init(struct smbXsrv_connection
*xconn
)
70 xconn
->smb1
.echo_handler
.trusted_fd
= -1;
71 xconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
72 #ifdef HAVE_ROBUST_MUTEXES
73 xconn
->smb1
.echo_handler
.socket_mutex
= NULL
;
77 static bool smbd_echo_active(struct smbXsrv_connection
*xconn
)
79 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
83 #ifdef HAVE_ROBUST_MUTEXES
84 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
92 static bool smbd_lock_socket_internal(struct smbXsrv_connection
*xconn
)
94 if (!smbd_echo_active(xconn
)) {
98 xconn
->smb1
.echo_handler
.ref_count
++;
100 if (xconn
->smb1
.echo_handler
.ref_count
> 1) {
104 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
106 #ifdef HAVE_ROBUST_MUTEXES
107 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
110 while (ret
== EINTR
) {
111 ret
= pthread_mutex_lock(
112 xconn
->smb1
.echo_handler
.socket_mutex
);
118 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
125 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
130 xconn
->smb1
.echo_handler
.socket_lock_fd
,
131 F_SETLKW
, 0, 0, F_WRLCK
);
132 } while (!ok
&& (errno
== EINTR
));
135 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
140 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
145 void smbd_lock_socket(struct smbXsrv_connection
*xconn
)
147 if (!smbd_lock_socket_internal(xconn
)) {
148 exit_server_cleanly("failed to lock socket");
152 static bool smbd_unlock_socket_internal(struct smbXsrv_connection
*xconn
)
154 if (!smbd_echo_active(xconn
)) {
158 xconn
->smb1
.echo_handler
.ref_count
--;
160 if (xconn
->smb1
.echo_handler
.ref_count
> 0) {
164 #ifdef HAVE_ROBUST_MUTEXES
165 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
167 ret
= pthread_mutex_unlock(
168 xconn
->smb1
.echo_handler
.socket_mutex
);
170 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
177 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
182 xconn
->smb1
.echo_handler
.socket_lock_fd
,
183 F_SETLKW
, 0, 0, F_UNLCK
);
184 } while (!ok
&& (errno
== EINTR
));
187 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
192 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
197 void smbd_unlock_socket(struct smbXsrv_connection
*xconn
)
199 if (!smbd_unlock_socket_internal(xconn
)) {
200 exit_server_cleanly("failed to unlock socket");
204 /* Accessor function for smb_read_error for smbd functions. */
206 /****************************************************************************
208 ****************************************************************************/
210 bool srv_send_smb(struct smbXsrv_connection
*xconn
, char *buffer
,
211 bool do_signing
, uint32_t seqnum
,
213 struct smb_perfcount_data
*pcd
)
217 char *buf_out
= buffer
;
219 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
221 * we're not supposed to do any io
226 smbd_lock_socket(xconn
);
229 /* Sign the outgoing packet if required. */
230 srv_calculate_sign_mac(xconn
, buf_out
, seqnum
);
234 NTSTATUS status
= srv_encrypt_buffer(xconn
, buffer
, &buf_out
);
235 if (!NT_STATUS_IS_OK(status
)) {
236 DEBUG(0, ("send_smb: SMB encryption failed "
237 "on outgoing packet! Error %s\n",
238 nt_errstr(status
) ));
244 len
= smb_len_large(buf_out
) + 4;
246 ret
= write_data(xconn
->transport
.sock
, buf_out
, len
);
248 int saved_errno
= errno
;
250 * Try and give an error message saying what
253 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
254 (int)getpid(), (int)len
,
255 smbXsrv_connection_dbg(xconn
),
256 (int)ret
, strerror(saved_errno
)));
259 srv_free_enc_buffer(xconn
, buf_out
);
263 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
264 srv_free_enc_buffer(xconn
, buf_out
);
266 SMB_PERFCOUNT_END(pcd
);
268 smbd_unlock_socket(xconn
);
272 /*******************************************************************
273 Setup the word count and byte count for a smb message.
274 ********************************************************************/
276 int srv_set_message(char *buf
,
281 if (zero
&& (num_words
|| num_bytes
)) {
282 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
284 SCVAL(buf
,smb_wct
,num_words
);
285 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
286 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
287 return (smb_size
+ num_words
*2 + num_bytes
);
290 static bool valid_smb_header(const uint8_t *inbuf
)
292 if (is_encrypted_packet(inbuf
)) {
296 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
297 * but it just looks weird to call strncmp for this one.
299 return (IVAL(smb_base(inbuf
), 0) == 0x424D53FF);
302 /* Socket functions for smbd packet processing. */
304 static bool valid_packet_size(size_t len
)
307 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
308 * of header. Don't print the error if this fits.... JRA.
311 if (len
> (LARGE_WRITEX_BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
312 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
313 (unsigned long)len
));
319 static NTSTATUS
read_packet_remainder(int fd
, char *buffer
,
320 unsigned int timeout
, ssize_t len
)
328 status
= read_fd_with_timeout(fd
, buffer
, len
, len
, timeout
, NULL
);
329 if (!NT_STATUS_IS_OK(status
)) {
330 char addr
[INET6_ADDRSTRLEN
];
331 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
333 get_peer_addr(fd
, addr
, sizeof(addr
)),
339 /****************************************************************************
340 Attempt a zerocopy writeX read. We know here that len > smb_size-4
341 ****************************************************************************/
344 * Unfortunately, earlier versions of smbclient/libsmbclient
345 * don't send this "standard" writeX header. I've fixed this
346 * for 3.2 but we'll use the old method with earlier versions.
347 * Windows and CIFSFS at least use this standard size. Not
351 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
352 (2*14) + /* word count (including bcc) */ \
355 static NTSTATUS
receive_smb_raw_talloc_partial_read(TALLOC_CTX
*mem_ctx
,
356 const char lenbuf
[4],
357 struct smbXsrv_connection
*xconn
,
360 unsigned int timeout
,
364 /* Size of a WRITEX call (+4 byte len). */
365 char writeX_header
[4 + STANDARD_WRITE_AND_X_HEADER_SIZE
];
366 ssize_t len
= smb_len_large(lenbuf
); /* Could be a UNIX large writeX. */
370 memcpy(writeX_header
, lenbuf
, 4);
372 status
= read_fd_with_timeout(
373 sock
, writeX_header
+ 4,
374 STANDARD_WRITE_AND_X_HEADER_SIZE
,
375 STANDARD_WRITE_AND_X_HEADER_SIZE
,
378 if (!NT_STATUS_IS_OK(status
)) {
379 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
381 smbXsrv_connection_dbg(xconn
),
387 * Ok - now try and see if this is a possible
391 if (is_valid_writeX_buffer(xconn
, (uint8_t *)writeX_header
)) {
393 * If the data offset is beyond what
394 * we've read, drain the extra bytes.
396 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
399 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
400 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
401 if (drain_socket(sock
, drain
) != drain
) {
402 smb_panic("receive_smb_raw_talloc_partial_read:"
403 " failed to drain pending bytes");
406 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
409 /* Spoof down the length and null out the bcc. */
410 set_message_bcc(writeX_header
, 0);
411 newlen
= smb_len(writeX_header
);
413 /* Copy the header we've written. */
415 *buffer
= (char *)talloc_memdup(mem_ctx
,
417 sizeof(writeX_header
));
419 if (*buffer
== NULL
) {
420 DEBUG(0, ("Could not allocate inbuf of length %d\n",
421 (int)sizeof(writeX_header
)));
422 return NT_STATUS_NO_MEMORY
;
425 /* Work out the remaining bytes. */
426 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
427 *len_ret
= newlen
+ 4;
431 if (!valid_packet_size(len
)) {
432 return NT_STATUS_INVALID_PARAMETER
;
436 * Not a valid writeX call. Just do the standard
440 *buffer
= talloc_array(mem_ctx
, char, len
+4);
442 if (*buffer
== NULL
) {
443 DEBUG(0, ("Could not allocate inbuf of length %d\n",
445 return NT_STATUS_NO_MEMORY
;
448 /* Copy in what we already read. */
451 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
452 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
455 status
= read_packet_remainder(
457 (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
460 if (!NT_STATUS_IS_OK(status
)) {
461 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
471 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
,
472 struct smbXsrv_connection
*xconn
,
474 char **buffer
, unsigned int timeout
,
475 size_t *p_unread
, size_t *plen
)
479 int min_recv_size
= lp_min_receive_file_size();
484 status
= read_smb_length_return_keepalive(sock
, lenbuf
, timeout
,
486 if (!NT_STATUS_IS_OK(status
)) {
490 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
491 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
492 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
493 !srv_is_signing_active(xconn
) &&
494 xconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
496 return receive_smb_raw_talloc_partial_read(
497 mem_ctx
, lenbuf
, xconn
, sock
, buffer
, timeout
,
501 if (!valid_packet_size(len
)) {
502 return NT_STATUS_INVALID_PARAMETER
;
506 * The +4 here can't wrap, we've checked the length above already.
509 *buffer
= talloc_array(mem_ctx
, char, len
+4);
511 if (*buffer
== NULL
) {
512 DEBUG(0, ("Could not allocate inbuf of length %d\n",
514 return NT_STATUS_NO_MEMORY
;
517 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
519 status
= read_packet_remainder(sock
, (*buffer
)+4, timeout
, len
);
520 if (!NT_STATUS_IS_OK(status
)) {
528 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
,
529 struct smbXsrv_connection
*xconn
,
531 char **buffer
, unsigned int timeout
,
532 size_t *p_unread
, bool *p_encrypted
,
535 bool trusted_channel
)
540 *p_encrypted
= false;
542 status
= receive_smb_raw_talloc(mem_ctx
, xconn
, sock
, buffer
, timeout
,
544 if (!NT_STATUS_IS_OK(status
)) {
545 DEBUG(NT_STATUS_EQUAL(status
, NT_STATUS_END_OF_FILE
)?5:1,
546 ("receive_smb_raw_talloc failed for client %s "
547 "read error = %s.\n",
548 smbXsrv_connection_dbg(xconn
),
549 nt_errstr(status
)) );
553 if (is_encrypted_packet((uint8_t *)*buffer
)) {
554 status
= srv_decrypt_buffer(xconn
, *buffer
);
555 if (!NT_STATUS_IS_OK(status
)) {
556 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
557 "incoming packet! Error %s\n",
558 nt_errstr(status
) ));
564 /* Check the incoming SMB signature. */
565 if (!srv_check_sign_mac(xconn
, *buffer
, seqnum
, trusted_channel
)) {
566 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
567 "incoming packet!\n"));
568 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
576 * Initialize a struct smb_request from an inbuf
579 static bool init_smb_request(struct smb_request
*req
,
580 struct smbd_server_connection
*sconn
,
581 struct smbXsrv_connection
*xconn
,
582 const uint8_t *inbuf
,
583 size_t unread_bytes
, bool encrypted
,
586 struct smbXsrv_tcon
*tcon
;
589 size_t req_size
= smb_len(inbuf
) + 4;
591 /* Ensure we have at least smb_size bytes. */
592 if (req_size
< smb_size
) {
593 DEBUG(0,("init_smb_request: invalid request size %u\n",
594 (unsigned int)req_size
));
598 req
->request_time
= timeval_current();
599 now
= timeval_to_nttime(&req
->request_time
);
601 req
->cmd
= CVAL(inbuf
, smb_com
);
602 req
->flags2
= SVAL(inbuf
, smb_flg2
);
603 req
->smbpid
= SVAL(inbuf
, smb_pid
);
604 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
605 req
->seqnum
= seqnum
;
606 req
->vuid
= SVAL(inbuf
, smb_uid
);
607 req
->tid
= SVAL(inbuf
, smb_tid
);
608 req
->wct
= CVAL(inbuf
, smb_wct
);
609 req
->vwv
= (const uint16_t *)(inbuf
+smb_vwv
);
610 req
->buflen
= smb_buflen(inbuf
);
611 req
->buf
= (const uint8_t *)smb_buf_const(inbuf
);
612 req
->unread_bytes
= unread_bytes
;
613 req
->encrypted
= encrypted
;
618 status
= smb1srv_tcon_lookup(xconn
, req
->tid
, now
, &tcon
);
619 if (NT_STATUS_IS_OK(status
)) {
620 req
->conn
= tcon
->compat
;
623 req
->chain_fsp
= NULL
;
625 req
->priv_paths
= NULL
;
627 req
->posix_pathnames
= lp_posix_pathnames();
628 smb_init_perfcount_data(&req
->pcd
);
630 /* Ensure we have at least wct words and 2 bytes of bcc. */
631 if (smb_size
+ req
->wct
*2 > req_size
) {
632 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
633 (unsigned int)req
->wct
,
634 (unsigned int)req_size
));
637 /* Ensure bcc is correct. */
638 if (((const uint8_t *)smb_buf_const(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
639 DEBUG(0,("init_smb_request: invalid bcc number %u "
640 "(wct = %u, size %u)\n",
641 (unsigned int)req
->buflen
,
642 (unsigned int)req
->wct
,
643 (unsigned int)req_size
));
651 static void process_smb(struct smbXsrv_connection
*xconn
,
652 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
653 uint32_t seqnum
, bool encrypted
,
654 struct smb_perfcount_data
*deferred_pcd
);
656 static void smbd_deferred_open_timer(struct tevent_context
*ev
,
657 struct tevent_timer
*te
,
658 struct timeval _tval
,
661 struct pending_message_list
*msg
= talloc_get_type(private_data
,
662 struct pending_message_list
);
663 struct smbd_server_connection
*sconn
= msg
->sconn
;
664 struct smbXsrv_connection
*xconn
= msg
->xconn
;
665 TALLOC_CTX
*mem_ctx
= talloc_tos();
666 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
669 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
672 exit_server("smbd_deferred_open_timer: talloc failed\n");
676 /* We leave this message on the queue so the open code can
677 know this is a retry. */
678 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
679 (unsigned long long)mid
));
681 /* Mark the message as processed so this is not
682 * re-processed in error. */
683 msg
->processed
= true;
685 process_smb(xconn
, inbuf
,
687 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
689 /* If it's still there and was processed, remove it. */
690 msg
= get_deferred_open_message_smb(sconn
, mid
);
691 if (msg
&& msg
->processed
) {
692 remove_deferred_open_message_smb(xconn
, mid
);
696 /****************************************************************************
697 Function to push a message onto the tail of a linked list of smb messages ready
699 ****************************************************************************/
701 static bool push_queued_message(struct smb_request
*req
,
702 struct timeval request_time
,
703 struct timeval end_time
,
704 struct deferred_open_record
*open_rec
)
706 int msg_len
= smb_len(req
->inbuf
) + 4;
707 struct pending_message_list
*msg
;
709 msg
= talloc_zero(NULL
, struct pending_message_list
);
712 DEBUG(0,("push_message: malloc fail (1)\n"));
715 msg
->sconn
= req
->sconn
;
716 msg
->xconn
= req
->xconn
;
718 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
719 if(msg
->buf
.data
== NULL
) {
720 DEBUG(0,("push_message: malloc fail (2)\n"));
725 msg
->request_time
= request_time
;
726 msg
->seqnum
= req
->seqnum
;
727 msg
->encrypted
= req
->encrypted
;
728 msg
->processed
= false;
729 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
732 msg
->open_rec
= talloc_move(msg
, &open_rec
);
736 msg
->te
= tevent_add_timer(msg
->sconn
->ev_ctx
,
739 smbd_deferred_open_timer
,
742 DEBUG(0,("push_message: event_add_timed failed\n"));
748 DLIST_ADD_END(req
->sconn
->deferred_open_queue
, msg
);
750 DEBUG(10,("push_message: pushed message length %u on "
751 "deferred_open_queue\n", (unsigned int)msg_len
));
756 /****************************************************************************
757 Function to delete a sharing violation open message by mid.
758 ****************************************************************************/
760 void remove_deferred_open_message_smb(struct smbXsrv_connection
*xconn
,
763 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
764 struct pending_message_list
*pml
;
766 if (sconn
->using_smb2
) {
767 remove_deferred_open_message_smb2(xconn
, mid
);
771 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
772 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
773 DEBUG(10,("remove_deferred_open_message_smb: "
774 "deleting mid %llu len %u\n",
775 (unsigned long long)mid
,
776 (unsigned int)pml
->buf
.length
));
777 DLIST_REMOVE(sconn
->deferred_open_queue
, pml
);
784 /****************************************************************************
785 Move a sharing violation open retry message to the front of the list and
786 schedule it for immediate processing.
787 ****************************************************************************/
789 bool schedule_deferred_open_message_smb(struct smbXsrv_connection
*xconn
,
792 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
793 struct pending_message_list
*pml
;
796 if (sconn
->using_smb2
) {
797 return schedule_deferred_open_message_smb2(xconn
, mid
);
800 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
801 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
803 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
806 (unsigned long long)msg_mid
));
808 if (mid
== msg_mid
) {
809 struct tevent_timer
*te
;
811 if (pml
->processed
) {
812 /* A processed message should not be
814 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
815 "message mid %llu was already processed\n",
816 (unsigned long long)msg_mid
));
820 DEBUG(10,("schedule_deferred_open_message_smb: "
821 "scheduling mid %llu\n",
822 (unsigned long long)mid
));
824 te
= tevent_add_timer(pml
->sconn
->ev_ctx
,
827 smbd_deferred_open_timer
,
830 DEBUG(10,("schedule_deferred_open_message_smb: "
831 "event_add_timed() failed, "
832 "skipping mid %llu\n",
833 (unsigned long long)msg_mid
));
836 TALLOC_FREE(pml
->te
);
838 DLIST_PROMOTE(sconn
->deferred_open_queue
, pml
);
843 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
844 "find message mid %llu\n",
845 (unsigned long long)mid
));
850 /****************************************************************************
851 Return true if this mid is on the deferred queue and was not yet processed.
852 ****************************************************************************/
854 bool open_was_deferred(struct smbXsrv_connection
*xconn
, uint64_t mid
)
856 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
857 struct pending_message_list
*pml
;
859 if (sconn
->using_smb2
) {
860 return open_was_deferred_smb2(xconn
, mid
);
863 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
864 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
871 /****************************************************************************
872 Return the message queued by this mid.
873 ****************************************************************************/
875 static struct pending_message_list
*get_deferred_open_message_smb(
876 struct smbd_server_connection
*sconn
, uint64_t mid
)
878 struct pending_message_list
*pml
;
880 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
881 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
888 /****************************************************************************
889 Get the state data queued by this mid.
890 ****************************************************************************/
892 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
893 struct timeval
*p_request_time
,
894 struct deferred_open_record
**open_rec
)
896 struct pending_message_list
*pml
;
898 if (smbreq
->sconn
->using_smb2
) {
899 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
904 pml
= get_deferred_open_message_smb(smbreq
->sconn
, smbreq
->mid
);
908 if (p_request_time
) {
909 *p_request_time
= pml
->request_time
;
911 if (open_rec
!= NULL
) {
912 *open_rec
= pml
->open_rec
;
917 /****************************************************************************
918 Function to push a deferred open smb message onto a linked list of local smb
919 messages ready for processing.
920 ****************************************************************************/
922 bool push_deferred_open_message_smb(struct smb_request
*req
,
923 struct timeval request_time
,
924 struct timeval timeout
,
926 struct deferred_open_record
*open_rec
)
928 struct timeval end_time
;
931 return push_deferred_open_message_smb2(req
->smb2req
,
938 if (req
->unread_bytes
) {
939 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
940 "unread_bytes = %u\n",
941 (unsigned int)req
->unread_bytes
));
942 smb_panic("push_deferred_open_message_smb: "
943 "logic error unread_bytes != 0" );
946 end_time
= timeval_sum(&request_time
, &timeout
);
948 DEBUG(10,("push_deferred_open_message_smb: pushing message "
949 "len %u mid %llu timeout time [%u.%06u]\n",
950 (unsigned int) smb_len(req
->inbuf
)+4,
951 (unsigned long long)req
->mid
,
952 (unsigned int)end_time
.tv_sec
,
953 (unsigned int)end_time
.tv_usec
));
955 return push_queued_message(req
, request_time
, end_time
, open_rec
);
958 static void smbd_sig_term_handler(struct tevent_context
*ev
,
959 struct tevent_signal
*se
,
965 exit_server_cleanly("termination signal");
968 void smbd_setup_sig_term_handler(struct smbd_server_connection
*sconn
)
970 struct tevent_signal
*se
;
972 se
= tevent_add_signal(sconn
->ev_ctx
,
975 smbd_sig_term_handler
,
978 exit_server("failed to setup SIGTERM handler");
982 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
983 struct tevent_signal
*se
,
989 struct smbd_server_connection
*sconn
=
990 talloc_get_type_abort(private_data
,
991 struct smbd_server_connection
);
993 change_to_root_user();
994 DEBUG(1,("Reloading services after SIGHUP\n"));
995 reload_services(sconn
, conn_snum_used
, false);
998 void smbd_setup_sig_hup_handler(struct smbd_server_connection
*sconn
)
1000 struct tevent_signal
*se
;
1002 se
= tevent_add_signal(sconn
->ev_ctx
,
1005 smbd_sig_hup_handler
,
1008 exit_server("failed to setup SIGHUP handler");
1012 static void smbd_conf_updated(struct messaging_context
*msg
,
1015 struct server_id server_id
,
1018 struct smbd_server_connection
*sconn
=
1019 talloc_get_type_abort(private_data
,
1020 struct smbd_server_connection
);
1022 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1023 "updated. Reloading.\n"));
1024 change_to_root_user();
1025 reload_services(sconn
, conn_snum_used
, false);
1029 * Only allow 5 outstanding trans requests. We're allocating memory, so
1033 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
1036 for (; list
!= NULL
; list
= list
->next
) {
1038 if (list
->mid
== mid
) {
1039 return NT_STATUS_INVALID_PARAMETER
;
1045 return NT_STATUS_INSUFFICIENT_RESOURCES
;
1048 return NT_STATUS_OK
;
1052 These flags determine some of the permissions required to do an operation
1054 Note that I don't set NEED_WRITE on some write operations because they
1055 are used by some brain-dead clients when printing, and I don't want to
1056 force write permissions on print services.
1058 #define AS_USER (1<<0)
1059 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1060 #define TIME_INIT (1<<2)
1061 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1062 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1063 #define DO_CHDIR (1<<6)
1066 define a list of possible SMB messages and their corresponding
1067 functions. Any message that has a NULL function is unimplemented -
1068 please feel free to contribute implementations!
1070 static const struct smb_message_struct
{
1072 void (*fn
)(struct smb_request
*req
);
1074 } smb_messages
[256] = {
1076 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1077 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1078 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1079 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1080 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1081 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1082 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1083 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1084 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1085 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1086 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1087 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1088 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1089 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1090 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1091 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1092 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1093 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1094 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1095 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1096 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1097 /* 0x15 */ { NULL
, NULL
, 0 },
1098 /* 0x16 */ { NULL
, NULL
, 0 },
1099 /* 0x17 */ { NULL
, NULL
, 0 },
1100 /* 0x18 */ { NULL
, NULL
, 0 },
1101 /* 0x19 */ { NULL
, NULL
, 0 },
1102 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1103 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1104 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1105 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1106 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1107 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1108 /* 0x20 */ { "SMBwritec", NULL
,0},
1109 /* 0x21 */ { NULL
, NULL
, 0 },
1110 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1111 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1112 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1113 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1114 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1115 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1116 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1117 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1118 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1119 /* 0x2b */ { "SMBecho",reply_echo
,0},
1120 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1121 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1122 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1123 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1124 /* 0x30 */ { NULL
, NULL
, 0 },
1125 /* 0x31 */ { NULL
, NULL
, 0 },
1126 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1127 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1128 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1129 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1130 /* 0x36 */ { NULL
, NULL
, 0 },
1131 /* 0x37 */ { NULL
, NULL
, 0 },
1132 /* 0x38 */ { NULL
, NULL
, 0 },
1133 /* 0x39 */ { NULL
, NULL
, 0 },
1134 /* 0x3a */ { NULL
, NULL
, 0 },
1135 /* 0x3b */ { NULL
, NULL
, 0 },
1136 /* 0x3c */ { NULL
, NULL
, 0 },
1137 /* 0x3d */ { NULL
, NULL
, 0 },
1138 /* 0x3e */ { NULL
, NULL
, 0 },
1139 /* 0x3f */ { NULL
, NULL
, 0 },
1140 /* 0x40 */ { NULL
, NULL
, 0 },
1141 /* 0x41 */ { NULL
, NULL
, 0 },
1142 /* 0x42 */ { NULL
, NULL
, 0 },
1143 /* 0x43 */ { NULL
, NULL
, 0 },
1144 /* 0x44 */ { NULL
, NULL
, 0 },
1145 /* 0x45 */ { NULL
, NULL
, 0 },
1146 /* 0x46 */ { NULL
, NULL
, 0 },
1147 /* 0x47 */ { NULL
, NULL
, 0 },
1148 /* 0x48 */ { NULL
, NULL
, 0 },
1149 /* 0x49 */ { NULL
, NULL
, 0 },
1150 /* 0x4a */ { NULL
, NULL
, 0 },
1151 /* 0x4b */ { NULL
, NULL
, 0 },
1152 /* 0x4c */ { NULL
, NULL
, 0 },
1153 /* 0x4d */ { NULL
, NULL
, 0 },
1154 /* 0x4e */ { NULL
, NULL
, 0 },
1155 /* 0x4f */ { NULL
, NULL
, 0 },
1156 /* 0x50 */ { NULL
, NULL
, 0 },
1157 /* 0x51 */ { NULL
, NULL
, 0 },
1158 /* 0x52 */ { NULL
, NULL
, 0 },
1159 /* 0x53 */ { NULL
, NULL
, 0 },
1160 /* 0x54 */ { NULL
, NULL
, 0 },
1161 /* 0x55 */ { NULL
, NULL
, 0 },
1162 /* 0x56 */ { NULL
, NULL
, 0 },
1163 /* 0x57 */ { NULL
, NULL
, 0 },
1164 /* 0x58 */ { NULL
, NULL
, 0 },
1165 /* 0x59 */ { NULL
, NULL
, 0 },
1166 /* 0x5a */ { NULL
, NULL
, 0 },
1167 /* 0x5b */ { NULL
, NULL
, 0 },
1168 /* 0x5c */ { NULL
, NULL
, 0 },
1169 /* 0x5d */ { NULL
, NULL
, 0 },
1170 /* 0x5e */ { NULL
, NULL
, 0 },
1171 /* 0x5f */ { NULL
, NULL
, 0 },
1172 /* 0x60 */ { NULL
, NULL
, 0 },
1173 /* 0x61 */ { NULL
, NULL
, 0 },
1174 /* 0x62 */ { NULL
, NULL
, 0 },
1175 /* 0x63 */ { NULL
, NULL
, 0 },
1176 /* 0x64 */ { NULL
, NULL
, 0 },
1177 /* 0x65 */ { NULL
, NULL
, 0 },
1178 /* 0x66 */ { NULL
, NULL
, 0 },
1179 /* 0x67 */ { NULL
, NULL
, 0 },
1180 /* 0x68 */ { NULL
, NULL
, 0 },
1181 /* 0x69 */ { NULL
, NULL
, 0 },
1182 /* 0x6a */ { NULL
, NULL
, 0 },
1183 /* 0x6b */ { NULL
, NULL
, 0 },
1184 /* 0x6c */ { NULL
, NULL
, 0 },
1185 /* 0x6d */ { NULL
, NULL
, 0 },
1186 /* 0x6e */ { NULL
, NULL
, 0 },
1187 /* 0x6f */ { NULL
, NULL
, 0 },
1188 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1189 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1190 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1191 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1192 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1193 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1194 /* 0x76 */ { NULL
, NULL
, 0 },
1195 /* 0x77 */ { NULL
, NULL
, 0 },
1196 /* 0x78 */ { NULL
, NULL
, 0 },
1197 /* 0x79 */ { NULL
, NULL
, 0 },
1198 /* 0x7a */ { NULL
, NULL
, 0 },
1199 /* 0x7b */ { NULL
, NULL
, 0 },
1200 /* 0x7c */ { NULL
, NULL
, 0 },
1201 /* 0x7d */ { NULL
, NULL
, 0 },
1202 /* 0x7e */ { NULL
, NULL
, 0 },
1203 /* 0x7f */ { NULL
, NULL
, 0 },
1204 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1205 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1206 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1207 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1208 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1209 /* 0x85 */ { NULL
, NULL
, 0 },
1210 /* 0x86 */ { NULL
, NULL
, 0 },
1211 /* 0x87 */ { NULL
, NULL
, 0 },
1212 /* 0x88 */ { NULL
, NULL
, 0 },
1213 /* 0x89 */ { NULL
, NULL
, 0 },
1214 /* 0x8a */ { NULL
, NULL
, 0 },
1215 /* 0x8b */ { NULL
, NULL
, 0 },
1216 /* 0x8c */ { NULL
, NULL
, 0 },
1217 /* 0x8d */ { NULL
, NULL
, 0 },
1218 /* 0x8e */ { NULL
, NULL
, 0 },
1219 /* 0x8f */ { NULL
, NULL
, 0 },
1220 /* 0x90 */ { NULL
, NULL
, 0 },
1221 /* 0x91 */ { NULL
, NULL
, 0 },
1222 /* 0x92 */ { NULL
, NULL
, 0 },
1223 /* 0x93 */ { NULL
, NULL
, 0 },
1224 /* 0x94 */ { NULL
, NULL
, 0 },
1225 /* 0x95 */ { NULL
, NULL
, 0 },
1226 /* 0x96 */ { NULL
, NULL
, 0 },
1227 /* 0x97 */ { NULL
, NULL
, 0 },
1228 /* 0x98 */ { NULL
, NULL
, 0 },
1229 /* 0x99 */ { NULL
, NULL
, 0 },
1230 /* 0x9a */ { NULL
, NULL
, 0 },
1231 /* 0x9b */ { NULL
, NULL
, 0 },
1232 /* 0x9c */ { NULL
, NULL
, 0 },
1233 /* 0x9d */ { NULL
, NULL
, 0 },
1234 /* 0x9e */ { NULL
, NULL
, 0 },
1235 /* 0x9f */ { NULL
, NULL
, 0 },
1236 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1237 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1238 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1239 /* 0xa3 */ { NULL
, NULL
, 0 },
1240 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1241 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1242 /* 0xa6 */ { NULL
, NULL
, 0 },
1243 /* 0xa7 */ { NULL
, NULL
, 0 },
1244 /* 0xa8 */ { NULL
, NULL
, 0 },
1245 /* 0xa9 */ { NULL
, NULL
, 0 },
1246 /* 0xaa */ { NULL
, NULL
, 0 },
1247 /* 0xab */ { NULL
, NULL
, 0 },
1248 /* 0xac */ { NULL
, NULL
, 0 },
1249 /* 0xad */ { NULL
, NULL
, 0 },
1250 /* 0xae */ { NULL
, NULL
, 0 },
1251 /* 0xaf */ { NULL
, NULL
, 0 },
1252 /* 0xb0 */ { NULL
, NULL
, 0 },
1253 /* 0xb1 */ { NULL
, NULL
, 0 },
1254 /* 0xb2 */ { NULL
, NULL
, 0 },
1255 /* 0xb3 */ { NULL
, NULL
, 0 },
1256 /* 0xb4 */ { NULL
, NULL
, 0 },
1257 /* 0xb5 */ { NULL
, NULL
, 0 },
1258 /* 0xb6 */ { NULL
, NULL
, 0 },
1259 /* 0xb7 */ { NULL
, NULL
, 0 },
1260 /* 0xb8 */ { NULL
, NULL
, 0 },
1261 /* 0xb9 */ { NULL
, NULL
, 0 },
1262 /* 0xba */ { NULL
, NULL
, 0 },
1263 /* 0xbb */ { NULL
, NULL
, 0 },
1264 /* 0xbc */ { NULL
, NULL
, 0 },
1265 /* 0xbd */ { NULL
, NULL
, 0 },
1266 /* 0xbe */ { NULL
, NULL
, 0 },
1267 /* 0xbf */ { NULL
, NULL
, 0 },
1268 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1269 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1270 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1271 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1272 /* 0xc4 */ { NULL
, NULL
, 0 },
1273 /* 0xc5 */ { NULL
, NULL
, 0 },
1274 /* 0xc6 */ { NULL
, NULL
, 0 },
1275 /* 0xc7 */ { NULL
, NULL
, 0 },
1276 /* 0xc8 */ { NULL
, NULL
, 0 },
1277 /* 0xc9 */ { NULL
, NULL
, 0 },
1278 /* 0xca */ { NULL
, NULL
, 0 },
1279 /* 0xcb */ { NULL
, NULL
, 0 },
1280 /* 0xcc */ { NULL
, NULL
, 0 },
1281 /* 0xcd */ { NULL
, NULL
, 0 },
1282 /* 0xce */ { NULL
, NULL
, 0 },
1283 /* 0xcf */ { NULL
, NULL
, 0 },
1284 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1285 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1286 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1287 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1288 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1289 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1290 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1291 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1292 /* 0xd8 */ { NULL
, NULL
, 0 },
1293 /* 0xd9 */ { NULL
, NULL
, 0 },
1294 /* 0xda */ { NULL
, NULL
, 0 },
1295 /* 0xdb */ { NULL
, NULL
, 0 },
1296 /* 0xdc */ { NULL
, NULL
, 0 },
1297 /* 0xdd */ { NULL
, NULL
, 0 },
1298 /* 0xde */ { NULL
, NULL
, 0 },
1299 /* 0xdf */ { NULL
, NULL
, 0 },
1300 /* 0xe0 */ { NULL
, NULL
, 0 },
1301 /* 0xe1 */ { NULL
, NULL
, 0 },
1302 /* 0xe2 */ { NULL
, NULL
, 0 },
1303 /* 0xe3 */ { NULL
, NULL
, 0 },
1304 /* 0xe4 */ { NULL
, NULL
, 0 },
1305 /* 0xe5 */ { NULL
, NULL
, 0 },
1306 /* 0xe6 */ { NULL
, NULL
, 0 },
1307 /* 0xe7 */ { NULL
, NULL
, 0 },
1308 /* 0xe8 */ { NULL
, NULL
, 0 },
1309 /* 0xe9 */ { NULL
, NULL
, 0 },
1310 /* 0xea */ { NULL
, NULL
, 0 },
1311 /* 0xeb */ { NULL
, NULL
, 0 },
1312 /* 0xec */ { NULL
, NULL
, 0 },
1313 /* 0xed */ { NULL
, NULL
, 0 },
1314 /* 0xee */ { NULL
, NULL
, 0 },
1315 /* 0xef */ { NULL
, NULL
, 0 },
1316 /* 0xf0 */ { NULL
, NULL
, 0 },
1317 /* 0xf1 */ { NULL
, NULL
, 0 },
1318 /* 0xf2 */ { NULL
, NULL
, 0 },
1319 /* 0xf3 */ { NULL
, NULL
, 0 },
1320 /* 0xf4 */ { NULL
, NULL
, 0 },
1321 /* 0xf5 */ { NULL
, NULL
, 0 },
1322 /* 0xf6 */ { NULL
, NULL
, 0 },
1323 /* 0xf7 */ { NULL
, NULL
, 0 },
1324 /* 0xf8 */ { NULL
, NULL
, 0 },
1325 /* 0xf9 */ { NULL
, NULL
, 0 },
1326 /* 0xfa */ { NULL
, NULL
, 0 },
1327 /* 0xfb */ { NULL
, NULL
, 0 },
1328 /* 0xfc */ { NULL
, NULL
, 0 },
1329 /* 0xfd */ { NULL
, NULL
, 0 },
1330 /* 0xfe */ { NULL
, NULL
, 0 },
1331 /* 0xff */ { NULL
, NULL
, 0 }
1335 /*******************************************************************
1336 allocate and initialize a reply packet
1337 ********************************************************************/
1339 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1340 const uint8_t *inbuf
, char **outbuf
,
1341 uint8_t num_words
, uint32_t num_bytes
)
1343 size_t smb_len
= MIN_SMB_SIZE
+ VWV(num_words
) + num_bytes
;
1346 * Protect against integer wrap.
1347 * The SMB layer reply can be up to 0xFFFFFF bytes.
1349 if ((num_bytes
> 0xffffff) || (smb_len
> 0xffffff)) {
1351 if (asprintf(&msg
, "num_bytes too large: %u",
1352 (unsigned)num_bytes
) == -1) {
1353 msg
= discard_const_p(char, "num_bytes too large");
1359 * Here we include the NBT header for now.
1361 *outbuf
= talloc_array(mem_ctx
, char,
1362 NBT_HDR_SIZE
+ smb_len
);
1363 if (*outbuf
== NULL
) {
1367 construct_reply_common(req
->cmd
, inbuf
, *outbuf
);
1368 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1370 * Zero out the word area, the caller has to take care of the bcc area
1373 if (num_words
!= 0) {
1374 memset(*outbuf
+ (NBT_HDR_SIZE
+ HDR_VWV
), 0, VWV(num_words
));
1380 void reply_outbuf(struct smb_request
*req
, uint8_t num_words
, uint32_t num_bytes
)
1383 if (!create_outbuf(req
, req
, req
->inbuf
, &outbuf
, num_words
,
1385 smb_panic("could not allocate output buffer\n");
1387 req
->outbuf
= (uint8_t *)outbuf
;
1391 /*******************************************************************
1392 Dump a packet to a file.
1393 ********************************************************************/
1395 static void smb_dump(const char *name
, int type
, const char *data
)
1400 if (DEBUGLEVEL
< 50) {
1404 len
= smb_len_tcp(data
)+4;
1405 for (i
=1;i
<100;i
++) {
1406 fname
= talloc_asprintf(talloc_tos(),
1410 type
? "req" : "resp");
1411 if (fname
== NULL
) {
1414 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1415 if (fd
!= -1 || errno
!= EEXIST
) break;
1419 ssize_t ret
= write(fd
, data
, len
);
1421 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1423 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1428 static void smb1srv_update_crypto_flags(struct smbXsrv_session
*session
,
1429 struct smb_request
*req
,
1431 bool *update_session_globalp
,
1432 bool *update_tcon_globalp
)
1434 connection_struct
*conn
= req
->conn
;
1435 struct smbXsrv_tcon
*tcon
= conn
? conn
->tcon
: NULL
;
1436 uint8_t encrypt_flag
= SMBXSRV_PROCESSED_UNENCRYPTED_PACKET
;
1437 uint8_t sign_flag
= SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
1438 bool update_session
= false;
1439 bool update_tcon
= false;
1441 if (req
->encrypted
) {
1442 encrypt_flag
= SMBXSRV_PROCESSED_ENCRYPTED_PACKET
;
1445 if (srv_is_signing_active(req
->xconn
)) {
1446 sign_flag
= SMBXSRV_PROCESSED_SIGNED_PACKET
;
1447 } else if ((type
== SMBecho
) || (type
== SMBsesssetupX
)) {
1449 * echo can be unsigned. Sesssion setup except final
1450 * session setup response too
1452 sign_flag
&= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET
;
1455 update_session
|= smbXsrv_set_crypto_flag(
1456 &session
->global
->encryption_flags
, encrypt_flag
);
1457 update_session
|= smbXsrv_set_crypto_flag(
1458 &session
->global
->signing_flags
, sign_flag
);
1461 update_tcon
|= smbXsrv_set_crypto_flag(
1462 &tcon
->global
->encryption_flags
, encrypt_flag
);
1463 update_tcon
|= smbXsrv_set_crypto_flag(
1464 &tcon
->global
->signing_flags
, sign_flag
);
1467 if (update_session
) {
1468 session
->global
->channels
[0].encryption_cipher
= SMB_ENCRYPTION_GSSAPI
;
1471 *update_session_globalp
= update_session
;
1472 *update_tcon_globalp
= update_tcon
;
1476 /****************************************************************************
1477 Prepare everything for calling the actual request function, and potentially
1478 call the request function via the "new" interface.
1480 Return False if the "legacy" function needs to be called, everything is
1483 Return True if we're done.
1485 I know this API sucks, but it is the one with the least code change I could
1487 ****************************************************************************/
1489 static connection_struct
*switch_message(uint8_t type
, struct smb_request
*req
)
1492 uint64_t session_tag
;
1493 connection_struct
*conn
= NULL
;
1494 struct smbXsrv_connection
*xconn
= req
->xconn
;
1495 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1496 struct smbXsrv_session
*session
= NULL
;
1501 if (!xconn
->smb1
.negprot
.done
) {
1504 * Without a negprot the request must
1505 * either be a negprot, or one of the
1506 * evil old SMB mailslot messaging types.
1514 exit_server_cleanly("The first request "
1515 "should be a negprot");
1519 if (smb_messages
[type
].fn
== NULL
) {
1520 DEBUG(0,("Unknown message type %d!\n",type
));
1521 smb_dump("Unknown", 1, (const char *)req
->inbuf
);
1522 reply_unknown_new(req
, type
);
1526 flags
= smb_messages
[type
].flags
;
1528 /* In share mode security we must ignore the vuid. */
1529 session_tag
= req
->vuid
;
1532 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1533 (int)getpid(), (unsigned long)conn
));
1535 smb_dump(smb_fn_name(type
), 1, (const char *)req
->inbuf
);
1537 /* Ensure this value is replaced in the incoming packet. */
1538 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_uid
,session_tag
);
1541 * Ensure the correct username is in current_user_info. This is a
1542 * really ugly bugfix for problems with multiple session_setup_and_X's
1543 * being done and allowing %U and %G substitutions to work correctly.
1544 * There is a reason this code is done here, don't move it unless you
1545 * know what you're doing... :-).
1550 * lookup an existing session
1552 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1553 * here, the main check is still in change_to_user()
1555 status
= smb1srv_session_lookup(xconn
,
1559 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
1562 status
= NT_STATUS_OK
;
1565 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1566 (unsigned long long)session_tag
,
1567 (unsigned long long)req
->mid
));
1568 reply_nterror(req
, NT_STATUS_NETWORK_SESSION_EXPIRED
);
1573 if (session_tag
!= xconn
->client
->last_session_id
) {
1574 struct user_struct
*vuser
= NULL
;
1576 xconn
->client
->last_session_id
= session_tag
;
1578 vuser
= session
->compat
;
1581 set_current_user_info(
1582 vuser
->session_info
->unix_info
->sanitized_username
,
1583 vuser
->session_info
->unix_info
->unix_name
,
1584 vuser
->session_info
->info
->domain_name
);
1588 /* Does this call need to be run as the connected user? */
1589 if (flags
& AS_USER
) {
1591 /* Does this call need a valid tree connection? */
1594 * Amazingly, the error code depends on the command
1597 if (type
== SMBntcreateX
) {
1598 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1600 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1605 if (!change_to_user(conn
,session_tag
)) {
1606 DEBUG(0, ("Error: Could not change to user. Removing "
1607 "deferred open, mid=%llu.\n",
1608 (unsigned long long)req
->mid
));
1609 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1613 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1615 /* Does it need write permission? */
1616 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1617 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1621 /* IPC services are limited */
1622 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1623 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1627 /* This call needs to be run as root */
1628 change_to_root_user();
1631 /* load service specific parameters */
1633 if (req
->encrypted
) {
1634 conn
->encrypted_tid
= true;
1635 /* encrypted required from now on. */
1636 conn
->encrypt_level
= SMB_SIGNING_REQUIRED
;
1637 } else if (ENCRYPTION_REQUIRED(conn
)) {
1638 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1639 DEBUG(1,("service[%s] requires encryption"
1640 "%s ACCESS_DENIED. mid=%llu\n",
1641 lp_servicename(talloc_tos(), SNUM(conn
)),
1643 (unsigned long long)req
->mid
));
1644 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1649 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1650 (flags
& (AS_USER
|DO_CHDIR
)
1652 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1655 conn
->num_smb_operations
++;
1659 * Does this protocol need to be run as guest? (Only archane
1660 * messenger service requests have this...)
1662 if (flags
& AS_GUEST
) {
1666 if (!change_to_guest()) {
1667 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1671 raddr
= tsocket_address_inet_addr_string(xconn
->remote_address
,
1673 if (raddr
== NULL
) {
1674 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1679 * Haven't we checked this in smbd_process already???
1682 ok
= allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1683 xconn
->remote_hostname
, raddr
);
1687 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1693 * Update encryption and signing state tracking flags that are
1694 * used by smbstatus to display signing and encryption status.
1696 if (session
!= NULL
) {
1697 bool update_session_global
= false;
1698 bool update_tcon_global
= false;
1700 smb1srv_update_crypto_flags(session
, req
, type
,
1701 &update_session_global
,
1702 &update_tcon_global
);
1704 if (update_session_global
) {
1705 status
= smbXsrv_session_update(session
);
1706 if (!NT_STATUS_IS_OK(status
)) {
1707 reply_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1712 if (update_tcon_global
) {
1713 status
= smbXsrv_tcon_update(req
->conn
->tcon
);
1714 if (!NT_STATUS_IS_OK(status
)) {
1715 reply_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1721 smb_messages
[type
].fn(req
);
1725 /****************************************************************************
1726 Construct a reply to the incoming packet.
1727 ****************************************************************************/
1729 static void construct_reply(struct smbXsrv_connection
*xconn
,
1730 char *inbuf
, int size
, size_t unread_bytes
,
1731 uint32_t seqnum
, bool encrypted
,
1732 struct smb_perfcount_data
*deferred_pcd
)
1734 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
1735 struct smb_request
*req
;
1737 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1738 smb_panic("could not allocate smb_request");
1741 if (!init_smb_request(req
, sconn
, xconn
, (uint8_t *)inbuf
, unread_bytes
,
1742 encrypted
, seqnum
)) {
1743 exit_server_cleanly("Invalid SMB request");
1746 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1748 /* we popped this message off the queue - keep original perf data */
1750 req
->pcd
= *deferred_pcd
;
1752 SMB_PERFCOUNT_START(&req
->pcd
);
1753 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1754 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1757 req
->conn
= switch_message(req
->cmd
, req
);
1759 if (req
->outbuf
== NULL
) {
1761 * Request has suspended itself, will come
1766 if (CVAL(req
->outbuf
,0) == 0) {
1767 show_msg((char *)req
->outbuf
);
1769 smb_request_done(req
);
1772 static void construct_reply_chain(struct smbXsrv_connection
*xconn
,
1773 char *inbuf
, int size
, uint32_t seqnum
,
1775 struct smb_perfcount_data
*deferred_pcd
)
1777 struct smb_request
**reqs
= NULL
;
1778 struct smb_request
*req
;
1782 ok
= smb1_parse_chain(xconn
, (uint8_t *)inbuf
, xconn
, encrypted
,
1783 seqnum
, &reqs
, &num_reqs
);
1785 char errbuf
[smb_size
];
1786 error_packet(errbuf
, 0, 0, NT_STATUS_INVALID_PARAMETER
,
1787 __LINE__
, __FILE__
);
1788 if (!srv_send_smb(xconn
, errbuf
, true, seqnum
, encrypted
,
1790 exit_server_cleanly("construct_reply_chain: "
1791 "srv_send_smb failed.");
1797 req
->inbuf
= (uint8_t *)talloc_move(reqs
, &inbuf
);
1799 req
->conn
= switch_message(req
->cmd
, req
);
1801 if (req
->outbuf
== NULL
) {
1803 * Request has suspended itself, will come
1808 smb_request_done(req
);
1812 * To be called from an async SMB handler that is potentially chained
1813 * when it is finished for shipping.
1816 void smb_request_done(struct smb_request
*req
)
1818 struct smb_request
**reqs
= NULL
;
1819 struct smb_request
*first_req
;
1820 size_t i
, num_reqs
, next_index
;
1823 if (req
->chain
== NULL
) {
1829 num_reqs
= talloc_array_length(reqs
);
1831 for (i
=0; i
<num_reqs
; i
++) {
1832 if (reqs
[i
] == req
) {
1836 if (i
== num_reqs
) {
1838 * Invalid chain, should not happen
1840 status
= NT_STATUS_INTERNAL_ERROR
;
1845 while ((next_index
< num_reqs
) && (IVAL(req
->outbuf
, smb_rcls
) == 0)) {
1846 struct smb_request
*next
= reqs
[next_index
];
1847 struct smbXsrv_tcon
*tcon
;
1848 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1850 next
->vuid
= SVAL(req
->outbuf
, smb_uid
);
1851 next
->tid
= SVAL(req
->outbuf
, smb_tid
);
1852 status
= smb1srv_tcon_lookup(req
->xconn
, next
->tid
,
1855 if (NT_STATUS_IS_OK(status
)) {
1856 next
->conn
= tcon
->compat
;
1860 next
->chain_fsp
= req
->chain_fsp
;
1861 next
->inbuf
= req
->inbuf
;
1864 req
->conn
= switch_message(req
->cmd
, req
);
1866 if (req
->outbuf
== NULL
) {
1868 * Request has suspended itself, will come
1876 first_req
= reqs
[0];
1878 for (i
=1; i
<next_index
; i
++) {
1881 ok
= smb_splice_chain(&first_req
->outbuf
, reqs
[i
]->outbuf
);
1883 status
= NT_STATUS_INTERNAL_ERROR
;
1888 SSVAL(first_req
->outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
1889 SSVAL(first_req
->outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
1892 * This scary statement intends to set the
1893 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1894 * to the value last_req->outbuf carries
1896 SSVAL(first_req
->outbuf
, smb_flg2
,
1897 (SVAL(first_req
->outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
1898 |(SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
1901 * Transfer the error codes from the subrequest to the main one
1903 SSVAL(first_req
->outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
1904 SSVAL(first_req
->outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
1907 first_req
->outbuf
, talloc_get_size(first_req
->outbuf
) - 4);
1910 if (!srv_send_smb(first_req
->xconn
,
1911 (char *)first_req
->outbuf
,
1912 true, first_req
->seqnum
+1,
1913 IS_CONN_ENCRYPTED(req
->conn
)||first_req
->encrypted
,
1915 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1918 TALLOC_FREE(req
); /* non-chained case */
1919 TALLOC_FREE(reqs
); /* chained case */
1924 char errbuf
[smb_size
];
1925 error_packet(errbuf
, 0, 0, status
, __LINE__
, __FILE__
);
1926 if (!srv_send_smb(req
->xconn
, errbuf
, true,
1927 req
->seqnum
+1, req
->encrypted
,
1929 exit_server_cleanly("construct_reply_chain: "
1930 "srv_send_smb failed.");
1933 TALLOC_FREE(req
); /* non-chained case */
1934 TALLOC_FREE(reqs
); /* chained case */
1937 /****************************************************************************
1938 Process an smb from the client
1939 ****************************************************************************/
1940 static void process_smb(struct smbXsrv_connection
*xconn
,
1941 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1942 uint32_t seqnum
, bool encrypted
,
1943 struct smb_perfcount_data
*deferred_pcd
)
1945 struct smbd_server_connection
*sconn
= xconn
->client
->sconn
;
1946 int msg_type
= CVAL(inbuf
,0);
1948 DO_PROFILE_INC(request
);
1950 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1952 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1953 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1955 if (msg_type
!= NBSSmessage
) {
1957 * NetBIOS session request, keepalive, etc.
1959 reply_special(xconn
, (char *)inbuf
, nread
);
1963 if (sconn
->using_smb2
) {
1964 /* At this point we're not really using smb2,
1965 * we make the decision here.. */
1966 if (smbd_is_smb2_header(inbuf
, nread
)) {
1967 const uint8_t *inpdu
= inbuf
+ NBT_HDR_SIZE
;
1968 size_t pdulen
= nread
- NBT_HDR_SIZE
;
1969 smbd_smb2_process_negprot(xconn
, 0, inpdu
, pdulen
);
1972 if (nread
>= smb_size
&& valid_smb_header(inbuf
)
1973 && CVAL(inbuf
, smb_com
) != 0x72) {
1974 /* This is a non-negprot SMB1 packet.
1975 Disable SMB2 from now on. */
1976 sconn
->using_smb2
= false;
1980 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1981 * so subtract 4 from it. */
1982 if ((nread
< (smb_size
- 4)) || !valid_smb_header(inbuf
)) {
1983 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1986 /* special magic for immediate exit */
1988 (IVAL(inbuf
, 4) == 0x74697865) &&
1989 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1990 uint8_t exitcode
= CVAL(inbuf
, 8);
1991 DEBUG(1, ("Exiting immediately with code %d\n",
1996 exit_server_cleanly("Non-SMB packet");
1999 show_msg((char *)inbuf
);
2001 if ((unread_bytes
== 0) && smb1_is_chain(inbuf
)) {
2002 construct_reply_chain(xconn
, (char *)inbuf
, nread
,
2003 seqnum
, encrypted
, deferred_pcd
);
2005 construct_reply(xconn
, (char *)inbuf
, nread
, unread_bytes
,
2006 seqnum
, encrypted
, deferred_pcd
);
2012 sconn
->num_requests
++;
2014 /* The timeout_processing function isn't run nearly
2015 often enough to implement 'max log size' without
2016 overrunning the size of the file by many megabytes.
2017 This is especially true if we are running at debug
2018 level 10. Checking every 50 SMBs is a nice
2019 tradeoff of performance vs log file size overrun. */
2021 if ((sconn
->num_requests
% 50) == 0 &&
2022 need_to_check_log_size()) {
2023 change_to_root_user();
2028 /****************************************************************************
2029 Return a string containing the function name of a SMB command.
2030 ****************************************************************************/
2032 const char *smb_fn_name(int type
)
2034 const char *unknown_name
= "SMBunknown";
2036 if (smb_messages
[type
].name
== NULL
)
2037 return(unknown_name
);
2039 return(smb_messages
[type
].name
);
2042 /****************************************************************************
2043 Helper functions for contruct_reply.
2044 ****************************************************************************/
2046 void add_to_common_flags2(uint32_t v
)
2051 void remove_from_common_flags2(uint32_t v
)
2053 common_flags2
&= ~v
;
2056 static void construct_reply_common(uint8_t cmd
, const uint8_t *inbuf
,
2059 uint16_t in_flags2
= SVAL(inbuf
,smb_flg2
);
2060 uint16_t out_flags2
= common_flags2
;
2062 out_flags2
|= in_flags2
& FLAGS2_UNICODE_STRINGS
;
2063 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
;
2064 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
;
2066 srv_set_message(outbuf
,0,0,false);
2068 SCVAL(outbuf
, smb_com
, cmd
);
2069 SIVAL(outbuf
,smb_rcls
,0);
2070 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
2071 SSVAL(outbuf
,smb_flg2
, out_flags2
);
2072 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
2073 memcpy(outbuf
+smb_ss_field
, inbuf
+smb_ss_field
, 8);
2075 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
2076 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
2077 SSVAL(outbuf
,smb_pidhigh
,SVAL(inbuf
,smb_pidhigh
));
2078 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
2079 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
2082 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
2084 construct_reply_common(req
->cmd
, req
->inbuf
, outbuf
);
2088 * @brief Find the smb_cmd offset of the last command pushed
2089 * @param[in] buf The buffer we're building up
2090 * @retval Where can we put our next andx cmd?
2092 * While chaining requests, the "next" request we're looking at needs to put
2093 * its SMB_Command before the data the previous request already built up added
2094 * to the chain. Find the offset to the place where we have to put our cmd.
2097 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
2102 cmd
= CVAL(buf
, smb_com
);
2104 if (!is_andx_req(cmd
)) {
2110 while (CVAL(buf
, ofs
) != 0xff) {
2112 if (!is_andx_req(CVAL(buf
, ofs
))) {
2117 * ofs is from start of smb header, so add the 4 length
2118 * bytes. The next cmd is right after the wct field.
2120 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
2122 if (ofs
+4 >= talloc_get_size(buf
)) {
2132 * @brief Do the smb chaining at a buffer level
2133 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2134 * @param[in] andx_buf Buffer to be appended
2137 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
)
2139 uint8_t smb_command
= CVAL(andx_buf
, smb_com
);
2140 uint8_t wct
= CVAL(andx_buf
, smb_wct
);
2141 const uint16_t *vwv
= (const uint16_t *)(andx_buf
+ smb_vwv
);
2142 uint32_t num_bytes
= smb_buflen(andx_buf
);
2143 const uint8_t *bytes
= (const uint8_t *)smb_buf_const(andx_buf
);
2146 size_t old_size
, new_size
;
2148 size_t chain_padding
= 0;
2149 size_t andx_cmd_ofs
;
2152 old_size
= talloc_get_size(*poutbuf
);
2154 if ((old_size
% 4) != 0) {
2156 * Align the wct field of subsequent requests to a 4-byte
2159 chain_padding
= 4 - (old_size
% 4);
2163 * After the old request comes the new wct field (1 byte), the vwv's
2164 * and the num_bytes field.
2167 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
2168 new_size
+= num_bytes
;
2170 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
2171 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2172 (unsigned)new_size
));
2176 outbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, new_size
);
2177 if (outbuf
== NULL
) {
2178 DEBUG(0, ("talloc failed\n"));
2183 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
2184 DEBUG(1, ("invalid command chain\n"));
2185 *poutbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, old_size
);
2189 if (chain_padding
!= 0) {
2190 memset(outbuf
+ old_size
, 0, chain_padding
);
2191 old_size
+= chain_padding
;
2194 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
2195 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
2200 * Push the chained request:
2205 SCVAL(outbuf
, ofs
, wct
);
2212 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
2217 * Read&X has an offset into its data buffer at
2218 * vwv[6]. reply_read_andx has no idea anymore that it's
2219 * running from within a chain, so we have to fix up the
2222 * Although it looks disgusting at this place, I want to keep
2223 * it here. The alternative would be to push knowledge about
2224 * the andx chain down into read&x again.
2227 if (smb_command
== SMBreadX
) {
2228 uint8_t *bytes_addr
;
2232 * Invalid read&x response
2237 bytes_addr
= outbuf
+ ofs
/* vwv start */
2238 + sizeof(uint16_t) * wct
/* vwv array */
2239 + sizeof(uint16_t) /* bcc */
2240 + 1; /* padding byte */
2242 SSVAL(outbuf
+ ofs
, 6 * sizeof(uint16_t),
2243 bytes_addr
- outbuf
- 4);
2246 ofs
+= sizeof(uint16_t) * wct
;
2252 SSVAL(outbuf
, ofs
, num_bytes
);
2253 ofs
+= sizeof(uint16_t);
2259 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
2264 bool smb1_is_chain(const uint8_t *buf
)
2266 uint8_t cmd
, wct
, andx_cmd
;
2268 cmd
= CVAL(buf
, smb_com
);
2269 if (!is_andx_req(cmd
)) {
2272 wct
= CVAL(buf
, smb_wct
);
2276 andx_cmd
= CVAL(buf
, smb_vwv
);
2277 return (andx_cmd
!= 0xFF);
2280 bool smb1_walk_chain(const uint8_t *buf
,
2281 bool (*fn
)(uint8_t cmd
,
2282 uint8_t wct
, const uint16_t *vwv
,
2283 uint16_t num_bytes
, const uint8_t *bytes
,
2284 void *private_data
),
2287 size_t smblen
= smb_len(buf
);
2288 const char *smb_buf
= smb_base(buf
);
2289 uint8_t cmd
, chain_cmd
;
2291 const uint16_t *vwv
;
2293 const uint8_t *bytes
;
2295 cmd
= CVAL(buf
, smb_com
);
2296 wct
= CVAL(buf
, smb_wct
);
2297 vwv
= (const uint16_t *)(buf
+ smb_vwv
);
2298 num_bytes
= smb_buflen(buf
);
2299 bytes
= (const uint8_t *)smb_buf_const(buf
);
2301 if (!fn(cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2305 if (!is_andx_req(cmd
)) {
2312 chain_cmd
= CVAL(vwv
, 0);
2314 while (chain_cmd
!= 0xff) {
2315 uint32_t chain_offset
; /* uint32_t to avoid overflow */
2316 size_t length_needed
;
2317 ptrdiff_t vwv_offset
;
2319 chain_offset
= SVAL(vwv
+1, 0);
2322 * Check if the client tries to fool us. The chain
2323 * offset needs to point beyond the current request in
2324 * the chain, it needs to strictly grow. Otherwise we
2325 * might be tricked into an endless loop always
2326 * processing the same request over and over again. We
2327 * used to assume that vwv and the byte buffer array
2328 * in a chain are always attached, but OS/2 the
2329 * Write&X/Read&X chain puts the Read&X vwv array
2330 * right behind the Write&X vwv chain. The Write&X bcc
2331 * array is put behind the Read&X vwv array. So now we
2332 * check whether the chain offset points strictly
2333 * behind the previous vwv array. req->buf points
2334 * right after the vwv array of the previous
2336 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2340 vwv_offset
= ((const char *)vwv
- smb_buf
);
2341 if (chain_offset
<= vwv_offset
) {
2346 * Next check: Make sure the chain offset does not
2347 * point beyond the overall smb request length.
2350 length_needed
= chain_offset
+1; /* wct */
2351 if (length_needed
> smblen
) {
2356 * Now comes the pointer magic. Goal here is to set up
2357 * vwv and buf correctly again. The chain offset (the
2358 * former vwv[1]) points at the new wct field.
2361 wct
= CVAL(smb_buf
, chain_offset
);
2363 if (is_andx_req(chain_cmd
) && (wct
< 2)) {
2368 * Next consistency check: Make the new vwv array fits
2369 * in the overall smb request.
2372 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2373 if (length_needed
> smblen
) {
2376 vwv
= (const uint16_t *)(smb_buf
+ chain_offset
+ 1);
2379 * Now grab the new byte buffer....
2382 num_bytes
= SVAL(vwv
+wct
, 0);
2385 * .. and check that it fits.
2388 length_needed
+= num_bytes
;
2389 if (length_needed
> smblen
) {
2392 bytes
= (const uint8_t *)(vwv
+wct
+1);
2394 if (!fn(chain_cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2398 if (!is_andx_req(chain_cmd
)) {
2401 chain_cmd
= CVAL(vwv
, 0);
2406 static bool smb1_chain_length_cb(uint8_t cmd
,
2407 uint8_t wct
, const uint16_t *vwv
,
2408 uint16_t num_bytes
, const uint8_t *bytes
,
2411 unsigned *count
= (unsigned *)private_data
;
2416 unsigned smb1_chain_length(const uint8_t *buf
)
2420 if (!smb1_walk_chain(buf
, smb1_chain_length_cb
, &count
)) {
2426 struct smb1_parse_chain_state
{
2427 TALLOC_CTX
*mem_ctx
;
2429 struct smbd_server_connection
*sconn
;
2430 struct smbXsrv_connection
*xconn
;
2434 struct smb_request
**reqs
;
2438 static bool smb1_parse_chain_cb(uint8_t cmd
,
2439 uint8_t wct
, const uint16_t *vwv
,
2440 uint16_t num_bytes
, const uint8_t *bytes
,
2443 struct smb1_parse_chain_state
*state
=
2444 (struct smb1_parse_chain_state
*)private_data
;
2445 struct smb_request
**reqs
;
2446 struct smb_request
*req
;
2449 reqs
= talloc_realloc(state
->mem_ctx
, state
->reqs
,
2450 struct smb_request
*, state
->num_reqs
+1);
2456 req
= talloc(reqs
, struct smb_request
);
2461 ok
= init_smb_request(req
, state
->sconn
, state
->xconn
, state
->buf
, 0,
2462 state
->encrypted
, state
->seqnum
);
2469 req
->buflen
= num_bytes
;
2472 reqs
[state
->num_reqs
] = req
;
2473 state
->num_reqs
+= 1;
2477 bool smb1_parse_chain(TALLOC_CTX
*mem_ctx
, const uint8_t *buf
,
2478 struct smbXsrv_connection
*xconn
,
2479 bool encrypted
, uint32_t seqnum
,
2480 struct smb_request
***reqs
, unsigned *num_reqs
)
2482 struct smbd_server_connection
*sconn
= NULL
;
2483 struct smb1_parse_chain_state state
;
2486 if (xconn
!= NULL
) {
2487 sconn
= xconn
->client
->sconn
;
2490 state
.mem_ctx
= mem_ctx
;
2492 state
.sconn
= sconn
;
2493 state
.xconn
= xconn
;
2494 state
.encrypted
= encrypted
;
2495 state
.seqnum
= seqnum
;
2499 if (!smb1_walk_chain(buf
, smb1_parse_chain_cb
, &state
)) {
2500 TALLOC_FREE(state
.reqs
);
2503 for (i
=0; i
<state
.num_reqs
; i
++) {
2504 state
.reqs
[i
]->chain
= state
.reqs
;
2507 *num_reqs
= state
.num_reqs
;
2511 /****************************************************************************
2512 Check if services need reloading.
2513 ****************************************************************************/
2515 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2518 if (last_smb_conf_reload_time
== 0) {
2519 last_smb_conf_reload_time
= t
;
2522 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2523 reload_services(sconn
, conn_snum_used
, true);
2524 last_smb_conf_reload_time
= t
;
2528 static bool fd_is_readable(int fd
)
2532 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2534 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2538 static void smbd_server_connection_write_handler(
2539 struct smbXsrv_connection
*xconn
)
2541 /* TODO: make write nonblocking */
2544 static void smbd_server_connection_read_handler(
2545 struct smbXsrv_connection
*xconn
, int fd
)
2547 uint8_t *inbuf
= NULL
;
2548 size_t inbuf_len
= 0;
2549 size_t unread_bytes
= 0;
2550 bool encrypted
= false;
2551 TALLOC_CTX
*mem_ctx
= talloc_tos();
2555 bool async_echo
= lp_async_smb_echo_handler();
2556 bool from_client
= false;
2559 if (fd_is_readable(xconn
->smb1
.echo_handler
.trusted_fd
)) {
2561 * This is the super-ugly hack to prefer the packets
2562 * forwarded by the echo handler over the ones by the
2565 fd
= xconn
->smb1
.echo_handler
.trusted_fd
;
2569 from_client
= (xconn
->transport
.sock
== fd
);
2571 if (async_echo
&& from_client
) {
2572 smbd_lock_socket(xconn
);
2574 if (!fd_is_readable(fd
)) {
2575 DEBUG(10,("the echo listener was faster\n"));
2576 smbd_unlock_socket(xconn
);
2581 /* TODO: make this completely nonblocking */
2582 status
= receive_smb_talloc(mem_ctx
, xconn
, fd
,
2583 (char **)(void *)&inbuf
,
2587 &inbuf_len
, &seqnum
,
2588 !from_client
/* trusted channel */);
2590 if (async_echo
&& from_client
) {
2591 smbd_unlock_socket(xconn
);
2594 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2597 if (NT_STATUS_IS_ERR(status
)) {
2598 exit_server_cleanly("failed to receive smb request");
2600 if (!NT_STATUS_IS_OK(status
)) {
2605 process_smb(xconn
, inbuf
, inbuf_len
, unread_bytes
,
2606 seqnum
, encrypted
, NULL
);
2609 static void smbd_server_connection_handler(struct tevent_context
*ev
,
2610 struct tevent_fd
*fde
,
2614 struct smbXsrv_connection
*xconn
=
2615 talloc_get_type_abort(private_data
,
2616 struct smbXsrv_connection
);
2618 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2620 * we're not supposed to do any io
2622 TEVENT_FD_NOT_READABLE(xconn
->transport
.fde
);
2623 TEVENT_FD_NOT_WRITEABLE(xconn
->transport
.fde
);
2627 if (flags
& TEVENT_FD_WRITE
) {
2628 smbd_server_connection_write_handler(xconn
);
2631 if (flags
& TEVENT_FD_READ
) {
2632 smbd_server_connection_read_handler(xconn
, xconn
->transport
.sock
);
2637 static void smbd_server_echo_handler(struct tevent_context
*ev
,
2638 struct tevent_fd
*fde
,
2642 struct smbXsrv_connection
*xconn
=
2643 talloc_get_type_abort(private_data
,
2644 struct smbXsrv_connection
);
2646 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2648 * we're not supposed to do any io
2650 TEVENT_FD_NOT_READABLE(xconn
->smb1
.echo_handler
.trusted_fde
);
2651 TEVENT_FD_NOT_WRITEABLE(xconn
->smb1
.echo_handler
.trusted_fde
);
2655 if (flags
& TEVENT_FD_WRITE
) {
2656 smbd_server_connection_write_handler(xconn
);
2659 if (flags
& TEVENT_FD_READ
) {
2660 smbd_server_connection_read_handler(
2661 xconn
, xconn
->smb1
.echo_handler
.trusted_fd
);
2666 struct smbd_release_ip_state
{
2667 struct smbXsrv_connection
*xconn
;
2668 struct tevent_immediate
*im
;
2669 char addr
[INET6_ADDRSTRLEN
];
2672 static void smbd_release_ip_immediate(struct tevent_context
*ctx
,
2673 struct tevent_immediate
*im
,
2676 struct smbd_release_ip_state
*state
=
2677 talloc_get_type_abort(private_data
,
2678 struct smbd_release_ip_state
);
2679 struct smbXsrv_connection
*xconn
= state
->xconn
;
2681 if (!NT_STATUS_EQUAL(xconn
->transport
.status
, NT_STATUS_ADDRESS_CLOSED
)) {
2683 * smbd_server_connection_terminate() already triggered ?
2688 smbd_server_connection_terminate(xconn
, "CTDB_SRVID_RELEASE_IP");
2691 /****************************************************************************
2692 received when we should release a specific IP
2693 ****************************************************************************/
2694 static int release_ip(struct tevent_context
*ev
,
2695 uint32_t src_vnn
, uint32_t dst_vnn
,
2697 const uint8_t *msg
, size_t msglen
,
2700 struct smbd_release_ip_state
*state
=
2701 talloc_get_type_abort(private_data
,
2702 struct smbd_release_ip_state
);
2703 struct smbXsrv_connection
*xconn
= state
->xconn
;
2705 const char *addr
= state
->addr
;
2706 const char *p
= addr
;
2711 if (msg
[msglen
-1] != '\0') {
2715 ip
= (const char *)msg
;
2717 if (!NT_STATUS_IS_OK(xconn
->transport
.status
)) {
2718 /* avoid recursion */
2722 if (strncmp("::ffff:", addr
, 7) == 0) {
2726 DEBUG(10, ("Got release IP message for %s, "
2727 "our address is %s\n", ip
, p
));
2729 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2730 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2733 * With SMB2 we should do a clean disconnect,
2734 * the previous_session_id in the session setup
2735 * will cleanup the old session, tcons and opens.
2737 * A clean disconnect is needed in order to support
2740 * Note: typically this is never triggered
2741 * as we got a TCP RST (triggered by ctdb event scripts)
2742 * before we get CTDB_SRVID_RELEASE_IP.
2744 * We used to call _exit(1) here, but as this was mostly never
2745 * triggered and has implication on our process model,
2746 * we can just use smbd_server_connection_terminate()
2749 * We don't call smbd_server_connection_terminate() directly
2750 * as we might be called from within ctdbd_migrate(),
2751 * we need to defer our action to the next event loop
2753 tevent_schedule_immediate(state
->im
, xconn
->ev_ctx
,
2754 smbd_release_ip_immediate
, state
);
2757 * Make sure we don't get any io on the connection.
2759 xconn
->transport
.status
= NT_STATUS_ADDRESS_CLOSED
;
2760 return EADDRNOTAVAIL
;
2766 static NTSTATUS
smbd_register_ips(struct smbXsrv_connection
*xconn
,
2767 struct sockaddr_storage
*srv
,
2768 struct sockaddr_storage
*clnt
)
2770 struct smbd_release_ip_state
*state
;
2771 struct ctdbd_connection
*cconn
;
2774 cconn
= messaging_ctdb_connection();
2775 if (cconn
== NULL
) {
2776 return NT_STATUS_NO_MEMORY
;
2779 state
= talloc_zero(xconn
, struct smbd_release_ip_state
);
2780 if (state
== NULL
) {
2781 return NT_STATUS_NO_MEMORY
;
2783 state
->xconn
= xconn
;
2784 state
->im
= tevent_create_immediate(state
);
2785 if (state
->im
== NULL
) {
2786 return NT_STATUS_NO_MEMORY
;
2788 if (print_sockaddr(state
->addr
, sizeof(state
->addr
), srv
) == NULL
) {
2789 return NT_STATUS_NO_MEMORY
;
2792 ret
= ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, state
);
2794 return map_nt_error_from_unix(ret
);
2796 return NT_STATUS_OK
;
2799 static void msg_kill_client_ip(struct messaging_context
*msg_ctx
,
2800 void *private_data
, uint32_t msg_type
,
2801 struct server_id server_id
, DATA_BLOB
*data
)
2803 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2804 private_data
, struct smbd_server_connection
);
2805 const char *ip
= (char *) data
->data
;
2808 DBG_DEBUG("Got kill request for client IP %s\n", ip
);
2810 client_ip
= tsocket_address_inet_addr_string(sconn
->remote_address
,
2812 if (client_ip
== NULL
) {
2816 if (strequal(ip
, client_ip
)) {
2817 DBG_WARNING("Got kill client message for %s - "
2818 "exiting immediately\n", ip
);
2819 exit_server_cleanly("Forced disconnect for client");
2822 TALLOC_FREE(client_ip
);
2826 * Send keepalive packets to our client
2828 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2830 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2831 private_data
, struct smbd_server_connection
);
2832 struct smbXsrv_connection
*xconn
= NULL
;
2835 if (sconn
->using_smb2
) {
2836 /* Don't do keepalives on an SMB2 connection. */
2841 * With SMB1 we only have 1 connection
2843 xconn
= sconn
->client
->connections
;
2844 smbd_lock_socket(xconn
);
2845 ret
= send_keepalive(xconn
->transport
.sock
);
2846 smbd_unlock_socket(xconn
);
2849 int saved_errno
= errno
;
2851 * Try and give an error message saying what
2854 DEBUG(0, ("send_keepalive failed for client %s. "
2855 "Error %s - exiting\n",
2856 smbXsrv_connection_dbg(xconn
),
2857 strerror(saved_errno
)));
2858 errno
= saved_errno
;
2865 * Do the recurring check if we're idle
2867 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2869 struct smbd_server_connection
*sconn
=
2870 (struct smbd_server_connection
*)private_data
;
2872 if ((conn_num_open(sconn
) == 0)
2873 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2874 DEBUG( 2, ( "Closing idle connection\n" ) );
2875 messaging_send(sconn
->msg_ctx
,
2876 messaging_server_id(sconn
->msg_ctx
),
2877 MSG_SHUTDOWN
, &data_blob_null
);
2885 * Do the recurring log file and smb.conf reload checks.
2888 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2890 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2891 private_data
, struct smbd_server_connection
);
2893 DEBUG(5, ("housekeeping\n"));
2895 change_to_root_user();
2897 /* update printer queue caches if necessary */
2898 update_monitored_printq_cache(sconn
->msg_ctx
);
2900 /* check if we need to reload services */
2901 check_reload(sconn
, time_mono(NULL
));
2904 * Force a log file check.
2906 force_check_log_size();
2912 * Read an smb packet in the echo handler child, giving the parent
2913 * smbd one second to react once the socket becomes readable.
2916 struct smbd_echo_read_state
{
2917 struct tevent_context
*ev
;
2918 struct smbXsrv_connection
*xconn
;
2925 static void smbd_echo_read_readable(struct tevent_req
*subreq
);
2926 static void smbd_echo_read_waited(struct tevent_req
*subreq
);
2928 static struct tevent_req
*smbd_echo_read_send(
2929 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2930 struct smbXsrv_connection
*xconn
)
2932 struct tevent_req
*req
, *subreq
;
2933 struct smbd_echo_read_state
*state
;
2935 req
= tevent_req_create(mem_ctx
, &state
,
2936 struct smbd_echo_read_state
);
2941 state
->xconn
= xconn
;
2943 subreq
= wait_for_read_send(state
, ev
, xconn
->transport
.sock
, false);
2944 if (tevent_req_nomem(subreq
, req
)) {
2945 return tevent_req_post(req
, ev
);
2947 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2951 static void smbd_echo_read_readable(struct tevent_req
*subreq
)
2953 struct tevent_req
*req
= tevent_req_callback_data(
2954 subreq
, struct tevent_req
);
2955 struct smbd_echo_read_state
*state
= tevent_req_data(
2956 req
, struct smbd_echo_read_state
);
2960 ok
= wait_for_read_recv(subreq
, &err
);
2961 TALLOC_FREE(subreq
);
2963 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
2968 * Give the parent smbd one second to step in
2971 subreq
= tevent_wakeup_send(
2972 state
, state
->ev
, timeval_current_ofs(1, 0));
2973 if (tevent_req_nomem(subreq
, req
)) {
2976 tevent_req_set_callback(subreq
, smbd_echo_read_waited
, req
);
2979 static void smbd_echo_read_waited(struct tevent_req
*subreq
)
2981 struct tevent_req
*req
= tevent_req_callback_data(
2982 subreq
, struct tevent_req
);
2983 struct smbd_echo_read_state
*state
= tevent_req_data(
2984 req
, struct smbd_echo_read_state
);
2985 struct smbXsrv_connection
*xconn
= state
->xconn
;
2991 ok
= tevent_wakeup_recv(subreq
);
2992 TALLOC_FREE(subreq
);
2994 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2998 ok
= smbd_lock_socket_internal(xconn
);
3000 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
3001 DEBUG(0, ("%s: failed to lock socket\n", __location__
));
3005 if (!fd_is_readable(xconn
->transport
.sock
)) {
3006 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3009 ok
= smbd_unlock_socket_internal(xconn
);
3011 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
3012 DEBUG(1, ("%s: failed to unlock socket\n",
3017 subreq
= wait_for_read_send(state
, state
->ev
,
3018 xconn
->transport
.sock
, false);
3019 if (tevent_req_nomem(subreq
, req
)) {
3022 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
3026 status
= receive_smb_talloc(state
, xconn
,
3027 xconn
->transport
.sock
,
3034 false /* trusted_channel*/);
3036 if (tevent_req_nterror(req
, status
)) {
3037 tevent_req_nterror(req
, status
);
3038 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3039 (int)getpid(), nt_errstr(status
)));
3043 ok
= smbd_unlock_socket_internal(xconn
);
3045 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
3046 DEBUG(1, ("%s: failed to unlock socket\n", __location__
));
3049 tevent_req_done(req
);
3052 static NTSTATUS
smbd_echo_read_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
3053 char **pbuf
, size_t *pbuflen
, uint32_t *pseqnum
)
3055 struct smbd_echo_read_state
*state
= tevent_req_data(
3056 req
, struct smbd_echo_read_state
);
3059 if (tevent_req_is_nterror(req
, &status
)) {
3062 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
3063 *pbuflen
= state
->buflen
;
3064 *pseqnum
= state
->seqnum
;
3065 return NT_STATUS_OK
;
3068 struct smbd_echo_state
{
3069 struct tevent_context
*ev
;
3070 struct iovec
*pending
;
3071 struct smbd_server_connection
*sconn
;
3072 struct smbXsrv_connection
*xconn
;
3075 struct tevent_fd
*parent_fde
;
3077 struct tevent_req
*write_req
;
3080 static void smbd_echo_writer_done(struct tevent_req
*req
);
3082 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
3086 if (state
->write_req
!= NULL
) {
3090 num_pending
= talloc_array_length(state
->pending
);
3091 if (num_pending
== 0) {
3095 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
3096 state
->parent_pipe
, false,
3097 state
->pending
, num_pending
);
3098 if (state
->write_req
== NULL
) {
3099 DEBUG(1, ("writev_send failed\n"));
3103 talloc_steal(state
->write_req
, state
->pending
);
3104 state
->pending
= NULL
;
3106 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
3110 static void smbd_echo_writer_done(struct tevent_req
*req
)
3112 struct smbd_echo_state
*state
= tevent_req_callback_data(
3113 req
, struct smbd_echo_state
);
3117 written
= writev_recv(req
, &err
);
3119 state
->write_req
= NULL
;
3120 if (written
== -1) {
3121 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
3124 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3125 smbd_echo_activate_writer(state
);
3128 static bool smbd_echo_reply(struct smbd_echo_state
*state
,
3129 uint8_t *inbuf
, size_t inbuf_len
,
3132 struct smb_request req
;
3133 uint16_t num_replies
;
3137 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == NBSSkeepalive
)) {
3138 DEBUG(10, ("Got netbios keepalive\n"));
3145 if (inbuf_len
< smb_size
) {
3146 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
3149 if (!valid_smb_header(inbuf
)) {
3150 DEBUG(10, ("Got invalid SMB header\n"));
3154 if (!init_smb_request(&req
, state
->sconn
, state
->xconn
, inbuf
, 0, false,
3160 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
3161 smb_messages
[req
.cmd
].name
3162 ? smb_messages
[req
.cmd
].name
: "unknown"));
3164 if (req
.cmd
!= SMBecho
) {
3171 num_replies
= SVAL(req
.vwv
+0, 0);
3172 if (num_replies
!= 1) {
3173 /* Not a Windows "Hey, you're still there?" request */
3177 if (!create_outbuf(talloc_tos(), &req
, req
.inbuf
, &outbuf
,
3179 DEBUG(10, ("create_outbuf failed\n"));
3182 req
.outbuf
= (uint8_t *)outbuf
;
3184 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
3186 if (req
.buflen
> 0) {
3187 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
3190 ok
= srv_send_smb(req
.xconn
,
3194 TALLOC_FREE(outbuf
);
3202 static void smbd_echo_exit(struct tevent_context
*ev
,
3203 struct tevent_fd
*fde
, uint16_t flags
,
3206 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3210 static void smbd_echo_got_packet(struct tevent_req
*req
);
3212 static void smbd_echo_loop(struct smbXsrv_connection
*xconn
,
3215 struct smbd_echo_state
*state
;
3216 struct tevent_req
*read_req
;
3218 state
= talloc_zero(xconn
, struct smbd_echo_state
);
3219 if (state
== NULL
) {
3220 DEBUG(1, ("talloc failed\n"));
3223 state
->xconn
= xconn
;
3224 state
->parent_pipe
= parent_pipe
;
3225 state
->ev
= samba_tevent_context_init(state
);
3226 if (state
->ev
== NULL
) {
3227 DEBUG(1, ("samba_tevent_context_init failed\n"));
3231 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
3232 TEVENT_FD_READ
, smbd_echo_exit
,
3234 if (state
->parent_fde
== NULL
) {
3235 DEBUG(1, ("tevent_add_fd failed\n"));
3240 read_req
= smbd_echo_read_send(state
, state
->ev
, xconn
);
3241 if (read_req
== NULL
) {
3242 DEBUG(1, ("smbd_echo_read_send failed\n"));
3246 tevent_req_set_callback(read_req
, smbd_echo_got_packet
, state
);
3249 if (tevent_loop_once(state
->ev
) == -1) {
3250 DEBUG(1, ("tevent_loop_once failed: %s\n",
3258 static void smbd_echo_got_packet(struct tevent_req
*req
)
3260 struct smbd_echo_state
*state
= tevent_req_callback_data(
3261 req
, struct smbd_echo_state
);
3265 uint32_t seqnum
= 0;
3268 status
= smbd_echo_read_recv(req
, state
, &buf
, &buflen
, &seqnum
);
3270 if (!NT_STATUS_IS_OK(status
)) {
3271 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3272 nt_errstr(status
)));
3276 reply
= smbd_echo_reply(state
, (uint8_t *)buf
, buflen
, seqnum
);
3282 num_pending
= talloc_array_length(state
->pending
);
3283 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
3286 DEBUG(1, ("talloc_realloc failed\n"));
3289 state
->pending
= tmp
;
3291 if (buflen
>= smb_size
) {
3293 * place the seqnum in the packet so that the main process
3294 * can reply with signing
3296 SIVAL(buf
, smb_ss_field
, seqnum
);
3297 SIVAL(buf
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
3300 iov
= &state
->pending
[num_pending
];
3301 iov
->iov_base
= talloc_move(state
->pending
, &buf
);
3302 iov
->iov_len
= buflen
;
3304 DEBUG(10,("echo_handler[%d]: forward to main\n",
3306 smbd_echo_activate_writer(state
);
3309 req
= smbd_echo_read_send(state
, state
->ev
, state
->xconn
);
3311 DEBUG(1, ("smbd_echo_read_send failed\n"));
3314 tevent_req_set_callback(req
, smbd_echo_got_packet
, state
);
3319 * Handle SMBecho requests in a forked child process
3321 bool fork_echo_handler(struct smbXsrv_connection
*xconn
)
3323 int listener_pipe
[2];
3326 bool use_mutex
= false;
3328 res
= pipe(listener_pipe
);
3330 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
3334 #ifdef HAVE_ROBUST_MUTEXES
3335 use_mutex
= tdb_runtime_check_for_robust_mutexes();
3338 pthread_mutexattr_t a
;
3340 xconn
->smb1
.echo_handler
.socket_mutex
=
3341 anonymous_shared_allocate(sizeof(pthread_mutex_t
));
3342 if (xconn
->smb1
.echo_handler
.socket_mutex
== NULL
) {
3343 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3348 res
= pthread_mutexattr_init(&a
);
3350 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3354 res
= pthread_mutexattr_settype(&a
, PTHREAD_MUTEX_ERRORCHECK
);
3356 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3358 pthread_mutexattr_destroy(&a
);
3361 res
= pthread_mutexattr_setpshared(&a
, PTHREAD_PROCESS_SHARED
);
3363 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3365 pthread_mutexattr_destroy(&a
);
3368 res
= pthread_mutexattr_setrobust(&a
, PTHREAD_MUTEX_ROBUST
);
3370 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3371 "%s\n", strerror(res
)));
3372 pthread_mutexattr_destroy(&a
);
3375 res
= pthread_mutex_init(xconn
->smb1
.echo_handler
.socket_mutex
,
3377 pthread_mutexattr_destroy(&a
);
3379 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3387 xconn
->smb1
.echo_handler
.socket_lock_fd
=
3388 create_unlink_tmp(lp_lock_directory());
3389 if (xconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
3390 DEBUG(1, ("Could not create lock fd: %s\n",
3400 close(listener_pipe
[0]);
3401 set_blocking(listener_pipe
[1], false);
3403 status
= smbd_reinit_after_fork(xconn
->msg_ctx
, xconn
->ev_ctx
,
3405 if (!NT_STATUS_IS_OK(status
)) {
3406 DEBUG(1, ("reinit_after_fork failed: %s\n",
3407 nt_errstr(status
)));
3410 initialize_password_db(true, xconn
->ev_ctx
);
3411 smbd_echo_loop(xconn
, listener_pipe
[1]);
3414 close(listener_pipe
[1]);
3415 listener_pipe
[1] = -1;
3416 xconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
3418 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child
));
3421 * Without smb signing this is the same as the normal smbd
3422 * listener. This needs to change once signing comes in.
3424 xconn
->smb1
.echo_handler
.trusted_fde
= tevent_add_fd(xconn
->ev_ctx
,
3426 xconn
->smb1
.echo_handler
.trusted_fd
,
3428 smbd_server_echo_handler
,
3430 if (xconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
3431 DEBUG(1, ("event_add_fd failed\n"));
3438 if (listener_pipe
[0] != -1) {
3439 close(listener_pipe
[0]);
3441 if (listener_pipe
[1] != -1) {
3442 close(listener_pipe
[1]);
3444 if (xconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
3445 close(xconn
->smb1
.echo_handler
.socket_lock_fd
);
3447 #ifdef HAVE_ROBUST_MUTEXES
3448 if (xconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
3449 pthread_mutex_destroy(xconn
->smb1
.echo_handler
.socket_mutex
);
3450 anonymous_shared_free(xconn
->smb1
.echo_handler
.socket_mutex
);
3453 smbd_echo_init(xconn
);
3458 static bool uid_in_use(const struct user_struct
*user
, uid_t uid
)
3461 if (user
->session_info
&&
3462 (user
->session_info
->unix_token
->uid
== uid
)) {
3470 static bool gid_in_use(const struct user_struct
*user
, gid_t gid
)
3473 if (user
->session_info
!= NULL
) {
3475 struct security_unix_token
*utok
;
3477 utok
= user
->session_info
->unix_token
;
3478 if (utok
->gid
== gid
) {
3481 for(i
=0; i
<utok
->ngroups
; i
++) {
3482 if (utok
->groups
[i
] == gid
) {
3492 static bool sid_in_use(const struct user_struct
*user
,
3493 const struct dom_sid
*psid
)
3496 struct security_token
*tok
;
3498 if (user
->session_info
== NULL
) {
3501 tok
= user
->session_info
->security_token
;
3504 * Not sure session_info->security_token can
3505 * ever be NULL. This check might be not
3510 if (security_token_has_sid(tok
, psid
)) {
3518 static bool id_in_use(const struct user_struct
*user
,
3519 const struct id_cache_ref
*id
)
3523 return uid_in_use(user
, id
->id
.uid
);
3525 return gid_in_use(user
, id
->id
.gid
);
3527 return sid_in_use(user
, &id
->id
.sid
);
3534 static void smbd_id_cache_kill(struct messaging_context
*msg_ctx
,
3537 struct server_id server_id
,
3540 const char *msg
= (data
&& data
->data
)
3541 ? (const char *)data
->data
: "<NULL>";
3542 struct id_cache_ref id
;
3543 struct smbd_server_connection
*sconn
=
3544 talloc_get_type_abort(private_data
,
3545 struct smbd_server_connection
);
3547 if (!id_cache_ref_parse(msg
, &id
)) {
3548 DEBUG(0, ("Invalid ?ID: %s\n", msg
));
3552 if (id_in_use(sconn
->users
, &id
)) {
3553 exit_server_cleanly(msg
);
3555 id_cache_delete_from_cache(&id
);
3558 NTSTATUS
smbXsrv_connection_init_tables(struct smbXsrv_connection
*conn
,
3559 enum protocol_types protocol
)
3563 conn
->protocol
= protocol
;
3565 if (conn
->client
->session_table
!= NULL
) {
3566 return NT_STATUS_OK
;
3569 if (protocol
>= PROTOCOL_SMB2_02
) {
3570 status
= smb2srv_session_table_init(conn
);
3571 if (!NT_STATUS_IS_OK(status
)) {
3572 conn
->protocol
= PROTOCOL_NONE
;
3576 status
= smb2srv_open_table_init(conn
);
3577 if (!NT_STATUS_IS_OK(status
)) {
3578 conn
->protocol
= PROTOCOL_NONE
;
3582 status
= smb1srv_session_table_init(conn
);
3583 if (!NT_STATUS_IS_OK(status
)) {
3584 conn
->protocol
= PROTOCOL_NONE
;
3588 status
= smb1srv_tcon_table_init(conn
);
3589 if (!NT_STATUS_IS_OK(status
)) {
3590 conn
->protocol
= PROTOCOL_NONE
;
3594 status
= smb1srv_open_table_init(conn
);
3595 if (!NT_STATUS_IS_OK(status
)) {
3596 conn
->protocol
= PROTOCOL_NONE
;
3601 set_Protocol(protocol
);
3602 return NT_STATUS_OK
;
3605 struct smbd_tevent_trace_state
{
3606 struct tevent_context
*ev
;
3608 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle
);
3611 static void smbd_tevent_trace_callback(enum tevent_trace_point point
,
3614 struct smbd_tevent_trace_state
*state
=
3615 (struct smbd_tevent_trace_state
*)private_data
;
3618 case TEVENT_TRACE_BEFORE_WAIT
:
3619 if (!smbprofile_dump_pending()) {
3621 * If there's no dump pending
3622 * we don't want to schedule a new 1 sec timer.
3624 * Instead we want to sleep as long as nothing happens.
3626 smbprofile_dump_setup(NULL
);
3628 SMBPROFILE_BASIC_ASYNC_START(idle
, profile_p
, state
->profile_idle
);
3630 case TEVENT_TRACE_AFTER_WAIT
:
3631 SMBPROFILE_BASIC_ASYNC_END(state
->profile_idle
);
3632 if (!smbprofile_dump_pending()) {
3634 * We need to flush our state after sleeping
3635 * (hopefully a long time).
3639 * future profiling events should trigger timers
3640 * on our main event context.
3642 smbprofile_dump_setup(state
->ev
);
3645 case TEVENT_TRACE_BEFORE_LOOP_ONCE
:
3646 TALLOC_FREE(state
->frame
);
3647 state
->frame
= talloc_stackframe_pool(8192);
3649 case TEVENT_TRACE_AFTER_LOOP_ONCE
:
3650 TALLOC_FREE(state
->frame
);
3658 * Create a debug string for the connection
3660 * This is allocated to talloc_tos() or a string constant
3661 * in certain corner cases. The returned string should
3662 * hence not be free'd directly but only via the talloc stack.
3664 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection
*xconn
)
3669 * TODO: this can be improved later
3670 * maybe including the client guid or more
3672 ret
= tsocket_address_string(xconn
->remote_address
, talloc_tos());
3674 return "<tsocket_address_string() failed>";
3680 NTSTATUS
smbd_add_connection(struct smbXsrv_client
*client
, int sock_fd
,
3681 struct smbXsrv_connection
**_xconn
)
3683 TALLOC_CTX
*frame
= talloc_stackframe();
3684 struct smbXsrv_connection
*xconn
;
3685 struct sockaddr_storage ss_srv
;
3686 void *sp_srv
= (void *)&ss_srv
;
3687 struct sockaddr
*sa_srv
= (struct sockaddr
*)sp_srv
;
3688 struct sockaddr_storage ss_clnt
;
3689 void *sp_clnt
= (void *)&ss_clnt
;
3690 struct sockaddr
*sa_clnt
= (struct sockaddr
*)sp_clnt
;
3691 socklen_t sa_socklen
;
3692 struct tsocket_address
*local_address
= NULL
;
3693 struct tsocket_address
*remote_address
= NULL
;
3694 const char *remaddr
= NULL
;
3696 const char *rhost
= NULL
;
3702 DO_PROFILE_INC(connect
);
3704 xconn
= talloc_zero(client
, struct smbXsrv_connection
);
3705 if (xconn
== NULL
) {
3706 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3708 return NT_STATUS_NO_MEMORY
;
3710 talloc_steal(frame
, xconn
);
3712 xconn
->ev_ctx
= client
->ev_ctx
;
3713 xconn
->msg_ctx
= client
->msg_ctx
;
3714 xconn
->transport
.sock
= sock_fd
;
3715 smbd_echo_init(xconn
);
3716 xconn
->protocol
= PROTOCOL_NONE
;
3718 /* Ensure child is set to blocking mode */
3719 set_blocking(sock_fd
,True
);
3721 set_socket_options(sock_fd
, "SO_KEEPALIVE");
3722 set_socket_options(sock_fd
, lp_socket_options());
3724 sa_socklen
= sizeof(ss_clnt
);
3725 ret
= getpeername(sock_fd
, sa_clnt
, &sa_socklen
);
3727 int saved_errno
= errno
;
3728 int level
= (errno
== ENOTCONN
)?2:0;
3729 DEBUG(level
,("getpeername() failed - %s\n",
3730 strerror(saved_errno
)));
3732 return map_nt_error_from_unix_common(saved_errno
);
3734 ret
= tsocket_address_bsd_from_sockaddr(xconn
,
3735 sa_clnt
, sa_socklen
,
3738 int saved_errno
= errno
;
3739 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3740 __location__
, strerror(saved_errno
)));
3742 return map_nt_error_from_unix_common(saved_errno
);
3745 sa_socklen
= sizeof(ss_srv
);
3746 ret
= getsockname(sock_fd
, sa_srv
, &sa_socklen
);
3748 int saved_errno
= errno
;
3749 int level
= (errno
== ENOTCONN
)?2:0;
3750 DEBUG(level
,("getsockname() failed - %s\n",
3751 strerror(saved_errno
)));
3753 return map_nt_error_from_unix_common(saved_errno
);
3755 ret
= tsocket_address_bsd_from_sockaddr(xconn
,
3759 int saved_errno
= errno
;
3760 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3761 __location__
, strerror(saved_errno
)));
3763 return map_nt_error_from_unix_common(saved_errno
);
3766 if (tsocket_address_is_inet(remote_address
, "ip")) {
3767 remaddr
= tsocket_address_inet_addr_string(remote_address
,
3769 if (remaddr
== NULL
) {
3770 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3771 __location__
, strerror(errno
)));
3773 return NT_STATUS_NO_MEMORY
;
3776 remaddr
= "0.0.0.0";
3780 * Before the first packet, check the global hosts allow/ hosts deny
3781 * parameters before doing any parsing of packets passed to us by the
3782 * client. This prevents attacks on our parsing code from hosts not in
3783 * the hosts allow list.
3786 ret
= get_remote_hostname(remote_address
,
3789 int saved_errno
= errno
;
3790 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3791 __location__
, strerror(saved_errno
)));
3793 return map_nt_error_from_unix_common(saved_errno
);
3796 if (strequal(rhost
, "UNKNOWN")) {
3800 xconn
->local_address
= local_address
;
3801 xconn
->remote_address
= remote_address
;
3802 xconn
->remote_hostname
= talloc_strdup(xconn
, rhost
);
3803 if (xconn
->remote_hostname
== NULL
) {
3804 return NT_STATUS_NO_MEMORY
;
3807 if (!srv_init_signing(xconn
)) {
3808 DEBUG(0, ("Failed to init smb_signing\n"));
3810 return NT_STATUS_INTERNAL_ERROR
;
3813 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3814 xconn
->remote_hostname
,
3816 DEBUG( 1, ("Connection denied from %s to %s\n",
3817 tsocket_address_string(remote_address
, talloc_tos()),
3818 tsocket_address_string(local_address
, talloc_tos())));
3821 * We return a valid xconn
3822 * so that the caller can return an error message
3825 client
->connections
= xconn
;
3826 xconn
->client
= client
;
3827 talloc_steal(client
, xconn
);
3831 return NT_STATUS_NETWORK_ACCESS_DENIED
;
3834 DEBUG(10, ("Connection allowed from %s to %s\n",
3835 tsocket_address_string(remote_address
, talloc_tos()),
3836 tsocket_address_string(local_address
, talloc_tos())));
3838 if (lp_clustering()) {
3840 * We need to tell ctdb about our client's TCP
3841 * connection, so that for failover ctdbd can send
3842 * tickle acks, triggering a reconnection by the
3847 status
= smbd_register_ips(xconn
, &ss_srv
, &ss_clnt
);
3848 if (!NT_STATUS_IS_OK(status
)) {
3849 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3850 nt_errstr(status
)));
3854 tmp
= lp_max_xmit();
3855 tmp
= MAX(tmp
, SMB_BUFFER_SIZE_MIN
);
3856 tmp
= MIN(tmp
, SMB_BUFFER_SIZE_MAX
);
3858 xconn
->smb1
.negprot
.max_recv
= tmp
;
3860 xconn
->smb1
.sessions
.done_sesssetup
= false;
3861 xconn
->smb1
.sessions
.max_send
= SMB_BUFFER_SIZE_MAX
;
3863 xconn
->transport
.fde
= tevent_add_fd(client
->ev_ctx
,
3867 smbd_server_connection_handler
,
3869 if (!xconn
->transport
.fde
) {
3871 return NT_STATUS_NO_MEMORY
;
3874 /* for now we only have one connection */
3875 DLIST_ADD_END(client
->connections
, xconn
);
3876 xconn
->client
= client
;
3877 talloc_steal(client
, xconn
);
3881 return NT_STATUS_OK
;
3884 /****************************************************************************
3885 Process commands from the client
3886 ****************************************************************************/
3888 void smbd_process(struct tevent_context
*ev_ctx
,
3889 struct messaging_context
*msg_ctx
,
3893 struct smbd_tevent_trace_state trace_state
= {
3895 .frame
= talloc_stackframe(),
3897 struct smbXsrv_client
*client
= NULL
;
3898 struct smbd_server_connection
*sconn
= NULL
;
3899 struct smbXsrv_connection
*xconn
= NULL
;
3900 const char *locaddr
= NULL
;
3901 const char *remaddr
= NULL
;
3904 struct timeval tv
= timeval_current();
3905 NTTIME now
= timeval_to_nttime(&tv
);
3906 char *chroot_dir
= NULL
;
3909 status
= smbXsrv_client_create(ev_ctx
, ev_ctx
, msg_ctx
, now
, &client
);
3910 if (!NT_STATUS_IS_OK(status
)) {
3911 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status
));
3912 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3916 * TODO: remove this...:-)
3918 global_smbXsrv_client
= client
;
3920 sconn
= talloc_zero(client
, struct smbd_server_connection
);
3921 if (sconn
== NULL
) {
3922 exit_server("failed to create smbd_server_connection");
3925 client
->sconn
= sconn
;
3926 sconn
->client
= client
;
3928 sconn
->ev_ctx
= ev_ctx
;
3929 sconn
->msg_ctx
= msg_ctx
;
3931 ret
= pthreadpool_tevent_init(sconn
, lp_aio_max_threads(),
3934 exit_server("pthreadpool_tevent_init() failed.");
3937 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02
) {
3939 * We're not making the decision here,
3940 * we're just allowing the client
3941 * to decide between SMB1 and SMB2
3942 * with the first negprot
3945 sconn
->using_smb2
= true;
3949 smbd_setup_sig_term_handler(sconn
);
3950 smbd_setup_sig_hup_handler(sconn
);
3953 status
= smbd_add_connection(client
, sock_fd
, &xconn
);
3954 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3956 * send a negative session response "not listening on calling
3959 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3960 (void)srv_send_smb(xconn
,(char *)buf
, false,
3962 exit_server_cleanly("connection denied");
3963 } else if (!NT_STATUS_IS_OK(status
)) {
3964 exit_server_cleanly(nt_errstr(status
));
3967 sconn
->local_address
=
3968 tsocket_address_copy(xconn
->local_address
, sconn
);
3969 if (sconn
->local_address
== NULL
) {
3970 exit_server_cleanly("tsocket_address_copy() failed");
3972 sconn
->remote_address
=
3973 tsocket_address_copy(xconn
->remote_address
, sconn
);
3974 if (sconn
->remote_address
== NULL
) {
3975 exit_server_cleanly("tsocket_address_copy() failed");
3977 sconn
->remote_hostname
=
3978 talloc_strdup(sconn
, xconn
->remote_hostname
);
3979 if (sconn
->remote_hostname
== NULL
) {
3980 exit_server_cleanly("tsocket_strdup() failed");
3983 if (tsocket_address_is_inet(sconn
->local_address
, "ip")) {
3984 locaddr
= tsocket_address_inet_addr_string(
3985 sconn
->local_address
,
3987 if (locaddr
== NULL
) {
3988 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3989 __location__
, strerror(errno
)));
3990 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3993 locaddr
= "0.0.0.0";
3996 if (tsocket_address_is_inet(sconn
->remote_address
, "ip")) {
3997 remaddr
= tsocket_address_inet_addr_string(
3998 sconn
->remote_address
,
4000 if (remaddr
== NULL
) {
4001 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4002 __location__
, strerror(errno
)));
4003 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4006 remaddr
= "0.0.0.0";
4009 /* this is needed so that we get decent entries
4010 in smbstatus for port 445 connects */
4011 set_remote_machine_name(remaddr
, false);
4012 reload_services(sconn
, conn_snum_used
, true);
4013 sub_set_socket_ids(remaddr
,
4014 sconn
->remote_hostname
,
4017 if (lp_preload_modules()) {
4018 smb_load_all_modules_absoute_path(lp_preload_modules());
4021 smb_perfcount_init();
4023 if (!init_account_policy()) {
4024 exit_server("Could not open account policy tdb.\n");
4027 chroot_dir
= lp_root_directory(talloc_tos());
4028 if (chroot_dir
[0] != '\0') {
4029 rc
= chdir(chroot_dir
);
4031 DBG_ERR("Failed to chdir to %s\n", chroot_dir
);
4032 exit_server("Failed to chdir()");
4035 rc
= chroot(chroot_dir
);
4037 DBG_ERR("Failed to change root to %s\n", chroot_dir
);
4038 exit_server("Failed to chroot()");
4040 DBG_WARNING("Changed root to %s\n", chroot_dir
);
4042 TALLOC_FREE(chroot_dir
);
4045 if (!file_init(sconn
)) {
4046 exit_server("file_init() failed");
4050 if (!init_oplocks(sconn
))
4051 exit_server("Failed to init oplocks");
4053 /* register our message handlers */
4054 messaging_register(sconn
->msg_ctx
, sconn
,
4055 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
4056 messaging_register(sconn
->msg_ctx
, sconn
,
4057 MSG_SMB_CLOSE_FILE
, msg_close_file
);
4058 messaging_register(sconn
->msg_ctx
, sconn
,
4059 MSG_SMB_FILE_RENAME
, msg_file_was_renamed
);
4061 id_cache_register_msgs(sconn
->msg_ctx
);
4062 messaging_deregister(sconn
->msg_ctx
, ID_CACHE_KILL
, NULL
);
4063 messaging_register(sconn
->msg_ctx
, sconn
,
4064 ID_CACHE_KILL
, smbd_id_cache_kill
);
4066 messaging_deregister(sconn
->msg_ctx
,
4067 MSG_SMB_CONF_UPDATED
, sconn
->ev_ctx
);
4068 messaging_register(sconn
->msg_ctx
, sconn
,
4069 MSG_SMB_CONF_UPDATED
, smbd_conf_updated
);
4071 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_KILL_CLIENT_IP
,
4073 messaging_register(sconn
->msg_ctx
, sconn
,
4074 MSG_SMB_KILL_CLIENT_IP
,
4075 msg_kill_client_ip
);
4077 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_TELL_NUM_CHILDREN
, NULL
);
4080 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4081 * MSGs to all child processes
4083 messaging_deregister(sconn
->msg_ctx
,
4085 messaging_register(sconn
->msg_ctx
, NULL
,
4086 MSG_DEBUG
, debug_message
);
4088 if ((lp_keepalive() != 0)
4089 && !(event_add_idle(ev_ctx
, NULL
,
4090 timeval_set(lp_keepalive(), 0),
4091 "keepalive", keepalive_fn
,
4093 DEBUG(0, ("Could not add keepalive event\n"));
4097 if (!(event_add_idle(ev_ctx
, NULL
,
4098 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
4099 "deadtime", deadtime_fn
, sconn
))) {
4100 DEBUG(0, ("Could not add deadtime event\n"));
4104 if (!(event_add_idle(ev_ctx
, NULL
,
4105 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
4106 "housekeeping", housekeeping_fn
, sconn
))) {
4107 DEBUG(0, ("Could not add housekeeping event\n"));
4111 smbprofile_dump_setup(ev_ctx
);
4113 if (!init_dptrs(sconn
)) {
4114 exit_server("init_dptrs() failed");
4117 TALLOC_FREE(trace_state
.frame
);
4119 tevent_set_trace_callback(ev_ctx
, smbd_tevent_trace_callback
,
4122 ret
= tevent_loop_wait(ev_ctx
);
4124 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4125 " exiting\n", ret
, strerror(errno
)));
4128 TALLOC_FREE(trace_state
.frame
);
4130 exit_server_cleanly(NULL
);
4133 bool req_is_in_chain(const struct smb_request
*req
)
4135 if (req
->vwv
!= (const uint16_t *)(req
->inbuf
+smb_vwv
)) {
4137 * We're right now handling a subsequent request, so we must
4143 if (!is_andx_req(req
->cmd
)) {
4149 * Okay, an illegal request, but definitely not chained :-)
4154 return (CVAL(req
->vwv
+0, 0) != 0xFF);