2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
43 #include "system/threads.h"
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list
{
47 struct pending_message_list
*next
, *prev
;
48 struct timeval request_time
; /* When was this first issued? */
49 struct smbd_server_connection
*sconn
;
50 struct tevent_timer
*te
;
51 struct smb_perfcount_data pcd
;
56 struct deferred_open_record
*open_rec
;
59 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
61 static struct pending_message_list
*get_deferred_open_message_smb(
62 struct smbd_server_connection
*sconn
, uint64_t mid
);
63 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
);
65 void smbd_echo_init(struct smbd_server_connection
*sconn
)
67 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
68 sconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
69 #ifdef HAVE_ROBUST_MUTEXES
70 sconn
->smb1
.echo_handler
.socket_mutex
= NULL
;
74 static bool smbd_echo_active(struct smbd_server_connection
*sconn
)
76 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
80 #ifdef HAVE_ROBUST_MUTEXES
81 if (sconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
89 static bool smbd_lock_socket_internal(struct smbd_server_connection
*sconn
)
91 if (!smbd_echo_active(sconn
)) {
95 sconn
->smb1
.echo_handler
.ref_count
++;
97 if (sconn
->smb1
.echo_handler
.ref_count
> 1) {
101 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
103 #ifdef HAVE_ROBUST_MUTEXES
104 if (sconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
107 while (ret
== EINTR
) {
108 ret
= pthread_mutex_lock(
109 sconn
->smb1
.echo_handler
.socket_mutex
);
115 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
122 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
127 sconn
->smb1
.echo_handler
.socket_lock_fd
,
128 F_SETLKW
, 0, 0, F_WRLCK
);
129 } while (!ok
&& (errno
== EINTR
));
132 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
137 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
142 void smbd_lock_socket(struct smbd_server_connection
*sconn
)
144 if (!smbd_lock_socket_internal(sconn
)) {
145 exit_server_cleanly("failed to lock socket");
149 static bool smbd_unlock_socket_internal(struct smbd_server_connection
*sconn
)
151 if (!smbd_echo_active(sconn
)) {
155 sconn
->smb1
.echo_handler
.ref_count
--;
157 if (sconn
->smb1
.echo_handler
.ref_count
> 0) {
161 #ifdef HAVE_ROBUST_MUTEXES
162 if (sconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
165 while (ret
== EINTR
) {
166 ret
= pthread_mutex_unlock(
167 sconn
->smb1
.echo_handler
.socket_mutex
);
173 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
180 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
185 sconn
->smb1
.echo_handler
.socket_lock_fd
,
186 F_SETLKW
, 0, 0, F_UNLCK
);
187 } while (!ok
&& (errno
== EINTR
));
190 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
195 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
200 void smbd_unlock_socket(struct smbd_server_connection
*sconn
)
202 if (!smbd_unlock_socket_internal(sconn
)) {
203 exit_server_cleanly("failed to unlock socket");
207 /* Accessor function for smb_read_error for smbd functions. */
209 /****************************************************************************
211 ****************************************************************************/
213 bool srv_send_smb(struct smbd_server_connection
*sconn
, char *buffer
,
214 bool do_signing
, uint32_t seqnum
,
216 struct smb_perfcount_data
*pcd
)
220 char *buf_out
= buffer
;
222 if (!NT_STATUS_IS_OK(sconn
->status
)) {
224 * we're not supposed to do any io
229 smbd_lock_socket(sconn
);
232 /* Sign the outgoing packet if required. */
233 srv_calculate_sign_mac(sconn
, buf_out
, seqnum
);
237 NTSTATUS status
= srv_encrypt_buffer(sconn
, buffer
, &buf_out
);
238 if (!NT_STATUS_IS_OK(status
)) {
239 DEBUG(0, ("send_smb: SMB encryption failed "
240 "on outgoing packet! Error %s\n",
241 nt_errstr(status
) ));
247 len
= smb_len_large(buf_out
) + 4;
249 ret
= write_data(sconn
->sock
, buf_out
, len
);
252 char addr
[INET6_ADDRSTRLEN
];
254 * Try and give an error message saying what
257 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
258 (int)getpid(), (int)len
,
259 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
260 (int)ret
, strerror(errno
) ));
262 srv_free_enc_buffer(sconn
, buf_out
);
266 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
267 srv_free_enc_buffer(sconn
, buf_out
);
269 SMB_PERFCOUNT_END(pcd
);
271 smbd_unlock_socket(sconn
);
275 /*******************************************************************
276 Setup the word count and byte count for a smb message.
277 ********************************************************************/
279 int srv_set_message(char *buf
,
284 if (zero
&& (num_words
|| num_bytes
)) {
285 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
287 SCVAL(buf
,smb_wct
,num_words
);
288 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
289 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
290 return (smb_size
+ num_words
*2 + num_bytes
);
293 static bool valid_smb_header(struct smbd_server_connection
*sconn
,
294 const uint8_t *inbuf
)
296 if (is_encrypted_packet(sconn
, inbuf
)) {
300 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
301 * but it just looks weird to call strncmp for this one.
303 return (IVAL(smb_base(inbuf
), 0) == 0x424D53FF);
306 /* Socket functions for smbd packet processing. */
308 static bool valid_packet_size(size_t len
)
311 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
312 * of header. Don't print the error if this fits.... JRA.
315 if (len
> (LARGE_WRITEX_BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
316 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
317 (unsigned long)len
));
323 static NTSTATUS
read_packet_remainder(int fd
, char *buffer
,
324 unsigned int timeout
, ssize_t len
)
332 status
= read_fd_with_timeout(fd
, buffer
, len
, len
, timeout
, NULL
);
333 if (!NT_STATUS_IS_OK(status
)) {
334 char addr
[INET6_ADDRSTRLEN
];
335 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
337 get_peer_addr(fd
, addr
, sizeof(addr
)),
343 /****************************************************************************
344 Attempt a zerocopy writeX read. We know here that len > smb_size-4
345 ****************************************************************************/
348 * Unfortunately, earlier versions of smbclient/libsmbclient
349 * don't send this "standard" writeX header. I've fixed this
350 * for 3.2 but we'll use the old method with earlier versions.
351 * Windows and CIFSFS at least use this standard size. Not
355 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
356 (2*14) + /* word count (including bcc) */ \
359 static NTSTATUS
receive_smb_raw_talloc_partial_read(TALLOC_CTX
*mem_ctx
,
360 const char lenbuf
[4],
361 struct smbd_server_connection
*sconn
,
364 unsigned int timeout
,
368 /* Size of a WRITEX call (+4 byte len). */
369 char writeX_header
[4 + STANDARD_WRITE_AND_X_HEADER_SIZE
];
370 ssize_t len
= smb_len_large(lenbuf
); /* Could be a UNIX large writeX. */
374 memcpy(writeX_header
, lenbuf
, 4);
376 status
= read_fd_with_timeout(
377 sock
, writeX_header
+ 4,
378 STANDARD_WRITE_AND_X_HEADER_SIZE
,
379 STANDARD_WRITE_AND_X_HEADER_SIZE
,
382 if (!NT_STATUS_IS_OK(status
)) {
383 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
385 tsocket_address_string(sconn
->remote_address
,
392 * Ok - now try and see if this is a possible
396 if (is_valid_writeX_buffer(sconn
, (uint8_t *)writeX_header
)) {
398 * If the data offset is beyond what
399 * we've read, drain the extra bytes.
401 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
404 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
405 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
406 if (drain_socket(sock
, drain
) != drain
) {
407 smb_panic("receive_smb_raw_talloc_partial_read:"
408 " failed to drain pending bytes");
411 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
414 /* Spoof down the length and null out the bcc. */
415 set_message_bcc(writeX_header
, 0);
416 newlen
= smb_len(writeX_header
);
418 /* Copy the header we've written. */
420 *buffer
= (char *)talloc_memdup(mem_ctx
,
422 sizeof(writeX_header
));
424 if (*buffer
== NULL
) {
425 DEBUG(0, ("Could not allocate inbuf of length %d\n",
426 (int)sizeof(writeX_header
)));
427 return NT_STATUS_NO_MEMORY
;
430 /* Work out the remaining bytes. */
431 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
432 *len_ret
= newlen
+ 4;
436 if (!valid_packet_size(len
)) {
437 return NT_STATUS_INVALID_PARAMETER
;
441 * Not a valid writeX call. Just do the standard
445 *buffer
= talloc_array(mem_ctx
, char, len
+4);
447 if (*buffer
== NULL
) {
448 DEBUG(0, ("Could not allocate inbuf of length %d\n",
450 return NT_STATUS_NO_MEMORY
;
453 /* Copy in what we already read. */
456 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
457 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
460 status
= read_packet_remainder(
462 (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
465 if (!NT_STATUS_IS_OK(status
)) {
466 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
476 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
,
477 struct smbd_server_connection
*sconn
,
479 char **buffer
, unsigned int timeout
,
480 size_t *p_unread
, size_t *plen
)
484 int min_recv_size
= lp_min_receive_file_size();
489 status
= read_smb_length_return_keepalive(sock
, lenbuf
, timeout
,
491 if (!NT_STATUS_IS_OK(status
)) {
495 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
496 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
497 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
498 !srv_is_signing_active(sconn
) &&
499 sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
501 return receive_smb_raw_talloc_partial_read(
502 mem_ctx
, lenbuf
, sconn
, sock
, buffer
, timeout
,
506 if (!valid_packet_size(len
)) {
507 return NT_STATUS_INVALID_PARAMETER
;
511 * The +4 here can't wrap, we've checked the length above already.
514 *buffer
= talloc_array(mem_ctx
, char, len
+4);
516 if (*buffer
== NULL
) {
517 DEBUG(0, ("Could not allocate inbuf of length %d\n",
519 return NT_STATUS_NO_MEMORY
;
522 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
524 status
= read_packet_remainder(sock
, (*buffer
)+4, timeout
, len
);
525 if (!NT_STATUS_IS_OK(status
)) {
533 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
,
534 struct smbd_server_connection
*sconn
,
536 char **buffer
, unsigned int timeout
,
537 size_t *p_unread
, bool *p_encrypted
,
540 bool trusted_channel
)
545 *p_encrypted
= false;
547 status
= receive_smb_raw_talloc(mem_ctx
, sconn
, sock
, buffer
, timeout
,
549 if (!NT_STATUS_IS_OK(status
)) {
550 DEBUG(NT_STATUS_EQUAL(status
, NT_STATUS_END_OF_FILE
)?5:1,
551 ("receive_smb_raw_talloc failed for client %s "
552 "read error = %s.\n",
553 tsocket_address_string(sconn
->remote_address
,
555 nt_errstr(status
)) );
559 if (is_encrypted_packet(sconn
, (uint8_t *)*buffer
)) {
560 status
= srv_decrypt_buffer(sconn
, *buffer
);
561 if (!NT_STATUS_IS_OK(status
)) {
562 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
563 "incoming packet! Error %s\n",
564 nt_errstr(status
) ));
570 /* Check the incoming SMB signature. */
571 if (!srv_check_sign_mac(sconn
, *buffer
, seqnum
, trusted_channel
)) {
572 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
573 "incoming packet!\n"));
574 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
582 * Initialize a struct smb_request from an inbuf
585 static bool init_smb_request(struct smb_request
*req
,
586 struct smbd_server_connection
*sconn
,
588 size_t unread_bytes
, bool encrypted
,
591 struct smbXsrv_tcon
*tcon
;
594 size_t req_size
= smb_len(inbuf
) + 4;
596 /* Ensure we have at least smb_size bytes. */
597 if (req_size
< smb_size
) {
598 DEBUG(0,("init_smb_request: invalid request size %u\n",
599 (unsigned int)req_size
));
603 req
->request_time
= timeval_current();
604 now
= timeval_to_nttime(&req
->request_time
);
606 req
->cmd
= CVAL(inbuf
, smb_com
);
607 req
->flags2
= SVAL(inbuf
, smb_flg2
);
608 req
->smbpid
= SVAL(inbuf
, smb_pid
);
609 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
610 req
->seqnum
= seqnum
;
611 req
->vuid
= SVAL(inbuf
, smb_uid
);
612 req
->tid
= SVAL(inbuf
, smb_tid
);
613 req
->wct
= CVAL(inbuf
, smb_wct
);
614 req
->vwv
= (const uint16_t *)(inbuf
+smb_vwv
);
615 req
->buflen
= smb_buflen(inbuf
);
616 req
->buf
= (const uint8_t *)smb_buf_const(inbuf
);
617 req
->unread_bytes
= unread_bytes
;
618 req
->encrypted
= encrypted
;
620 status
= smb1srv_tcon_lookup(sconn
->conn
, req
->tid
, now
, &tcon
);
621 if (NT_STATUS_IS_OK(status
)) {
622 req
->conn
= tcon
->compat
;
626 req
->chain_fsp
= NULL
;
628 req
->priv_paths
= NULL
;
630 smb_init_perfcount_data(&req
->pcd
);
632 /* Ensure we have at least wct words and 2 bytes of bcc. */
633 if (smb_size
+ req
->wct
*2 > req_size
) {
634 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
635 (unsigned int)req
->wct
,
636 (unsigned int)req_size
));
639 /* Ensure bcc is correct. */
640 if (((const uint8_t *)smb_buf_const(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
641 DEBUG(0,("init_smb_request: invalid bcc number %u "
642 "(wct = %u, size %u)\n",
643 (unsigned int)req
->buflen
,
644 (unsigned int)req
->wct
,
645 (unsigned int)req_size
));
653 static void process_smb(struct smbd_server_connection
*conn
,
654 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
655 uint32_t seqnum
, bool encrypted
,
656 struct smb_perfcount_data
*deferred_pcd
);
658 static void smbd_deferred_open_timer(struct tevent_context
*ev
,
659 struct tevent_timer
*te
,
660 struct timeval _tval
,
663 struct pending_message_list
*msg
= talloc_get_type(private_data
,
664 struct pending_message_list
);
665 struct smbd_server_connection
*sconn
= msg
->sconn
;
666 TALLOC_CTX
*mem_ctx
= talloc_tos();
667 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
670 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
673 exit_server("smbd_deferred_open_timer: talloc failed\n");
677 /* We leave this message on the queue so the open code can
678 know this is a retry. */
679 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
680 (unsigned long long)mid
));
682 /* Mark the message as processed so this is not
683 * re-processed in error. */
684 msg
->processed
= true;
686 process_smb(sconn
, inbuf
,
688 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
690 /* If it's still there and was processed, remove it. */
691 msg
= get_deferred_open_message_smb(sconn
, mid
);
692 if (msg
&& msg
->processed
) {
693 remove_deferred_open_message_smb(sconn
, mid
);
697 /****************************************************************************
698 Function to push a message onto the tail of a linked list of smb messages ready
700 ****************************************************************************/
702 static bool push_queued_message(struct smb_request
*req
,
703 struct timeval request_time
,
704 struct timeval end_time
,
705 struct deferred_open_record
*open_rec
)
707 int msg_len
= smb_len(req
->inbuf
) + 4;
708 struct pending_message_list
*msg
;
710 msg
= talloc_zero(NULL
, struct pending_message_list
);
713 DEBUG(0,("push_message: malloc fail (1)\n"));
716 msg
->sconn
= req
->sconn
;
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
,
749 struct pending_message_list
*);
751 DEBUG(10,("push_message: pushed message length %u on "
752 "deferred_open_queue\n", (unsigned int)msg_len
));
757 /****************************************************************************
758 Function to delete a sharing violation open message by mid.
759 ****************************************************************************/
761 void remove_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
764 struct pending_message_list
*pml
;
766 if (sconn
->using_smb2
) {
767 remove_deferred_open_message_smb2(sconn
, 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 smbd_server_connection
*sconn
,
792 struct pending_message_list
*pml
;
795 if (sconn
->using_smb2
) {
796 return schedule_deferred_open_message_smb2(sconn
, mid
);
799 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
800 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
802 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
805 (unsigned long long)msg_mid
));
807 if (mid
== msg_mid
) {
808 struct tevent_timer
*te
;
810 if (pml
->processed
) {
811 /* A processed message should not be
813 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
814 "message mid %llu was already processed\n",
815 (unsigned long long)msg_mid
));
819 DEBUG(10,("schedule_deferred_open_message_smb: "
820 "scheduling mid %llu\n",
821 (unsigned long long)mid
));
823 te
= tevent_add_timer(pml
->sconn
->ev_ctx
,
826 smbd_deferred_open_timer
,
829 DEBUG(10,("schedule_deferred_open_message_smb: "
830 "event_add_timed() failed, "
831 "skipping mid %llu\n",
832 (unsigned long long)msg_mid
));
835 TALLOC_FREE(pml
->te
);
837 DLIST_PROMOTE(sconn
->deferred_open_queue
, pml
);
842 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
843 "find message mid %llu\n",
844 (unsigned long long)mid
));
849 /****************************************************************************
850 Return true if this mid is on the deferred queue and was not yet processed.
851 ****************************************************************************/
853 bool open_was_deferred(struct smbd_server_connection
*sconn
, uint64_t mid
)
855 struct pending_message_list
*pml
;
857 if (sconn
->using_smb2
) {
858 return open_was_deferred_smb2(sconn
, mid
);
861 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
862 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
869 /****************************************************************************
870 Return the message queued by this mid.
871 ****************************************************************************/
873 static struct pending_message_list
*get_deferred_open_message_smb(
874 struct smbd_server_connection
*sconn
, uint64_t mid
)
876 struct pending_message_list
*pml
;
878 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
879 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
886 /****************************************************************************
887 Get the state data queued by this mid.
888 ****************************************************************************/
890 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
891 struct timeval
*p_request_time
,
892 struct deferred_open_record
**open_rec
)
894 struct pending_message_list
*pml
;
896 if (smbreq
->sconn
->using_smb2
) {
897 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
902 pml
= get_deferred_open_message_smb(smbreq
->sconn
, smbreq
->mid
);
906 if (p_request_time
) {
907 *p_request_time
= pml
->request_time
;
909 if (open_rec
!= NULL
) {
910 *open_rec
= pml
->open_rec
;
915 /****************************************************************************
916 Function to push a deferred open smb message onto a linked list of local smb
917 messages ready for processing.
918 ****************************************************************************/
920 bool push_deferred_open_message_smb(struct smb_request
*req
,
921 struct timeval request_time
,
922 struct timeval timeout
,
924 struct deferred_open_record
*open_rec
)
926 struct timeval end_time
;
929 return push_deferred_open_message_smb2(req
->smb2req
,
936 if (req
->unread_bytes
) {
937 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
938 "unread_bytes = %u\n",
939 (unsigned int)req
->unread_bytes
));
940 smb_panic("push_deferred_open_message_smb: "
941 "logic error unread_bytes != 0" );
944 end_time
= timeval_sum(&request_time
, &timeout
);
946 DEBUG(10,("push_deferred_open_message_smb: pushing message "
947 "len %u mid %llu timeout time [%u.%06u]\n",
948 (unsigned int) smb_len(req
->inbuf
)+4,
949 (unsigned long long)req
->mid
,
950 (unsigned int)end_time
.tv_sec
,
951 (unsigned int)end_time
.tv_usec
));
953 return push_queued_message(req
, request_time
, end_time
, open_rec
);
956 static void smbd_sig_term_handler(struct tevent_context
*ev
,
957 struct tevent_signal
*se
,
963 exit_server_cleanly("termination signal");
966 void smbd_setup_sig_term_handler(struct smbd_server_connection
*sconn
)
968 struct tevent_signal
*se
;
970 se
= tevent_add_signal(sconn
->ev_ctx
,
973 smbd_sig_term_handler
,
976 exit_server("failed to setup SIGTERM handler");
980 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
981 struct tevent_signal
*se
,
987 struct smbd_server_connection
*sconn
=
988 talloc_get_type_abort(private_data
,
989 struct smbd_server_connection
);
991 change_to_root_user();
992 DEBUG(1,("Reloading services after SIGHUP\n"));
993 reload_services(sconn
, conn_snum_used
, false);
996 void smbd_setup_sig_hup_handler(struct smbd_server_connection
*sconn
)
998 struct tevent_signal
*se
;
1000 se
= tevent_add_signal(sconn
->ev_ctx
,
1003 smbd_sig_hup_handler
,
1006 exit_server("failed to setup SIGHUP handler");
1010 static void smbd_conf_updated(struct messaging_context
*msg
,
1013 struct server_id server_id
,
1016 struct smbd_server_connection
*sconn
=
1017 talloc_get_type_abort(private_data
,
1018 struct smbd_server_connection
);
1020 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1021 "updated. Reloading.\n"));
1022 change_to_root_user();
1023 reload_services(sconn
, conn_snum_used
, false);
1027 * Only allow 5 outstanding trans requests. We're allocating memory, so
1031 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
1034 for (; list
!= NULL
; list
= list
->next
) {
1036 if (list
->mid
== mid
) {
1037 return NT_STATUS_INVALID_PARAMETER
;
1043 return NT_STATUS_INSUFFICIENT_RESOURCES
;
1046 return NT_STATUS_OK
;
1050 These flags determine some of the permissions required to do an operation
1052 Note that I don't set NEED_WRITE on some write operations because they
1053 are used by some brain-dead clients when printing, and I don't want to
1054 force write permissions on print services.
1056 #define AS_USER (1<<0)
1057 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1058 #define TIME_INIT (1<<2)
1059 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1060 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1061 #define DO_CHDIR (1<<6)
1064 define a list of possible SMB messages and their corresponding
1065 functions. Any message that has a NULL function is unimplemented -
1066 please feel free to contribute implementations!
1068 static const struct smb_message_struct
{
1070 void (*fn
)(struct smb_request
*req
);
1072 } smb_messages
[256] = {
1074 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1075 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1076 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1077 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1078 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1079 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1080 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1081 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1082 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1083 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1084 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1085 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1086 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1087 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1088 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1089 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1090 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1091 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1092 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1093 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1094 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1095 /* 0x15 */ { NULL
, NULL
, 0 },
1096 /* 0x16 */ { NULL
, NULL
, 0 },
1097 /* 0x17 */ { NULL
, NULL
, 0 },
1098 /* 0x18 */ { NULL
, NULL
, 0 },
1099 /* 0x19 */ { NULL
, NULL
, 0 },
1100 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1101 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1102 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1103 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1104 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1105 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1106 /* 0x20 */ { "SMBwritec", NULL
,0},
1107 /* 0x21 */ { NULL
, NULL
, 0 },
1108 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1109 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1110 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1111 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1112 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1113 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1114 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1115 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1116 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1117 /* 0x2b */ { "SMBecho",reply_echo
,0},
1118 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1119 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1120 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1121 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1122 /* 0x30 */ { NULL
, NULL
, 0 },
1123 /* 0x31 */ { NULL
, NULL
, 0 },
1124 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1125 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1126 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1127 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1128 /* 0x36 */ { NULL
, NULL
, 0 },
1129 /* 0x37 */ { NULL
, NULL
, 0 },
1130 /* 0x38 */ { NULL
, NULL
, 0 },
1131 /* 0x39 */ { NULL
, NULL
, 0 },
1132 /* 0x3a */ { NULL
, NULL
, 0 },
1133 /* 0x3b */ { NULL
, NULL
, 0 },
1134 /* 0x3c */ { NULL
, NULL
, 0 },
1135 /* 0x3d */ { NULL
, NULL
, 0 },
1136 /* 0x3e */ { NULL
, NULL
, 0 },
1137 /* 0x3f */ { NULL
, NULL
, 0 },
1138 /* 0x40 */ { NULL
, NULL
, 0 },
1139 /* 0x41 */ { NULL
, NULL
, 0 },
1140 /* 0x42 */ { NULL
, NULL
, 0 },
1141 /* 0x43 */ { NULL
, NULL
, 0 },
1142 /* 0x44 */ { NULL
, NULL
, 0 },
1143 /* 0x45 */ { NULL
, NULL
, 0 },
1144 /* 0x46 */ { NULL
, NULL
, 0 },
1145 /* 0x47 */ { NULL
, NULL
, 0 },
1146 /* 0x48 */ { NULL
, NULL
, 0 },
1147 /* 0x49 */ { NULL
, NULL
, 0 },
1148 /* 0x4a */ { NULL
, NULL
, 0 },
1149 /* 0x4b */ { NULL
, NULL
, 0 },
1150 /* 0x4c */ { NULL
, NULL
, 0 },
1151 /* 0x4d */ { NULL
, NULL
, 0 },
1152 /* 0x4e */ { NULL
, NULL
, 0 },
1153 /* 0x4f */ { NULL
, NULL
, 0 },
1154 /* 0x50 */ { NULL
, NULL
, 0 },
1155 /* 0x51 */ { NULL
, NULL
, 0 },
1156 /* 0x52 */ { NULL
, NULL
, 0 },
1157 /* 0x53 */ { NULL
, NULL
, 0 },
1158 /* 0x54 */ { NULL
, NULL
, 0 },
1159 /* 0x55 */ { NULL
, NULL
, 0 },
1160 /* 0x56 */ { NULL
, NULL
, 0 },
1161 /* 0x57 */ { NULL
, NULL
, 0 },
1162 /* 0x58 */ { NULL
, NULL
, 0 },
1163 /* 0x59 */ { NULL
, NULL
, 0 },
1164 /* 0x5a */ { NULL
, NULL
, 0 },
1165 /* 0x5b */ { NULL
, NULL
, 0 },
1166 /* 0x5c */ { NULL
, NULL
, 0 },
1167 /* 0x5d */ { NULL
, NULL
, 0 },
1168 /* 0x5e */ { NULL
, NULL
, 0 },
1169 /* 0x5f */ { NULL
, NULL
, 0 },
1170 /* 0x60 */ { NULL
, NULL
, 0 },
1171 /* 0x61 */ { NULL
, NULL
, 0 },
1172 /* 0x62 */ { NULL
, NULL
, 0 },
1173 /* 0x63 */ { NULL
, NULL
, 0 },
1174 /* 0x64 */ { NULL
, NULL
, 0 },
1175 /* 0x65 */ { NULL
, NULL
, 0 },
1176 /* 0x66 */ { NULL
, NULL
, 0 },
1177 /* 0x67 */ { NULL
, NULL
, 0 },
1178 /* 0x68 */ { NULL
, NULL
, 0 },
1179 /* 0x69 */ { NULL
, NULL
, 0 },
1180 /* 0x6a */ { NULL
, NULL
, 0 },
1181 /* 0x6b */ { NULL
, NULL
, 0 },
1182 /* 0x6c */ { NULL
, NULL
, 0 },
1183 /* 0x6d */ { NULL
, NULL
, 0 },
1184 /* 0x6e */ { NULL
, NULL
, 0 },
1185 /* 0x6f */ { NULL
, NULL
, 0 },
1186 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1187 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1188 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1189 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1190 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1191 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1192 /* 0x76 */ { NULL
, NULL
, 0 },
1193 /* 0x77 */ { NULL
, NULL
, 0 },
1194 /* 0x78 */ { NULL
, NULL
, 0 },
1195 /* 0x79 */ { NULL
, NULL
, 0 },
1196 /* 0x7a */ { NULL
, NULL
, 0 },
1197 /* 0x7b */ { NULL
, NULL
, 0 },
1198 /* 0x7c */ { NULL
, NULL
, 0 },
1199 /* 0x7d */ { NULL
, NULL
, 0 },
1200 /* 0x7e */ { NULL
, NULL
, 0 },
1201 /* 0x7f */ { NULL
, NULL
, 0 },
1202 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1203 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1204 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1205 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1206 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1207 /* 0x85 */ { NULL
, NULL
, 0 },
1208 /* 0x86 */ { NULL
, NULL
, 0 },
1209 /* 0x87 */ { NULL
, NULL
, 0 },
1210 /* 0x88 */ { NULL
, NULL
, 0 },
1211 /* 0x89 */ { NULL
, NULL
, 0 },
1212 /* 0x8a */ { NULL
, NULL
, 0 },
1213 /* 0x8b */ { NULL
, NULL
, 0 },
1214 /* 0x8c */ { NULL
, NULL
, 0 },
1215 /* 0x8d */ { NULL
, NULL
, 0 },
1216 /* 0x8e */ { NULL
, NULL
, 0 },
1217 /* 0x8f */ { NULL
, NULL
, 0 },
1218 /* 0x90 */ { NULL
, NULL
, 0 },
1219 /* 0x91 */ { NULL
, NULL
, 0 },
1220 /* 0x92 */ { NULL
, NULL
, 0 },
1221 /* 0x93 */ { NULL
, NULL
, 0 },
1222 /* 0x94 */ { NULL
, NULL
, 0 },
1223 /* 0x95 */ { NULL
, NULL
, 0 },
1224 /* 0x96 */ { NULL
, NULL
, 0 },
1225 /* 0x97 */ { NULL
, NULL
, 0 },
1226 /* 0x98 */ { NULL
, NULL
, 0 },
1227 /* 0x99 */ { NULL
, NULL
, 0 },
1228 /* 0x9a */ { NULL
, NULL
, 0 },
1229 /* 0x9b */ { NULL
, NULL
, 0 },
1230 /* 0x9c */ { NULL
, NULL
, 0 },
1231 /* 0x9d */ { NULL
, NULL
, 0 },
1232 /* 0x9e */ { NULL
, NULL
, 0 },
1233 /* 0x9f */ { NULL
, NULL
, 0 },
1234 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1235 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1236 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1237 /* 0xa3 */ { NULL
, NULL
, 0 },
1238 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1239 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1240 /* 0xa6 */ { NULL
, NULL
, 0 },
1241 /* 0xa7 */ { NULL
, NULL
, 0 },
1242 /* 0xa8 */ { NULL
, NULL
, 0 },
1243 /* 0xa9 */ { NULL
, NULL
, 0 },
1244 /* 0xaa */ { NULL
, NULL
, 0 },
1245 /* 0xab */ { NULL
, NULL
, 0 },
1246 /* 0xac */ { NULL
, NULL
, 0 },
1247 /* 0xad */ { NULL
, NULL
, 0 },
1248 /* 0xae */ { NULL
, NULL
, 0 },
1249 /* 0xaf */ { NULL
, NULL
, 0 },
1250 /* 0xb0 */ { NULL
, NULL
, 0 },
1251 /* 0xb1 */ { NULL
, NULL
, 0 },
1252 /* 0xb2 */ { NULL
, NULL
, 0 },
1253 /* 0xb3 */ { NULL
, NULL
, 0 },
1254 /* 0xb4 */ { NULL
, NULL
, 0 },
1255 /* 0xb5 */ { NULL
, NULL
, 0 },
1256 /* 0xb6 */ { NULL
, NULL
, 0 },
1257 /* 0xb7 */ { NULL
, NULL
, 0 },
1258 /* 0xb8 */ { NULL
, NULL
, 0 },
1259 /* 0xb9 */ { NULL
, NULL
, 0 },
1260 /* 0xba */ { NULL
, NULL
, 0 },
1261 /* 0xbb */ { NULL
, NULL
, 0 },
1262 /* 0xbc */ { NULL
, NULL
, 0 },
1263 /* 0xbd */ { NULL
, NULL
, 0 },
1264 /* 0xbe */ { NULL
, NULL
, 0 },
1265 /* 0xbf */ { NULL
, NULL
, 0 },
1266 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1267 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1268 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1269 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1270 /* 0xc4 */ { NULL
, NULL
, 0 },
1271 /* 0xc5 */ { NULL
, NULL
, 0 },
1272 /* 0xc6 */ { NULL
, NULL
, 0 },
1273 /* 0xc7 */ { NULL
, NULL
, 0 },
1274 /* 0xc8 */ { NULL
, NULL
, 0 },
1275 /* 0xc9 */ { NULL
, NULL
, 0 },
1276 /* 0xca */ { NULL
, NULL
, 0 },
1277 /* 0xcb */ { NULL
, NULL
, 0 },
1278 /* 0xcc */ { NULL
, NULL
, 0 },
1279 /* 0xcd */ { NULL
, NULL
, 0 },
1280 /* 0xce */ { NULL
, NULL
, 0 },
1281 /* 0xcf */ { NULL
, NULL
, 0 },
1282 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1283 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1284 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1285 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1286 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1287 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1288 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1289 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1290 /* 0xd8 */ { NULL
, NULL
, 0 },
1291 /* 0xd9 */ { NULL
, NULL
, 0 },
1292 /* 0xda */ { NULL
, NULL
, 0 },
1293 /* 0xdb */ { NULL
, NULL
, 0 },
1294 /* 0xdc */ { NULL
, NULL
, 0 },
1295 /* 0xdd */ { NULL
, NULL
, 0 },
1296 /* 0xde */ { NULL
, NULL
, 0 },
1297 /* 0xdf */ { NULL
, NULL
, 0 },
1298 /* 0xe0 */ { NULL
, NULL
, 0 },
1299 /* 0xe1 */ { NULL
, NULL
, 0 },
1300 /* 0xe2 */ { NULL
, NULL
, 0 },
1301 /* 0xe3 */ { NULL
, NULL
, 0 },
1302 /* 0xe4 */ { NULL
, NULL
, 0 },
1303 /* 0xe5 */ { NULL
, NULL
, 0 },
1304 /* 0xe6 */ { NULL
, NULL
, 0 },
1305 /* 0xe7 */ { NULL
, NULL
, 0 },
1306 /* 0xe8 */ { NULL
, NULL
, 0 },
1307 /* 0xe9 */ { NULL
, NULL
, 0 },
1308 /* 0xea */ { NULL
, NULL
, 0 },
1309 /* 0xeb */ { NULL
, NULL
, 0 },
1310 /* 0xec */ { NULL
, NULL
, 0 },
1311 /* 0xed */ { NULL
, NULL
, 0 },
1312 /* 0xee */ { NULL
, NULL
, 0 },
1313 /* 0xef */ { NULL
, NULL
, 0 },
1314 /* 0xf0 */ { NULL
, NULL
, 0 },
1315 /* 0xf1 */ { NULL
, NULL
, 0 },
1316 /* 0xf2 */ { NULL
, NULL
, 0 },
1317 /* 0xf3 */ { NULL
, NULL
, 0 },
1318 /* 0xf4 */ { NULL
, NULL
, 0 },
1319 /* 0xf5 */ { NULL
, NULL
, 0 },
1320 /* 0xf6 */ { NULL
, NULL
, 0 },
1321 /* 0xf7 */ { NULL
, NULL
, 0 },
1322 /* 0xf8 */ { NULL
, NULL
, 0 },
1323 /* 0xf9 */ { NULL
, NULL
, 0 },
1324 /* 0xfa */ { NULL
, NULL
, 0 },
1325 /* 0xfb */ { NULL
, NULL
, 0 },
1326 /* 0xfc */ { NULL
, NULL
, 0 },
1327 /* 0xfd */ { NULL
, NULL
, 0 },
1328 /* 0xfe */ { NULL
, NULL
, 0 },
1329 /* 0xff */ { NULL
, NULL
, 0 }
1333 /*******************************************************************
1334 allocate and initialize a reply packet
1335 ********************************************************************/
1337 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1338 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1341 size_t smb_len
= MIN_SMB_SIZE
+ VWV(num_words
) + num_bytes
;
1344 * Protect against integer wrap.
1345 * The SMB layer reply can be up to 0xFFFFFF bytes.
1347 if ((num_bytes
> 0xffffff) || (smb_len
> 0xffffff)) {
1349 if (asprintf(&msg
, "num_bytes too large: %u",
1350 (unsigned)num_bytes
) == -1) {
1351 msg
= discard_const_p(char, "num_bytes too large");
1357 * Here we include the NBT header for now.
1359 *outbuf
= talloc_array(mem_ctx
, char,
1360 NBT_HDR_SIZE
+ smb_len
);
1361 if (*outbuf
== NULL
) {
1365 construct_reply_common(req
, inbuf
, *outbuf
);
1366 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1368 * Zero out the word area, the caller has to take care of the bcc area
1371 if (num_words
!= 0) {
1372 memset(*outbuf
+ (NBT_HDR_SIZE
+ HDR_VWV
), 0, VWV(num_words
));
1378 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1381 if (!create_outbuf(req
, req
, (const char *)req
->inbuf
, &outbuf
, num_words
,
1383 smb_panic("could not allocate output buffer\n");
1385 req
->outbuf
= (uint8_t *)outbuf
;
1389 /*******************************************************************
1390 Dump a packet to a file.
1391 ********************************************************************/
1393 static void smb_dump(const char *name
, int type
, const char *data
)
1398 if (DEBUGLEVEL
< 50) {
1402 len
= smb_len_tcp(data
)+4;
1403 for (i
=1;i
<100;i
++) {
1404 fname
= talloc_asprintf(talloc_tos(),
1408 type
? "req" : "resp");
1409 if (fname
== NULL
) {
1412 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1413 if (fd
!= -1 || errno
!= EEXIST
) break;
1417 ssize_t ret
= write(fd
, data
, len
);
1419 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1421 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1426 /****************************************************************************
1427 Prepare everything for calling the actual request function, and potentially
1428 call the request function via the "new" interface.
1430 Return False if the "legacy" function needs to be called, everything is
1433 Return True if we're done.
1435 I know this API sucks, but it is the one with the least code change I could
1437 ****************************************************************************/
1439 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
)
1442 uint64_t session_tag
;
1443 connection_struct
*conn
= NULL
;
1444 struct smbd_server_connection
*sconn
= req
->sconn
;
1445 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1446 struct smbXsrv_session
*session
= NULL
;
1451 if (smb_messages
[type
].fn
== NULL
) {
1452 DEBUG(0,("Unknown message type %d!\n",type
));
1453 smb_dump("Unknown", 1, (const char *)req
->inbuf
);
1454 reply_unknown_new(req
, type
);
1458 flags
= smb_messages
[type
].flags
;
1460 /* In share mode security we must ignore the vuid. */
1461 session_tag
= req
->vuid
;
1464 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1465 (int)getpid(), (unsigned long)conn
));
1467 smb_dump(smb_fn_name(type
), 1, (const char *)req
->inbuf
);
1469 /* Ensure this value is replaced in the incoming packet. */
1470 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_uid
,session_tag
);
1473 * Ensure the correct username is in current_user_info. This is a
1474 * really ugly bugfix for problems with multiple session_setup_and_X's
1475 * being done and allowing %U and %G substitutions to work correctly.
1476 * There is a reason this code is done here, don't move it unless you
1477 * know what you're doing... :-).
1482 * lookup an existing session
1484 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1485 * here, the main check is still in change_to_user()
1487 status
= smb1srv_session_lookup(sconn
->conn
,
1491 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
1494 status
= NT_STATUS_OK
;
1497 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1498 (unsigned long long)session_tag
,
1499 (unsigned long long)req
->mid
));
1500 reply_nterror(req
, NT_STATUS_NETWORK_SESSION_EXPIRED
);
1505 if (session_tag
!= sconn
->conn
->last_session_id
) {
1506 struct user_struct
*vuser
= NULL
;
1508 sconn
->conn
->last_session_id
= session_tag
;
1510 vuser
= session
->compat
;
1513 set_current_user_info(
1514 vuser
->session_info
->unix_info
->sanitized_username
,
1515 vuser
->session_info
->unix_info
->unix_name
,
1516 vuser
->session_info
->info
->domain_name
);
1520 /* Does this call need to be run as the connected user? */
1521 if (flags
& AS_USER
) {
1523 /* Does this call need a valid tree connection? */
1526 * Amazingly, the error code depends on the command
1529 if (type
== SMBntcreateX
) {
1530 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1532 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1537 if (!change_to_user(conn
,session_tag
)) {
1538 DEBUG(0, ("Error: Could not change to user. Removing "
1539 "deferred open, mid=%llu.\n",
1540 (unsigned long long)req
->mid
));
1541 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1545 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1547 /* Does it need write permission? */
1548 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1549 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1553 /* IPC services are limited */
1554 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1555 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1559 /* This call needs to be run as root */
1560 change_to_root_user();
1563 /* load service specific parameters */
1565 if (req
->encrypted
) {
1566 conn
->encrypted_tid
= true;
1567 /* encrypted required from now on. */
1568 conn
->encrypt_level
= SMB_SIGNING_REQUIRED
;
1569 } else if (ENCRYPTION_REQUIRED(conn
)) {
1570 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1571 DEBUG(1,("service[%s] requires encryption"
1572 "%s ACCESS_DENIED. mid=%llu\n",
1573 lp_servicename(talloc_tos(), SNUM(conn
)),
1575 (unsigned long long)req
->mid
));
1576 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1581 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1582 (flags
& (AS_USER
|DO_CHDIR
)
1584 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1587 conn
->num_smb_operations
++;
1591 * Does this protocol need to be run as guest? (Only archane
1592 * messenger service requests have this...)
1594 if (flags
& AS_GUEST
) {
1598 if (!change_to_guest()) {
1599 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1603 raddr
= tsocket_address_inet_addr_string(sconn
->remote_address
,
1605 if (raddr
== NULL
) {
1606 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1611 * Haven't we checked this in smbd_process already???
1614 ok
= allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1615 sconn
->remote_hostname
, raddr
);
1619 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1624 smb_messages
[type
].fn(req
);
1628 /****************************************************************************
1629 Construct a reply to the incoming packet.
1630 ****************************************************************************/
1632 static void construct_reply(struct smbd_server_connection
*sconn
,
1633 char *inbuf
, int size
, size_t unread_bytes
,
1634 uint32_t seqnum
, bool encrypted
,
1635 struct smb_perfcount_data
*deferred_pcd
)
1637 connection_struct
*conn
;
1638 struct smb_request
*req
;
1640 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1641 smb_panic("could not allocate smb_request");
1644 if (!init_smb_request(req
, sconn
, (uint8
*)inbuf
, unread_bytes
,
1645 encrypted
, seqnum
)) {
1646 exit_server_cleanly("Invalid SMB request");
1649 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1651 /* we popped this message off the queue - keep original perf data */
1653 req
->pcd
= *deferred_pcd
;
1655 SMB_PERFCOUNT_START(&req
->pcd
);
1656 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1657 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1660 conn
= switch_message(req
->cmd
, req
);
1662 if (req
->outbuf
== NULL
) {
1666 if (CVAL(req
->outbuf
,0) == 0) {
1667 show_msg((char *)req
->outbuf
);
1670 if (!srv_send_smb(req
->sconn
,
1671 (char *)req
->outbuf
,
1672 true, req
->seqnum
+1,
1673 IS_CONN_ENCRYPTED(conn
)||req
->encrypted
,
1675 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1683 static void construct_reply_chain(struct smbd_server_connection
*sconn
,
1684 char *inbuf
, int size
, uint32_t seqnum
,
1686 struct smb_perfcount_data
*deferred_pcd
)
1688 struct smb_request
**reqs
= NULL
;
1689 struct smb_request
*req
;
1693 ok
= smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf
, sconn
, encrypted
,
1694 seqnum
, &reqs
, &num_reqs
);
1696 char errbuf
[smb_size
];
1697 error_packet(errbuf
, 0, 0, NT_STATUS_INVALID_PARAMETER
,
1698 __LINE__
, __FILE__
);
1699 if (!srv_send_smb(sconn
, errbuf
, true, seqnum
, encrypted
,
1701 exit_server_cleanly("construct_reply_chain: "
1702 "srv_send_smb failed.");
1708 req
->inbuf
= (uint8_t *)talloc_move(reqs
, &inbuf
);
1710 req
->conn
= switch_message(req
->cmd
, req
);
1712 if (req
->outbuf
== NULL
) {
1714 * Request has suspended itself, will come
1719 smb_request_done(req
);
1723 * To be called from an async SMB handler that is potentially chained
1724 * when it is finished for shipping.
1727 void smb_request_done(struct smb_request
*req
)
1729 struct smb_request
**reqs
= NULL
;
1730 struct smb_request
*first_req
;
1731 size_t i
, num_reqs
, next_index
;
1734 if (req
->chain
== NULL
) {
1740 num_reqs
= talloc_array_length(reqs
);
1742 for (i
=0; i
<num_reqs
; i
++) {
1743 if (reqs
[i
] == req
) {
1747 if (i
== num_reqs
) {
1749 * Invalid chain, should not happen
1751 status
= NT_STATUS_INTERNAL_ERROR
;
1756 while ((next_index
< num_reqs
) && (IVAL(req
->outbuf
, smb_rcls
) == 0)) {
1757 struct smb_request
*next
= reqs
[next_index
];
1758 struct smbXsrv_tcon
*tcon
;
1759 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1761 next
->vuid
= SVAL(req
->outbuf
, smb_uid
);
1762 next
->tid
= SVAL(req
->outbuf
, smb_tid
);
1763 status
= smb1srv_tcon_lookup(req
->sconn
->conn
, req
->tid
,
1765 if (NT_STATUS_IS_OK(status
)) {
1766 req
->conn
= tcon
->compat
;
1770 next
->chain_fsp
= req
->chain_fsp
;
1771 next
->inbuf
= req
->inbuf
;
1774 req
->conn
= switch_message(req
->cmd
, req
);
1776 if (req
->outbuf
== NULL
) {
1778 * Request has suspended itself, will come
1786 first_req
= reqs
[0];
1788 for (i
=1; i
<next_index
; i
++) {
1791 ok
= smb_splice_chain(&first_req
->outbuf
, reqs
[i
]->outbuf
);
1793 status
= NT_STATUS_INTERNAL_ERROR
;
1798 SSVAL(first_req
->outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
1799 SSVAL(first_req
->outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
1802 * This scary statement intends to set the
1803 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1804 * to the value last_req->outbuf carries
1806 SSVAL(first_req
->outbuf
, smb_flg2
,
1807 (SVAL(first_req
->outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
1808 |(SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
1811 * Transfer the error codes from the subrequest to the main one
1813 SSVAL(first_req
->outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
1814 SSVAL(first_req
->outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
1817 first_req
->outbuf
, talloc_get_size(first_req
->outbuf
) - 4);
1820 if (!srv_send_smb(first_req
->sconn
,
1821 (char *)first_req
->outbuf
,
1822 true, first_req
->seqnum
+1,
1823 IS_CONN_ENCRYPTED(req
->conn
)||first_req
->encrypted
,
1825 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1828 TALLOC_FREE(req
); /* non-chained case */
1829 TALLOC_FREE(reqs
); /* chained case */
1834 char errbuf
[smb_size
];
1835 error_packet(errbuf
, 0, 0, status
, __LINE__
, __FILE__
);
1836 if (!srv_send_smb(req
->sconn
, errbuf
, true,
1837 req
->seqnum
+1, req
->encrypted
,
1839 exit_server_cleanly("construct_reply_chain: "
1840 "srv_send_smb failed.");
1843 TALLOC_FREE(req
); /* non-chained case */
1844 TALLOC_FREE(reqs
); /* chained case */
1847 /****************************************************************************
1848 Process an smb from the client
1849 ****************************************************************************/
1850 static void process_smb(struct smbd_server_connection
*sconn
,
1851 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1852 uint32_t seqnum
, bool encrypted
,
1853 struct smb_perfcount_data
*deferred_pcd
)
1855 int msg_type
= CVAL(inbuf
,0);
1857 DO_PROFILE_INC(smb_count
);
1859 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1861 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1862 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1864 if (msg_type
!= NBSSmessage
) {
1866 * NetBIOS session request, keepalive, etc.
1868 reply_special(sconn
, (char *)inbuf
, nread
);
1872 if (sconn
->using_smb2
) {
1873 /* At this point we're not really using smb2,
1874 * we make the decision here.. */
1875 if (smbd_is_smb2_header(inbuf
, nread
)) {
1876 smbd_smb2_first_negprot(sconn
, inbuf
, nread
);
1878 } else if (nread
>= smb_size
&& valid_smb_header(sconn
, inbuf
)
1879 && CVAL(inbuf
, smb_com
) != 0x72) {
1880 /* This is a non-negprot SMB1 packet.
1881 Disable SMB2 from now on. */
1882 sconn
->using_smb2
= false;
1886 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1887 * so subtract 4 from it. */
1888 if ((nread
< (smb_size
- 4)) || !valid_smb_header(sconn
, inbuf
)) {
1889 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1892 /* special magic for immediate exit */
1894 (IVAL(inbuf
, 4) == 0x74697865) &&
1895 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1896 uint8_t exitcode
= CVAL(inbuf
, 8);
1897 DEBUG(1, ("Exiting immediately with code %d\n",
1902 exit_server_cleanly("Non-SMB packet");
1905 show_msg((char *)inbuf
);
1907 if ((unread_bytes
== 0) && smb1_is_chain(inbuf
)) {
1908 construct_reply_chain(sconn
, (char *)inbuf
, nread
,
1909 seqnum
, encrypted
, deferred_pcd
);
1911 construct_reply(sconn
, (char *)inbuf
, nread
, unread_bytes
,
1912 seqnum
, encrypted
, deferred_pcd
);
1918 sconn
->num_requests
++;
1920 /* The timeout_processing function isn't run nearly
1921 often enough to implement 'max log size' without
1922 overrunning the size of the file by many megabytes.
1923 This is especially true if we are running at debug
1924 level 10. Checking every 50 SMBs is a nice
1925 tradeoff of performance vs log file size overrun. */
1927 if ((sconn
->num_requests
% 50) == 0 &&
1928 need_to_check_log_size()) {
1929 change_to_root_user();
1934 /****************************************************************************
1935 Return a string containing the function name of a SMB command.
1936 ****************************************************************************/
1938 const char *smb_fn_name(int type
)
1940 const char *unknown_name
= "SMBunknown";
1942 if (smb_messages
[type
].name
== NULL
)
1943 return(unknown_name
);
1945 return(smb_messages
[type
].name
);
1948 /****************************************************************************
1949 Helper functions for contruct_reply.
1950 ****************************************************************************/
1952 void add_to_common_flags2(uint32 v
)
1957 void remove_from_common_flags2(uint32 v
)
1959 common_flags2
&= ~v
;
1962 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1965 uint16_t in_flags2
= SVAL(inbuf
,smb_flg2
);
1966 uint16_t out_flags2
= common_flags2
;
1968 out_flags2
|= in_flags2
& FLAGS2_UNICODE_STRINGS
;
1969 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
;
1970 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
;
1972 srv_set_message(outbuf
,0,0,false);
1974 SCVAL(outbuf
, smb_com
, req
->cmd
);
1975 SIVAL(outbuf
,smb_rcls
,0);
1976 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1977 SSVAL(outbuf
,smb_flg2
, out_flags2
);
1978 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1979 memcpy(outbuf
+smb_ss_field
, inbuf
+smb_ss_field
, 8);
1981 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
1982 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
1983 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
1984 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
1987 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
1989 construct_reply_common(req
, (const char *)req
->inbuf
, outbuf
);
1993 * @brief Find the smb_cmd offset of the last command pushed
1994 * @param[in] buf The buffer we're building up
1995 * @retval Where can we put our next andx cmd?
1997 * While chaining requests, the "next" request we're looking at needs to put
1998 * its SMB_Command before the data the previous request already built up added
1999 * to the chain. Find the offset to the place where we have to put our cmd.
2002 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
2007 cmd
= CVAL(buf
, smb_com
);
2009 if (!is_andx_req(cmd
)) {
2015 while (CVAL(buf
, ofs
) != 0xff) {
2017 if (!is_andx_req(CVAL(buf
, ofs
))) {
2022 * ofs is from start of smb header, so add the 4 length
2023 * bytes. The next cmd is right after the wct field.
2025 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
2027 if (ofs
+4 >= talloc_get_size(buf
)) {
2037 * @brief Do the smb chaining at a buffer level
2038 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2039 * @param[in] andx_buf Buffer to be appended
2042 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
)
2044 uint8_t smb_command
= CVAL(andx_buf
, smb_com
);
2045 uint8_t wct
= CVAL(andx_buf
, smb_wct
);
2046 const uint16_t *vwv
= (const uint16_t *)(andx_buf
+ smb_vwv
);
2047 uint32_t num_bytes
= smb_buflen(andx_buf
);
2048 const uint8_t *bytes
= (const uint8_t *)smb_buf_const(andx_buf
);
2051 size_t old_size
, new_size
;
2053 size_t chain_padding
= 0;
2054 size_t andx_cmd_ofs
;
2057 old_size
= talloc_get_size(*poutbuf
);
2059 if ((old_size
% 4) != 0) {
2061 * Align the wct field of subsequent requests to a 4-byte
2064 chain_padding
= 4 - (old_size
% 4);
2068 * After the old request comes the new wct field (1 byte), the vwv's
2069 * and the num_bytes field.
2072 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
2073 new_size
+= num_bytes
;
2075 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
2076 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2077 (unsigned)new_size
));
2081 outbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, new_size
);
2082 if (outbuf
== NULL
) {
2083 DEBUG(0, ("talloc failed\n"));
2088 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
2089 DEBUG(1, ("invalid command chain\n"));
2090 *poutbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, old_size
);
2094 if (chain_padding
!= 0) {
2095 memset(outbuf
+ old_size
, 0, chain_padding
);
2096 old_size
+= chain_padding
;
2099 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
2100 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
2105 * Push the chained request:
2110 SCVAL(outbuf
, ofs
, wct
);
2117 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
2122 * Read&X has an offset into its data buffer at
2123 * vwv[6]. reply_read_andx has no idea anymore that it's
2124 * running from within a chain, so we have to fix up the
2127 * Although it looks disgusting at this place, I want to keep
2128 * it here. The alternative would be to push knowledge about
2129 * the andx chain down into read&x again.
2132 if (smb_command
== SMBreadX
) {
2133 uint8_t *bytes_addr
;
2137 * Invalid read&x response
2142 bytes_addr
= outbuf
+ ofs
/* vwv start */
2143 + sizeof(uint16_t) * wct
/* vwv array */
2144 + sizeof(uint16_t); /* bcc */
2146 SSVAL(outbuf
+ ofs
, 6 * sizeof(uint16_t),
2147 bytes_addr
- outbuf
- 4);
2150 ofs
+= sizeof(uint16_t) * wct
;
2156 SSVAL(outbuf
, ofs
, num_bytes
);
2157 ofs
+= sizeof(uint16_t);
2163 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
2168 bool smb1_is_chain(const uint8_t *buf
)
2170 uint8_t cmd
, wct
, andx_cmd
;
2172 cmd
= CVAL(buf
, smb_com
);
2173 if (!is_andx_req(cmd
)) {
2176 wct
= CVAL(buf
, smb_wct
);
2180 andx_cmd
= CVAL(buf
, smb_vwv
);
2181 return (andx_cmd
!= 0xFF);
2184 bool smb1_walk_chain(const uint8_t *buf
,
2185 bool (*fn
)(uint8_t cmd
,
2186 uint8_t wct
, const uint16_t *vwv
,
2187 uint16_t num_bytes
, const uint8_t *bytes
,
2188 void *private_data
),
2191 size_t smblen
= smb_len(buf
);
2192 const char *smb_buf
= smb_base(buf
);
2193 uint8_t cmd
, chain_cmd
;
2195 const uint16_t *vwv
;
2197 const uint8_t *bytes
;
2199 cmd
= CVAL(buf
, smb_com
);
2200 wct
= CVAL(buf
, smb_wct
);
2201 vwv
= (const uint16_t *)(buf
+ smb_vwv
);
2202 num_bytes
= smb_buflen(buf
);
2203 bytes
= (const uint8_t *)smb_buf_const(buf
);
2205 if (!fn(cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2209 if (!is_andx_req(cmd
)) {
2216 chain_cmd
= CVAL(vwv
, 0);
2218 while (chain_cmd
!= 0xff) {
2219 uint32_t chain_offset
; /* uint32_t to avoid overflow */
2220 size_t length_needed
;
2221 ptrdiff_t vwv_offset
;
2223 chain_offset
= SVAL(vwv
+1, 0);
2226 * Check if the client tries to fool us. The chain
2227 * offset needs to point beyond the current request in
2228 * the chain, it needs to strictly grow. Otherwise we
2229 * might be tricked into an endless loop always
2230 * processing the same request over and over again. We
2231 * used to assume that vwv and the byte buffer array
2232 * in a chain are always attached, but OS/2 the
2233 * Write&X/Read&X chain puts the Read&X vwv array
2234 * right behind the Write&X vwv chain. The Write&X bcc
2235 * array is put behind the Read&X vwv array. So now we
2236 * check whether the chain offset points strictly
2237 * behind the previous vwv array. req->buf points
2238 * right after the vwv array of the previous
2240 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2244 vwv_offset
= ((const char *)vwv
- smb_buf
);
2245 if (chain_offset
<= vwv_offset
) {
2250 * Next check: Make sure the chain offset does not
2251 * point beyond the overall smb request length.
2254 length_needed
= chain_offset
+1; /* wct */
2255 if (length_needed
> smblen
) {
2260 * Now comes the pointer magic. Goal here is to set up
2261 * vwv and buf correctly again. The chain offset (the
2262 * former vwv[1]) points at the new wct field.
2265 wct
= CVAL(smb_buf
, chain_offset
);
2267 if (is_andx_req(chain_cmd
) && (wct
< 2)) {
2272 * Next consistency check: Make the new vwv array fits
2273 * in the overall smb request.
2276 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2277 if (length_needed
> smblen
) {
2280 vwv
= (const uint16_t *)(smb_buf
+ chain_offset
+ 1);
2283 * Now grab the new byte buffer....
2286 num_bytes
= SVAL(vwv
+wct
, 0);
2289 * .. and check that it fits.
2292 length_needed
+= num_bytes
;
2293 if (length_needed
> smblen
) {
2296 bytes
= (const uint8_t *)(vwv
+wct
+1);
2298 if (!fn(chain_cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2302 if (!is_andx_req(chain_cmd
)) {
2305 chain_cmd
= CVAL(vwv
, 0);
2310 static bool smb1_chain_length_cb(uint8_t cmd
,
2311 uint8_t wct
, const uint16_t *vwv
,
2312 uint16_t num_bytes
, const uint8_t *bytes
,
2315 unsigned *count
= (unsigned *)private_data
;
2320 unsigned smb1_chain_length(const uint8_t *buf
)
2324 if (!smb1_walk_chain(buf
, smb1_chain_length_cb
, &count
)) {
2330 struct smb1_parse_chain_state
{
2331 TALLOC_CTX
*mem_ctx
;
2333 struct smbd_server_connection
*sconn
;
2337 struct smb_request
**reqs
;
2341 static bool smb1_parse_chain_cb(uint8_t cmd
,
2342 uint8_t wct
, const uint16_t *vwv
,
2343 uint16_t num_bytes
, const uint8_t *bytes
,
2346 struct smb1_parse_chain_state
*state
=
2347 (struct smb1_parse_chain_state
*)private_data
;
2348 struct smb_request
**reqs
;
2349 struct smb_request
*req
;
2352 reqs
= talloc_realloc(state
->mem_ctx
, state
->reqs
,
2353 struct smb_request
*, state
->num_reqs
+1);
2359 req
= talloc(reqs
, struct smb_request
);
2364 ok
= init_smb_request(req
, state
->sconn
, state
->buf
, 0,
2365 state
->encrypted
, state
->seqnum
);
2372 req
->buflen
= num_bytes
;
2375 reqs
[state
->num_reqs
] = req
;
2376 state
->num_reqs
+= 1;
2380 bool smb1_parse_chain(TALLOC_CTX
*mem_ctx
, const uint8_t *buf
,
2381 struct smbd_server_connection
*sconn
,
2382 bool encrypted
, uint32_t seqnum
,
2383 struct smb_request
***reqs
, unsigned *num_reqs
)
2385 struct smb1_parse_chain_state state
;
2388 state
.mem_ctx
= mem_ctx
;
2390 state
.sconn
= sconn
;
2391 state
.encrypted
= encrypted
;
2392 state
.seqnum
= seqnum
;
2396 if (!smb1_walk_chain(buf
, smb1_parse_chain_cb
, &state
)) {
2397 TALLOC_FREE(state
.reqs
);
2400 for (i
=0; i
<state
.num_reqs
; i
++) {
2401 state
.reqs
[i
]->chain
= state
.reqs
;
2404 *num_reqs
= state
.num_reqs
;
2408 /****************************************************************************
2409 Check if services need reloading.
2410 ****************************************************************************/
2412 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2415 if (last_smb_conf_reload_time
== 0) {
2416 last_smb_conf_reload_time
= t
;
2419 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2420 reload_services(sconn
, conn_snum_used
, true);
2421 last_smb_conf_reload_time
= t
;
2425 static bool fd_is_readable(int fd
)
2429 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2431 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2435 static void smbd_server_connection_write_handler(
2436 struct smbd_server_connection
*sconn
)
2438 /* TODO: make write nonblocking */
2441 static void smbd_server_connection_read_handler(
2442 struct smbd_server_connection
*sconn
, int fd
)
2444 uint8_t *inbuf
= NULL
;
2445 size_t inbuf_len
= 0;
2446 size_t unread_bytes
= 0;
2447 bool encrypted
= false;
2448 TALLOC_CTX
*mem_ctx
= talloc_tos();
2452 bool async_echo
= lp_async_smb_echo_handler();
2453 bool from_client
= false;
2456 if (fd_is_readable(sconn
->smb1
.echo_handler
.trusted_fd
)) {
2458 * This is the super-ugly hack to prefer the packets
2459 * forwarded by the echo handler over the ones by the
2462 fd
= sconn
->smb1
.echo_handler
.trusted_fd
;
2466 from_client
= (sconn
->sock
== fd
);
2468 if (async_echo
&& from_client
) {
2469 smbd_lock_socket(sconn
);
2471 if (!fd_is_readable(fd
)) {
2472 DEBUG(10,("the echo listener was faster\n"));
2473 smbd_unlock_socket(sconn
);
2478 /* TODO: make this completely nonblocking */
2479 status
= receive_smb_talloc(mem_ctx
, sconn
, fd
,
2480 (char **)(void *)&inbuf
,
2484 &inbuf_len
, &seqnum
,
2485 !from_client
/* trusted channel */);
2487 if (async_echo
&& from_client
) {
2488 smbd_unlock_socket(sconn
);
2491 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2494 if (NT_STATUS_IS_ERR(status
)) {
2495 exit_server_cleanly("failed to receive smb request");
2497 if (!NT_STATUS_IS_OK(status
)) {
2502 process_smb(sconn
, inbuf
, inbuf_len
, unread_bytes
,
2503 seqnum
, encrypted
, NULL
);
2506 static void smbd_server_connection_handler(struct tevent_context
*ev
,
2507 struct tevent_fd
*fde
,
2511 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2512 struct smbd_server_connection
);
2514 if (!NT_STATUS_IS_OK(conn
->status
)) {
2516 * we're not supposed to do any io
2518 TEVENT_FD_NOT_READABLE(conn
->smb1
.fde
);
2519 TEVENT_FD_NOT_WRITEABLE(conn
->smb1
.fde
);
2523 if (flags
& TEVENT_FD_WRITE
) {
2524 smbd_server_connection_write_handler(conn
);
2527 if (flags
& TEVENT_FD_READ
) {
2528 smbd_server_connection_read_handler(conn
, conn
->sock
);
2533 static void smbd_server_echo_handler(struct tevent_context
*ev
,
2534 struct tevent_fd
*fde
,
2538 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2539 struct smbd_server_connection
);
2541 if (!NT_STATUS_IS_OK(conn
->status
)) {
2543 * we're not supposed to do any io
2545 TEVENT_FD_NOT_READABLE(conn
->smb1
.echo_handler
.trusted_fde
);
2546 TEVENT_FD_NOT_WRITEABLE(conn
->smb1
.echo_handler
.trusted_fde
);
2550 if (flags
& TEVENT_FD_WRITE
) {
2551 smbd_server_connection_write_handler(conn
);
2554 if (flags
& TEVENT_FD_READ
) {
2555 smbd_server_connection_read_handler(
2556 conn
, conn
->smb1
.echo_handler
.trusted_fd
);
2561 struct smbd_release_ip_state
{
2562 struct smbd_server_connection
*sconn
;
2563 struct tevent_immediate
*im
;
2564 char addr
[INET6_ADDRSTRLEN
];
2567 static void smbd_release_ip_immediate(struct tevent_context
*ctx
,
2568 struct tevent_immediate
*im
,
2571 struct smbd_release_ip_state
*state
=
2572 talloc_get_type_abort(private_data
,
2573 struct smbd_release_ip_state
);
2575 if (!NT_STATUS_EQUAL(state
->sconn
->status
, NT_STATUS_ADDRESS_CLOSED
)) {
2577 * smbd_server_connection_terminate() already triggered ?
2582 smbd_server_connection_terminate(state
->sconn
, "CTDB_SRVID_RELEASE_IP");
2585 /****************************************************************************
2586 received when we should release a specific IP
2587 ****************************************************************************/
2588 static bool release_ip(const char *ip
, void *priv
)
2590 struct smbd_release_ip_state
*state
=
2591 talloc_get_type_abort(priv
,
2592 struct smbd_release_ip_state
);
2593 const char *addr
= state
->addr
;
2594 const char *p
= addr
;
2596 if (!NT_STATUS_IS_OK(state
->sconn
->status
)) {
2597 /* avoid recursion */
2601 if (strncmp("::ffff:", addr
, 7) == 0) {
2605 DEBUG(10, ("Got release IP message for %s, "
2606 "our address is %s\n", ip
, p
));
2608 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2609 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2612 * With SMB2 we should do a clean disconnect,
2613 * the previous_session_id in the session setup
2614 * will cleanup the old session, tcons and opens.
2616 * A clean disconnect is needed in order to support
2619 * Note: typically this is never triggered
2620 * as we got a TCP RST (triggered by ctdb event scripts)
2621 * before we get CTDB_SRVID_RELEASE_IP.
2623 * We used to call _exit(1) here, but as this was mostly never
2624 * triggered and has implication on our process model,
2625 * we can just use smbd_server_connection_terminate()
2628 * We don't call smbd_server_connection_terminate() directly
2629 * as we might be called from within ctdbd_migrate(),
2630 * we need to defer our action to the next event loop
2632 tevent_schedule_immediate(state
->im
, state
->sconn
->ev_ctx
,
2633 smbd_release_ip_immediate
, state
);
2636 * Make sure we don't get any io on the connection.
2638 state
->sconn
->status
= NT_STATUS_ADDRESS_CLOSED
;
2645 static NTSTATUS
smbd_register_ips(struct smbd_server_connection
*sconn
,
2646 struct sockaddr_storage
*srv
,
2647 struct sockaddr_storage
*clnt
)
2649 struct smbd_release_ip_state
*state
;
2650 struct ctdbd_connection
*cconn
;
2652 cconn
= messaging_ctdbd_connection();
2653 if (cconn
== NULL
) {
2654 return NT_STATUS_NO_MEMORY
;
2657 state
= talloc_zero(sconn
, struct smbd_release_ip_state
);
2658 if (state
== NULL
) {
2659 return NT_STATUS_NO_MEMORY
;
2661 state
->sconn
= sconn
;
2662 state
->im
= tevent_create_immediate(state
);
2663 if (state
->im
== NULL
) {
2664 return NT_STATUS_NO_MEMORY
;
2666 if (print_sockaddr(state
->addr
, sizeof(state
->addr
), srv
) == NULL
) {
2667 return NT_STATUS_NO_MEMORY
;
2670 return ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, state
);
2673 static int client_get_tcp_info(int sock
, struct sockaddr_storage
*server
,
2674 struct sockaddr_storage
*client
)
2677 length
= sizeof(*server
);
2678 if (getsockname(sock
, (struct sockaddr
*)server
, &length
) != 0) {
2681 length
= sizeof(*client
);
2682 if (getpeername(sock
, (struct sockaddr
*)client
, &length
) != 0) {
2688 static void msg_kill_client_ip(struct messaging_context
*msg_ctx
,
2689 void *private_data
, uint32_t msg_type
,
2690 struct server_id server_id
, DATA_BLOB
*data
)
2692 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2693 private_data
, struct smbd_server_connection
);
2694 const char *ip
= (char *) data
->data
;
2697 DEBUG(10, ("Got kill request for client IP %s\n", ip
));
2699 client_ip
= tsocket_address_inet_addr_string(sconn
->remote_address
,
2701 if (client_ip
== NULL
) {
2705 if (strequal(ip
, client_ip
)) {
2706 DEBUG(1, ("Got kill client message for %s - "
2707 "exiting immediately\n", ip
));
2708 exit_server_cleanly("Forced disconnect for client");
2711 TALLOC_FREE(client_ip
);
2715 * Send keepalive packets to our client
2717 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2719 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2720 private_data
, struct smbd_server_connection
);
2723 if (sconn
->using_smb2
) {
2724 /* Don't do keepalives on an SMB2 connection. */
2728 smbd_lock_socket(sconn
);
2729 ret
= send_keepalive(sconn
->sock
);
2730 smbd_unlock_socket(sconn
);
2733 char addr
[INET6_ADDRSTRLEN
];
2735 * Try and give an error message saying what
2738 DEBUG(0, ("send_keepalive failed for client %s. "
2739 "Error %s - exiting\n",
2740 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
2748 * Do the recurring check if we're idle
2750 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2752 struct smbd_server_connection
*sconn
=
2753 (struct smbd_server_connection
*)private_data
;
2755 if ((conn_num_open(sconn
) == 0)
2756 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2757 DEBUG( 2, ( "Closing idle connection\n" ) );
2758 messaging_send(sconn
->msg_ctx
,
2759 messaging_server_id(sconn
->msg_ctx
),
2760 MSG_SHUTDOWN
, &data_blob_null
);
2768 * Do the recurring log file and smb.conf reload checks.
2771 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2773 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2774 private_data
, struct smbd_server_connection
);
2776 DEBUG(5, ("housekeeping\n"));
2778 change_to_root_user();
2780 /* update printer queue caches if necessary */
2781 update_monitored_printq_cache(sconn
->msg_ctx
);
2783 /* check if we need to reload services */
2784 check_reload(sconn
, time_mono(NULL
));
2787 * Force a log file check.
2789 force_check_log_size();
2795 * Read an smb packet in the echo handler child, giving the parent
2796 * smbd one second to react once the socket becomes readable.
2799 struct smbd_echo_read_state
{
2800 struct tevent_context
*ev
;
2801 struct smbd_server_connection
*sconn
;
2808 static void smbd_echo_read_readable(struct tevent_req
*subreq
);
2809 static void smbd_echo_read_waited(struct tevent_req
*subreq
);
2811 static struct tevent_req
*smbd_echo_read_send(
2812 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2813 struct smbd_server_connection
*sconn
)
2815 struct tevent_req
*req
, *subreq
;
2816 struct smbd_echo_read_state
*state
;
2818 req
= tevent_req_create(mem_ctx
, &state
,
2819 struct smbd_echo_read_state
);
2824 state
->sconn
= sconn
;
2826 subreq
= wait_for_read_send(state
, ev
, sconn
->sock
);
2827 if (tevent_req_nomem(subreq
, req
)) {
2828 return tevent_req_post(req
, ev
);
2830 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2834 static void smbd_echo_read_readable(struct tevent_req
*subreq
)
2836 struct tevent_req
*req
= tevent_req_callback_data(
2837 subreq
, struct tevent_req
);
2838 struct smbd_echo_read_state
*state
= tevent_req_data(
2839 req
, struct smbd_echo_read_state
);
2843 ok
= wait_for_read_recv(subreq
, &err
);
2844 TALLOC_FREE(subreq
);
2846 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
2851 * Give the parent smbd one second to step in
2854 subreq
= tevent_wakeup_send(
2855 state
, state
->ev
, timeval_current_ofs(1, 0));
2856 if (tevent_req_nomem(subreq
, req
)) {
2859 tevent_req_set_callback(subreq
, smbd_echo_read_waited
, req
);
2862 static void smbd_echo_read_waited(struct tevent_req
*subreq
)
2864 struct tevent_req
*req
= tevent_req_callback_data(
2865 subreq
, struct tevent_req
);
2866 struct smbd_echo_read_state
*state
= tevent_req_data(
2867 req
, struct smbd_echo_read_state
);
2868 struct smbd_server_connection
*sconn
= state
->sconn
;
2874 ok
= tevent_wakeup_recv(subreq
);
2875 TALLOC_FREE(subreq
);
2877 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2881 ok
= smbd_lock_socket_internal(sconn
);
2883 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2884 DEBUG(0, ("%s: failed to lock socket\n", __location__
));
2888 if (!fd_is_readable(sconn
->sock
)) {
2889 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2892 ok
= smbd_unlock_socket_internal(sconn
);
2894 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2895 DEBUG(1, ("%s: failed to unlock socket\n",
2900 subreq
= wait_for_read_send(state
, state
->ev
, sconn
->sock
);
2901 if (tevent_req_nomem(subreq
, req
)) {
2904 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2908 status
= receive_smb_talloc(state
, sconn
, sconn
->sock
, &state
->buf
,
2914 false /* trusted_channel*/);
2916 if (tevent_req_nterror(req
, status
)) {
2917 tevent_req_nterror(req
, status
);
2918 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2919 (int)getpid(), nt_errstr(status
)));
2923 ok
= smbd_unlock_socket_internal(sconn
);
2925 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2926 DEBUG(1, ("%s: failed to unlock socket\n", __location__
));
2929 tevent_req_done(req
);
2932 static NTSTATUS
smbd_echo_read_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2933 char **pbuf
, size_t *pbuflen
, uint32_t *pseqnum
)
2935 struct smbd_echo_read_state
*state
= tevent_req_data(
2936 req
, struct smbd_echo_read_state
);
2939 if (tevent_req_is_nterror(req
, &status
)) {
2942 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
2943 *pbuflen
= state
->buflen
;
2944 *pseqnum
= state
->seqnum
;
2945 return NT_STATUS_OK
;
2948 struct smbd_echo_state
{
2949 struct tevent_context
*ev
;
2950 struct iovec
*pending
;
2951 struct smbd_server_connection
*sconn
;
2954 struct tevent_fd
*parent_fde
;
2956 struct tevent_req
*write_req
;
2959 static void smbd_echo_writer_done(struct tevent_req
*req
);
2961 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2965 if (state
->write_req
!= NULL
) {
2969 num_pending
= talloc_array_length(state
->pending
);
2970 if (num_pending
== 0) {
2974 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
2975 state
->parent_pipe
, false,
2976 state
->pending
, num_pending
);
2977 if (state
->write_req
== NULL
) {
2978 DEBUG(1, ("writev_send failed\n"));
2982 talloc_steal(state
->write_req
, state
->pending
);
2983 state
->pending
= NULL
;
2985 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
2989 static void smbd_echo_writer_done(struct tevent_req
*req
)
2991 struct smbd_echo_state
*state
= tevent_req_callback_data(
2992 req
, struct smbd_echo_state
);
2996 written
= writev_recv(req
, &err
);
2998 state
->write_req
= NULL
;
2999 if (written
== -1) {
3000 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
3003 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3004 smbd_echo_activate_writer(state
);
3007 static bool smbd_echo_reply(struct smbd_echo_state
*state
,
3008 uint8_t *inbuf
, size_t inbuf_len
,
3011 struct smb_request req
;
3012 uint16_t num_replies
;
3016 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == NBSSkeepalive
)) {
3017 DEBUG(10, ("Got netbios keepalive\n"));
3024 if (inbuf_len
< smb_size
) {
3025 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
3028 if (!valid_smb_header(state
->sconn
, inbuf
)) {
3029 DEBUG(10, ("Got invalid SMB header\n"));
3033 if (!init_smb_request(&req
, state
->sconn
, inbuf
, 0, false,
3039 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
3040 smb_messages
[req
.cmd
].name
3041 ? smb_messages
[req
.cmd
].name
: "unknown"));
3043 if (req
.cmd
!= SMBecho
) {
3050 num_replies
= SVAL(req
.vwv
+0, 0);
3051 if (num_replies
!= 1) {
3052 /* Not a Windows "Hey, you're still there?" request */
3056 if (!create_outbuf(talloc_tos(), &req
, (const char *)req
.inbuf
, &outbuf
,
3058 DEBUG(10, ("create_outbuf failed\n"));
3061 req
.outbuf
= (uint8_t *)outbuf
;
3063 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
3065 if (req
.buflen
> 0) {
3066 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
3069 ok
= srv_send_smb(req
.sconn
,
3073 TALLOC_FREE(outbuf
);
3081 static void smbd_echo_exit(struct tevent_context
*ev
,
3082 struct tevent_fd
*fde
, uint16_t flags
,
3085 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3089 static void smbd_echo_got_packet(struct tevent_req
*req
);
3091 static void smbd_echo_loop(struct smbd_server_connection
*sconn
,
3094 struct smbd_echo_state
*state
;
3095 struct tevent_req
*read_req
;
3097 state
= talloc_zero(sconn
, struct smbd_echo_state
);
3098 if (state
== NULL
) {
3099 DEBUG(1, ("talloc failed\n"));
3102 state
->sconn
= sconn
;
3103 state
->parent_pipe
= parent_pipe
;
3104 state
->ev
= s3_tevent_context_init(state
);
3105 if (state
->ev
== NULL
) {
3106 DEBUG(1, ("tevent_context_init failed\n"));
3110 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
3111 TEVENT_FD_READ
, smbd_echo_exit
,
3113 if (state
->parent_fde
== NULL
) {
3114 DEBUG(1, ("tevent_add_fd failed\n"));
3119 read_req
= smbd_echo_read_send(state
, state
->ev
, sconn
);
3120 if (read_req
== NULL
) {
3121 DEBUG(1, ("smbd_echo_read_send failed\n"));
3125 tevent_req_set_callback(read_req
, smbd_echo_got_packet
, state
);
3128 if (tevent_loop_once(state
->ev
) == -1) {
3129 DEBUG(1, ("tevent_loop_once failed: %s\n",
3137 static void smbd_echo_got_packet(struct tevent_req
*req
)
3139 struct smbd_echo_state
*state
= tevent_req_callback_data(
3140 req
, struct smbd_echo_state
);
3144 uint32_t seqnum
= 0;
3147 status
= smbd_echo_read_recv(req
, state
, &buf
, &buflen
, &seqnum
);
3149 if (!NT_STATUS_IS_OK(status
)) {
3150 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3151 nt_errstr(status
)));
3155 reply
= smbd_echo_reply(state
, (uint8_t *)buf
, buflen
, seqnum
);
3161 num_pending
= talloc_array_length(state
->pending
);
3162 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
3165 DEBUG(1, ("talloc_realloc failed\n"));
3168 state
->pending
= tmp
;
3170 if (buflen
>= smb_size
) {
3172 * place the seqnum in the packet so that the main process
3173 * can reply with signing
3175 SIVAL(buf
, smb_ss_field
, seqnum
);
3176 SIVAL(buf
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
3179 iov
= &state
->pending
[num_pending
];
3180 iov
->iov_base
= talloc_move(state
->pending
, &buf
);
3181 iov
->iov_len
= buflen
;
3183 DEBUG(10,("echo_handler[%d]: forward to main\n",
3185 smbd_echo_activate_writer(state
);
3188 req
= smbd_echo_read_send(state
, state
->ev
, state
->sconn
);
3190 DEBUG(1, ("smbd_echo_read_send failed\n"));
3193 tevent_req_set_callback(req
, smbd_echo_got_packet
, state
);
3198 * Handle SMBecho requests in a forked child process
3200 bool fork_echo_handler(struct smbd_server_connection
*sconn
)
3202 int listener_pipe
[2];
3205 bool use_mutex
= false;
3207 res
= pipe(listener_pipe
);
3209 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
3213 #ifdef HAVE_ROBUST_MUTEXES
3214 use_mutex
= tdb_runtime_check_for_robust_mutexes();
3217 pthread_mutexattr_t a
;
3219 sconn
->smb1
.echo_handler
.socket_mutex
=
3220 anonymous_shared_allocate(sizeof(pthread_mutex_t
));
3221 if (sconn
->smb1
.echo_handler
.socket_mutex
== NULL
) {
3222 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3227 res
= pthread_mutexattr_init(&a
);
3229 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3233 res
= pthread_mutexattr_settype(&a
, PTHREAD_MUTEX_ERRORCHECK
);
3235 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3237 pthread_mutexattr_destroy(&a
);
3240 res
= pthread_mutexattr_setpshared(&a
, PTHREAD_PROCESS_SHARED
);
3242 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3244 pthread_mutexattr_destroy(&a
);
3247 res
= pthread_mutexattr_setrobust(&a
, PTHREAD_MUTEX_ROBUST
);
3249 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3250 "%s\n", strerror(res
)));
3251 pthread_mutexattr_destroy(&a
);
3254 res
= pthread_mutex_init(sconn
->smb1
.echo_handler
.socket_mutex
,
3256 pthread_mutexattr_destroy(&a
);
3258 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3266 sconn
->smb1
.echo_handler
.socket_lock_fd
=
3267 create_unlink_tmp(lp_lock_directory());
3268 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
3269 DEBUG(1, ("Could not create lock fd: %s\n",
3279 close(listener_pipe
[0]);
3280 set_blocking(listener_pipe
[1], false);
3282 status
= reinit_after_fork(sconn
->msg_ctx
,
3285 if (!NT_STATUS_IS_OK(status
)) {
3286 DEBUG(1, ("reinit_after_fork failed: %s\n",
3287 nt_errstr(status
)));
3290 smbd_echo_loop(sconn
, listener_pipe
[1]);
3293 close(listener_pipe
[1]);
3294 listener_pipe
[1] = -1;
3295 sconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
3297 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child
));
3300 * Without smb signing this is the same as the normal smbd
3301 * listener. This needs to change once signing comes in.
3303 sconn
->smb1
.echo_handler
.trusted_fde
= tevent_add_fd(sconn
->ev_ctx
,
3305 sconn
->smb1
.echo_handler
.trusted_fd
,
3307 smbd_server_echo_handler
,
3309 if (sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
3310 DEBUG(1, ("event_add_fd failed\n"));
3317 if (listener_pipe
[0] != -1) {
3318 close(listener_pipe
[0]);
3320 if (listener_pipe
[1] != -1) {
3321 close(listener_pipe
[1]);
3323 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
3324 close(sconn
->smb1
.echo_handler
.socket_lock_fd
);
3327 #ifdef HAVE_ROBUST_MUTEXES
3328 if (sconn
->smb1
.echo_handler
.socket_mutex
!= NULL
) {
3329 pthread_mutex_destroy(sconn
->smb1
.echo_handler
.socket_mutex
);
3330 anonymous_shared_free(sconn
->smb1
.echo_handler
.socket_mutex
);
3333 smbd_echo_init(sconn
);
3338 static bool uid_in_use(const struct user_struct
*user
, uid_t uid
)
3341 if (user
->session_info
&&
3342 (user
->session_info
->unix_token
->uid
== uid
)) {
3350 static bool gid_in_use(const struct user_struct
*user
, gid_t gid
)
3353 if (user
->session_info
!= NULL
) {
3355 struct security_unix_token
*utok
;
3357 utok
= user
->session_info
->unix_token
;
3358 if (utok
->gid
== gid
) {
3361 for(i
=0; i
<utok
->ngroups
; i
++) {
3362 if (utok
->groups
[i
] == gid
) {
3372 static bool sid_in_use(const struct user_struct
*user
,
3373 const struct dom_sid
*psid
)
3376 struct security_token
*tok
;
3378 if (user
->session_info
== NULL
) {
3381 tok
= user
->session_info
->security_token
;
3384 * Not sure session_info->security_token can
3385 * ever be NULL. This check might be not
3390 if (security_token_has_sid(tok
, psid
)) {
3398 static bool id_in_use(const struct user_struct
*user
,
3399 const struct id_cache_ref
*id
)
3403 return uid_in_use(user
, id
->id
.uid
);
3405 return gid_in_use(user
, id
->id
.gid
);
3407 return sid_in_use(user
, &id
->id
.sid
);
3414 static void smbd_id_cache_kill(struct messaging_context
*msg_ctx
,
3417 struct server_id server_id
,
3420 const char *msg
= (data
&& data
->data
)
3421 ? (const char *)data
->data
: "<NULL>";
3422 struct id_cache_ref id
;
3423 struct smbd_server_connection
*sconn
=
3424 talloc_get_type_abort(private_data
,
3425 struct smbd_server_connection
);
3427 if (!id_cache_ref_parse(msg
, &id
)) {
3428 DEBUG(0, ("Invalid ?ID: %s\n", msg
));
3432 if (id_in_use(sconn
->users
, &id
)) {
3433 exit_server_cleanly(msg
);
3435 id_cache_delete_from_cache(&id
);
3438 NTSTATUS
smbXsrv_connection_init_tables(struct smbXsrv_connection
*conn
,
3439 enum protocol_types protocol
)
3443 set_Protocol(protocol
);
3444 conn
->protocol
= protocol
;
3446 if (protocol
>= PROTOCOL_SMB2_02
) {
3447 status
= smb2srv_session_table_init(conn
);
3448 if (!NT_STATUS_IS_OK(status
)) {
3452 status
= smb2srv_open_table_init(conn
);
3453 if (!NT_STATUS_IS_OK(status
)) {
3457 status
= smb1srv_session_table_init(conn
);
3458 if (!NT_STATUS_IS_OK(status
)) {
3462 status
= smb1srv_tcon_table_init(conn
);
3463 if (!NT_STATUS_IS_OK(status
)) {
3467 status
= smb1srv_open_table_init(conn
);
3468 if (!NT_STATUS_IS_OK(status
)) {
3473 return NT_STATUS_OK
;
3476 static void smbd_tevent_trace_callback(enum tevent_trace_point point
,
3479 struct smbXsrv_connection
*conn
=
3480 talloc_get_type_abort(private_data
,
3481 struct smbXsrv_connection
);
3484 case TEVENT_TRACE_BEFORE_WAIT
:
3486 * This just removes compiler warning
3487 * without profile support
3489 conn
->smbd_idle_profstamp
= 0;
3490 START_PROFILE_STAMP(smbd_idle
, conn
->smbd_idle_profstamp
);
3492 case TEVENT_TRACE_AFTER_WAIT
:
3493 END_PROFILE_STAMP(smbd_idle
, conn
->smbd_idle_profstamp
);
3495 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3496 case TEVENT_TRACE_BEFORE_LOOP_ONCE
:
3497 case TEVENT_TRACE_AFTER_LOOP_ONCE
:
3503 /****************************************************************************
3504 Process commands from the client
3505 ****************************************************************************/
3507 void smbd_process(struct tevent_context
*ev_ctx
,
3508 struct messaging_context
*msg_ctx
,
3512 TALLOC_CTX
*frame
= talloc_stackframe();
3513 struct smbXsrv_connection
*conn
;
3514 struct smbd_server_connection
*sconn
;
3515 struct sockaddr_storage ss
;
3516 struct sockaddr
*sa
= NULL
;
3517 socklen_t sa_socklen
;
3518 struct tsocket_address
*local_address
= NULL
;
3519 struct tsocket_address
*remote_address
= NULL
;
3520 const char *locaddr
= NULL
;
3521 const char *remaddr
= NULL
;
3526 conn
= talloc_zero(ev_ctx
, struct smbXsrv_connection
);
3528 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3529 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3532 conn
->ev_ctx
= ev_ctx
;
3533 conn
->msg_ctx
= msg_ctx
;
3535 sconn
= talloc_zero(conn
, struct smbd_server_connection
);
3537 exit_server("failed to create smbd_server_connection");
3540 conn
->sconn
= sconn
;
3544 * TODO: remove this...:-)
3546 global_smbXsrv_connection
= conn
;
3548 sconn
->ev_ctx
= ev_ctx
;
3549 sconn
->msg_ctx
= msg_ctx
;
3550 sconn
->sock
= sock_fd
;
3551 smbd_echo_init(sconn
);
3554 smbd_setup_sig_term_handler(sconn
);
3555 smbd_setup_sig_hup_handler(sconn
);
3557 if (!serverid_register(messaging_server_id(msg_ctx
),
3558 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
3560 |FLAG_MSG_PRINT_GENERAL
)) {
3561 exit_server_cleanly("Could not register myself in "
3566 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02
) {
3568 * We're not making the decision here,
3569 * we're just allowing the client
3570 * to decide between SMB1 and SMB2
3571 * with the first negprot
3574 sconn
->using_smb2
= true;
3577 /* Ensure child is set to blocking mode */
3578 set_blocking(sconn
->sock
,True
);
3580 set_socket_options(sconn
->sock
, "SO_KEEPALIVE");
3581 set_socket_options(sconn
->sock
, lp_socket_options());
3583 sa
= (struct sockaddr
*)(void *)&ss
;
3584 sa_socklen
= sizeof(ss
);
3585 ret
= getpeername(sconn
->sock
, sa
, &sa_socklen
);
3587 int level
= (errno
== ENOTCONN
)?2:0;
3588 DEBUG(level
,("getpeername() failed - %s\n", strerror(errno
)));
3589 exit_server_cleanly("getpeername() failed.\n");
3591 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3595 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3596 __location__
, strerror(errno
)));
3597 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3600 sa
= (struct sockaddr
*)(void *)&ss
;
3601 sa_socklen
= sizeof(ss
);
3602 ret
= getsockname(sconn
->sock
, sa
, &sa_socklen
);
3604 int level
= (errno
== ENOTCONN
)?2:0;
3605 DEBUG(level
,("getsockname() failed - %s\n", strerror(errno
)));
3606 exit_server_cleanly("getsockname() failed.\n");
3608 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3612 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3613 __location__
, strerror(errno
)));
3614 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3617 sconn
->local_address
= local_address
;
3618 sconn
->remote_address
= remote_address
;
3620 if (tsocket_address_is_inet(local_address
, "ip")) {
3621 locaddr
= tsocket_address_inet_addr_string(
3622 sconn
->local_address
,
3624 if (locaddr
== NULL
) {
3625 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3626 __location__
, strerror(errno
)));
3627 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3630 locaddr
= "0.0.0.0";
3633 if (tsocket_address_is_inet(remote_address
, "ip")) {
3634 remaddr
= tsocket_address_inet_addr_string(
3635 sconn
->remote_address
,
3637 if (remaddr
== NULL
) {
3638 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3639 __location__
, strerror(errno
)));
3640 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3643 remaddr
= "0.0.0.0";
3646 /* this is needed so that we get decent entries
3647 in smbstatus for port 445 connects */
3648 set_remote_machine_name(remaddr
, false);
3649 reload_services(sconn
, conn_snum_used
, true);
3652 * Before the first packet, check the global hosts allow/ hosts deny
3653 * parameters before doing any parsing of packets passed to us by the
3654 * client. This prevents attacks on our parsing code from hosts not in
3655 * the hosts allow list.
3658 ret
= get_remote_hostname(remote_address
,
3662 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3663 __location__
, strerror(errno
)));
3664 exit_server_cleanly("get_remote_hostname failed.\n");
3666 if (strequal(rhost
, "UNKNOWN")) {
3667 rhost
= talloc_strdup(talloc_tos(), remaddr
);
3669 sconn
->remote_hostname
= talloc_move(sconn
, &rhost
);
3671 sub_set_socket_ids(remaddr
,
3672 sconn
->remote_hostname
,
3675 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3676 sconn
->remote_hostname
,
3679 * send a negative session response "not listening on calling
3682 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3683 DEBUG( 1, ("Connection denied from %s to %s\n",
3684 tsocket_address_string(remote_address
, talloc_tos()),
3685 tsocket_address_string(local_address
, talloc_tos())));
3686 (void)srv_send_smb(sconn
,(char *)buf
, false,
3688 exit_server_cleanly("connection denied");
3691 DEBUG(10, ("Connection allowed from %s to %s\n",
3692 tsocket_address_string(remote_address
, talloc_tos()),
3693 tsocket_address_string(local_address
, talloc_tos())));
3695 if (lp_preload_modules()) {
3696 smb_load_modules(lp_preload_modules());
3699 smb_perfcount_init();
3701 if (!init_account_policy()) {
3702 exit_server("Could not open account policy tdb.\n");
3705 if (*lp_root_directory(talloc_tos())) {
3706 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3707 DEBUG(0,("Failed to change root to %s\n",
3708 lp_root_directory(talloc_tos())));
3709 exit_server("Failed to chroot()");
3711 if (chdir("/") == -1) {
3712 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3713 exit_server("Failed to chroot()");
3715 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3718 if (!srv_init_signing(sconn
)) {
3719 exit_server("Failed to init smb_signing");
3722 if (!file_init(sconn
)) {
3723 exit_server("file_init() failed");
3727 if (!init_oplocks(sconn
))
3728 exit_server("Failed to init oplocks");
3730 /* register our message handlers */
3731 messaging_register(sconn
->msg_ctx
, sconn
,
3732 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3733 messaging_register(sconn
->msg_ctx
, sconn
,
3734 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3735 messaging_register(sconn
->msg_ctx
, sconn
,
3736 MSG_SMB_FILE_RENAME
, msg_file_was_renamed
);
3738 id_cache_register_msgs(sconn
->msg_ctx
);
3739 messaging_deregister(sconn
->msg_ctx
, ID_CACHE_KILL
, NULL
);
3740 messaging_register(sconn
->msg_ctx
, sconn
,
3741 ID_CACHE_KILL
, smbd_id_cache_kill
);
3743 messaging_deregister(sconn
->msg_ctx
,
3744 MSG_SMB_CONF_UPDATED
, sconn
->ev_ctx
);
3745 messaging_register(sconn
->msg_ctx
, sconn
,
3746 MSG_SMB_CONF_UPDATED
, smbd_conf_updated
);
3748 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_KILL_CLIENT_IP
,
3750 messaging_register(sconn
->msg_ctx
, sconn
,
3751 MSG_SMB_KILL_CLIENT_IP
,
3752 msg_kill_client_ip
);
3754 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_TELL_NUM_CHILDREN
, NULL
);
3757 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3758 * MSGs to all child processes
3760 messaging_deregister(sconn
->msg_ctx
,
3762 messaging_register(sconn
->msg_ctx
, NULL
,
3763 MSG_DEBUG
, debug_message
);
3765 if ((lp_keepalive() != 0)
3766 && !(event_add_idle(ev_ctx
, NULL
,
3767 timeval_set(lp_keepalive(), 0),
3768 "keepalive", keepalive_fn
,
3770 DEBUG(0, ("Could not add keepalive event\n"));
3774 if (!(event_add_idle(ev_ctx
, NULL
,
3775 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3776 "deadtime", deadtime_fn
, sconn
))) {
3777 DEBUG(0, ("Could not add deadtime event\n"));
3781 if (!(event_add_idle(ev_ctx
, NULL
,
3782 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
3783 "housekeeping", housekeeping_fn
, sconn
))) {
3784 DEBUG(0, ("Could not add housekeeping event\n"));
3788 if (lp_clustering()) {
3790 * We need to tell ctdb about our client's TCP
3791 * connection, so that for failover ctdbd can send
3792 * tickle acks, triggering a reconnection by the
3796 struct sockaddr_storage srv
, clnt
;
3798 if (client_get_tcp_info(sconn
->sock
, &srv
, &clnt
) == 0) {
3800 status
= smbd_register_ips(sconn
, &srv
, &clnt
);
3801 if (!NT_STATUS_IS_OK(status
)) {
3802 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3803 nt_errstr(status
)));
3806 int level
= (errno
== ENOTCONN
)?2:0;
3807 DEBUG(level
,("Unable to get tcp info for "
3808 "smbd_register_ips: %s\n",
3810 exit_server_cleanly("client_get_tcp_info() failed.\n");
3814 sconn
->nbt
.got_session
= false;
3816 tmp
= lp_max_xmit();
3817 tmp
= MAX(tmp
, SMB_BUFFER_SIZE_MIN
);
3818 tmp
= MIN(tmp
, SMB_BUFFER_SIZE_MAX
);
3820 sconn
->smb1
.negprot
.max_recv
= tmp
;
3822 sconn
->smb1
.sessions
.done_sesssetup
= false;
3823 sconn
->smb1
.sessions
.max_send
= SMB_BUFFER_SIZE_MAX
;
3825 if (!init_dptrs(sconn
)) {
3826 exit_server("init_dptrs() failed");
3829 sconn
->smb1
.fde
= tevent_add_fd(ev_ctx
,
3833 smbd_server_connection_handler
,
3835 if (!sconn
->smb1
.fde
) {
3836 exit_server("failed to create smbd_server_connection fde");
3839 sconn
->conn
->local_address
= sconn
->local_address
;
3840 sconn
->conn
->remote_address
= sconn
->remote_address
;
3841 sconn
->conn
->remote_hostname
= sconn
->remote_hostname
;
3842 sconn
->conn
->protocol
= PROTOCOL_NONE
;
3846 tevent_set_trace_callback(ev_ctx
, smbd_tevent_trace_callback
, conn
);
3849 frame
= talloc_stackframe_pool(8192);
3852 if (tevent_loop_once(ev_ctx
) == -1) {
3853 if (errno
!= EINTR
) {
3854 DEBUG(3, ("tevent_loop_once failed: %s,"
3855 " exiting\n", strerror(errno
) ));
3863 exit_server_cleanly(NULL
);
3866 bool req_is_in_chain(const struct smb_request
*req
)
3868 if (req
->vwv
!= (const uint16_t *)(req
->inbuf
+smb_vwv
)) {
3870 * We're right now handling a subsequent request, so we must
3876 if (!is_andx_req(req
->cmd
)) {
3882 * Okay, an illegal request, but definitely not chained :-)
3887 return (CVAL(req
->vwv
+0, 0) != 0xFF);