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"
44 /* Internal message queue for deferred opens. */
45 struct pending_message_list
{
46 struct pending_message_list
*next
, *prev
;
47 struct timeval request_time
; /* When was this first issued? */
48 struct smbd_server_connection
*sconn
;
49 struct tevent_timer
*te
;
50 struct smb_perfcount_data pcd
;
55 DATA_BLOB private_data
;
58 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
60 static struct pending_message_list
*get_deferred_open_message_smb(
61 struct smbd_server_connection
*sconn
, uint64_t mid
);
62 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
);
64 static bool smbd_lock_socket_internal(struct smbd_server_connection
*sconn
)
68 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
72 sconn
->smb1
.echo_handler
.ref_count
++;
74 if (sconn
->smb1
.echo_handler
.ref_count
> 1) {
78 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
82 sconn
->smb1
.echo_handler
.socket_lock_fd
,
83 F_SETLKW
, 0, 0, F_WRLCK
);
84 } while (!ok
&& (errno
== EINTR
));
87 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
91 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
96 void smbd_lock_socket(struct smbd_server_connection
*sconn
)
98 if (!smbd_lock_socket_internal(sconn
)) {
99 exit_server_cleanly("failed to lock socket");
103 static bool smbd_unlock_socket_internal(struct smbd_server_connection
*sconn
)
107 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
111 sconn
->smb1
.echo_handler
.ref_count
--;
113 if (sconn
->smb1
.echo_handler
.ref_count
> 0) {
119 sconn
->smb1
.echo_handler
.socket_lock_fd
,
120 F_SETLKW
, 0, 0, F_UNLCK
);
121 } while (!ok
&& (errno
== EINTR
));
124 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
128 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
133 void smbd_unlock_socket(struct smbd_server_connection
*sconn
)
135 if (!smbd_unlock_socket_internal(sconn
)) {
136 exit_server_cleanly("failed to unlock socket");
140 /* Accessor function for smb_read_error for smbd functions. */
142 /****************************************************************************
144 ****************************************************************************/
146 bool srv_send_smb(struct smbd_server_connection
*sconn
, char *buffer
,
147 bool do_signing
, uint32_t seqnum
,
149 struct smb_perfcount_data
*pcd
)
153 char *buf_out
= buffer
;
155 if (!NT_STATUS_IS_OK(sconn
->status
)) {
157 * we're not supposed to do any io
162 smbd_lock_socket(sconn
);
165 /* Sign the outgoing packet if required. */
166 srv_calculate_sign_mac(sconn
, buf_out
, seqnum
);
170 NTSTATUS status
= srv_encrypt_buffer(sconn
, buffer
, &buf_out
);
171 if (!NT_STATUS_IS_OK(status
)) {
172 DEBUG(0, ("send_smb: SMB encryption failed "
173 "on outgoing packet! Error %s\n",
174 nt_errstr(status
) ));
180 len
= smb_len_large(buf_out
) + 4;
182 ret
= write_data(sconn
->sock
, buf_out
, len
);
185 char addr
[INET6_ADDRSTRLEN
];
187 * Try and give an error message saying what
190 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
191 (int)getpid(), (int)len
,
192 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
193 (int)ret
, strerror(errno
) ));
195 srv_free_enc_buffer(sconn
, buf_out
);
199 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
200 srv_free_enc_buffer(sconn
, buf_out
);
202 SMB_PERFCOUNT_END(pcd
);
204 smbd_unlock_socket(sconn
);
208 /*******************************************************************
209 Setup the word count and byte count for a smb message.
210 ********************************************************************/
212 int srv_set_message(char *buf
,
217 if (zero
&& (num_words
|| num_bytes
)) {
218 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
220 SCVAL(buf
,smb_wct
,num_words
);
221 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
222 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
223 return (smb_size
+ num_words
*2 + num_bytes
);
226 static bool valid_smb_header(struct smbd_server_connection
*sconn
,
227 const uint8_t *inbuf
)
229 if (is_encrypted_packet(sconn
, inbuf
)) {
233 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
234 * but it just looks weird to call strncmp for this one.
236 return (IVAL(smb_base(inbuf
), 0) == 0x424D53FF);
239 /* Socket functions for smbd packet processing. */
241 static bool valid_packet_size(size_t len
)
244 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
245 * of header. Don't print the error if this fits.... JRA.
248 if (len
> (LARGE_WRITEX_BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
249 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
250 (unsigned long)len
));
256 static NTSTATUS
read_packet_remainder(int fd
, char *buffer
,
257 unsigned int timeout
, ssize_t len
)
265 status
= read_fd_with_timeout(fd
, buffer
, len
, len
, timeout
, NULL
);
266 if (!NT_STATUS_IS_OK(status
)) {
267 char addr
[INET6_ADDRSTRLEN
];
268 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
270 get_peer_addr(fd
, addr
, sizeof(addr
)),
276 /****************************************************************************
277 Attempt a zerocopy writeX read. We know here that len > smb_size-4
278 ****************************************************************************/
281 * Unfortunately, earlier versions of smbclient/libsmbclient
282 * don't send this "standard" writeX header. I've fixed this
283 * for 3.2 but we'll use the old method with earlier versions.
284 * Windows and CIFSFS at least use this standard size. Not
288 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
289 (2*14) + /* word count (including bcc) */ \
292 static NTSTATUS
receive_smb_raw_talloc_partial_read(TALLOC_CTX
*mem_ctx
,
293 const char lenbuf
[4],
294 struct smbd_server_connection
*sconn
,
297 unsigned int timeout
,
301 /* Size of a WRITEX call (+4 byte len). */
302 char writeX_header
[4 + STANDARD_WRITE_AND_X_HEADER_SIZE
];
303 ssize_t len
= smb_len_large(lenbuf
); /* Could be a UNIX large writeX. */
307 memcpy(writeX_header
, lenbuf
, 4);
309 status
= read_fd_with_timeout(
310 sock
, writeX_header
+ 4,
311 STANDARD_WRITE_AND_X_HEADER_SIZE
,
312 STANDARD_WRITE_AND_X_HEADER_SIZE
,
315 if (!NT_STATUS_IS_OK(status
)) {
316 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
318 tsocket_address_string(sconn
->remote_address
,
325 * Ok - now try and see if this is a possible
329 if (is_valid_writeX_buffer(sconn
, (uint8_t *)writeX_header
)) {
331 * If the data offset is beyond what
332 * we've read, drain the extra bytes.
334 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
337 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
338 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
339 if (drain_socket(sock
, drain
) != drain
) {
340 smb_panic("receive_smb_raw_talloc_partial_read:"
341 " failed to drain pending bytes");
344 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
347 /* Spoof down the length and null out the bcc. */
348 set_message_bcc(writeX_header
, 0);
349 newlen
= smb_len(writeX_header
);
351 /* Copy the header we've written. */
353 *buffer
= (char *)talloc_memdup(mem_ctx
,
355 sizeof(writeX_header
));
357 if (*buffer
== NULL
) {
358 DEBUG(0, ("Could not allocate inbuf of length %d\n",
359 (int)sizeof(writeX_header
)));
360 return NT_STATUS_NO_MEMORY
;
363 /* Work out the remaining bytes. */
364 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
365 *len_ret
= newlen
+ 4;
369 if (!valid_packet_size(len
)) {
370 return NT_STATUS_INVALID_PARAMETER
;
374 * Not a valid writeX call. Just do the standard
378 *buffer
= talloc_array(mem_ctx
, char, len
+4);
380 if (*buffer
== NULL
) {
381 DEBUG(0, ("Could not allocate inbuf of length %d\n",
383 return NT_STATUS_NO_MEMORY
;
386 /* Copy in what we already read. */
389 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
390 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
393 status
= read_packet_remainder(
395 (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
398 if (!NT_STATUS_IS_OK(status
)) {
399 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
409 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
,
410 struct smbd_server_connection
*sconn
,
412 char **buffer
, unsigned int timeout
,
413 size_t *p_unread
, size_t *plen
)
417 int min_recv_size
= lp_min_receive_file_size();
422 status
= read_smb_length_return_keepalive(sock
, lenbuf
, timeout
,
424 if (!NT_STATUS_IS_OK(status
)) {
428 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
429 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
430 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
431 !srv_is_signing_active(sconn
) &&
432 sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
434 return receive_smb_raw_talloc_partial_read(
435 mem_ctx
, lenbuf
, sconn
, sock
, buffer
, timeout
,
439 if (!valid_packet_size(len
)) {
440 return NT_STATUS_INVALID_PARAMETER
;
444 * The +4 here can't wrap, we've checked the length above already.
447 *buffer
= talloc_array(mem_ctx
, char, len
+4);
449 if (*buffer
== NULL
) {
450 DEBUG(0, ("Could not allocate inbuf of length %d\n",
452 return NT_STATUS_NO_MEMORY
;
455 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
457 status
= read_packet_remainder(sock
, (*buffer
)+4, timeout
, len
);
458 if (!NT_STATUS_IS_OK(status
)) {
466 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
,
467 struct smbd_server_connection
*sconn
,
469 char **buffer
, unsigned int timeout
,
470 size_t *p_unread
, bool *p_encrypted
,
473 bool trusted_channel
)
478 *p_encrypted
= false;
480 status
= receive_smb_raw_talloc(mem_ctx
, sconn
, sock
, buffer
, timeout
,
482 if (!NT_STATUS_IS_OK(status
)) {
483 DEBUG(NT_STATUS_EQUAL(status
, NT_STATUS_END_OF_FILE
)?5:1,
484 ("receive_smb_raw_talloc failed for client %s "
485 "read error = %s.\n",
486 tsocket_address_string(sconn
->remote_address
,
488 nt_errstr(status
)) );
492 if (is_encrypted_packet(sconn
, (uint8_t *)*buffer
)) {
493 status
= srv_decrypt_buffer(sconn
, *buffer
);
494 if (!NT_STATUS_IS_OK(status
)) {
495 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
496 "incoming packet! Error %s\n",
497 nt_errstr(status
) ));
503 /* Check the incoming SMB signature. */
504 if (!srv_check_sign_mac(sconn
, *buffer
, seqnum
, trusted_channel
)) {
505 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
506 "incoming packet!\n"));
507 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
515 * Initialize a struct smb_request from an inbuf
518 static bool init_smb_request(struct smb_request
*req
,
519 struct smbd_server_connection
*sconn
,
521 size_t unread_bytes
, bool encrypted
,
524 struct smbXsrv_tcon
*tcon
;
527 size_t req_size
= smb_len(inbuf
) + 4;
529 /* Ensure we have at least smb_size bytes. */
530 if (req_size
< smb_size
) {
531 DEBUG(0,("init_smb_request: invalid request size %u\n",
532 (unsigned int)req_size
));
536 req
->request_time
= timeval_current();
537 now
= timeval_to_nttime(&req
->request_time
);
539 req
->cmd
= CVAL(inbuf
, smb_com
);
540 req
->flags2
= SVAL(inbuf
, smb_flg2
);
541 req
->smbpid
= SVAL(inbuf
, smb_pid
);
542 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
543 req
->seqnum
= seqnum
;
544 req
->vuid
= SVAL(inbuf
, smb_uid
);
545 req
->tid
= SVAL(inbuf
, smb_tid
);
546 req
->wct
= CVAL(inbuf
, smb_wct
);
547 req
->vwv
= (const uint16_t *)(inbuf
+smb_vwv
);
548 req
->buflen
= smb_buflen(inbuf
);
549 req
->buf
= (const uint8_t *)smb_buf_const(inbuf
);
550 req
->unread_bytes
= unread_bytes
;
551 req
->encrypted
= encrypted
;
553 status
= smb1srv_tcon_lookup(sconn
->conn
, req
->tid
, now
, &tcon
);
554 if (NT_STATUS_IS_OK(status
)) {
555 req
->conn
= tcon
->compat
;
559 req
->chain_fsp
= NULL
;
561 req
->priv_paths
= NULL
;
563 smb_init_perfcount_data(&req
->pcd
);
565 /* Ensure we have at least wct words and 2 bytes of bcc. */
566 if (smb_size
+ req
->wct
*2 > req_size
) {
567 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
568 (unsigned int)req
->wct
,
569 (unsigned int)req_size
));
572 /* Ensure bcc is correct. */
573 if (((const uint8_t *)smb_buf_const(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
574 DEBUG(0,("init_smb_request: invalid bcc number %u "
575 "(wct = %u, size %u)\n",
576 (unsigned int)req
->buflen
,
577 (unsigned int)req
->wct
,
578 (unsigned int)req_size
));
586 static void process_smb(struct smbd_server_connection
*conn
,
587 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
588 uint32_t seqnum
, bool encrypted
,
589 struct smb_perfcount_data
*deferred_pcd
);
591 static void smbd_deferred_open_timer(struct tevent_context
*ev
,
592 struct tevent_timer
*te
,
593 struct timeval _tval
,
596 struct pending_message_list
*msg
= talloc_get_type(private_data
,
597 struct pending_message_list
);
598 struct smbd_server_connection
*sconn
= msg
->sconn
;
599 TALLOC_CTX
*mem_ctx
= talloc_tos();
600 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
603 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
606 exit_server("smbd_deferred_open_timer: talloc failed\n");
610 /* We leave this message on the queue so the open code can
611 know this is a retry. */
612 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
613 (unsigned long long)mid
));
615 /* Mark the message as processed so this is not
616 * re-processed in error. */
617 msg
->processed
= true;
619 process_smb(sconn
, inbuf
,
621 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
623 /* If it's still there and was processed, remove it. */
624 msg
= get_deferred_open_message_smb(sconn
, mid
);
625 if (msg
&& msg
->processed
) {
626 remove_deferred_open_message_smb(sconn
, mid
);
630 /****************************************************************************
631 Function to push a message onto the tail of a linked list of smb messages ready
633 ****************************************************************************/
635 static bool push_queued_message(struct smb_request
*req
,
636 struct timeval request_time
,
637 struct timeval end_time
,
638 char *private_data
, size_t private_len
)
640 int msg_len
= smb_len(req
->inbuf
) + 4;
641 struct pending_message_list
*msg
;
643 msg
= talloc_zero(NULL
, struct pending_message_list
);
646 DEBUG(0,("push_message: malloc fail (1)\n"));
649 msg
->sconn
= req
->sconn
;
651 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
652 if(msg
->buf
.data
== NULL
) {
653 DEBUG(0,("push_message: malloc fail (2)\n"));
658 msg
->request_time
= request_time
;
659 msg
->seqnum
= req
->seqnum
;
660 msg
->encrypted
= req
->encrypted
;
661 msg
->processed
= false;
662 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
665 msg
->private_data
= data_blob_talloc(msg
, private_data
,
667 if (msg
->private_data
.data
== NULL
) {
668 DEBUG(0,("push_message: malloc fail (3)\n"));
675 msg
->te
= tevent_add_timer(msg
->sconn
->ev_ctx
,
678 smbd_deferred_open_timer
,
681 DEBUG(0,("push_message: event_add_timed failed\n"));
687 DLIST_ADD_END(req
->sconn
->deferred_open_queue
, msg
,
688 struct pending_message_list
*);
690 DEBUG(10,("push_message: pushed message length %u on "
691 "deferred_open_queue\n", (unsigned int)msg_len
));
696 /****************************************************************************
697 Function to delete a sharing violation open message by mid.
698 ****************************************************************************/
700 void remove_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
703 struct pending_message_list
*pml
;
705 if (sconn
->using_smb2
) {
706 remove_deferred_open_message_smb2(sconn
, mid
);
710 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
711 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
712 DEBUG(10,("remove_deferred_open_message_smb: "
713 "deleting mid %llu len %u\n",
714 (unsigned long long)mid
,
715 (unsigned int)pml
->buf
.length
));
716 DLIST_REMOVE(sconn
->deferred_open_queue
, pml
);
723 /****************************************************************************
724 Move a sharing violation open retry message to the front of the list and
725 schedule it for immediate processing.
726 ****************************************************************************/
728 bool schedule_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
731 struct pending_message_list
*pml
;
734 if (sconn
->using_smb2
) {
735 return schedule_deferred_open_message_smb2(sconn
, mid
);
738 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
739 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
741 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
744 (unsigned long long)msg_mid
));
746 if (mid
== msg_mid
) {
747 struct tevent_timer
*te
;
749 if (pml
->processed
) {
750 /* A processed message should not be
752 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
753 "message mid %llu was already processed\n",
754 (unsigned long long)msg_mid
));
758 DEBUG(10,("schedule_deferred_open_message_smb: "
759 "scheduling mid %llu\n",
760 (unsigned long long)mid
));
762 te
= tevent_add_timer(pml
->sconn
->ev_ctx
,
765 smbd_deferred_open_timer
,
768 DEBUG(10,("schedule_deferred_open_message_smb: "
769 "event_add_timed() failed, "
770 "skipping mid %llu\n",
771 (unsigned long long)msg_mid
));
774 TALLOC_FREE(pml
->te
);
776 DLIST_PROMOTE(sconn
->deferred_open_queue
, pml
);
781 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
782 "find message mid %llu\n",
783 (unsigned long long)mid
));
788 /****************************************************************************
789 Return true if this mid is on the deferred queue and was not yet processed.
790 ****************************************************************************/
792 bool open_was_deferred(struct smbd_server_connection
*sconn
, uint64_t mid
)
794 struct pending_message_list
*pml
;
796 if (sconn
->using_smb2
) {
797 return open_was_deferred_smb2(sconn
, mid
);
800 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
801 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
808 /****************************************************************************
809 Return the message queued by this mid.
810 ****************************************************************************/
812 static struct pending_message_list
*get_deferred_open_message_smb(
813 struct smbd_server_connection
*sconn
, uint64_t mid
)
815 struct pending_message_list
*pml
;
817 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
818 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
825 /****************************************************************************
826 Get the state data queued by this mid.
827 ****************************************************************************/
829 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
830 struct timeval
*p_request_time
,
833 struct pending_message_list
*pml
;
835 if (smbreq
->sconn
->using_smb2
) {
836 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
841 pml
= get_deferred_open_message_smb(smbreq
->sconn
, smbreq
->mid
);
845 if (p_request_time
) {
846 *p_request_time
= pml
->request_time
;
849 *pp_state
= (void *)pml
->private_data
.data
;
854 /****************************************************************************
855 Function to push a deferred open smb message onto a linked list of local smb
856 messages ready for processing.
857 ****************************************************************************/
859 bool push_deferred_open_message_smb(struct smb_request
*req
,
860 struct timeval request_time
,
861 struct timeval timeout
,
863 char *private_data
, size_t priv_len
)
865 struct timeval end_time
;
868 return push_deferred_open_message_smb2(req
->smb2req
,
876 if (req
->unread_bytes
) {
877 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
878 "unread_bytes = %u\n",
879 (unsigned int)req
->unread_bytes
));
880 smb_panic("push_deferred_open_message_smb: "
881 "logic error unread_bytes != 0" );
884 end_time
= timeval_sum(&request_time
, &timeout
);
886 DEBUG(10,("push_deferred_open_message_smb: pushing message "
887 "len %u mid %llu timeout time [%u.%06u]\n",
888 (unsigned int) smb_len(req
->inbuf
)+4,
889 (unsigned long long)req
->mid
,
890 (unsigned int)end_time
.tv_sec
,
891 (unsigned int)end_time
.tv_usec
));
893 return push_queued_message(req
, request_time
, end_time
,
894 private_data
, priv_len
);
897 static void smbd_sig_term_handler(struct tevent_context
*ev
,
898 struct tevent_signal
*se
,
904 exit_server_cleanly("termination signal");
907 void smbd_setup_sig_term_handler(struct smbd_server_connection
*sconn
)
909 struct tevent_signal
*se
;
911 se
= tevent_add_signal(sconn
->ev_ctx
,
914 smbd_sig_term_handler
,
917 exit_server("failed to setup SIGTERM handler");
921 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
922 struct tevent_signal
*se
,
928 struct smbd_server_connection
*sconn
=
929 talloc_get_type_abort(private_data
,
930 struct smbd_server_connection
);
932 change_to_root_user();
933 DEBUG(1,("Reloading services after SIGHUP\n"));
934 reload_services(sconn
, conn_snum_used
, false);
937 void smbd_setup_sig_hup_handler(struct smbd_server_connection
*sconn
)
939 struct tevent_signal
*se
;
941 se
= tevent_add_signal(sconn
->ev_ctx
,
944 smbd_sig_hup_handler
,
947 exit_server("failed to setup SIGHUP handler");
951 static void smbd_conf_updated(struct messaging_context
*msg
,
954 struct server_id server_id
,
957 struct smbd_server_connection
*sconn
=
958 talloc_get_type_abort(private_data
,
959 struct smbd_server_connection
);
961 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
962 "updated. Reloading.\n"));
963 change_to_root_user();
964 reload_services(sconn
, conn_snum_used
, false);
968 * Only allow 5 outstanding trans requests. We're allocating memory, so
972 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
975 for (; list
!= NULL
; list
= list
->next
) {
977 if (list
->mid
== mid
) {
978 return NT_STATUS_INVALID_PARAMETER
;
984 return NT_STATUS_INSUFFICIENT_RESOURCES
;
991 These flags determine some of the permissions required to do an operation
993 Note that I don't set NEED_WRITE on some write operations because they
994 are used by some brain-dead clients when printing, and I don't want to
995 force write permissions on print services.
997 #define AS_USER (1<<0)
998 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
999 #define TIME_INIT (1<<2)
1000 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1001 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1002 #define DO_CHDIR (1<<6)
1005 define a list of possible SMB messages and their corresponding
1006 functions. Any message that has a NULL function is unimplemented -
1007 please feel free to contribute implementations!
1009 static const struct smb_message_struct
{
1011 void (*fn
)(struct smb_request
*req
);
1013 } smb_messages
[256] = {
1015 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1016 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1017 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1018 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1019 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1020 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1021 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1022 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1023 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1024 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1025 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1026 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1027 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1028 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1029 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1030 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1031 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1032 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1033 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1034 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1035 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1036 /* 0x15 */ { NULL
, NULL
, 0 },
1037 /* 0x16 */ { NULL
, NULL
, 0 },
1038 /* 0x17 */ { NULL
, NULL
, 0 },
1039 /* 0x18 */ { NULL
, NULL
, 0 },
1040 /* 0x19 */ { NULL
, NULL
, 0 },
1041 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1042 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1043 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1044 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1045 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1046 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1047 /* 0x20 */ { "SMBwritec", NULL
,0},
1048 /* 0x21 */ { NULL
, NULL
, 0 },
1049 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1050 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1051 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1052 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1053 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1054 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1055 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1056 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1057 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1058 /* 0x2b */ { "SMBecho",reply_echo
,0},
1059 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1060 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1061 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1062 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1063 /* 0x30 */ { NULL
, NULL
, 0 },
1064 /* 0x31 */ { NULL
, NULL
, 0 },
1065 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1066 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1067 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1068 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1069 /* 0x36 */ { NULL
, NULL
, 0 },
1070 /* 0x37 */ { NULL
, NULL
, 0 },
1071 /* 0x38 */ { NULL
, NULL
, 0 },
1072 /* 0x39 */ { NULL
, NULL
, 0 },
1073 /* 0x3a */ { NULL
, NULL
, 0 },
1074 /* 0x3b */ { NULL
, NULL
, 0 },
1075 /* 0x3c */ { NULL
, NULL
, 0 },
1076 /* 0x3d */ { NULL
, NULL
, 0 },
1077 /* 0x3e */ { NULL
, NULL
, 0 },
1078 /* 0x3f */ { NULL
, NULL
, 0 },
1079 /* 0x40 */ { NULL
, NULL
, 0 },
1080 /* 0x41 */ { NULL
, NULL
, 0 },
1081 /* 0x42 */ { NULL
, NULL
, 0 },
1082 /* 0x43 */ { NULL
, NULL
, 0 },
1083 /* 0x44 */ { NULL
, NULL
, 0 },
1084 /* 0x45 */ { NULL
, NULL
, 0 },
1085 /* 0x46 */ { NULL
, NULL
, 0 },
1086 /* 0x47 */ { NULL
, NULL
, 0 },
1087 /* 0x48 */ { NULL
, NULL
, 0 },
1088 /* 0x49 */ { NULL
, NULL
, 0 },
1089 /* 0x4a */ { NULL
, NULL
, 0 },
1090 /* 0x4b */ { NULL
, NULL
, 0 },
1091 /* 0x4c */ { NULL
, NULL
, 0 },
1092 /* 0x4d */ { NULL
, NULL
, 0 },
1093 /* 0x4e */ { NULL
, NULL
, 0 },
1094 /* 0x4f */ { NULL
, NULL
, 0 },
1095 /* 0x50 */ { NULL
, NULL
, 0 },
1096 /* 0x51 */ { NULL
, NULL
, 0 },
1097 /* 0x52 */ { NULL
, NULL
, 0 },
1098 /* 0x53 */ { NULL
, NULL
, 0 },
1099 /* 0x54 */ { NULL
, NULL
, 0 },
1100 /* 0x55 */ { NULL
, NULL
, 0 },
1101 /* 0x56 */ { NULL
, NULL
, 0 },
1102 /* 0x57 */ { NULL
, NULL
, 0 },
1103 /* 0x58 */ { NULL
, NULL
, 0 },
1104 /* 0x59 */ { NULL
, NULL
, 0 },
1105 /* 0x5a */ { NULL
, NULL
, 0 },
1106 /* 0x5b */ { NULL
, NULL
, 0 },
1107 /* 0x5c */ { NULL
, NULL
, 0 },
1108 /* 0x5d */ { NULL
, NULL
, 0 },
1109 /* 0x5e */ { NULL
, NULL
, 0 },
1110 /* 0x5f */ { NULL
, NULL
, 0 },
1111 /* 0x60 */ { NULL
, NULL
, 0 },
1112 /* 0x61 */ { NULL
, NULL
, 0 },
1113 /* 0x62 */ { NULL
, NULL
, 0 },
1114 /* 0x63 */ { NULL
, NULL
, 0 },
1115 /* 0x64 */ { NULL
, NULL
, 0 },
1116 /* 0x65 */ { NULL
, NULL
, 0 },
1117 /* 0x66 */ { NULL
, NULL
, 0 },
1118 /* 0x67 */ { NULL
, NULL
, 0 },
1119 /* 0x68 */ { NULL
, NULL
, 0 },
1120 /* 0x69 */ { NULL
, NULL
, 0 },
1121 /* 0x6a */ { NULL
, NULL
, 0 },
1122 /* 0x6b */ { NULL
, NULL
, 0 },
1123 /* 0x6c */ { NULL
, NULL
, 0 },
1124 /* 0x6d */ { NULL
, NULL
, 0 },
1125 /* 0x6e */ { NULL
, NULL
, 0 },
1126 /* 0x6f */ { NULL
, NULL
, 0 },
1127 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1128 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1129 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1130 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1131 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1132 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1133 /* 0x76 */ { NULL
, NULL
, 0 },
1134 /* 0x77 */ { NULL
, NULL
, 0 },
1135 /* 0x78 */ { NULL
, NULL
, 0 },
1136 /* 0x79 */ { NULL
, NULL
, 0 },
1137 /* 0x7a */ { NULL
, NULL
, 0 },
1138 /* 0x7b */ { NULL
, NULL
, 0 },
1139 /* 0x7c */ { NULL
, NULL
, 0 },
1140 /* 0x7d */ { NULL
, NULL
, 0 },
1141 /* 0x7e */ { NULL
, NULL
, 0 },
1142 /* 0x7f */ { NULL
, NULL
, 0 },
1143 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1144 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1145 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1146 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1147 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1148 /* 0x85 */ { NULL
, NULL
, 0 },
1149 /* 0x86 */ { NULL
, NULL
, 0 },
1150 /* 0x87 */ { NULL
, NULL
, 0 },
1151 /* 0x88 */ { NULL
, NULL
, 0 },
1152 /* 0x89 */ { NULL
, NULL
, 0 },
1153 /* 0x8a */ { NULL
, NULL
, 0 },
1154 /* 0x8b */ { NULL
, NULL
, 0 },
1155 /* 0x8c */ { NULL
, NULL
, 0 },
1156 /* 0x8d */ { NULL
, NULL
, 0 },
1157 /* 0x8e */ { NULL
, NULL
, 0 },
1158 /* 0x8f */ { NULL
, NULL
, 0 },
1159 /* 0x90 */ { NULL
, NULL
, 0 },
1160 /* 0x91 */ { NULL
, NULL
, 0 },
1161 /* 0x92 */ { NULL
, NULL
, 0 },
1162 /* 0x93 */ { NULL
, NULL
, 0 },
1163 /* 0x94 */ { NULL
, NULL
, 0 },
1164 /* 0x95 */ { NULL
, NULL
, 0 },
1165 /* 0x96 */ { NULL
, NULL
, 0 },
1166 /* 0x97 */ { NULL
, NULL
, 0 },
1167 /* 0x98 */ { NULL
, NULL
, 0 },
1168 /* 0x99 */ { NULL
, NULL
, 0 },
1169 /* 0x9a */ { NULL
, NULL
, 0 },
1170 /* 0x9b */ { NULL
, NULL
, 0 },
1171 /* 0x9c */ { NULL
, NULL
, 0 },
1172 /* 0x9d */ { NULL
, NULL
, 0 },
1173 /* 0x9e */ { NULL
, NULL
, 0 },
1174 /* 0x9f */ { NULL
, NULL
, 0 },
1175 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1176 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1177 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1178 /* 0xa3 */ { NULL
, NULL
, 0 },
1179 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1180 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1181 /* 0xa6 */ { NULL
, NULL
, 0 },
1182 /* 0xa7 */ { NULL
, NULL
, 0 },
1183 /* 0xa8 */ { NULL
, NULL
, 0 },
1184 /* 0xa9 */ { NULL
, NULL
, 0 },
1185 /* 0xaa */ { NULL
, NULL
, 0 },
1186 /* 0xab */ { NULL
, NULL
, 0 },
1187 /* 0xac */ { NULL
, NULL
, 0 },
1188 /* 0xad */ { NULL
, NULL
, 0 },
1189 /* 0xae */ { NULL
, NULL
, 0 },
1190 /* 0xaf */ { NULL
, NULL
, 0 },
1191 /* 0xb0 */ { NULL
, NULL
, 0 },
1192 /* 0xb1 */ { NULL
, NULL
, 0 },
1193 /* 0xb2 */ { NULL
, NULL
, 0 },
1194 /* 0xb3 */ { NULL
, NULL
, 0 },
1195 /* 0xb4 */ { NULL
, NULL
, 0 },
1196 /* 0xb5 */ { NULL
, NULL
, 0 },
1197 /* 0xb6 */ { NULL
, NULL
, 0 },
1198 /* 0xb7 */ { NULL
, NULL
, 0 },
1199 /* 0xb8 */ { NULL
, NULL
, 0 },
1200 /* 0xb9 */ { NULL
, NULL
, 0 },
1201 /* 0xba */ { NULL
, NULL
, 0 },
1202 /* 0xbb */ { NULL
, NULL
, 0 },
1203 /* 0xbc */ { NULL
, NULL
, 0 },
1204 /* 0xbd */ { NULL
, NULL
, 0 },
1205 /* 0xbe */ { NULL
, NULL
, 0 },
1206 /* 0xbf */ { NULL
, NULL
, 0 },
1207 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1208 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1209 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1210 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1211 /* 0xc4 */ { NULL
, NULL
, 0 },
1212 /* 0xc5 */ { NULL
, NULL
, 0 },
1213 /* 0xc6 */ { NULL
, NULL
, 0 },
1214 /* 0xc7 */ { NULL
, NULL
, 0 },
1215 /* 0xc8 */ { NULL
, NULL
, 0 },
1216 /* 0xc9 */ { NULL
, NULL
, 0 },
1217 /* 0xca */ { NULL
, NULL
, 0 },
1218 /* 0xcb */ { NULL
, NULL
, 0 },
1219 /* 0xcc */ { NULL
, NULL
, 0 },
1220 /* 0xcd */ { NULL
, NULL
, 0 },
1221 /* 0xce */ { NULL
, NULL
, 0 },
1222 /* 0xcf */ { NULL
, NULL
, 0 },
1223 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1224 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1225 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1226 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1227 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1228 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1229 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1230 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1231 /* 0xd8 */ { NULL
, NULL
, 0 },
1232 /* 0xd9 */ { NULL
, NULL
, 0 },
1233 /* 0xda */ { NULL
, NULL
, 0 },
1234 /* 0xdb */ { NULL
, NULL
, 0 },
1235 /* 0xdc */ { NULL
, NULL
, 0 },
1236 /* 0xdd */ { NULL
, NULL
, 0 },
1237 /* 0xde */ { NULL
, NULL
, 0 },
1238 /* 0xdf */ { NULL
, NULL
, 0 },
1239 /* 0xe0 */ { NULL
, NULL
, 0 },
1240 /* 0xe1 */ { NULL
, NULL
, 0 },
1241 /* 0xe2 */ { NULL
, NULL
, 0 },
1242 /* 0xe3 */ { NULL
, NULL
, 0 },
1243 /* 0xe4 */ { NULL
, NULL
, 0 },
1244 /* 0xe5 */ { NULL
, NULL
, 0 },
1245 /* 0xe6 */ { NULL
, NULL
, 0 },
1246 /* 0xe7 */ { NULL
, NULL
, 0 },
1247 /* 0xe8 */ { NULL
, NULL
, 0 },
1248 /* 0xe9 */ { NULL
, NULL
, 0 },
1249 /* 0xea */ { NULL
, NULL
, 0 },
1250 /* 0xeb */ { NULL
, NULL
, 0 },
1251 /* 0xec */ { NULL
, NULL
, 0 },
1252 /* 0xed */ { NULL
, NULL
, 0 },
1253 /* 0xee */ { NULL
, NULL
, 0 },
1254 /* 0xef */ { NULL
, NULL
, 0 },
1255 /* 0xf0 */ { NULL
, NULL
, 0 },
1256 /* 0xf1 */ { NULL
, NULL
, 0 },
1257 /* 0xf2 */ { NULL
, NULL
, 0 },
1258 /* 0xf3 */ { NULL
, NULL
, 0 },
1259 /* 0xf4 */ { NULL
, NULL
, 0 },
1260 /* 0xf5 */ { NULL
, NULL
, 0 },
1261 /* 0xf6 */ { NULL
, NULL
, 0 },
1262 /* 0xf7 */ { NULL
, NULL
, 0 },
1263 /* 0xf8 */ { NULL
, NULL
, 0 },
1264 /* 0xf9 */ { NULL
, NULL
, 0 },
1265 /* 0xfa */ { NULL
, NULL
, 0 },
1266 /* 0xfb */ { NULL
, NULL
, 0 },
1267 /* 0xfc */ { NULL
, NULL
, 0 },
1268 /* 0xfd */ { NULL
, NULL
, 0 },
1269 /* 0xfe */ { NULL
, NULL
, 0 },
1270 /* 0xff */ { NULL
, NULL
, 0 }
1274 /*******************************************************************
1275 allocate and initialize a reply packet
1276 ********************************************************************/
1278 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1279 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1282 size_t smb_len
= MIN_SMB_SIZE
+ VWV(num_words
) + num_bytes
;
1285 * Protect against integer wrap.
1286 * The SMB layer reply can be up to 0xFFFFFF bytes.
1288 if ((num_bytes
> 0xffffff) || (smb_len
> 0xffffff)) {
1290 if (asprintf(&msg
, "num_bytes too large: %u",
1291 (unsigned)num_bytes
) == -1) {
1292 msg
= discard_const_p(char, "num_bytes too large");
1298 * Here we include the NBT header for now.
1300 *outbuf
= talloc_array(mem_ctx
, char,
1301 NBT_HDR_SIZE
+ smb_len
);
1302 if (*outbuf
== NULL
) {
1306 construct_reply_common(req
, inbuf
, *outbuf
);
1307 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1309 * Zero out the word area, the caller has to take care of the bcc area
1312 if (num_words
!= 0) {
1313 memset(*outbuf
+ (NBT_HDR_SIZE
+ HDR_VWV
), 0, VWV(num_words
));
1319 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1322 if (!create_outbuf(req
, req
, (const char *)req
->inbuf
, &outbuf
, num_words
,
1324 smb_panic("could not allocate output buffer\n");
1326 req
->outbuf
= (uint8_t *)outbuf
;
1330 /*******************************************************************
1331 Dump a packet to a file.
1332 ********************************************************************/
1334 static void smb_dump(const char *name
, int type
, const char *data
)
1339 if (DEBUGLEVEL
< 50) {
1343 len
= smb_len_tcp(data
)+4;
1344 for (i
=1;i
<100;i
++) {
1345 fname
= talloc_asprintf(talloc_tos(),
1349 type
? "req" : "resp");
1350 if (fname
== NULL
) {
1353 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1354 if (fd
!= -1 || errno
!= EEXIST
) break;
1358 ssize_t ret
= write(fd
, data
, len
);
1360 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1362 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1367 /****************************************************************************
1368 Prepare everything for calling the actual request function, and potentially
1369 call the request function via the "new" interface.
1371 Return False if the "legacy" function needs to be called, everything is
1374 Return True if we're done.
1376 I know this API sucks, but it is the one with the least code change I could
1378 ****************************************************************************/
1380 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
)
1383 uint64_t session_tag
;
1384 connection_struct
*conn
= NULL
;
1385 struct smbd_server_connection
*sconn
= req
->sconn
;
1386 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1387 struct smbXsrv_session
*session
= NULL
;
1392 if (smb_messages
[type
].fn
== NULL
) {
1393 DEBUG(0,("Unknown message type %d!\n",type
));
1394 smb_dump("Unknown", 1, (const char *)req
->inbuf
);
1395 reply_unknown_new(req
, type
);
1399 flags
= smb_messages
[type
].flags
;
1401 /* In share mode security we must ignore the vuid. */
1402 session_tag
= req
->vuid
;
1405 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1406 (int)getpid(), (unsigned long)conn
));
1408 smb_dump(smb_fn_name(type
), 1, (const char *)req
->inbuf
);
1410 /* Ensure this value is replaced in the incoming packet. */
1411 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_uid
,session_tag
);
1414 * Ensure the correct username is in current_user_info. This is a
1415 * really ugly bugfix for problems with multiple session_setup_and_X's
1416 * being done and allowing %U and %G substitutions to work correctly.
1417 * There is a reason this code is done here, don't move it unless you
1418 * know what you're doing... :-).
1423 * lookup an existing session
1425 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1426 * here, the main check is still in change_to_user()
1428 status
= smb1srv_session_lookup(sconn
->conn
,
1432 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
1435 status
= NT_STATUS_OK
;
1438 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1439 (unsigned long long)session_tag
,
1440 (unsigned long long)req
->mid
));
1441 reply_nterror(req
, NT_STATUS_NETWORK_SESSION_EXPIRED
);
1446 if (session_tag
!= sconn
->conn
->last_session_id
) {
1447 struct user_struct
*vuser
= NULL
;
1449 sconn
->conn
->last_session_id
= session_tag
;
1451 vuser
= session
->compat
;
1454 set_current_user_info(
1455 vuser
->session_info
->unix_info
->sanitized_username
,
1456 vuser
->session_info
->unix_info
->unix_name
,
1457 vuser
->session_info
->info
->domain_name
);
1461 /* Does this call need to be run as the connected user? */
1462 if (flags
& AS_USER
) {
1464 /* Does this call need a valid tree connection? */
1467 * Amazingly, the error code depends on the command
1470 if (type
== SMBntcreateX
) {
1471 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1473 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1478 if (!change_to_user(conn
,session_tag
)) {
1479 DEBUG(0, ("Error: Could not change to user. Removing "
1480 "deferred open, mid=%llu.\n",
1481 (unsigned long long)req
->mid
));
1482 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1486 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1488 /* Does it need write permission? */
1489 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1490 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1494 /* IPC services are limited */
1495 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1496 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1500 /* This call needs to be run as root */
1501 change_to_root_user();
1504 /* load service specific parameters */
1506 if (req
->encrypted
) {
1507 conn
->encrypted_tid
= true;
1508 /* encrypted required from now on. */
1509 conn
->encrypt_level
= SMB_SIGNING_REQUIRED
;
1510 } else if (ENCRYPTION_REQUIRED(conn
)) {
1511 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1512 DEBUG(1,("service[%s] requires encryption"
1513 "%s ACCESS_DENIED. mid=%llu\n",
1514 lp_servicename(talloc_tos(), SNUM(conn
)),
1516 (unsigned long long)req
->mid
));
1517 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1522 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1523 (flags
& (AS_USER
|DO_CHDIR
)
1525 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1528 conn
->num_smb_operations
++;
1532 * Does this protocol need to be run as guest? (Only archane
1533 * messenger service requests have this...)
1535 if (flags
& AS_GUEST
) {
1539 if (!change_to_guest()) {
1540 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1544 raddr
= tsocket_address_inet_addr_string(sconn
->remote_address
,
1546 if (raddr
== NULL
) {
1547 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1552 * Haven't we checked this in smbd_process already???
1555 ok
= allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1556 sconn
->remote_hostname
, raddr
);
1560 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1565 smb_messages
[type
].fn(req
);
1569 /****************************************************************************
1570 Construct a reply to the incoming packet.
1571 ****************************************************************************/
1573 static void construct_reply(struct smbd_server_connection
*sconn
,
1574 char *inbuf
, int size
, size_t unread_bytes
,
1575 uint32_t seqnum
, bool encrypted
,
1576 struct smb_perfcount_data
*deferred_pcd
)
1578 connection_struct
*conn
;
1579 struct smb_request
*req
;
1581 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1582 smb_panic("could not allocate smb_request");
1585 if (!init_smb_request(req
, sconn
, (uint8
*)inbuf
, unread_bytes
,
1586 encrypted
, seqnum
)) {
1587 exit_server_cleanly("Invalid SMB request");
1590 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1592 /* we popped this message off the queue - keep original perf data */
1594 req
->pcd
= *deferred_pcd
;
1596 SMB_PERFCOUNT_START(&req
->pcd
);
1597 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1598 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1601 conn
= switch_message(req
->cmd
, req
);
1603 if (req
->outbuf
== NULL
) {
1607 if (CVAL(req
->outbuf
,0) == 0) {
1608 show_msg((char *)req
->outbuf
);
1611 if (!srv_send_smb(req
->sconn
,
1612 (char *)req
->outbuf
,
1613 true, req
->seqnum
+1,
1614 IS_CONN_ENCRYPTED(conn
)||req
->encrypted
,
1616 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1624 static void construct_reply_chain(struct smbd_server_connection
*sconn
,
1625 char *inbuf
, int size
, uint32_t seqnum
,
1627 struct smb_perfcount_data
*deferred_pcd
)
1629 struct smb_request
**reqs
= NULL
;
1630 struct smb_request
*req
;
1634 ok
= smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf
, sconn
, encrypted
,
1635 seqnum
, &reqs
, &num_reqs
);
1637 char errbuf
[smb_size
];
1638 error_packet(errbuf
, 0, 0, NT_STATUS_INVALID_PARAMETER
,
1639 __LINE__
, __FILE__
);
1640 if (!srv_send_smb(sconn
, errbuf
, true, seqnum
, encrypted
,
1642 exit_server_cleanly("construct_reply_chain: "
1643 "srv_send_smb failed.");
1649 req
->inbuf
= (uint8_t *)talloc_move(reqs
, &inbuf
);
1651 req
->conn
= switch_message(req
->cmd
, req
);
1653 if (req
->outbuf
== NULL
) {
1655 * Request has suspended itself, will come
1660 smb_request_done(req
);
1664 * To be called from an async SMB handler that is potentially chained
1665 * when it is finished for shipping.
1668 void smb_request_done(struct smb_request
*req
)
1670 struct smb_request
**reqs
= NULL
;
1671 struct smb_request
*first_req
;
1672 size_t i
, num_reqs
, next_index
;
1675 if (req
->chain
== NULL
) {
1681 num_reqs
= talloc_array_length(reqs
);
1683 for (i
=0; i
<num_reqs
; i
++) {
1684 if (reqs
[i
] == req
) {
1688 if (i
== num_reqs
) {
1690 * Invalid chain, should not happen
1692 status
= NT_STATUS_INTERNAL_ERROR
;
1697 while ((next_index
< num_reqs
) && (IVAL(req
->outbuf
, smb_rcls
) == 0)) {
1698 struct smb_request
*next
= reqs
[next_index
];
1699 struct smbXsrv_tcon
*tcon
;
1700 NTTIME now
= timeval_to_nttime(&req
->request_time
);
1702 next
->vuid
= SVAL(req
->outbuf
, smb_uid
);
1703 next
->tid
= SVAL(req
->outbuf
, smb_tid
);
1704 status
= smb1srv_tcon_lookup(req
->sconn
->conn
, req
->tid
,
1706 if (NT_STATUS_IS_OK(status
)) {
1707 req
->conn
= tcon
->compat
;
1711 next
->chain_fsp
= req
->chain_fsp
;
1712 next
->inbuf
= req
->inbuf
;
1715 req
->conn
= switch_message(req
->cmd
, req
);
1717 if (req
->outbuf
== NULL
) {
1719 * Request has suspended itself, will come
1727 first_req
= reqs
[0];
1729 for (i
=1; i
<next_index
; i
++) {
1732 ok
= smb_splice_chain(&first_req
->outbuf
, reqs
[i
]->outbuf
);
1734 status
= NT_STATUS_INTERNAL_ERROR
;
1739 SSVAL(first_req
->outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
1740 SSVAL(first_req
->outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
1743 * This scary statement intends to set the
1744 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1745 * to the value last_req->outbuf carries
1747 SSVAL(first_req
->outbuf
, smb_flg2
,
1748 (SVAL(first_req
->outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
1749 |(SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
1752 * Transfer the error codes from the subrequest to the main one
1754 SSVAL(first_req
->outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
1755 SSVAL(first_req
->outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
1758 first_req
->outbuf
, talloc_get_size(first_req
->outbuf
) - 4);
1761 if (!srv_send_smb(first_req
->sconn
,
1762 (char *)first_req
->outbuf
,
1763 true, first_req
->seqnum
+1,
1764 IS_CONN_ENCRYPTED(req
->conn
)||first_req
->encrypted
,
1766 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1769 TALLOC_FREE(req
); /* non-chained case */
1770 TALLOC_FREE(reqs
); /* chained case */
1775 char errbuf
[smb_size
];
1776 error_packet(errbuf
, 0, 0, status
, __LINE__
, __FILE__
);
1777 if (!srv_send_smb(req
->sconn
, errbuf
, true,
1778 req
->seqnum
+1, req
->encrypted
,
1780 exit_server_cleanly("construct_reply_chain: "
1781 "srv_send_smb failed.");
1784 TALLOC_FREE(req
); /* non-chained case */
1785 TALLOC_FREE(reqs
); /* chained case */
1788 /****************************************************************************
1789 Process an smb from the client
1790 ****************************************************************************/
1791 static void process_smb(struct smbd_server_connection
*sconn
,
1792 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1793 uint32_t seqnum
, bool encrypted
,
1794 struct smb_perfcount_data
*deferred_pcd
)
1796 int msg_type
= CVAL(inbuf
,0);
1798 DO_PROFILE_INC(smb_count
);
1800 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1802 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1803 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1805 if (msg_type
!= NBSSmessage
) {
1807 * NetBIOS session request, keepalive, etc.
1809 reply_special(sconn
, (char *)inbuf
, nread
);
1813 if (sconn
->using_smb2
) {
1814 /* At this point we're not really using smb2,
1815 * we make the decision here.. */
1816 if (smbd_is_smb2_header(inbuf
, nread
)) {
1817 smbd_smb2_first_negprot(sconn
, inbuf
, nread
);
1819 } else if (nread
>= smb_size
&& valid_smb_header(sconn
, inbuf
)
1820 && CVAL(inbuf
, smb_com
) != 0x72) {
1821 /* This is a non-negprot SMB1 packet.
1822 Disable SMB2 from now on. */
1823 sconn
->using_smb2
= false;
1827 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1828 * so subtract 4 from it. */
1829 if ((nread
< (smb_size
- 4)) || !valid_smb_header(sconn
, inbuf
)) {
1830 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1833 /* special magic for immediate exit */
1835 (IVAL(inbuf
, 4) == 0x74697865) &&
1836 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1837 uint8_t exitcode
= CVAL(inbuf
, 8);
1838 DEBUG(1, ("Exiting immediately with code %d\n",
1843 exit_server_cleanly("Non-SMB packet");
1846 show_msg((char *)inbuf
);
1848 if ((unread_bytes
== 0) && smb1_is_chain(inbuf
)) {
1849 construct_reply_chain(sconn
, (char *)inbuf
, nread
,
1850 seqnum
, encrypted
, deferred_pcd
);
1852 construct_reply(sconn
, (char *)inbuf
, nread
, unread_bytes
,
1853 seqnum
, encrypted
, deferred_pcd
);
1859 sconn
->num_requests
++;
1861 /* The timeout_processing function isn't run nearly
1862 often enough to implement 'max log size' without
1863 overrunning the size of the file by many megabytes.
1864 This is especially true if we are running at debug
1865 level 10. Checking every 50 SMBs is a nice
1866 tradeoff of performance vs log file size overrun. */
1868 if ((sconn
->num_requests
% 50) == 0 &&
1869 need_to_check_log_size()) {
1870 change_to_root_user();
1875 /****************************************************************************
1876 Return a string containing the function name of a SMB command.
1877 ****************************************************************************/
1879 const char *smb_fn_name(int type
)
1881 const char *unknown_name
= "SMBunknown";
1883 if (smb_messages
[type
].name
== NULL
)
1884 return(unknown_name
);
1886 return(smb_messages
[type
].name
);
1889 /****************************************************************************
1890 Helper functions for contruct_reply.
1891 ****************************************************************************/
1893 void add_to_common_flags2(uint32 v
)
1898 void remove_from_common_flags2(uint32 v
)
1900 common_flags2
&= ~v
;
1903 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1906 uint16_t in_flags2
= SVAL(inbuf
,smb_flg2
);
1907 uint16_t out_flags2
= common_flags2
;
1909 out_flags2
|= in_flags2
& FLAGS2_UNICODE_STRINGS
;
1910 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
;
1911 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
;
1913 srv_set_message(outbuf
,0,0,false);
1915 SCVAL(outbuf
, smb_com
, req
->cmd
);
1916 SIVAL(outbuf
,smb_rcls
,0);
1917 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1918 SSVAL(outbuf
,smb_flg2
, out_flags2
);
1919 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1920 memcpy(outbuf
+smb_ss_field
, inbuf
+smb_ss_field
, 8);
1922 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
1923 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
1924 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
1925 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
1928 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
1930 construct_reply_common(req
, (const char *)req
->inbuf
, outbuf
);
1934 * @brief Find the smb_cmd offset of the last command pushed
1935 * @param[in] buf The buffer we're building up
1936 * @retval Where can we put our next andx cmd?
1938 * While chaining requests, the "next" request we're looking at needs to put
1939 * its SMB_Command before the data the previous request already built up added
1940 * to the chain. Find the offset to the place where we have to put our cmd.
1943 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
1948 cmd
= CVAL(buf
, smb_com
);
1950 if (!is_andx_req(cmd
)) {
1956 while (CVAL(buf
, ofs
) != 0xff) {
1958 if (!is_andx_req(CVAL(buf
, ofs
))) {
1963 * ofs is from start of smb header, so add the 4 length
1964 * bytes. The next cmd is right after the wct field.
1966 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
1968 if (ofs
+4 >= talloc_get_size(buf
)) {
1978 * @brief Do the smb chaining at a buffer level
1979 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1980 * @param[in] andx_buf Buffer to be appended
1983 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
)
1985 uint8_t smb_command
= CVAL(andx_buf
, smb_com
);
1986 uint8_t wct
= CVAL(andx_buf
, smb_wct
);
1987 const uint16_t *vwv
= (const uint16_t *)(andx_buf
+ smb_vwv
);
1988 uint32_t num_bytes
= smb_buflen(andx_buf
);
1989 const uint8_t *bytes
= (const uint8_t *)smb_buf_const(andx_buf
);
1992 size_t old_size
, new_size
;
1994 size_t chain_padding
= 0;
1995 size_t andx_cmd_ofs
;
1998 old_size
= talloc_get_size(*poutbuf
);
2000 if ((old_size
% 4) != 0) {
2002 * Align the wct field of subsequent requests to a 4-byte
2005 chain_padding
= 4 - (old_size
% 4);
2009 * After the old request comes the new wct field (1 byte), the vwv's
2010 * and the num_bytes field.
2013 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
2014 new_size
+= num_bytes
;
2016 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
2017 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2018 (unsigned)new_size
));
2022 outbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, new_size
);
2023 if (outbuf
== NULL
) {
2024 DEBUG(0, ("talloc failed\n"));
2029 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
2030 DEBUG(1, ("invalid command chain\n"));
2031 *poutbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, old_size
);
2035 if (chain_padding
!= 0) {
2036 memset(outbuf
+ old_size
, 0, chain_padding
);
2037 old_size
+= chain_padding
;
2040 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
2041 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
2046 * Push the chained request:
2051 SCVAL(outbuf
, ofs
, wct
);
2058 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
2063 * Read&X has an offset into its data buffer at
2064 * vwv[6]. reply_read_andx has no idea anymore that it's
2065 * running from within a chain, so we have to fix up the
2068 * Although it looks disgusting at this place, I want to keep
2069 * it here. The alternative would be to push knowledge about
2070 * the andx chain down into read&x again.
2073 if (smb_command
== SMBreadX
) {
2074 uint8_t *bytes_addr
;
2078 * Invalid read&x response
2083 bytes_addr
= outbuf
+ ofs
/* vwv start */
2084 + sizeof(uint16_t) * wct
/* vwv array */
2085 + sizeof(uint16_t); /* bcc */
2087 SSVAL(outbuf
+ ofs
, 6 * sizeof(uint16_t),
2088 bytes_addr
- outbuf
- 4);
2091 ofs
+= sizeof(uint16_t) * wct
;
2097 SSVAL(outbuf
, ofs
, num_bytes
);
2098 ofs
+= sizeof(uint16_t);
2104 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
2109 bool smb1_is_chain(const uint8_t *buf
)
2111 uint8_t cmd
, wct
, andx_cmd
;
2113 cmd
= CVAL(buf
, smb_com
);
2114 if (!is_andx_req(cmd
)) {
2117 wct
= CVAL(buf
, smb_wct
);
2121 andx_cmd
= CVAL(buf
, smb_vwv
);
2122 return (andx_cmd
!= 0xFF);
2125 bool smb1_walk_chain(const uint8_t *buf
,
2126 bool (*fn
)(uint8_t cmd
,
2127 uint8_t wct
, const uint16_t *vwv
,
2128 uint16_t num_bytes
, const uint8_t *bytes
,
2129 void *private_data
),
2132 size_t smblen
= smb_len(buf
);
2133 const char *smb_buf
= smb_base(buf
);
2134 uint8_t cmd
, chain_cmd
;
2136 const uint16_t *vwv
;
2138 const uint8_t *bytes
;
2140 cmd
= CVAL(buf
, smb_com
);
2141 wct
= CVAL(buf
, smb_wct
);
2142 vwv
= (const uint16_t *)(buf
+ smb_vwv
);
2143 num_bytes
= smb_buflen(buf
);
2144 bytes
= (const uint8_t *)smb_buf_const(buf
);
2146 if (!fn(cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2150 if (!is_andx_req(cmd
)) {
2157 chain_cmd
= CVAL(vwv
, 0);
2159 while (chain_cmd
!= 0xff) {
2160 uint32_t chain_offset
; /* uint32_t to avoid overflow */
2161 size_t length_needed
;
2162 ptrdiff_t vwv_offset
;
2164 chain_offset
= SVAL(vwv
+1, 0);
2167 * Check if the client tries to fool us. The chain
2168 * offset needs to point beyond the current request in
2169 * the chain, it needs to strictly grow. Otherwise we
2170 * might be tricked into an endless loop always
2171 * processing the same request over and over again. We
2172 * used to assume that vwv and the byte buffer array
2173 * in a chain are always attached, but OS/2 the
2174 * Write&X/Read&X chain puts the Read&X vwv array
2175 * right behind the Write&X vwv chain. The Write&X bcc
2176 * array is put behind the Read&X vwv array. So now we
2177 * check whether the chain offset points strictly
2178 * behind the previous vwv array. req->buf points
2179 * right after the vwv array of the previous
2181 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2185 vwv_offset
= ((const char *)vwv
- smb_buf
);
2186 if (chain_offset
<= vwv_offset
) {
2191 * Next check: Make sure the chain offset does not
2192 * point beyond the overall smb request length.
2195 length_needed
= chain_offset
+1; /* wct */
2196 if (length_needed
> smblen
) {
2201 * Now comes the pointer magic. Goal here is to set up
2202 * vwv and buf correctly again. The chain offset (the
2203 * former vwv[1]) points at the new wct field.
2206 wct
= CVAL(smb_buf
, chain_offset
);
2208 if (is_andx_req(chain_cmd
) && (wct
< 2)) {
2213 * Next consistency check: Make the new vwv array fits
2214 * in the overall smb request.
2217 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2218 if (length_needed
> smblen
) {
2221 vwv
= (const uint16_t *)(smb_buf
+ chain_offset
+ 1);
2224 * Now grab the new byte buffer....
2227 num_bytes
= SVAL(vwv
+wct
, 0);
2230 * .. and check that it fits.
2233 length_needed
+= num_bytes
;
2234 if (length_needed
> smblen
) {
2237 bytes
= (const uint8_t *)(vwv
+wct
+1);
2239 if (!fn(chain_cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2243 if (!is_andx_req(chain_cmd
)) {
2246 chain_cmd
= CVAL(vwv
, 0);
2251 static bool smb1_chain_length_cb(uint8_t cmd
,
2252 uint8_t wct
, const uint16_t *vwv
,
2253 uint16_t num_bytes
, const uint8_t *bytes
,
2256 unsigned *count
= (unsigned *)private_data
;
2261 unsigned smb1_chain_length(const uint8_t *buf
)
2265 if (!smb1_walk_chain(buf
, smb1_chain_length_cb
, &count
)) {
2271 struct smb1_parse_chain_state
{
2272 TALLOC_CTX
*mem_ctx
;
2274 struct smbd_server_connection
*sconn
;
2278 struct smb_request
**reqs
;
2282 static bool smb1_parse_chain_cb(uint8_t cmd
,
2283 uint8_t wct
, const uint16_t *vwv
,
2284 uint16_t num_bytes
, const uint8_t *bytes
,
2287 struct smb1_parse_chain_state
*state
=
2288 (struct smb1_parse_chain_state
*)private_data
;
2289 struct smb_request
**reqs
;
2290 struct smb_request
*req
;
2293 reqs
= talloc_realloc(state
->mem_ctx
, state
->reqs
,
2294 struct smb_request
*, state
->num_reqs
+1);
2300 req
= talloc(reqs
, struct smb_request
);
2305 ok
= init_smb_request(req
, state
->sconn
, state
->buf
, 0,
2306 state
->encrypted
, state
->seqnum
);
2313 req
->buflen
= num_bytes
;
2316 reqs
[state
->num_reqs
] = req
;
2317 state
->num_reqs
+= 1;
2321 bool smb1_parse_chain(TALLOC_CTX
*mem_ctx
, const uint8_t *buf
,
2322 struct smbd_server_connection
*sconn
,
2323 bool encrypted
, uint32_t seqnum
,
2324 struct smb_request
***reqs
, unsigned *num_reqs
)
2326 struct smb1_parse_chain_state state
;
2329 state
.mem_ctx
= mem_ctx
;
2331 state
.sconn
= sconn
;
2332 state
.encrypted
= encrypted
;
2333 state
.seqnum
= seqnum
;
2337 if (!smb1_walk_chain(buf
, smb1_parse_chain_cb
, &state
)) {
2338 TALLOC_FREE(state
.reqs
);
2341 for (i
=0; i
<state
.num_reqs
; i
++) {
2342 state
.reqs
[i
]->chain
= state
.reqs
;
2345 *num_reqs
= state
.num_reqs
;
2349 /****************************************************************************
2350 Check if services need reloading.
2351 ****************************************************************************/
2353 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2356 if (last_smb_conf_reload_time
== 0) {
2357 last_smb_conf_reload_time
= t
;
2360 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2361 reload_services(sconn
, conn_snum_used
, true);
2362 last_smb_conf_reload_time
= t
;
2366 static bool fd_is_readable(int fd
)
2370 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2372 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2376 static void smbd_server_connection_write_handler(
2377 struct smbd_server_connection
*sconn
)
2379 /* TODO: make write nonblocking */
2382 static void smbd_server_connection_read_handler(
2383 struct smbd_server_connection
*sconn
, int fd
)
2385 uint8_t *inbuf
= NULL
;
2386 size_t inbuf_len
= 0;
2387 size_t unread_bytes
= 0;
2388 bool encrypted
= false;
2389 TALLOC_CTX
*mem_ctx
= talloc_tos();
2393 bool async_echo
= lp_async_smb_echo_handler();
2394 bool from_client
= false;
2397 if (fd_is_readable(sconn
->smb1
.echo_handler
.trusted_fd
)) {
2399 * This is the super-ugly hack to prefer the packets
2400 * forwarded by the echo handler over the ones by the
2403 fd
= sconn
->smb1
.echo_handler
.trusted_fd
;
2407 from_client
= (sconn
->sock
== fd
);
2409 if (async_echo
&& from_client
) {
2410 smbd_lock_socket(sconn
);
2412 if (!fd_is_readable(fd
)) {
2413 DEBUG(10,("the echo listener was faster\n"));
2414 smbd_unlock_socket(sconn
);
2419 /* TODO: make this completely nonblocking */
2420 status
= receive_smb_talloc(mem_ctx
, sconn
, fd
,
2421 (char **)(void *)&inbuf
,
2425 &inbuf_len
, &seqnum
,
2426 !from_client
/* trusted channel */);
2428 if (async_echo
&& from_client
) {
2429 smbd_unlock_socket(sconn
);
2432 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2435 if (NT_STATUS_IS_ERR(status
)) {
2436 exit_server_cleanly("failed to receive smb request");
2438 if (!NT_STATUS_IS_OK(status
)) {
2443 process_smb(sconn
, inbuf
, inbuf_len
, unread_bytes
,
2444 seqnum
, encrypted
, NULL
);
2447 static void smbd_server_connection_handler(struct tevent_context
*ev
,
2448 struct tevent_fd
*fde
,
2452 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2453 struct smbd_server_connection
);
2455 if (!NT_STATUS_IS_OK(conn
->status
)) {
2457 * we're not supposed to do any io
2459 TEVENT_FD_NOT_READABLE(conn
->smb1
.fde
);
2460 TEVENT_FD_NOT_WRITEABLE(conn
->smb1
.fde
);
2464 if (flags
& TEVENT_FD_WRITE
) {
2465 smbd_server_connection_write_handler(conn
);
2468 if (flags
& TEVENT_FD_READ
) {
2469 smbd_server_connection_read_handler(conn
, conn
->sock
);
2474 static void smbd_server_echo_handler(struct tevent_context
*ev
,
2475 struct tevent_fd
*fde
,
2479 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2480 struct smbd_server_connection
);
2482 if (!NT_STATUS_IS_OK(conn
->status
)) {
2484 * we're not supposed to do any io
2486 TEVENT_FD_NOT_READABLE(conn
->smb1
.echo_handler
.trusted_fde
);
2487 TEVENT_FD_NOT_WRITEABLE(conn
->smb1
.echo_handler
.trusted_fde
);
2491 if (flags
& TEVENT_FD_WRITE
) {
2492 smbd_server_connection_write_handler(conn
);
2495 if (flags
& TEVENT_FD_READ
) {
2496 smbd_server_connection_read_handler(
2497 conn
, conn
->smb1
.echo_handler
.trusted_fd
);
2502 #ifdef CLUSTER_SUPPORT
2504 struct smbd_release_ip_state
{
2505 struct smbd_server_connection
*sconn
;
2506 struct tevent_immediate
*im
;
2507 char addr
[INET6_ADDRSTRLEN
];
2510 static void smbd_release_ip_immediate(struct tevent_context
*ctx
,
2511 struct tevent_immediate
*im
,
2514 struct smbd_release_ip_state
*state
=
2515 talloc_get_type_abort(private_data
,
2516 struct smbd_release_ip_state
);
2518 if (!NT_STATUS_EQUAL(state
->sconn
->status
, NT_STATUS_ADDRESS_CLOSED
)) {
2520 * smbd_server_connection_terminate() already triggered ?
2525 smbd_server_connection_terminate(state
->sconn
, "CTDB_SRVID_RELEASE_IP");
2528 /****************************************************************************
2529 received when we should release a specific IP
2530 ****************************************************************************/
2531 static bool release_ip(const char *ip
, void *priv
)
2533 struct smbd_release_ip_state
*state
=
2534 talloc_get_type_abort(priv
,
2535 struct smbd_release_ip_state
);
2536 const char *addr
= state
->addr
;
2537 const char *p
= addr
;
2539 if (!NT_STATUS_IS_OK(state
->sconn
->status
)) {
2540 /* avoid recursion */
2544 if (strncmp("::ffff:", addr
, 7) == 0) {
2548 DEBUG(10, ("Got release IP message for %s, "
2549 "our address is %s\n", ip
, p
));
2551 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2552 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2555 * With SMB2 we should do a clean disconnect,
2556 * the previous_session_id in the session setup
2557 * will cleanup the old session, tcons and opens.
2559 * A clean disconnect is needed in order to support
2562 * Note: typically this is never triggered
2563 * as we got a TCP RST (triggered by ctdb event scripts)
2564 * before we get CTDB_SRVID_RELEASE_IP.
2566 * We used to call _exit(1) here, but as this was mostly never
2567 * triggered and has implication on our process model,
2568 * we can just use smbd_server_connection_terminate()
2571 * We don't call smbd_server_connection_terminate() directly
2572 * as we might be called from within ctdbd_migrate(),
2573 * we need to defer our action to the next event loop
2575 tevent_schedule_immediate(state
->im
, state
->sconn
->ev_ctx
,
2576 smbd_release_ip_immediate
, state
);
2579 * Make sure we don't get any io on the connection.
2581 state
->sconn
->status
= NT_STATUS_ADDRESS_CLOSED
;
2588 static NTSTATUS
smbd_register_ips(struct smbd_server_connection
*sconn
,
2589 struct sockaddr_storage
*srv
,
2590 struct sockaddr_storage
*clnt
)
2592 struct smbd_release_ip_state
*state
;
2593 struct ctdbd_connection
*cconn
;
2595 cconn
= messaging_ctdbd_connection();
2596 if (cconn
== NULL
) {
2597 return NT_STATUS_NO_MEMORY
;
2600 state
= talloc_zero(sconn
, struct smbd_release_ip_state
);
2601 if (state
== NULL
) {
2602 return NT_STATUS_NO_MEMORY
;
2604 state
->sconn
= sconn
;
2605 state
->im
= tevent_create_immediate(state
);
2606 if (state
->im
== NULL
) {
2607 return NT_STATUS_NO_MEMORY
;
2609 if (print_sockaddr(state
->addr
, sizeof(state
->addr
), srv
) == NULL
) {
2610 return NT_STATUS_NO_MEMORY
;
2613 return ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, state
);
2616 static int client_get_tcp_info(int sock
, struct sockaddr_storage
*server
,
2617 struct sockaddr_storage
*client
)
2620 length
= sizeof(*server
);
2621 if (getsockname(sock
, (struct sockaddr
*)server
, &length
) != 0) {
2624 length
= sizeof(*client
);
2625 if (getpeername(sock
, (struct sockaddr
*)client
, &length
) != 0) {
2632 static void msg_kill_client_ip(struct messaging_context
*msg_ctx
,
2633 void *private_data
, uint32_t msg_type
,
2634 struct server_id server_id
, DATA_BLOB
*data
)
2636 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2637 private_data
, struct smbd_server_connection
);
2638 const char *ip
= (char *) data
->data
;
2641 DEBUG(10, ("Got kill request for client IP %s\n", ip
));
2643 client_ip
= tsocket_address_inet_addr_string(sconn
->remote_address
,
2645 if (client_ip
== NULL
) {
2649 if (strequal(ip
, client_ip
)) {
2650 DEBUG(1, ("Got kill client message for %s - "
2651 "exiting immediately\n", ip
));
2652 exit_server_cleanly("Forced disconnect for client");
2655 TALLOC_FREE(client_ip
);
2659 * Send keepalive packets to our client
2661 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2663 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2664 private_data
, struct smbd_server_connection
);
2667 if (sconn
->using_smb2
) {
2668 /* Don't do keepalives on an SMB2 connection. */
2672 smbd_lock_socket(sconn
);
2673 ret
= send_keepalive(sconn
->sock
);
2674 smbd_unlock_socket(sconn
);
2677 char addr
[INET6_ADDRSTRLEN
];
2679 * Try and give an error message saying what
2682 DEBUG(0, ("send_keepalive failed for client %s. "
2683 "Error %s - exiting\n",
2684 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
2692 * Do the recurring check if we're idle
2694 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2696 struct smbd_server_connection
*sconn
=
2697 (struct smbd_server_connection
*)private_data
;
2699 if ((conn_num_open(sconn
) == 0)
2700 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2701 DEBUG( 2, ( "Closing idle connection\n" ) );
2702 messaging_send(sconn
->msg_ctx
,
2703 messaging_server_id(sconn
->msg_ctx
),
2704 MSG_SHUTDOWN
, &data_blob_null
);
2712 * Do the recurring log file and smb.conf reload checks.
2715 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2717 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2718 private_data
, struct smbd_server_connection
);
2720 DEBUG(5, ("housekeeping\n"));
2722 change_to_root_user();
2724 /* update printer queue caches if necessary */
2725 update_monitored_printq_cache(sconn
->msg_ctx
);
2727 /* check if we need to reload services */
2728 check_reload(sconn
, time_mono(NULL
));
2731 * Force a log file check.
2733 force_check_log_size();
2739 * Read an smb packet in the echo handler child, giving the parent
2740 * smbd one second to react once the socket becomes readable.
2743 struct smbd_echo_read_state
{
2744 struct tevent_context
*ev
;
2745 struct smbd_server_connection
*sconn
;
2752 static void smbd_echo_read_readable(struct tevent_req
*subreq
);
2753 static void smbd_echo_read_waited(struct tevent_req
*subreq
);
2755 static struct tevent_req
*smbd_echo_read_send(
2756 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2757 struct smbd_server_connection
*sconn
)
2759 struct tevent_req
*req
, *subreq
;
2760 struct smbd_echo_read_state
*state
;
2762 req
= tevent_req_create(mem_ctx
, &state
,
2763 struct smbd_echo_read_state
);
2768 state
->sconn
= sconn
;
2770 subreq
= wait_for_read_send(state
, ev
, sconn
->sock
);
2771 if (tevent_req_nomem(subreq
, req
)) {
2772 return tevent_req_post(req
, ev
);
2774 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2778 static void smbd_echo_read_readable(struct tevent_req
*subreq
)
2780 struct tevent_req
*req
= tevent_req_callback_data(
2781 subreq
, struct tevent_req
);
2782 struct smbd_echo_read_state
*state
= tevent_req_data(
2783 req
, struct smbd_echo_read_state
);
2787 ok
= wait_for_read_recv(subreq
, &err
);
2788 TALLOC_FREE(subreq
);
2790 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
2795 * Give the parent smbd one second to step in
2798 subreq
= tevent_wakeup_send(
2799 state
, state
->ev
, timeval_current_ofs(1, 0));
2800 if (tevent_req_nomem(subreq
, req
)) {
2803 tevent_req_set_callback(subreq
, smbd_echo_read_waited
, req
);
2806 static void smbd_echo_read_waited(struct tevent_req
*subreq
)
2808 struct tevent_req
*req
= tevent_req_callback_data(
2809 subreq
, struct tevent_req
);
2810 struct smbd_echo_read_state
*state
= tevent_req_data(
2811 req
, struct smbd_echo_read_state
);
2812 struct smbd_server_connection
*sconn
= state
->sconn
;
2818 ok
= tevent_wakeup_recv(subreq
);
2819 TALLOC_FREE(subreq
);
2821 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2825 ok
= smbd_lock_socket_internal(sconn
);
2827 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2828 DEBUG(0, ("%s: failed to lock socket\n", __location__
));
2832 if (!fd_is_readable(sconn
->sock
)) {
2833 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2836 ok
= smbd_unlock_socket_internal(sconn
);
2838 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2839 DEBUG(1, ("%s: failed to unlock socket\n",
2844 subreq
= wait_for_read_send(state
, state
->ev
, sconn
->sock
);
2845 if (tevent_req_nomem(subreq
, req
)) {
2848 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2852 status
= receive_smb_talloc(state
, sconn
, sconn
->sock
, &state
->buf
,
2858 false /* trusted_channel*/);
2860 if (tevent_req_nterror(req
, status
)) {
2861 tevent_req_nterror(req
, status
);
2862 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2863 (int)getpid(), nt_errstr(status
)));
2867 ok
= smbd_unlock_socket_internal(sconn
);
2869 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2870 DEBUG(1, ("%s: failed to unlock socket\n", __location__
));
2873 tevent_req_done(req
);
2876 static NTSTATUS
smbd_echo_read_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2877 char **pbuf
, size_t *pbuflen
, uint32_t *pseqnum
)
2879 struct smbd_echo_read_state
*state
= tevent_req_data(
2880 req
, struct smbd_echo_read_state
);
2883 if (tevent_req_is_nterror(req
, &status
)) {
2886 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
2887 *pbuflen
= state
->buflen
;
2888 *pseqnum
= state
->seqnum
;
2889 return NT_STATUS_OK
;
2892 struct smbd_echo_state
{
2893 struct tevent_context
*ev
;
2894 struct iovec
*pending
;
2895 struct smbd_server_connection
*sconn
;
2898 struct tevent_fd
*parent_fde
;
2900 struct tevent_req
*write_req
;
2903 static void smbd_echo_writer_done(struct tevent_req
*req
);
2905 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2909 if (state
->write_req
!= NULL
) {
2913 num_pending
= talloc_array_length(state
->pending
);
2914 if (num_pending
== 0) {
2918 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
2919 state
->parent_pipe
, false,
2920 state
->pending
, num_pending
);
2921 if (state
->write_req
== NULL
) {
2922 DEBUG(1, ("writev_send failed\n"));
2926 talloc_steal(state
->write_req
, state
->pending
);
2927 state
->pending
= NULL
;
2929 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
2933 static void smbd_echo_writer_done(struct tevent_req
*req
)
2935 struct smbd_echo_state
*state
= tevent_req_callback_data(
2936 req
, struct smbd_echo_state
);
2940 written
= writev_recv(req
, &err
);
2942 state
->write_req
= NULL
;
2943 if (written
== -1) {
2944 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
2947 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2948 smbd_echo_activate_writer(state
);
2951 static bool smbd_echo_reply(struct smbd_echo_state
*state
,
2952 uint8_t *inbuf
, size_t inbuf_len
,
2955 struct smb_request req
;
2956 uint16_t num_replies
;
2960 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == NBSSkeepalive
)) {
2961 DEBUG(10, ("Got netbios keepalive\n"));
2968 if (inbuf_len
< smb_size
) {
2969 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
2972 if (!valid_smb_header(state
->sconn
, inbuf
)) {
2973 DEBUG(10, ("Got invalid SMB header\n"));
2977 if (!init_smb_request(&req
, state
->sconn
, inbuf
, 0, false,
2983 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
2984 smb_messages
[req
.cmd
].name
2985 ? smb_messages
[req
.cmd
].name
: "unknown"));
2987 if (req
.cmd
!= SMBecho
) {
2994 num_replies
= SVAL(req
.vwv
+0, 0);
2995 if (num_replies
!= 1) {
2996 /* Not a Windows "Hey, you're still there?" request */
3000 if (!create_outbuf(talloc_tos(), &req
, (const char *)req
.inbuf
, &outbuf
,
3002 DEBUG(10, ("create_outbuf failed\n"));
3005 req
.outbuf
= (uint8_t *)outbuf
;
3007 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
3009 if (req
.buflen
> 0) {
3010 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
3013 ok
= srv_send_smb(req
.sconn
,
3017 TALLOC_FREE(outbuf
);
3025 static void smbd_echo_exit(struct tevent_context
*ev
,
3026 struct tevent_fd
*fde
, uint16_t flags
,
3029 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3033 static void smbd_echo_got_packet(struct tevent_req
*req
);
3035 static void smbd_echo_loop(struct smbd_server_connection
*sconn
,
3038 struct smbd_echo_state
*state
;
3039 struct tevent_req
*read_req
;
3041 state
= talloc_zero(sconn
, struct smbd_echo_state
);
3042 if (state
== NULL
) {
3043 DEBUG(1, ("talloc failed\n"));
3046 state
->sconn
= sconn
;
3047 state
->parent_pipe
= parent_pipe
;
3048 state
->ev
= s3_tevent_context_init(state
);
3049 if (state
->ev
== NULL
) {
3050 DEBUG(1, ("tevent_context_init failed\n"));
3054 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
3055 TEVENT_FD_READ
, smbd_echo_exit
,
3057 if (state
->parent_fde
== NULL
) {
3058 DEBUG(1, ("tevent_add_fd failed\n"));
3063 read_req
= smbd_echo_read_send(state
, state
->ev
, sconn
);
3064 if (read_req
== NULL
) {
3065 DEBUG(1, ("smbd_echo_read_send failed\n"));
3069 tevent_req_set_callback(read_req
, smbd_echo_got_packet
, state
);
3072 if (tevent_loop_once(state
->ev
) == -1) {
3073 DEBUG(1, ("tevent_loop_once failed: %s\n",
3081 static void smbd_echo_got_packet(struct tevent_req
*req
)
3083 struct smbd_echo_state
*state
= tevent_req_callback_data(
3084 req
, struct smbd_echo_state
);
3088 uint32_t seqnum
= 0;
3091 status
= smbd_echo_read_recv(req
, state
, &buf
, &buflen
, &seqnum
);
3093 if (!NT_STATUS_IS_OK(status
)) {
3094 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3095 nt_errstr(status
)));
3099 reply
= smbd_echo_reply(state
, (uint8_t *)buf
, buflen
, seqnum
);
3105 num_pending
= talloc_array_length(state
->pending
);
3106 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
3109 DEBUG(1, ("talloc_realloc failed\n"));
3112 state
->pending
= tmp
;
3114 if (buflen
>= smb_size
) {
3116 * place the seqnum in the packet so that the main process
3117 * can reply with signing
3119 SIVAL(buf
, smb_ss_field
, seqnum
);
3120 SIVAL(buf
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
3123 iov
= &state
->pending
[num_pending
];
3124 iov
->iov_base
= talloc_move(state
->pending
, &buf
);
3125 iov
->iov_len
= buflen
;
3127 DEBUG(10,("echo_handler[%d]: forward to main\n",
3129 smbd_echo_activate_writer(state
);
3132 req
= smbd_echo_read_send(state
, state
->ev
, state
->sconn
);
3134 DEBUG(1, ("smbd_echo_read_send failed\n"));
3137 tevent_req_set_callback(req
, smbd_echo_got_packet
, state
);
3142 * Handle SMBecho requests in a forked child process
3144 bool fork_echo_handler(struct smbd_server_connection
*sconn
)
3146 int listener_pipe
[2];
3150 res
= pipe(listener_pipe
);
3152 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
3155 sconn
->smb1
.echo_handler
.socket_lock_fd
= create_unlink_tmp(lp_lock_directory());
3156 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
3157 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno
)));
3165 close(listener_pipe
[0]);
3166 set_blocking(listener_pipe
[1], false);
3168 status
= reinit_after_fork(sconn
->msg_ctx
,
3171 if (!NT_STATUS_IS_OK(status
)) {
3172 DEBUG(1, ("reinit_after_fork failed: %s\n",
3173 nt_errstr(status
)));
3176 smbd_echo_loop(sconn
, listener_pipe
[1]);
3179 close(listener_pipe
[1]);
3180 listener_pipe
[1] = -1;
3181 sconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
3183 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child
));
3186 * Without smb signing this is the same as the normal smbd
3187 * listener. This needs to change once signing comes in.
3189 sconn
->smb1
.echo_handler
.trusted_fde
= tevent_add_fd(sconn
->ev_ctx
,
3191 sconn
->smb1
.echo_handler
.trusted_fd
,
3193 smbd_server_echo_handler
,
3195 if (sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
3196 DEBUG(1, ("event_add_fd failed\n"));
3203 if (listener_pipe
[0] != -1) {
3204 close(listener_pipe
[0]);
3206 if (listener_pipe
[1] != -1) {
3207 close(listener_pipe
[1]);
3209 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
3210 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
3211 close(sconn
->smb1
.echo_handler
.socket_lock_fd
);
3213 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
3214 sconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
3218 static bool uid_in_use(const struct user_struct
*user
, uid_t uid
)
3221 if (user
->session_info
&&
3222 (user
->session_info
->unix_token
->uid
== uid
)) {
3230 static bool gid_in_use(const struct user_struct
*user
, gid_t gid
)
3233 if (user
->session_info
!= NULL
) {
3235 struct security_unix_token
*utok
;
3237 utok
= user
->session_info
->unix_token
;
3238 if (utok
->gid
== gid
) {
3241 for(i
=0; i
<utok
->ngroups
; i
++) {
3242 if (utok
->groups
[i
] == gid
) {
3252 static bool sid_in_use(const struct user_struct
*user
,
3253 const struct dom_sid
*psid
)
3256 struct security_token
*tok
;
3258 if (user
->session_info
== NULL
) {
3261 tok
= user
->session_info
->security_token
;
3264 * Not sure session_info->security_token can
3265 * ever be NULL. This check might be not
3270 if (security_token_has_sid(tok
, psid
)) {
3278 static bool id_in_use(const struct user_struct
*user
,
3279 const struct id_cache_ref
*id
)
3283 return uid_in_use(user
, id
->id
.uid
);
3285 return gid_in_use(user
, id
->id
.gid
);
3287 return sid_in_use(user
, &id
->id
.sid
);
3294 static void smbd_id_cache_kill(struct messaging_context
*msg_ctx
,
3297 struct server_id server_id
,
3300 const char *msg
= (data
&& data
->data
)
3301 ? (const char *)data
->data
: "<NULL>";
3302 struct id_cache_ref id
;
3303 struct smbd_server_connection
*sconn
=
3304 talloc_get_type_abort(private_data
,
3305 struct smbd_server_connection
);
3307 if (!id_cache_ref_parse(msg
, &id
)) {
3308 DEBUG(0, ("Invalid ?ID: %s\n", msg
));
3312 if (id_in_use(sconn
->users
, &id
)) {
3313 exit_server_cleanly(msg
);
3315 id_cache_delete_from_cache(&id
);
3318 NTSTATUS
smbXsrv_connection_init_tables(struct smbXsrv_connection
*conn
,
3319 enum protocol_types protocol
)
3323 set_Protocol(protocol
);
3324 conn
->protocol
= protocol
;
3326 if (protocol
>= PROTOCOL_SMB2_02
) {
3327 status
= smb2srv_session_table_init(conn
);
3328 if (!NT_STATUS_IS_OK(status
)) {
3332 status
= smb2srv_open_table_init(conn
);
3333 if (!NT_STATUS_IS_OK(status
)) {
3337 status
= smb1srv_session_table_init(conn
);
3338 if (!NT_STATUS_IS_OK(status
)) {
3342 status
= smb1srv_tcon_table_init(conn
);
3343 if (!NT_STATUS_IS_OK(status
)) {
3347 status
= smb1srv_open_table_init(conn
);
3348 if (!NT_STATUS_IS_OK(status
)) {
3353 return NT_STATUS_OK
;
3356 static void smbd_tevent_trace_callback(enum tevent_trace_point point
,
3359 struct smbXsrv_connection
*conn
=
3360 talloc_get_type_abort(private_data
,
3361 struct smbXsrv_connection
);
3364 case TEVENT_TRACE_BEFORE_WAIT
:
3366 * This just removes compiler warning
3367 * without profile support
3369 conn
->smbd_idle_profstamp
= 0;
3370 START_PROFILE_STAMP(smbd_idle
, conn
->smbd_idle_profstamp
);
3372 case TEVENT_TRACE_AFTER_WAIT
:
3373 END_PROFILE_STAMP(smbd_idle
, conn
->smbd_idle_profstamp
);
3378 /****************************************************************************
3379 Process commands from the client
3380 ****************************************************************************/
3382 void smbd_process(struct tevent_context
*ev_ctx
,
3383 struct messaging_context
*msg_ctx
,
3387 TALLOC_CTX
*frame
= talloc_stackframe();
3388 struct smbXsrv_connection
*conn
;
3389 struct smbd_server_connection
*sconn
;
3390 struct sockaddr_storage ss
;
3391 struct sockaddr
*sa
= NULL
;
3392 socklen_t sa_socklen
;
3393 struct tsocket_address
*local_address
= NULL
;
3394 struct tsocket_address
*remote_address
= NULL
;
3395 const char *locaddr
= NULL
;
3396 const char *remaddr
= NULL
;
3401 conn
= talloc_zero(ev_ctx
, struct smbXsrv_connection
);
3403 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3404 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3407 conn
->ev_ctx
= ev_ctx
;
3408 conn
->msg_ctx
= msg_ctx
;
3410 sconn
= talloc_zero(conn
, struct smbd_server_connection
);
3412 exit_server("failed to create smbd_server_connection");
3415 conn
->sconn
= sconn
;
3419 * TODO: remove this...:-)
3421 global_smbXsrv_connection
= conn
;
3423 sconn
->ev_ctx
= ev_ctx
;
3424 sconn
->msg_ctx
= msg_ctx
;
3425 sconn
->sock
= sock_fd
;
3426 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
3427 sconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
3430 smbd_setup_sig_term_handler(sconn
);
3431 smbd_setup_sig_hup_handler(sconn
);
3433 if (!serverid_register(messaging_server_id(msg_ctx
),
3434 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
3436 |FLAG_MSG_PRINT_GENERAL
)) {
3437 exit_server_cleanly("Could not register myself in "
3442 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02
) {
3444 * We're not making the decision here,
3445 * we're just allowing the client
3446 * to decide between SMB1 and SMB2
3447 * with the first negprot
3450 sconn
->using_smb2
= true;
3453 /* Ensure child is set to blocking mode */
3454 set_blocking(sconn
->sock
,True
);
3456 set_socket_options(sconn
->sock
, "SO_KEEPALIVE");
3457 set_socket_options(sconn
->sock
, lp_socket_options());
3459 sa
= (struct sockaddr
*)(void *)&ss
;
3460 sa_socklen
= sizeof(ss
);
3461 ret
= getpeername(sconn
->sock
, sa
, &sa_socklen
);
3463 int level
= (errno
== ENOTCONN
)?2:0;
3464 DEBUG(level
,("getpeername() failed - %s\n", strerror(errno
)));
3465 exit_server_cleanly("getpeername() failed.\n");
3467 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3471 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3472 __location__
, strerror(errno
)));
3473 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3476 sa
= (struct sockaddr
*)(void *)&ss
;
3477 sa_socklen
= sizeof(ss
);
3478 ret
= getsockname(sconn
->sock
, sa
, &sa_socklen
);
3480 int level
= (errno
== ENOTCONN
)?2:0;
3481 DEBUG(level
,("getsockname() failed - %s\n", strerror(errno
)));
3482 exit_server_cleanly("getsockname() failed.\n");
3484 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3488 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3489 __location__
, strerror(errno
)));
3490 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3493 sconn
->local_address
= local_address
;
3494 sconn
->remote_address
= remote_address
;
3496 if (tsocket_address_is_inet(local_address
, "ip")) {
3497 locaddr
= tsocket_address_inet_addr_string(
3498 sconn
->local_address
,
3500 if (locaddr
== NULL
) {
3501 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3502 __location__
, strerror(errno
)));
3503 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3506 locaddr
= "0.0.0.0";
3509 if (tsocket_address_is_inet(remote_address
, "ip")) {
3510 remaddr
= tsocket_address_inet_addr_string(
3511 sconn
->remote_address
,
3513 if (remaddr
== NULL
) {
3514 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3515 __location__
, strerror(errno
)));
3516 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3519 remaddr
= "0.0.0.0";
3522 /* this is needed so that we get decent entries
3523 in smbstatus for port 445 connects */
3524 set_remote_machine_name(remaddr
, false);
3525 reload_services(sconn
, conn_snum_used
, true);
3528 * Before the first packet, check the global hosts allow/ hosts deny
3529 * parameters before doing any parsing of packets passed to us by the
3530 * client. This prevents attacks on our parsing code from hosts not in
3531 * the hosts allow list.
3534 ret
= get_remote_hostname(remote_address
,
3538 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3539 __location__
, strerror(errno
)));
3540 exit_server_cleanly("get_remote_hostname failed.\n");
3542 if (strequal(rhost
, "UNKNOWN")) {
3543 rhost
= talloc_strdup(talloc_tos(), remaddr
);
3545 sconn
->remote_hostname
= talloc_move(sconn
, &rhost
);
3547 sub_set_socket_ids(remaddr
,
3548 sconn
->remote_hostname
,
3551 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3552 sconn
->remote_hostname
,
3555 * send a negative session response "not listening on calling
3558 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3559 DEBUG( 1, ("Connection denied from %s to %s\n",
3560 tsocket_address_string(remote_address
, talloc_tos()),
3561 tsocket_address_string(local_address
, talloc_tos())));
3562 (void)srv_send_smb(sconn
,(char *)buf
, false,
3564 exit_server_cleanly("connection denied");
3567 DEBUG(10, ("Connection allowed from %s to %s\n",
3568 tsocket_address_string(remote_address
, talloc_tos()),
3569 tsocket_address_string(local_address
, talloc_tos())));
3571 if (lp_preload_modules()) {
3572 smb_load_modules(lp_preload_modules());
3575 smb_perfcount_init();
3577 if (!init_account_policy()) {
3578 exit_server("Could not open account policy tdb.\n");
3581 if (*lp_root_directory(talloc_tos())) {
3582 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3583 DEBUG(0,("Failed to change root to %s\n",
3584 lp_root_directory(talloc_tos())));
3585 exit_server("Failed to chroot()");
3587 if (chdir("/") == -1) {
3588 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3589 exit_server("Failed to chroot()");
3591 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3594 if (!srv_init_signing(sconn
)) {
3595 exit_server("Failed to init smb_signing");
3598 if (!file_init(sconn
)) {
3599 exit_server("file_init() failed");
3603 if (!init_oplocks(sconn
))
3604 exit_server("Failed to init oplocks");
3606 /* register our message handlers */
3607 messaging_register(sconn
->msg_ctx
, sconn
,
3608 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3609 messaging_register(sconn
->msg_ctx
, sconn
,
3610 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3611 messaging_register(sconn
->msg_ctx
, sconn
,
3612 MSG_SMB_FILE_RENAME
, msg_file_was_renamed
);
3614 id_cache_register_msgs(sconn
->msg_ctx
);
3615 messaging_deregister(sconn
->msg_ctx
, ID_CACHE_KILL
, NULL
);
3616 messaging_register(sconn
->msg_ctx
, sconn
,
3617 ID_CACHE_KILL
, smbd_id_cache_kill
);
3619 messaging_deregister(sconn
->msg_ctx
,
3620 MSG_SMB_CONF_UPDATED
, sconn
->ev_ctx
);
3621 messaging_register(sconn
->msg_ctx
, sconn
,
3622 MSG_SMB_CONF_UPDATED
, smbd_conf_updated
);
3624 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_KILL_CLIENT_IP
,
3626 messaging_register(sconn
->msg_ctx
, sconn
,
3627 MSG_SMB_KILL_CLIENT_IP
,
3628 msg_kill_client_ip
);
3630 messaging_deregister(sconn
->msg_ctx
, MSG_SMB_TELL_NUM_CHILDREN
, NULL
);
3633 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3634 * MSGs to all child processes
3636 messaging_deregister(sconn
->msg_ctx
,
3638 messaging_register(sconn
->msg_ctx
, NULL
,
3639 MSG_DEBUG
, debug_message
);
3641 if ((lp_keepalive() != 0)
3642 && !(event_add_idle(ev_ctx
, NULL
,
3643 timeval_set(lp_keepalive(), 0),
3644 "keepalive", keepalive_fn
,
3646 DEBUG(0, ("Could not add keepalive event\n"));
3650 if (!(event_add_idle(ev_ctx
, NULL
,
3651 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3652 "deadtime", deadtime_fn
, sconn
))) {
3653 DEBUG(0, ("Could not add deadtime event\n"));
3657 if (!(event_add_idle(ev_ctx
, NULL
,
3658 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
3659 "housekeeping", housekeeping_fn
, sconn
))) {
3660 DEBUG(0, ("Could not add housekeeping event\n"));
3664 #ifdef CLUSTER_SUPPORT
3666 if (lp_clustering()) {
3668 * We need to tell ctdb about our client's TCP
3669 * connection, so that for failover ctdbd can send
3670 * tickle acks, triggering a reconnection by the
3674 struct sockaddr_storage srv
, clnt
;
3676 if (client_get_tcp_info(sconn
->sock
, &srv
, &clnt
) == 0) {
3678 status
= smbd_register_ips(sconn
, &srv
, &clnt
);
3679 if (!NT_STATUS_IS_OK(status
)) {
3680 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3681 nt_errstr(status
)));
3684 int level
= (errno
== ENOTCONN
)?2:0;
3685 DEBUG(level
,("Unable to get tcp info for "
3686 "smbd_register_ips: %s\n",
3688 exit_server_cleanly("client_get_tcp_info() failed.\n");
3694 sconn
->nbt
.got_session
= false;
3696 tmp
= lp_max_xmit();
3697 tmp
= MAX(tmp
, SMB_BUFFER_SIZE_MIN
);
3698 tmp
= MIN(tmp
, SMB_BUFFER_SIZE_MAX
);
3700 sconn
->smb1
.negprot
.max_recv
= tmp
;
3702 sconn
->smb1
.sessions
.done_sesssetup
= false;
3703 sconn
->smb1
.sessions
.max_send
= SMB_BUFFER_SIZE_MAX
;
3705 if (!init_dptrs(sconn
)) {
3706 exit_server("init_dptrs() failed");
3709 sconn
->smb1
.fde
= tevent_add_fd(ev_ctx
,
3713 smbd_server_connection_handler
,
3715 if (!sconn
->smb1
.fde
) {
3716 exit_server("failed to create smbd_server_connection fde");
3719 sconn
->conn
->local_address
= sconn
->local_address
;
3720 sconn
->conn
->remote_address
= sconn
->remote_address
;
3721 sconn
->conn
->remote_hostname
= sconn
->remote_hostname
;
3722 sconn
->conn
->protocol
= PROTOCOL_NONE
;
3726 tevent_set_trace_callback(ev_ctx
, smbd_tevent_trace_callback
, conn
);
3729 frame
= talloc_stackframe_pool(8192);
3732 if (tevent_loop_once(ev_ctx
) == -1) {
3733 if (errno
!= EINTR
) {
3734 DEBUG(3, ("tevent_loop_once failed: %s,"
3735 " exiting\n", strerror(errno
) ));
3743 exit_server_cleanly(NULL
);
3746 bool req_is_in_chain(const struct smb_request
*req
)
3748 if (req
->vwv
!= (const uint16_t *)(req
->inbuf
+smb_vwv
)) {
3750 * We're right now handling a subsequent request, so we must
3756 if (!is_andx_req(req
->cmd
)) {
3762 * Okay, an illegal request, but definitely not chained :-)
3767 return (CVAL(req
->vwv
+0, 0) != 0xFF);