2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
43 extern bool global_machine_password_needs_changing
;
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list
{
47 struct pending_message_list
*next
, *prev
;
48 struct timeval request_time
; /* When was this first issued? */
49 struct smbd_server_connection
*sconn
;
50 struct timed_event
*te
;
51 struct smb_perfcount_data pcd
;
56 DATA_BLOB private_data
;
59 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
61 static struct pending_message_list
*get_deferred_open_message_smb(
62 struct smbd_server_connection
*sconn
, uint64_t mid
);
63 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
);
65 static bool smbd_lock_socket_internal(struct smbd_server_connection
*sconn
)
69 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
73 sconn
->smb1
.echo_handler
.ref_count
++;
75 if (sconn
->smb1
.echo_handler
.ref_count
> 1) {
79 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
83 sconn
->smb1
.echo_handler
.socket_lock_fd
,
84 SMB_F_SETLKW
, 0, 0, F_WRLCK
);
85 } while (!ok
&& (errno
== EINTR
));
88 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
92 DEBUG(10,("pid[%d] got for socket lock\n", (int)getpid()));
97 void smbd_lock_socket(struct smbd_server_connection
*sconn
)
99 if (!smbd_lock_socket_internal(sconn
)) {
100 exit_server_cleanly("failed to lock socket");
104 static bool smbd_unlock_socket_internal(struct smbd_server_connection
*sconn
)
108 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
112 sconn
->smb1
.echo_handler
.ref_count
--;
114 if (sconn
->smb1
.echo_handler
.ref_count
> 0) {
120 sconn
->smb1
.echo_handler
.socket_lock_fd
,
121 SMB_F_SETLKW
, 0, 0, F_UNLCK
);
122 } while (!ok
&& (errno
== EINTR
));
125 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
129 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
134 void smbd_unlock_socket(struct smbd_server_connection
*sconn
)
136 if (!smbd_unlock_socket_internal(sconn
)) {
137 exit_server_cleanly("failed to unlock socket");
141 /* Accessor function for smb_read_error for smbd functions. */
143 /****************************************************************************
145 ****************************************************************************/
147 bool srv_send_smb(struct smbd_server_connection
*sconn
, char *buffer
,
148 bool do_signing
, uint32_t seqnum
,
150 struct smb_perfcount_data
*pcd
)
155 char *buf_out
= buffer
;
157 smbd_lock_socket(sconn
);
160 /* Sign the outgoing packet if required. */
161 srv_calculate_sign_mac(sconn
, buf_out
, seqnum
);
165 NTSTATUS status
= srv_encrypt_buffer(sconn
, buffer
, &buf_out
);
166 if (!NT_STATUS_IS_OK(status
)) {
167 DEBUG(0, ("send_smb: SMB encryption failed "
168 "on outgoing packet! Error %s\n",
169 nt_errstr(status
) ));
174 len
= smb_len(buf_out
) + 4;
176 ret
= write_data(sconn
->sock
, buf_out
+nwritten
, len
- nwritten
);
179 char addr
[INET6_ADDRSTRLEN
];
181 * Try and give an error message saying what
184 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
185 (int)getpid(), (int)len
,
186 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
187 (int)ret
, strerror(errno
) ));
189 srv_free_enc_buffer(sconn
, buf_out
);
193 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
194 srv_free_enc_buffer(sconn
, buf_out
);
196 SMB_PERFCOUNT_END(pcd
);
198 smbd_unlock_socket(sconn
);
202 /*******************************************************************
203 Setup the word count and byte count for a smb message.
204 ********************************************************************/
206 int srv_set_message(char *buf
,
211 if (zero
&& (num_words
|| num_bytes
)) {
212 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
214 SCVAL(buf
,smb_wct
,num_words
);
215 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
216 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
217 return (smb_size
+ num_words
*2 + num_bytes
);
220 static bool valid_smb_header(struct smbd_server_connection
*sconn
,
221 const uint8_t *inbuf
)
223 if (is_encrypted_packet(sconn
, inbuf
)) {
227 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
228 * but it just looks weird to call strncmp for this one.
230 return (IVAL(smb_base(inbuf
), 0) == 0x424D53FF);
233 /* Socket functions for smbd packet processing. */
235 static bool valid_packet_size(size_t len
)
238 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
239 * of header. Don't print the error if this fits.... JRA.
242 if (len
> (BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
243 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
244 (unsigned long)len
));
250 static NTSTATUS
read_packet_remainder(int fd
, char *buffer
,
251 unsigned int timeout
, ssize_t len
)
259 status
= read_fd_with_timeout(fd
, buffer
, len
, len
, timeout
, NULL
);
260 if (!NT_STATUS_IS_OK(status
)) {
261 char addr
[INET6_ADDRSTRLEN
];
262 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
264 get_peer_addr(fd
, addr
, sizeof(addr
)),
270 /****************************************************************************
271 Attempt a zerocopy writeX read. We know here that len > smb_size-4
272 ****************************************************************************/
275 * Unfortunately, earlier versions of smbclient/libsmbclient
276 * don't send this "standard" writeX header. I've fixed this
277 * for 3.2 but we'll use the old method with earlier versions.
278 * Windows and CIFSFS at least use this standard size. Not
282 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
283 (2*14) + /* word count (including bcc) */ \
286 static NTSTATUS
receive_smb_raw_talloc_partial_read(TALLOC_CTX
*mem_ctx
,
287 const char lenbuf
[4],
288 struct smbd_server_connection
*sconn
,
291 unsigned int timeout
,
295 /* Size of a WRITEX call (+4 byte len). */
296 char writeX_header
[4 + STANDARD_WRITE_AND_X_HEADER_SIZE
];
297 ssize_t len
= smb_len_large(lenbuf
); /* Could be a UNIX large writeX. */
301 memcpy(writeX_header
, lenbuf
, 4);
303 status
= read_fd_with_timeout(
304 sock
, writeX_header
+ 4,
305 STANDARD_WRITE_AND_X_HEADER_SIZE
,
306 STANDARD_WRITE_AND_X_HEADER_SIZE
,
309 if (!NT_STATUS_IS_OK(status
)) {
310 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
312 tsocket_address_string(sconn
->remote_address
,
319 * Ok - now try and see if this is a possible
323 if (is_valid_writeX_buffer(sconn
, (uint8_t *)writeX_header
)) {
325 * If the data offset is beyond what
326 * we've read, drain the extra bytes.
328 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
331 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
332 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
333 if (drain_socket(sock
, drain
) != drain
) {
334 smb_panic("receive_smb_raw_talloc_partial_read:"
335 " failed to drain pending bytes");
338 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
341 /* Spoof down the length and null out the bcc. */
342 set_message_bcc(writeX_header
, 0);
343 newlen
= smb_len(writeX_header
);
345 /* Copy the header we've written. */
347 *buffer
= (char *)talloc_memdup(mem_ctx
,
349 sizeof(writeX_header
));
351 if (*buffer
== NULL
) {
352 DEBUG(0, ("Could not allocate inbuf of length %d\n",
353 (int)sizeof(writeX_header
)));
354 return NT_STATUS_NO_MEMORY
;
357 /* Work out the remaining bytes. */
358 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
359 *len_ret
= newlen
+ 4;
363 if (!valid_packet_size(len
)) {
364 return NT_STATUS_INVALID_PARAMETER
;
368 * Not a valid writeX call. Just do the standard
372 *buffer
= talloc_array(mem_ctx
, char, len
+4);
374 if (*buffer
== NULL
) {
375 DEBUG(0, ("Could not allocate inbuf of length %d\n",
377 return NT_STATUS_NO_MEMORY
;
380 /* Copy in what we already read. */
383 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
384 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
387 status
= read_packet_remainder(
389 (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
392 if (!NT_STATUS_IS_OK(status
)) {
393 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
403 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
,
404 struct smbd_server_connection
*sconn
,
406 char **buffer
, unsigned int timeout
,
407 size_t *p_unread
, size_t *plen
)
411 int min_recv_size
= lp_min_receive_file_size();
416 status
= read_smb_length_return_keepalive(sock
, lenbuf
, timeout
,
418 if (!NT_STATUS_IS_OK(status
)) {
422 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
423 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
424 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
425 !srv_is_signing_active(sconn
) &&
426 sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
428 return receive_smb_raw_talloc_partial_read(
429 mem_ctx
, lenbuf
, sconn
, sock
, buffer
, timeout
,
433 if (!valid_packet_size(len
)) {
434 return NT_STATUS_INVALID_PARAMETER
;
438 * The +4 here can't wrap, we've checked the length above already.
441 *buffer
= talloc_array(mem_ctx
, char, len
+4);
443 if (*buffer
== NULL
) {
444 DEBUG(0, ("Could not allocate inbuf of length %d\n",
446 return NT_STATUS_NO_MEMORY
;
449 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
451 status
= read_packet_remainder(sock
, (*buffer
)+4, timeout
, len
);
452 if (!NT_STATUS_IS_OK(status
)) {
460 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
,
461 struct smbd_server_connection
*sconn
,
463 char **buffer
, unsigned int timeout
,
464 size_t *p_unread
, bool *p_encrypted
,
467 bool trusted_channel
)
472 *p_encrypted
= false;
474 status
= receive_smb_raw_talloc(mem_ctx
, sconn
, sock
, buffer
, timeout
,
476 if (!NT_STATUS_IS_OK(status
)) {
477 DEBUG(NT_STATUS_EQUAL(status
, NT_STATUS_END_OF_FILE
)?5:1,
478 ("receive_smb_raw_talloc failed for client %s "
479 "read error = %s.\n",
480 tsocket_address_string(sconn
->remote_address
,
482 nt_errstr(status
)) );
486 if (is_encrypted_packet(sconn
, (uint8_t *)*buffer
)) {
487 status
= srv_decrypt_buffer(sconn
, *buffer
);
488 if (!NT_STATUS_IS_OK(status
)) {
489 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
490 "incoming packet! Error %s\n",
491 nt_errstr(status
) ));
497 /* Check the incoming SMB signature. */
498 if (!srv_check_sign_mac(sconn
, *buffer
, seqnum
, trusted_channel
)) {
499 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
500 "incoming packet!\n"));
501 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
509 * Initialize a struct smb_request from an inbuf
512 static bool init_smb_request(struct smb_request
*req
,
513 struct smbd_server_connection
*sconn
,
515 size_t unread_bytes
, bool encrypted
,
518 size_t req_size
= smb_len(inbuf
) + 4;
519 /* Ensure we have at least smb_size bytes. */
520 if (req_size
< smb_size
) {
521 DEBUG(0,("init_smb_request: invalid request size %u\n",
522 (unsigned int)req_size
));
525 req
->cmd
= CVAL(inbuf
, smb_com
);
526 req
->flags2
= SVAL(inbuf
, smb_flg2
);
527 req
->smbpid
= SVAL(inbuf
, smb_pid
);
528 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
529 req
->seqnum
= seqnum
;
530 req
->vuid
= SVAL(inbuf
, smb_uid
);
531 req
->tid
= SVAL(inbuf
, smb_tid
);
532 req
->wct
= CVAL(inbuf
, smb_wct
);
533 req
->vwv
= (const uint16_t *)(inbuf
+smb_vwv
);
534 req
->buflen
= smb_buflen(inbuf
);
535 req
->buf
= (const uint8_t *)smb_buf_const(inbuf
);
536 req
->unread_bytes
= unread_bytes
;
537 req
->encrypted
= encrypted
;
539 req
->conn
= conn_find(sconn
,req
->tid
);
540 req
->chain_fsp
= NULL
;
542 req
->priv_paths
= NULL
;
544 smb_init_perfcount_data(&req
->pcd
);
546 /* Ensure we have at least wct words and 2 bytes of bcc. */
547 if (smb_size
+ req
->wct
*2 > req_size
) {
548 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
549 (unsigned int)req
->wct
,
550 (unsigned int)req_size
));
553 /* Ensure bcc is correct. */
554 if (((const uint8_t *)smb_buf_const(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
555 DEBUG(0,("init_smb_request: invalid bcc number %u "
556 "(wct = %u, size %u)\n",
557 (unsigned int)req
->buflen
,
558 (unsigned int)req
->wct
,
559 (unsigned int)req_size
));
567 static void process_smb(struct smbd_server_connection
*conn
,
568 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
569 uint32_t seqnum
, bool encrypted
,
570 struct smb_perfcount_data
*deferred_pcd
);
572 static void smbd_deferred_open_timer(struct event_context
*ev
,
573 struct timed_event
*te
,
574 struct timeval _tval
,
577 struct pending_message_list
*msg
= talloc_get_type(private_data
,
578 struct pending_message_list
);
579 struct smbd_server_connection
*sconn
= msg
->sconn
;
580 TALLOC_CTX
*mem_ctx
= talloc_tos();
581 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
584 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
587 exit_server("smbd_deferred_open_timer: talloc failed\n");
591 /* We leave this message on the queue so the open code can
592 know this is a retry. */
593 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
594 (unsigned long long)mid
));
596 /* Mark the message as processed so this is not
597 * re-processed in error. */
598 msg
->processed
= true;
600 process_smb(sconn
, inbuf
,
602 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
604 /* If it's still there and was processed, remove it. */
605 msg
= get_deferred_open_message_smb(sconn
, mid
);
606 if (msg
&& msg
->processed
) {
607 remove_deferred_open_message_smb(sconn
, mid
);
611 /****************************************************************************
612 Function to push a message onto the tail of a linked list of smb messages ready
614 ****************************************************************************/
616 static bool push_queued_message(struct smb_request
*req
,
617 struct timeval request_time
,
618 struct timeval end_time
,
619 char *private_data
, size_t private_len
)
621 int msg_len
= smb_len(req
->inbuf
) + 4;
622 struct pending_message_list
*msg
;
624 msg
= talloc_zero(NULL
, struct pending_message_list
);
627 DEBUG(0,("push_message: malloc fail (1)\n"));
630 msg
->sconn
= req
->sconn
;
632 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
633 if(msg
->buf
.data
== NULL
) {
634 DEBUG(0,("push_message: malloc fail (2)\n"));
639 msg
->request_time
= request_time
;
640 msg
->seqnum
= req
->seqnum
;
641 msg
->encrypted
= req
->encrypted
;
642 msg
->processed
= false;
643 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
646 msg
->private_data
= data_blob_talloc(msg
, private_data
,
648 if (msg
->private_data
.data
== NULL
) {
649 DEBUG(0,("push_message: malloc fail (3)\n"));
655 msg
->te
= tevent_add_timer(msg
->sconn
->ev_ctx
,
658 smbd_deferred_open_timer
,
661 DEBUG(0,("push_message: event_add_timed failed\n"));
666 DLIST_ADD_END(req
->sconn
->deferred_open_queue
, msg
,
667 struct pending_message_list
*);
669 DEBUG(10,("push_message: pushed message length %u on "
670 "deferred_open_queue\n", (unsigned int)msg_len
));
675 /****************************************************************************
676 Function to delete a sharing violation open message by mid.
677 ****************************************************************************/
679 void remove_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
682 struct pending_message_list
*pml
;
684 if (sconn
->using_smb2
) {
685 remove_deferred_open_message_smb2(sconn
, mid
);
689 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
690 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
691 DEBUG(10,("remove_deferred_open_message_smb: "
692 "deleting mid %llu len %u\n",
693 (unsigned long long)mid
,
694 (unsigned int)pml
->buf
.length
));
695 DLIST_REMOVE(sconn
->deferred_open_queue
, pml
);
702 /****************************************************************************
703 Move a sharing violation open retry message to the front of the list and
704 schedule it for immediate processing.
705 ****************************************************************************/
707 void schedule_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
710 struct pending_message_list
*pml
;
713 if (sconn
->using_smb2
) {
714 schedule_deferred_open_message_smb2(sconn
, mid
);
718 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
719 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
721 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
724 (unsigned long long)msg_mid
));
726 if (mid
== msg_mid
) {
727 struct timed_event
*te
;
729 if (pml
->processed
) {
730 /* A processed message should not be
732 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
733 "message mid %llu was already processed\n",
734 (unsigned long long)msg_mid
));
738 DEBUG(10,("schedule_deferred_open_message_smb: "
739 "scheduling mid %llu\n",
740 (unsigned long long)mid
));
742 te
= tevent_add_timer(pml
->sconn
->ev_ctx
,
745 smbd_deferred_open_timer
,
748 DEBUG(10,("schedule_deferred_open_message_smb: "
749 "event_add_timed() failed, "
750 "skipping mid %llu\n",
751 (unsigned long long)msg_mid
));
754 TALLOC_FREE(pml
->te
);
756 DLIST_PROMOTE(sconn
->deferred_open_queue
, pml
);
761 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
762 "find message mid %llu\n",
763 (unsigned long long)mid
));
766 /****************************************************************************
767 Return true if this mid is on the deferred queue and was not yet processed.
768 ****************************************************************************/
770 bool open_was_deferred(struct smbd_server_connection
*sconn
, uint64_t mid
)
772 struct pending_message_list
*pml
;
774 if (sconn
->using_smb2
) {
775 return open_was_deferred_smb2(sconn
, mid
);
778 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
779 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
786 /****************************************************************************
787 Return the message queued by this mid.
788 ****************************************************************************/
790 static struct pending_message_list
*get_deferred_open_message_smb(
791 struct smbd_server_connection
*sconn
, uint64_t mid
)
793 struct pending_message_list
*pml
;
795 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
796 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
803 /****************************************************************************
804 Get the state data queued by this mid.
805 ****************************************************************************/
807 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
808 struct timeval
*p_request_time
,
811 struct pending_message_list
*pml
;
813 if (smbreq
->sconn
->using_smb2
) {
814 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
819 pml
= get_deferred_open_message_smb(smbreq
->sconn
, smbreq
->mid
);
823 if (p_request_time
) {
824 *p_request_time
= pml
->request_time
;
827 *pp_state
= (void *)pml
->private_data
.data
;
832 /****************************************************************************
833 Function to push a deferred open smb message onto a linked list of local smb
834 messages ready for processing.
835 ****************************************************************************/
837 bool push_deferred_open_message_smb(struct smb_request
*req
,
838 struct timeval request_time
,
839 struct timeval timeout
,
841 char *private_data
, size_t priv_len
)
843 struct timeval end_time
;
846 return push_deferred_open_message_smb2(req
->smb2req
,
854 if (req
->unread_bytes
) {
855 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
856 "unread_bytes = %u\n",
857 (unsigned int)req
->unread_bytes
));
858 smb_panic("push_deferred_open_message_smb: "
859 "logic error unread_bytes != 0" );
862 end_time
= timeval_sum(&request_time
, &timeout
);
864 DEBUG(10,("push_deferred_open_message_smb: pushing message "
865 "len %u mid %llu timeout time [%u.%06u]\n",
866 (unsigned int) smb_len(req
->inbuf
)+4,
867 (unsigned long long)req
->mid
,
868 (unsigned int)end_time
.tv_sec
,
869 (unsigned int)end_time
.tv_usec
));
871 return push_queued_message(req
, request_time
, end_time
,
872 private_data
, priv_len
);
875 static void smbd_sig_term_handler(struct tevent_context
*ev
,
876 struct tevent_signal
*se
,
882 exit_server_cleanly("termination signal");
885 void smbd_setup_sig_term_handler(struct smbd_server_connection
*sconn
)
887 struct tevent_signal
*se
;
889 se
= tevent_add_signal(sconn
->ev_ctx
,
892 smbd_sig_term_handler
,
895 exit_server("failed to setup SIGTERM handler");
899 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
900 struct tevent_signal
*se
,
906 struct smbd_server_connection
*sconn
=
907 talloc_get_type_abort(private_data
,
908 struct smbd_server_connection
);
910 change_to_root_user();
911 DEBUG(1,("Reloading services after SIGHUP\n"));
912 reload_services(sconn
, conn_snum_used
, false);
915 void smbd_setup_sig_hup_handler(struct smbd_server_connection
*sconn
)
917 struct tevent_signal
*se
;
919 se
= tevent_add_signal(sconn
->ev_ctx
,
922 smbd_sig_hup_handler
,
925 exit_server("failed to setup SIGHUP handler");
929 static void smbd_conf_updated(struct messaging_context
*msg
,
932 struct server_id server_id
,
935 struct smbd_server_connection
*sconn
=
936 talloc_get_type_abort(private_data
,
937 struct smbd_server_connection
);
939 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
940 "updated. Reloading.\n"));
941 change_to_root_user();
942 reload_services(sconn
, conn_snum_used
, false);
946 * Only allow 5 outstanding trans requests. We're allocating memory, so
950 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
953 for (; list
!= NULL
; list
= list
->next
) {
955 if (list
->mid
== mid
) {
956 return NT_STATUS_INVALID_PARAMETER
;
962 return NT_STATUS_INSUFFICIENT_RESOURCES
;
969 These flags determine some of the permissions required to do an operation
971 Note that I don't set NEED_WRITE on some write operations because they
972 are used by some brain-dead clients when printing, and I don't want to
973 force write permissions on print services.
975 #define AS_USER (1<<0)
976 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
977 #define TIME_INIT (1<<2)
978 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
979 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
980 #define DO_CHDIR (1<<6)
983 define a list of possible SMB messages and their corresponding
984 functions. Any message that has a NULL function is unimplemented -
985 please feel free to contribute implementations!
987 static const struct smb_message_struct
{
989 void (*fn
)(struct smb_request
*req
);
991 } smb_messages
[256] = {
993 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
994 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
995 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
996 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
997 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
998 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
999 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1000 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1001 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1002 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1003 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1004 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1005 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1006 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1007 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1008 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1009 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1010 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1011 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1012 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1013 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1014 /* 0x15 */ { NULL
, NULL
, 0 },
1015 /* 0x16 */ { NULL
, NULL
, 0 },
1016 /* 0x17 */ { NULL
, NULL
, 0 },
1017 /* 0x18 */ { NULL
, NULL
, 0 },
1018 /* 0x19 */ { NULL
, NULL
, 0 },
1019 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1020 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1021 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1022 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1023 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1024 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1025 /* 0x20 */ { "SMBwritec", NULL
,0},
1026 /* 0x21 */ { NULL
, NULL
, 0 },
1027 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1028 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1029 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1030 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1031 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1032 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1033 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1034 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1035 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1036 /* 0x2b */ { "SMBecho",reply_echo
,0},
1037 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1038 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1039 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1040 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1041 /* 0x30 */ { NULL
, NULL
, 0 },
1042 /* 0x31 */ { NULL
, NULL
, 0 },
1043 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1044 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1045 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1046 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1047 /* 0x36 */ { NULL
, NULL
, 0 },
1048 /* 0x37 */ { NULL
, NULL
, 0 },
1049 /* 0x38 */ { NULL
, NULL
, 0 },
1050 /* 0x39 */ { NULL
, NULL
, 0 },
1051 /* 0x3a */ { NULL
, NULL
, 0 },
1052 /* 0x3b */ { NULL
, NULL
, 0 },
1053 /* 0x3c */ { NULL
, NULL
, 0 },
1054 /* 0x3d */ { NULL
, NULL
, 0 },
1055 /* 0x3e */ { NULL
, NULL
, 0 },
1056 /* 0x3f */ { NULL
, NULL
, 0 },
1057 /* 0x40 */ { NULL
, NULL
, 0 },
1058 /* 0x41 */ { NULL
, NULL
, 0 },
1059 /* 0x42 */ { NULL
, NULL
, 0 },
1060 /* 0x43 */ { NULL
, NULL
, 0 },
1061 /* 0x44 */ { NULL
, NULL
, 0 },
1062 /* 0x45 */ { NULL
, NULL
, 0 },
1063 /* 0x46 */ { NULL
, NULL
, 0 },
1064 /* 0x47 */ { NULL
, NULL
, 0 },
1065 /* 0x48 */ { NULL
, NULL
, 0 },
1066 /* 0x49 */ { NULL
, NULL
, 0 },
1067 /* 0x4a */ { NULL
, NULL
, 0 },
1068 /* 0x4b */ { NULL
, NULL
, 0 },
1069 /* 0x4c */ { NULL
, NULL
, 0 },
1070 /* 0x4d */ { NULL
, NULL
, 0 },
1071 /* 0x4e */ { NULL
, NULL
, 0 },
1072 /* 0x4f */ { NULL
, NULL
, 0 },
1073 /* 0x50 */ { NULL
, NULL
, 0 },
1074 /* 0x51 */ { NULL
, NULL
, 0 },
1075 /* 0x52 */ { NULL
, NULL
, 0 },
1076 /* 0x53 */ { NULL
, NULL
, 0 },
1077 /* 0x54 */ { NULL
, NULL
, 0 },
1078 /* 0x55 */ { NULL
, NULL
, 0 },
1079 /* 0x56 */ { NULL
, NULL
, 0 },
1080 /* 0x57 */ { NULL
, NULL
, 0 },
1081 /* 0x58 */ { NULL
, NULL
, 0 },
1082 /* 0x59 */ { NULL
, NULL
, 0 },
1083 /* 0x5a */ { NULL
, NULL
, 0 },
1084 /* 0x5b */ { NULL
, NULL
, 0 },
1085 /* 0x5c */ { NULL
, NULL
, 0 },
1086 /* 0x5d */ { NULL
, NULL
, 0 },
1087 /* 0x5e */ { NULL
, NULL
, 0 },
1088 /* 0x5f */ { NULL
, NULL
, 0 },
1089 /* 0x60 */ { NULL
, NULL
, 0 },
1090 /* 0x61 */ { NULL
, NULL
, 0 },
1091 /* 0x62 */ { NULL
, NULL
, 0 },
1092 /* 0x63 */ { NULL
, NULL
, 0 },
1093 /* 0x64 */ { NULL
, NULL
, 0 },
1094 /* 0x65 */ { NULL
, NULL
, 0 },
1095 /* 0x66 */ { NULL
, NULL
, 0 },
1096 /* 0x67 */ { NULL
, NULL
, 0 },
1097 /* 0x68 */ { NULL
, NULL
, 0 },
1098 /* 0x69 */ { NULL
, NULL
, 0 },
1099 /* 0x6a */ { NULL
, NULL
, 0 },
1100 /* 0x6b */ { NULL
, NULL
, 0 },
1101 /* 0x6c */ { NULL
, NULL
, 0 },
1102 /* 0x6d */ { NULL
, NULL
, 0 },
1103 /* 0x6e */ { NULL
, NULL
, 0 },
1104 /* 0x6f */ { NULL
, NULL
, 0 },
1105 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1106 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1107 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1108 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1109 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1110 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1111 /* 0x76 */ { NULL
, NULL
, 0 },
1112 /* 0x77 */ { NULL
, NULL
, 0 },
1113 /* 0x78 */ { NULL
, NULL
, 0 },
1114 /* 0x79 */ { NULL
, NULL
, 0 },
1115 /* 0x7a */ { NULL
, NULL
, 0 },
1116 /* 0x7b */ { NULL
, NULL
, 0 },
1117 /* 0x7c */ { NULL
, NULL
, 0 },
1118 /* 0x7d */ { NULL
, NULL
, 0 },
1119 /* 0x7e */ { NULL
, NULL
, 0 },
1120 /* 0x7f */ { NULL
, NULL
, 0 },
1121 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1122 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1123 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1124 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1125 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1126 /* 0x85 */ { NULL
, NULL
, 0 },
1127 /* 0x86 */ { NULL
, NULL
, 0 },
1128 /* 0x87 */ { NULL
, NULL
, 0 },
1129 /* 0x88 */ { NULL
, NULL
, 0 },
1130 /* 0x89 */ { NULL
, NULL
, 0 },
1131 /* 0x8a */ { NULL
, NULL
, 0 },
1132 /* 0x8b */ { NULL
, NULL
, 0 },
1133 /* 0x8c */ { NULL
, NULL
, 0 },
1134 /* 0x8d */ { NULL
, NULL
, 0 },
1135 /* 0x8e */ { NULL
, NULL
, 0 },
1136 /* 0x8f */ { NULL
, NULL
, 0 },
1137 /* 0x90 */ { NULL
, NULL
, 0 },
1138 /* 0x91 */ { NULL
, NULL
, 0 },
1139 /* 0x92 */ { NULL
, NULL
, 0 },
1140 /* 0x93 */ { NULL
, NULL
, 0 },
1141 /* 0x94 */ { NULL
, NULL
, 0 },
1142 /* 0x95 */ { NULL
, NULL
, 0 },
1143 /* 0x96 */ { NULL
, NULL
, 0 },
1144 /* 0x97 */ { NULL
, NULL
, 0 },
1145 /* 0x98 */ { NULL
, NULL
, 0 },
1146 /* 0x99 */ { NULL
, NULL
, 0 },
1147 /* 0x9a */ { NULL
, NULL
, 0 },
1148 /* 0x9b */ { NULL
, NULL
, 0 },
1149 /* 0x9c */ { NULL
, NULL
, 0 },
1150 /* 0x9d */ { NULL
, NULL
, 0 },
1151 /* 0x9e */ { NULL
, NULL
, 0 },
1152 /* 0x9f */ { NULL
, NULL
, 0 },
1153 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1154 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1155 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1156 /* 0xa3 */ { NULL
, NULL
, 0 },
1157 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1158 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1159 /* 0xa6 */ { NULL
, NULL
, 0 },
1160 /* 0xa7 */ { NULL
, NULL
, 0 },
1161 /* 0xa8 */ { NULL
, NULL
, 0 },
1162 /* 0xa9 */ { NULL
, NULL
, 0 },
1163 /* 0xaa */ { NULL
, NULL
, 0 },
1164 /* 0xab */ { NULL
, NULL
, 0 },
1165 /* 0xac */ { NULL
, NULL
, 0 },
1166 /* 0xad */ { NULL
, NULL
, 0 },
1167 /* 0xae */ { NULL
, NULL
, 0 },
1168 /* 0xaf */ { NULL
, NULL
, 0 },
1169 /* 0xb0 */ { NULL
, NULL
, 0 },
1170 /* 0xb1 */ { NULL
, NULL
, 0 },
1171 /* 0xb2 */ { NULL
, NULL
, 0 },
1172 /* 0xb3 */ { NULL
, NULL
, 0 },
1173 /* 0xb4 */ { NULL
, NULL
, 0 },
1174 /* 0xb5 */ { NULL
, NULL
, 0 },
1175 /* 0xb6 */ { NULL
, NULL
, 0 },
1176 /* 0xb7 */ { NULL
, NULL
, 0 },
1177 /* 0xb8 */ { NULL
, NULL
, 0 },
1178 /* 0xb9 */ { NULL
, NULL
, 0 },
1179 /* 0xba */ { NULL
, NULL
, 0 },
1180 /* 0xbb */ { NULL
, NULL
, 0 },
1181 /* 0xbc */ { NULL
, NULL
, 0 },
1182 /* 0xbd */ { NULL
, NULL
, 0 },
1183 /* 0xbe */ { NULL
, NULL
, 0 },
1184 /* 0xbf */ { NULL
, NULL
, 0 },
1185 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1186 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1187 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1188 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1189 /* 0xc4 */ { NULL
, NULL
, 0 },
1190 /* 0xc5 */ { NULL
, NULL
, 0 },
1191 /* 0xc6 */ { NULL
, NULL
, 0 },
1192 /* 0xc7 */ { NULL
, NULL
, 0 },
1193 /* 0xc8 */ { NULL
, NULL
, 0 },
1194 /* 0xc9 */ { NULL
, NULL
, 0 },
1195 /* 0xca */ { NULL
, NULL
, 0 },
1196 /* 0xcb */ { NULL
, NULL
, 0 },
1197 /* 0xcc */ { NULL
, NULL
, 0 },
1198 /* 0xcd */ { NULL
, NULL
, 0 },
1199 /* 0xce */ { NULL
, NULL
, 0 },
1200 /* 0xcf */ { NULL
, NULL
, 0 },
1201 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1202 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1203 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1204 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1205 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1206 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1207 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1208 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1209 /* 0xd8 */ { NULL
, NULL
, 0 },
1210 /* 0xd9 */ { NULL
, NULL
, 0 },
1211 /* 0xda */ { NULL
, NULL
, 0 },
1212 /* 0xdb */ { NULL
, NULL
, 0 },
1213 /* 0xdc */ { NULL
, NULL
, 0 },
1214 /* 0xdd */ { NULL
, NULL
, 0 },
1215 /* 0xde */ { NULL
, NULL
, 0 },
1216 /* 0xdf */ { NULL
, NULL
, 0 },
1217 /* 0xe0 */ { NULL
, NULL
, 0 },
1218 /* 0xe1 */ { NULL
, NULL
, 0 },
1219 /* 0xe2 */ { NULL
, NULL
, 0 },
1220 /* 0xe3 */ { NULL
, NULL
, 0 },
1221 /* 0xe4 */ { NULL
, NULL
, 0 },
1222 /* 0xe5 */ { NULL
, NULL
, 0 },
1223 /* 0xe6 */ { NULL
, NULL
, 0 },
1224 /* 0xe7 */ { NULL
, NULL
, 0 },
1225 /* 0xe8 */ { NULL
, NULL
, 0 },
1226 /* 0xe9 */ { NULL
, NULL
, 0 },
1227 /* 0xea */ { NULL
, NULL
, 0 },
1228 /* 0xeb */ { NULL
, NULL
, 0 },
1229 /* 0xec */ { NULL
, NULL
, 0 },
1230 /* 0xed */ { NULL
, NULL
, 0 },
1231 /* 0xee */ { NULL
, NULL
, 0 },
1232 /* 0xef */ { NULL
, NULL
, 0 },
1233 /* 0xf0 */ { NULL
, NULL
, 0 },
1234 /* 0xf1 */ { NULL
, NULL
, 0 },
1235 /* 0xf2 */ { NULL
, NULL
, 0 },
1236 /* 0xf3 */ { NULL
, NULL
, 0 },
1237 /* 0xf4 */ { NULL
, NULL
, 0 },
1238 /* 0xf5 */ { NULL
, NULL
, 0 },
1239 /* 0xf6 */ { NULL
, NULL
, 0 },
1240 /* 0xf7 */ { NULL
, NULL
, 0 },
1241 /* 0xf8 */ { NULL
, NULL
, 0 },
1242 /* 0xf9 */ { NULL
, NULL
, 0 },
1243 /* 0xfa */ { NULL
, NULL
, 0 },
1244 /* 0xfb */ { NULL
, NULL
, 0 },
1245 /* 0xfc */ { NULL
, NULL
, 0 },
1246 /* 0xfd */ { NULL
, NULL
, 0 },
1247 /* 0xfe */ { NULL
, NULL
, 0 },
1248 /* 0xff */ { NULL
, NULL
, 0 }
1252 /*******************************************************************
1253 allocate and initialize a reply packet
1254 ********************************************************************/
1256 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1257 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1261 * Protect against integer wrap
1263 if ((num_bytes
> 0xffffff)
1264 || ((num_bytes
+ smb_size
+ num_words
*2) > 0xffffff)) {
1266 if (asprintf(&msg
, "num_bytes too large: %u",
1267 (unsigned)num_bytes
) == -1) {
1268 msg
= discard_const_p(char, "num_bytes too large");
1273 *outbuf
= talloc_array(mem_ctx
, char,
1274 smb_size
+ num_words
*2 + num_bytes
);
1275 if (*outbuf
== NULL
) {
1279 construct_reply_common(req
, inbuf
, *outbuf
);
1280 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1282 * Zero out the word area, the caller has to take care of the bcc area
1285 if (num_words
!= 0) {
1286 memset(*outbuf
+ smb_vwv0
, 0, num_words
*2);
1292 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1295 if (!create_outbuf(req
, req
, (const char *)req
->inbuf
, &outbuf
, num_words
,
1297 smb_panic("could not allocate output buffer\n");
1299 req
->outbuf
= (uint8_t *)outbuf
;
1303 /*******************************************************************
1304 Dump a packet to a file.
1305 ********************************************************************/
1307 static void smb_dump(const char *name
, int type
, const char *data
)
1312 if (DEBUGLEVEL
< 50) {
1316 len
= smb_len_tcp(data
)+4;
1317 for (i
=1;i
<100;i
++) {
1318 fname
= talloc_asprintf(talloc_tos(),
1322 type
? "req" : "resp");
1323 if (fname
== NULL
) {
1326 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1327 if (fd
!= -1 || errno
!= EEXIST
) break;
1331 ssize_t ret
= write(fd
, data
, len
);
1333 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1335 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1340 /****************************************************************************
1341 Prepare everything for calling the actual request function, and potentially
1342 call the request function via the "new" interface.
1344 Return False if the "legacy" function needs to be called, everything is
1347 Return True if we're done.
1349 I know this API sucks, but it is the one with the least code change I could
1351 ****************************************************************************/
1353 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
)
1357 connection_struct
*conn
= NULL
;
1358 struct smbd_server_connection
*sconn
= req
->sconn
;
1362 if (smb_messages
[type
].fn
== NULL
) {
1363 DEBUG(0,("Unknown message type %d!\n",type
));
1364 smb_dump("Unknown", 1, (const char *)req
->inbuf
);
1365 reply_unknown_new(req
, type
);
1369 flags
= smb_messages
[type
].flags
;
1371 /* In share mode security we must ignore the vuid. */
1372 session_tag
= req
->vuid
;
1375 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1376 (int)getpid(), (unsigned long)conn
));
1378 smb_dump(smb_fn_name(type
), 1, (const char *)req
->inbuf
);
1380 /* Ensure this value is replaced in the incoming packet. */
1381 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_uid
,session_tag
);
1384 * Ensure the correct username is in current_user_info. This is a
1385 * really ugly bugfix for problems with multiple session_setup_and_X's
1386 * being done and allowing %U and %G substitutions to work correctly.
1387 * There is a reason this code is done here, don't move it unless you
1388 * know what you're doing... :-).
1392 if (session_tag
!= sconn
->smb1
.sessions
.last_session_tag
) {
1393 user_struct
*vuser
= NULL
;
1395 sconn
->smb1
.sessions
.last_session_tag
= session_tag
;
1396 if(session_tag
!= UID_FIELD_INVALID
) {
1397 vuser
= get_valid_user_struct(sconn
, session_tag
);
1399 set_current_user_info(
1400 vuser
->session_info
->unix_info
->sanitized_username
,
1401 vuser
->session_info
->unix_info
->unix_name
,
1402 vuser
->session_info
->info
->domain_name
);
1407 /* Does this call need to be run as the connected user? */
1408 if (flags
& AS_USER
) {
1410 /* Does this call need a valid tree connection? */
1413 * Amazingly, the error code depends on the command
1416 if (type
== SMBntcreateX
) {
1417 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1419 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1424 if (!change_to_user(conn
,session_tag
)) {
1425 DEBUG(0, ("Error: Could not change to user. Removing "
1426 "deferred open, mid=%llu.\n",
1427 (unsigned long long)req
->mid
));
1428 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1432 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1434 /* Does it need write permission? */
1435 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1436 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1440 /* IPC services are limited */
1441 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1442 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1446 /* This call needs to be run as root */
1447 change_to_root_user();
1450 /* load service specific parameters */
1452 if (req
->encrypted
) {
1453 conn
->encrypted_tid
= true;
1454 /* encrypted required from now on. */
1455 conn
->encrypt_level
= Required
;
1456 } else if (ENCRYPTION_REQUIRED(conn
)) {
1457 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1458 exit_server_cleanly("encryption required "
1464 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1465 (flags
& (AS_USER
|DO_CHDIR
)
1467 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1470 conn
->num_smb_operations
++;
1474 * Does this protocol need to be run as guest? (Only archane
1475 * messenger service requests have this...)
1477 if (flags
& AS_GUEST
) {
1481 if (!change_to_guest()) {
1482 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1486 raddr
= tsocket_address_inet_addr_string(sconn
->remote_address
,
1488 if (raddr
== NULL
) {
1489 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1494 * Haven't we checked this in smbd_process already???
1497 ok
= allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1498 sconn
->remote_hostname
, raddr
);
1502 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1507 smb_messages
[type
].fn(req
);
1511 /****************************************************************************
1512 Construct a reply to the incoming packet.
1513 ****************************************************************************/
1515 static void construct_reply(struct smbd_server_connection
*sconn
,
1516 char *inbuf
, int size
, size_t unread_bytes
,
1517 uint32_t seqnum
, bool encrypted
,
1518 struct smb_perfcount_data
*deferred_pcd
)
1520 connection_struct
*conn
;
1521 struct smb_request
*req
;
1523 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1524 smb_panic("could not allocate smb_request");
1527 if (!init_smb_request(req
, sconn
, (uint8
*)inbuf
, unread_bytes
,
1528 encrypted
, seqnum
)) {
1529 exit_server_cleanly("Invalid SMB request");
1532 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1534 /* we popped this message off the queue - keep original perf data */
1536 req
->pcd
= *deferred_pcd
;
1538 SMB_PERFCOUNT_START(&req
->pcd
);
1539 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1540 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1543 conn
= switch_message(req
->cmd
, req
);
1545 if (req
->outbuf
== NULL
) {
1549 if (CVAL(req
->outbuf
,0) == 0) {
1550 show_msg((char *)req
->outbuf
);
1553 if (!srv_send_smb(req
->sconn
,
1554 (char *)req
->outbuf
,
1555 true, req
->seqnum
+1,
1556 IS_CONN_ENCRYPTED(conn
)||req
->encrypted
,
1558 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1566 static void construct_reply_chain(struct smbd_server_connection
*sconn
,
1567 char *inbuf
, int size
, uint32_t seqnum
,
1569 struct smb_perfcount_data
*deferred_pcd
)
1571 struct smb_request
**reqs
= NULL
;
1572 struct smb_request
*req
;
1576 ok
= smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf
, sconn
, encrypted
,
1577 seqnum
, &reqs
, &num_reqs
);
1579 char errbuf
[smb_size
];
1580 error_packet(errbuf
, 0, 0, NT_STATUS_INVALID_PARAMETER
,
1581 __LINE__
, __FILE__
);
1582 if (!srv_send_smb(sconn
, errbuf
, true, seqnum
, encrypted
,
1584 exit_server_cleanly("construct_reply_chain: "
1585 "srv_send_smb failed.");
1591 req
->inbuf
= (uint8_t *)talloc_move(reqs
, &inbuf
);
1593 req
->conn
= switch_message(req
->cmd
, req
);
1595 if (req
->outbuf
== NULL
) {
1597 * Request has suspended itself, will come
1602 smb_request_done(req
);
1606 * To be called from an async SMB handler that is potentially chained
1607 * when it is finished for shipping.
1610 void smb_request_done(struct smb_request
*req
)
1612 struct smb_request
**reqs
= NULL
;
1613 struct smb_request
*first_req
;
1614 size_t i
, num_reqs
, next_index
;
1617 if (req
->chain
== NULL
) {
1623 num_reqs
= talloc_array_length(reqs
);
1625 for (i
=0; i
<num_reqs
; i
++) {
1626 if (reqs
[i
] == req
) {
1630 if (i
== num_reqs
) {
1632 * Invalid chain, should not happen
1634 status
= NT_STATUS_INTERNAL_ERROR
;
1639 while ((next_index
< num_reqs
) && (IVAL(req
->outbuf
, smb_rcls
) == 0)) {
1640 struct smb_request
*next
= reqs
[next_index
];
1642 next
->vuid
= SVAL(req
->outbuf
, smb_uid
);
1643 next
->tid
= SVAL(req
->outbuf
, smb_tid
);
1644 next
->conn
= conn_find(req
->sconn
, req
->tid
);
1645 next
->chain_fsp
= req
->chain_fsp
;
1646 next
->inbuf
= (uint8_t *)req
->inbuf
;
1649 req
->conn
= switch_message(req
->cmd
, req
);
1651 if (req
->outbuf
== NULL
) {
1653 * Request has suspended itself, will come
1661 first_req
= reqs
[0];
1663 for (i
=1; i
<next_index
; i
++) {
1666 ok
= smb_splice_chain(&first_req
->outbuf
, reqs
[i
]->outbuf
);
1668 status
= NT_STATUS_INTERNAL_ERROR
;
1673 SSVAL(first_req
->outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
1674 SSVAL(first_req
->outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
1677 * This scary statement intends to set the
1678 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1679 * to the value last_req->outbuf carries
1681 SSVAL(first_req
->outbuf
, smb_flg2
,
1682 (SVAL(first_req
->outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
1683 |(SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
1686 * Transfer the error codes from the subrequest to the main one
1688 SSVAL(first_req
->outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
1689 SSVAL(first_req
->outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
1692 first_req
->outbuf
, talloc_get_size(first_req
->outbuf
) - 4);
1695 if (!srv_send_smb(first_req
->sconn
,
1696 (char *)first_req
->outbuf
,
1697 true, first_req
->seqnum
+1,
1698 IS_CONN_ENCRYPTED(req
->conn
)||first_req
->encrypted
,
1700 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1703 TALLOC_FREE(req
); /* non-chained case */
1704 TALLOC_FREE(reqs
); /* chained case */
1709 char errbuf
[smb_size
];
1710 error_packet(errbuf
, 0, 0, status
, __LINE__
, __FILE__
);
1711 if (!srv_send_smb(req
->sconn
, errbuf
, true,
1712 req
->seqnum
+1, req
->encrypted
,
1714 exit_server_cleanly("construct_reply_chain: "
1715 "srv_send_smb failed.");
1718 TALLOC_FREE(req
); /* non-chained case */
1719 TALLOC_FREE(reqs
); /* chained case */
1722 /****************************************************************************
1723 Process an smb from the client
1724 ****************************************************************************/
1725 static void process_smb(struct smbd_server_connection
*sconn
,
1726 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1727 uint32_t seqnum
, bool encrypted
,
1728 struct smb_perfcount_data
*deferred_pcd
)
1730 int msg_type
= CVAL(inbuf
,0);
1732 DO_PROFILE_INC(smb_count
);
1734 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1736 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1737 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1739 if (msg_type
!= NBSSmessage
) {
1741 * NetBIOS session request, keepalive, etc.
1743 reply_special(sconn
, (char *)inbuf
, nread
);
1747 if (sconn
->using_smb2
) {
1748 /* At this point we're not really using smb2,
1749 * we make the decision here.. */
1750 if (smbd_is_smb2_header(inbuf
, nread
)) {
1751 smbd_smb2_first_negprot(sconn
, inbuf
, nread
);
1753 } else if (nread
>= smb_size
&& valid_smb_header(sconn
, inbuf
)
1754 && CVAL(inbuf
, smb_com
) != 0x72) {
1755 /* This is a non-negprot SMB1 packet.
1756 Disable SMB2 from now on. */
1757 sconn
->using_smb2
= false;
1761 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1762 * so subtract 4 from it. */
1763 if ((nread
< (smb_size
- 4)) || !valid_smb_header(sconn
, inbuf
)) {
1764 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1767 /* special magic for immediate exit */
1769 (IVAL(inbuf
, 4) == 0x74697865) &&
1770 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1771 uint8_t exitcode
= CVAL(inbuf
, 8);
1772 DEBUG(1, ("Exiting immediately with code %d\n",
1777 exit_server_cleanly("Non-SMB packet");
1780 show_msg((char *)inbuf
);
1782 if ((unread_bytes
== 0) && smb1_is_chain(inbuf
)) {
1783 construct_reply_chain(sconn
, (char *)inbuf
, nread
,
1784 seqnum
, encrypted
, deferred_pcd
);
1786 construct_reply(sconn
, (char *)inbuf
, nread
, unread_bytes
,
1787 seqnum
, encrypted
, deferred_pcd
);
1793 sconn
->num_requests
++;
1795 /* The timeout_processing function isn't run nearly
1796 often enough to implement 'max log size' without
1797 overrunning the size of the file by many megabytes.
1798 This is especially true if we are running at debug
1799 level 10. Checking every 50 SMBs is a nice
1800 tradeoff of performance vs log file size overrun. */
1802 if ((sconn
->num_requests
% 50) == 0 &&
1803 need_to_check_log_size()) {
1804 change_to_root_user();
1809 /****************************************************************************
1810 Return a string containing the function name of a SMB command.
1811 ****************************************************************************/
1813 const char *smb_fn_name(int type
)
1815 const char *unknown_name
= "SMBunknown";
1817 if (smb_messages
[type
].name
== NULL
)
1818 return(unknown_name
);
1820 return(smb_messages
[type
].name
);
1823 /****************************************************************************
1824 Helper functions for contruct_reply.
1825 ****************************************************************************/
1827 void add_to_common_flags2(uint32 v
)
1832 void remove_from_common_flags2(uint32 v
)
1834 common_flags2
&= ~v
;
1837 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1840 uint16_t in_flags2
= SVAL(inbuf
,smb_flg2
);
1841 uint16_t out_flags2
= common_flags2
;
1843 out_flags2
|= in_flags2
& FLAGS2_UNICODE_STRINGS
;
1844 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
;
1845 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
;
1847 srv_set_message(outbuf
,0,0,false);
1849 SCVAL(outbuf
, smb_com
, req
->cmd
);
1850 SIVAL(outbuf
,smb_rcls
,0);
1851 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1852 SSVAL(outbuf
,smb_flg2
, out_flags2
);
1853 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1854 memcpy(outbuf
+smb_ss_field
, inbuf
+smb_ss_field
, 8);
1856 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
1857 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
1858 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
1859 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
1862 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
1864 construct_reply_common(req
, (const char *)req
->inbuf
, outbuf
);
1868 * @brief Find the smb_cmd offset of the last command pushed
1869 * @param[in] buf The buffer we're building up
1870 * @retval Where can we put our next andx cmd?
1872 * While chaining requests, the "next" request we're looking at needs to put
1873 * its SMB_Command before the data the previous request already built up added
1874 * to the chain. Find the offset to the place where we have to put our cmd.
1877 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
1882 cmd
= CVAL(buf
, smb_com
);
1884 if (!is_andx_req(cmd
)) {
1890 while (CVAL(buf
, ofs
) != 0xff) {
1892 if (!is_andx_req(CVAL(buf
, ofs
))) {
1897 * ofs is from start of smb header, so add the 4 length
1898 * bytes. The next cmd is right after the wct field.
1900 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
1902 if (ofs
+4 >= talloc_get_size(buf
)) {
1912 * @brief Do the smb chaining at a buffer level
1913 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1914 * @param[in] andx_buf Buffer to be appended
1917 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
)
1919 uint8_t smb_command
= CVAL(andx_buf
, smb_com
);
1920 uint8_t wct
= CVAL(andx_buf
, smb_wct
);
1921 const uint16_t *vwv
= (const uint16_t *)(andx_buf
+ smb_vwv
);
1922 uint32_t num_bytes
= smb_buflen(andx_buf
);
1923 const uint8_t *bytes
= (const uint8_t *)smb_buf_const(andx_buf
);
1926 size_t old_size
, new_size
;
1928 size_t chain_padding
= 0;
1929 size_t andx_cmd_ofs
;
1932 old_size
= talloc_get_size(*poutbuf
);
1934 if ((old_size
% 4) != 0) {
1936 * Align the wct field of subsequent requests to a 4-byte
1939 chain_padding
= 4 - (old_size
% 4);
1943 * After the old request comes the new wct field (1 byte), the vwv's
1944 * and the num_bytes field.
1947 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
1948 new_size
+= num_bytes
;
1950 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
1951 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
1952 (unsigned)new_size
));
1956 outbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, new_size
);
1957 if (outbuf
== NULL
) {
1958 DEBUG(0, ("talloc failed\n"));
1963 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
1964 DEBUG(1, ("invalid command chain\n"));
1965 *poutbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, old_size
);
1969 if (chain_padding
!= 0) {
1970 memset(outbuf
+ old_size
, 0, chain_padding
);
1971 old_size
+= chain_padding
;
1974 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
1975 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
1980 * Push the chained request:
1985 SCVAL(outbuf
, ofs
, wct
);
1992 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
1997 * Read&X has an offset into its data buffer at
1998 * vwv[6]. reply_read_andx has no idea anymore that it's
1999 * running from within a chain, so we have to fix up the
2002 * Although it looks disgusting at this place, I want to keep
2003 * it here. The alternative would be to push knowledge about
2004 * the andx chain down into read&x again.
2007 if (smb_command
== SMBreadX
) {
2008 uint8_t *bytes_addr
;
2012 * Invalid read&x response
2017 bytes_addr
= outbuf
+ ofs
/* vwv start */
2018 + sizeof(uint16_t) * wct
/* vwv array */
2019 + sizeof(uint16_t); /* bcc */
2021 SSVAL(outbuf
+ ofs
, 6 * sizeof(uint16_t),
2022 bytes_addr
- outbuf
- 4);
2025 ofs
+= sizeof(uint16_t) * wct
;
2031 SSVAL(outbuf
, ofs
, num_bytes
);
2032 ofs
+= sizeof(uint16_t);
2038 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
2043 bool smb1_is_chain(const uint8_t *buf
)
2045 uint8_t cmd
, wct
, andx_cmd
;
2047 cmd
= CVAL(buf
, smb_com
);
2048 if (!is_andx_req(cmd
)) {
2051 wct
= CVAL(buf
, smb_wct
);
2055 andx_cmd
= CVAL(buf
, smb_vwv
);
2056 return (andx_cmd
!= 0xFF);
2059 bool smb1_walk_chain(const uint8_t *buf
,
2060 bool (*fn
)(uint8_t cmd
,
2061 uint8_t wct
, const uint16_t *vwv
,
2062 uint16_t num_bytes
, const uint8_t *bytes
,
2063 void *private_data
),
2066 size_t smblen
= smb_len(buf
);
2067 const char *smb_buf
= smb_base(buf
);
2068 uint8_t cmd
, chain_cmd
;
2070 const uint16_t *vwv
;
2072 const uint8_t *bytes
;
2074 cmd
= CVAL(buf
, smb_com
);
2075 wct
= CVAL(buf
, smb_wct
);
2076 vwv
= (const uint16_t *)(buf
+ smb_vwv
);
2077 num_bytes
= smb_buflen(buf
);
2078 bytes
= (uint8_t *)smb_buf_const(buf
);
2080 if (!fn(cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2084 if (!is_andx_req(cmd
)) {
2091 chain_cmd
= CVAL(vwv
, 0);
2093 while (chain_cmd
!= 0xff) {
2094 uint32_t chain_offset
; /* uint32_t to avoid overflow */
2095 size_t length_needed
;
2096 ptrdiff_t vwv_offset
;
2098 chain_offset
= SVAL(vwv
+1, 0);
2101 * Check if the client tries to fool us. The chain
2102 * offset needs to point beyond the current request in
2103 * the chain, it needs to strictly grow. Otherwise we
2104 * might be tricked into an endless loop always
2105 * processing the same request over and over again. We
2106 * used to assume that vwv and the byte buffer array
2107 * in a chain are always attached, but OS/2 the
2108 * Write&X/Read&X chain puts the Read&X vwv array
2109 * right behind the Write&X vwv chain. The Write&X bcc
2110 * array is put behind the Read&X vwv array. So now we
2111 * check whether the chain offset points strictly
2112 * behind the previous vwv array. req->buf points
2113 * right after the vwv array of the previous
2115 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2119 vwv_offset
= ((const char *)vwv
- smb_buf
);
2120 if (chain_offset
<= vwv_offset
) {
2125 * Next check: Make sure the chain offset does not
2126 * point beyond the overall smb request length.
2129 length_needed
= chain_offset
+1; /* wct */
2130 if (length_needed
> smblen
) {
2135 * Now comes the pointer magic. Goal here is to set up
2136 * vwv and buf correctly again. The chain offset (the
2137 * former vwv[1]) points at the new wct field.
2140 wct
= CVAL(smb_buf
, chain_offset
);
2142 if (is_andx_req(chain_cmd
) && (wct
< 2)) {
2147 * Next consistency check: Make the new vwv array fits
2148 * in the overall smb request.
2151 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2152 if (length_needed
> smblen
) {
2155 vwv
= (const uint16_t *)(smb_buf
+ chain_offset
+ 1);
2158 * Now grab the new byte buffer....
2161 num_bytes
= SVAL(vwv
+wct
, 0);
2164 * .. and check that it fits.
2167 length_needed
+= num_bytes
;
2168 if (length_needed
> smblen
) {
2171 bytes
= (const uint8_t *)(vwv
+wct
+1);
2173 if (!fn(chain_cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2177 if (!is_andx_req(chain_cmd
)) {
2180 chain_cmd
= CVAL(vwv
, 0);
2185 static bool smb1_chain_length_cb(uint8_t cmd
,
2186 uint8_t wct
, const uint16_t *vwv
,
2187 uint16_t num_bytes
, const uint8_t *bytes
,
2190 unsigned *count
= (unsigned *)private_data
;
2195 unsigned smb1_chain_length(const uint8_t *buf
)
2199 if (!smb1_walk_chain(buf
, smb1_chain_length_cb
, &count
)) {
2205 struct smb1_parse_chain_state
{
2206 TALLOC_CTX
*mem_ctx
;
2208 struct smbd_server_connection
*sconn
;
2212 struct smb_request
**reqs
;
2216 static bool smb1_parse_chain_cb(uint8_t cmd
,
2217 uint8_t wct
, const uint16_t *vwv
,
2218 uint16_t num_bytes
, const uint8_t *bytes
,
2221 struct smb1_parse_chain_state
*state
=
2222 (struct smb1_parse_chain_state
*)private_data
;
2223 struct smb_request
**reqs
;
2224 struct smb_request
*req
;
2227 reqs
= talloc_realloc(state
->mem_ctx
, state
->reqs
,
2228 struct smb_request
*, state
->num_reqs
+1);
2234 req
= talloc(reqs
, struct smb_request
);
2239 ok
= init_smb_request(req
, state
->sconn
, state
->buf
, 0,
2240 state
->encrypted
, state
->seqnum
);
2247 req
->buflen
= num_bytes
;
2250 reqs
[state
->num_reqs
] = req
;
2251 state
->num_reqs
+= 1;
2255 bool smb1_parse_chain(TALLOC_CTX
*mem_ctx
, const uint8_t *buf
,
2256 struct smbd_server_connection
*sconn
,
2257 bool encrypted
, uint32_t seqnum
,
2258 struct smb_request
***reqs
, unsigned *num_reqs
)
2260 struct smb1_parse_chain_state state
;
2263 state
.mem_ctx
= mem_ctx
;
2265 state
.sconn
= sconn
;
2266 state
.encrypted
= encrypted
;
2267 state
.seqnum
= seqnum
;
2271 if (!smb1_walk_chain(buf
, smb1_parse_chain_cb
, &state
)) {
2272 TALLOC_FREE(state
.reqs
);
2275 for (i
=0; i
<state
.num_reqs
; i
++) {
2276 state
.reqs
[i
]->chain
= state
.reqs
;
2279 *num_reqs
= state
.num_reqs
;
2283 /****************************************************************************
2284 Check if services need reloading.
2285 ****************************************************************************/
2287 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2290 if (last_smb_conf_reload_time
== 0) {
2291 last_smb_conf_reload_time
= t
;
2294 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2295 reload_services(sconn
, conn_snum_used
, true);
2296 last_smb_conf_reload_time
= t
;
2300 static bool fd_is_readable(int fd
)
2304 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2306 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2310 static void smbd_server_connection_write_handler(
2311 struct smbd_server_connection
*sconn
)
2313 /* TODO: make write nonblocking */
2316 static void smbd_server_connection_read_handler(
2317 struct smbd_server_connection
*sconn
, int fd
)
2319 uint8_t *inbuf
= NULL
;
2320 size_t inbuf_len
= 0;
2321 size_t unread_bytes
= 0;
2322 bool encrypted
= false;
2323 TALLOC_CTX
*mem_ctx
= talloc_tos();
2329 if (lp_async_smb_echo_handler()
2330 && fd_is_readable(sconn
->smb1
.echo_handler
.trusted_fd
)) {
2332 * This is the super-ugly hack to prefer the packets
2333 * forwarded by the echo handler over the ones by the
2336 fd
= sconn
->smb1
.echo_handler
.trusted_fd
;
2339 from_client
= (sconn
->sock
== fd
);
2342 smbd_lock_socket(sconn
);
2344 if (!fd_is_readable(fd
)) {
2345 DEBUG(10,("the echo listener was faster\n"));
2346 smbd_unlock_socket(sconn
);
2351 /* TODO: make this completely nonblocking */
2352 status
= receive_smb_talloc(mem_ctx
, sconn
, fd
,
2353 (char **)(void *)&inbuf
,
2357 &inbuf_len
, &seqnum
,
2358 false /* trusted channel */);
2361 smbd_unlock_socket(sconn
);
2364 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2367 if (NT_STATUS_IS_ERR(status
)) {
2368 exit_server_cleanly("failed to receive smb request");
2370 if (!NT_STATUS_IS_OK(status
)) {
2375 process_smb(sconn
, inbuf
, inbuf_len
, unread_bytes
,
2376 seqnum
, encrypted
, NULL
);
2379 static void smbd_server_connection_handler(struct event_context
*ev
,
2380 struct fd_event
*fde
,
2384 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2385 struct smbd_server_connection
);
2387 if (flags
& EVENT_FD_WRITE
) {
2388 smbd_server_connection_write_handler(conn
);
2391 if (flags
& EVENT_FD_READ
) {
2392 smbd_server_connection_read_handler(conn
, conn
->sock
);
2397 static void smbd_server_echo_handler(struct event_context
*ev
,
2398 struct fd_event
*fde
,
2402 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2403 struct smbd_server_connection
);
2405 if (flags
& EVENT_FD_WRITE
) {
2406 smbd_server_connection_write_handler(conn
);
2409 if (flags
& EVENT_FD_READ
) {
2410 smbd_server_connection_read_handler(
2411 conn
, conn
->smb1
.echo_handler
.trusted_fd
);
2416 #ifdef CLUSTER_SUPPORT
2417 /****************************************************************************
2418 received when we should release a specific IP
2419 ****************************************************************************/
2420 static void release_ip(const char *ip
, void *priv
)
2422 const char *addr
= (const char *)priv
;
2423 const char *p
= addr
;
2425 if (strncmp("::ffff:", addr
, 7) == 0) {
2429 DEBUG(10, ("Got release IP message for %s, "
2430 "our address is %s\n", ip
, p
));
2432 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2433 /* we can't afford to do a clean exit - that involves
2434 database writes, which would potentially mean we
2435 are still running after the failover has finished -
2436 we have to get rid of this process ID straight
2438 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2440 /* note we must exit with non-zero status so the unclean handler gets
2441 called in the parent, so that the brl database is tickled */
2446 static int client_get_tcp_info(int sock
, struct sockaddr_storage
*server
,
2447 struct sockaddr_storage
*client
)
2450 length
= sizeof(*server
);
2451 if (getsockname(sock
, (struct sockaddr
*)server
, &length
) != 0) {
2454 length
= sizeof(*client
);
2455 if (getpeername(sock
, (struct sockaddr
*)client
, &length
) != 0) {
2463 * Send keepalive packets to our client
2465 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2467 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2468 private_data
, struct smbd_server_connection
);
2471 if (sconn
->using_smb2
) {
2472 /* Don't do keepalives on an SMB2 connection. */
2476 smbd_lock_socket(sconn
);
2477 ret
= send_keepalive(sconn
->sock
);
2478 smbd_unlock_socket(sconn
);
2481 char addr
[INET6_ADDRSTRLEN
];
2483 * Try and give an error message saying what
2486 DEBUG(0, ("send_keepalive failed for client %s. "
2487 "Error %s - exiting\n",
2488 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
2496 * Do the recurring check if we're idle
2498 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2500 struct smbd_server_connection
*sconn
=
2501 (struct smbd_server_connection
*)private_data
;
2503 if ((conn_num_open(sconn
) == 0)
2504 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2505 DEBUG( 2, ( "Closing idle connection\n" ) );
2506 messaging_send(sconn
->msg_ctx
,
2507 messaging_server_id(sconn
->msg_ctx
),
2508 MSG_SHUTDOWN
, &data_blob_null
);
2516 * Do the recurring log file and smb.conf reload checks.
2519 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2521 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2522 private_data
, struct smbd_server_connection
);
2524 DEBUG(5, ("housekeeping\n"));
2526 change_to_root_user();
2528 /* update printer queue caches if necessary */
2529 update_monitored_printq_cache(sconn
->msg_ctx
);
2531 /* check if we need to reload services */
2532 check_reload(sconn
, time_mono(NULL
));
2534 /* Change machine password if neccessary. */
2535 attempt_machine_password_change();
2538 * Force a log file check.
2540 force_check_log_size();
2546 * Read an smb packet in the echo handler child, giving the parent
2547 * smbd one second to react once the socket becomes readable.
2550 struct smbd_echo_read_state
{
2551 struct tevent_context
*ev
;
2552 struct smbd_server_connection
*sconn
;
2559 static void smbd_echo_read_readable(struct tevent_req
*subreq
);
2560 static void smbd_echo_read_waited(struct tevent_req
*subreq
);
2562 static struct tevent_req
*smbd_echo_read_send(
2563 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2564 struct smbd_server_connection
*sconn
)
2566 struct tevent_req
*req
, *subreq
;
2567 struct smbd_echo_read_state
*state
;
2569 req
= tevent_req_create(mem_ctx
, &state
,
2570 struct smbd_echo_read_state
);
2575 state
->sconn
= sconn
;
2577 subreq
= wait_for_read_send(state
, ev
, sconn
->sock
);
2578 if (tevent_req_nomem(subreq
, req
)) {
2579 return tevent_req_post(req
, ev
);
2581 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2585 static void smbd_echo_read_readable(struct tevent_req
*subreq
)
2587 struct tevent_req
*req
= tevent_req_callback_data(
2588 subreq
, struct tevent_req
);
2589 struct smbd_echo_read_state
*state
= tevent_req_data(
2590 req
, struct smbd_echo_read_state
);
2594 ok
= wait_for_read_recv(subreq
, &err
);
2595 TALLOC_FREE(subreq
);
2597 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
2602 * Give the parent smbd one second to step in
2605 subreq
= tevent_wakeup_send(
2606 state
, state
->ev
, timeval_current_ofs(1, 0));
2607 if (tevent_req_nomem(subreq
, req
)) {
2610 tevent_req_set_callback(subreq
, smbd_echo_read_waited
, req
);
2613 static void smbd_echo_read_waited(struct tevent_req
*subreq
)
2615 struct tevent_req
*req
= tevent_req_callback_data(
2616 subreq
, struct tevent_req
);
2617 struct smbd_echo_read_state
*state
= tevent_req_data(
2618 req
, struct smbd_echo_read_state
);
2619 struct smbd_server_connection
*sconn
= state
->sconn
;
2625 ok
= tevent_wakeup_recv(subreq
);
2626 TALLOC_FREE(subreq
);
2628 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2632 ok
= smbd_lock_socket_internal(sconn
);
2634 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2635 DEBUG(0, ("%s: failed to lock socket\n", __location__
));
2639 if (!fd_is_readable(sconn
->sock
)) {
2640 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2643 ok
= smbd_unlock_socket_internal(sconn
);
2645 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2646 DEBUG(1, ("%s: failed to unlock socket\n",
2651 subreq
= wait_for_read_send(state
, state
->ev
, sconn
->sock
);
2652 if (tevent_req_nomem(subreq
, req
)) {
2655 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2659 status
= receive_smb_talloc(state
, sconn
, sconn
->sock
, &state
->buf
,
2665 false /* trusted_channel*/);
2667 if (tevent_req_nterror(req
, status
)) {
2668 tevent_req_nterror(req
, status
);
2669 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2670 (int)getpid(), nt_errstr(status
)));
2674 ok
= smbd_unlock_socket_internal(sconn
);
2676 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2677 DEBUG(1, ("%s: failed to unlock socket\n", __location__
));
2680 tevent_req_done(req
);
2683 static NTSTATUS
smbd_echo_read_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2684 char **pbuf
, size_t *pbuflen
, uint32_t *pseqnum
)
2686 struct smbd_echo_read_state
*state
= tevent_req_data(
2687 req
, struct smbd_echo_read_state
);
2690 if (tevent_req_is_nterror(req
, &status
)) {
2693 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
2694 *pbuflen
= state
->buflen
;
2695 *pseqnum
= state
->seqnum
;
2696 return NT_STATUS_OK
;
2699 struct smbd_echo_state
{
2700 struct tevent_context
*ev
;
2701 struct iovec
*pending
;
2702 struct smbd_server_connection
*sconn
;
2705 struct tevent_fd
*parent_fde
;
2707 struct tevent_req
*write_req
;
2710 static void smbd_echo_writer_done(struct tevent_req
*req
);
2712 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2716 if (state
->write_req
!= NULL
) {
2720 num_pending
= talloc_array_length(state
->pending
);
2721 if (num_pending
== 0) {
2725 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
2726 state
->parent_pipe
, false,
2727 state
->pending
, num_pending
);
2728 if (state
->write_req
== NULL
) {
2729 DEBUG(1, ("writev_send failed\n"));
2733 talloc_steal(state
->write_req
, state
->pending
);
2734 state
->pending
= NULL
;
2736 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
2740 static void smbd_echo_writer_done(struct tevent_req
*req
)
2742 struct smbd_echo_state
*state
= tevent_req_callback_data(
2743 req
, struct smbd_echo_state
);
2747 written
= writev_recv(req
, &err
);
2749 state
->write_req
= NULL
;
2750 if (written
== -1) {
2751 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
2754 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2755 smbd_echo_activate_writer(state
);
2758 static bool smbd_echo_reply(struct smbd_echo_state
*state
,
2759 uint8_t *inbuf
, size_t inbuf_len
,
2762 struct smb_request req
;
2763 uint16_t num_replies
;
2767 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == NBSSkeepalive
)) {
2768 DEBUG(10, ("Got netbios keepalive\n"));
2775 if (inbuf_len
< smb_size
) {
2776 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
2779 if (!valid_smb_header(state
->sconn
, inbuf
)) {
2780 DEBUG(10, ("Got invalid SMB header\n"));
2784 if (!init_smb_request(&req
, state
->sconn
, inbuf
, 0, false,
2790 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
2791 smb_messages
[req
.cmd
].name
2792 ? smb_messages
[req
.cmd
].name
: "unknown"));
2794 if (req
.cmd
!= SMBecho
) {
2801 num_replies
= SVAL(req
.vwv
+0, 0);
2802 if (num_replies
!= 1) {
2803 /* Not a Windows "Hey, you're still there?" request */
2807 if (!create_outbuf(talloc_tos(), &req
, (const char *)req
.inbuf
, &outbuf
,
2809 DEBUG(10, ("create_outbuf failed\n"));
2812 req
.outbuf
= (uint8_t *)outbuf
;
2814 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
2816 if (req
.buflen
> 0) {
2817 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
2820 ok
= srv_send_smb(req
.sconn
,
2824 TALLOC_FREE(outbuf
);
2832 static void smbd_echo_exit(struct tevent_context
*ev
,
2833 struct tevent_fd
*fde
, uint16_t flags
,
2836 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2840 static void smbd_echo_got_packet(struct tevent_req
*req
);
2842 static void smbd_echo_loop(struct smbd_server_connection
*sconn
,
2845 struct smbd_echo_state
*state
;
2846 struct tevent_req
*read_req
;
2848 state
= talloc_zero(sconn
, struct smbd_echo_state
);
2849 if (state
== NULL
) {
2850 DEBUG(1, ("talloc failed\n"));
2853 state
->sconn
= sconn
;
2854 state
->parent_pipe
= parent_pipe
;
2855 state
->ev
= s3_tevent_context_init(state
);
2856 if (state
->ev
== NULL
) {
2857 DEBUG(1, ("tevent_context_init failed\n"));
2861 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
2862 TEVENT_FD_READ
, smbd_echo_exit
,
2864 if (state
->parent_fde
== NULL
) {
2865 DEBUG(1, ("tevent_add_fd failed\n"));
2870 read_req
= smbd_echo_read_send(state
, state
->ev
, sconn
);
2871 if (read_req
== NULL
) {
2872 DEBUG(1, ("smbd_echo_read_send failed\n"));
2876 tevent_req_set_callback(read_req
, smbd_echo_got_packet
, state
);
2879 if (tevent_loop_once(state
->ev
) == -1) {
2880 DEBUG(1, ("tevent_loop_once failed: %s\n",
2888 static void smbd_echo_got_packet(struct tevent_req
*req
)
2890 struct smbd_echo_state
*state
= tevent_req_callback_data(
2891 req
, struct smbd_echo_state
);
2895 uint32_t seqnum
= 0;
2898 status
= smbd_echo_read_recv(req
, state
, &buf
, &buflen
, &seqnum
);
2900 if (!NT_STATUS_IS_OK(status
)) {
2901 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2902 nt_errstr(status
)));
2906 reply
= smbd_echo_reply(state
, (uint8_t *)buf
, buflen
, seqnum
);
2912 num_pending
= talloc_array_length(state
->pending
);
2913 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
2916 DEBUG(1, ("talloc_realloc failed\n"));
2919 state
->pending
= tmp
;
2921 if (buflen
>= smb_size
) {
2923 * place the seqnum in the packet so that the main process
2924 * can reply with signing
2926 SIVAL(buf
, smb_ss_field
, seqnum
);
2927 SIVAL(buf
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
2930 iov
= &state
->pending
[num_pending
];
2931 iov
->iov_base
= buf
;
2932 iov
->iov_len
= buflen
;
2934 DEBUG(10,("echo_handler[%d]: forward to main\n",
2936 smbd_echo_activate_writer(state
);
2939 req
= smbd_echo_read_send(state
, state
->ev
, state
->sconn
);
2941 DEBUG(1, ("smbd_echo_read_send failed\n"));
2944 tevent_req_set_callback(req
, smbd_echo_got_packet
, state
);
2949 * Handle SMBecho requests in a forked child process
2951 bool fork_echo_handler(struct smbd_server_connection
*sconn
)
2953 int listener_pipe
[2];
2957 res
= pipe(listener_pipe
);
2959 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
2962 sconn
->smb1
.echo_handler
.socket_lock_fd
= create_unlink_tmp(lp_lockdir());
2963 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
2964 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno
)));
2972 close(listener_pipe
[0]);
2973 set_blocking(listener_pipe
[1], false);
2975 status
= reinit_after_fork(sconn
->msg_ctx
,
2978 if (!NT_STATUS_IS_OK(status
)) {
2979 DEBUG(1, ("reinit_after_fork failed: %s\n",
2980 nt_errstr(status
)));
2983 smbd_echo_loop(sconn
, listener_pipe
[1]);
2986 close(listener_pipe
[1]);
2987 listener_pipe
[1] = -1;
2988 sconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
2990 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), child
));
2993 * Without smb signing this is the same as the normal smbd
2994 * listener. This needs to change once signing comes in.
2996 sconn
->smb1
.echo_handler
.trusted_fde
= tevent_add_fd(sconn
->ev_ctx
,
2998 sconn
->smb1
.echo_handler
.trusted_fd
,
3000 smbd_server_echo_handler
,
3002 if (sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
3003 DEBUG(1, ("event_add_fd failed\n"));
3010 if (listener_pipe
[0] != -1) {
3011 close(listener_pipe
[0]);
3013 if (listener_pipe
[1] != -1) {
3014 close(listener_pipe
[1]);
3016 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
3017 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
3018 close(sconn
->smb1
.echo_handler
.socket_lock_fd
);
3020 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
3021 sconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
3027 static NTSTATUS
smbd_register_ips(struct smbd_server_connection
*sconn
,
3028 struct sockaddr_storage
*srv
,
3029 struct sockaddr_storage
*clnt
)
3031 struct ctdbd_connection
*cconn
;
3032 char tmp_addr
[INET6_ADDRSTRLEN
];
3035 cconn
= messaging_ctdbd_connection();
3036 if (cconn
== NULL
) {
3037 return NT_STATUS_NO_MEMORY
;
3040 if (client_socket_addr(sconn
->sock
, tmp_addr
, sizeof(tmp_addr
)) == NULL
) {
3041 return NT_STATUS_NO_MEMORY
;
3043 addr
= talloc_strdup(cconn
, tmp_addr
);
3045 return NT_STATUS_NO_MEMORY
;
3047 return ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, addr
);
3052 static bool uid_in_use(const struct user_struct
*user
, uid_t uid
)
3055 if (user
->session_info
&&
3056 (user
->session_info
->unix_token
->uid
== uid
)) {
3064 static bool gid_in_use(const struct user_struct
*user
, gid_t gid
)
3067 if (user
->session_info
!= NULL
) {
3069 struct security_unix_token
*utok
;
3071 utok
= user
->session_info
->unix_token
;
3072 if (utok
->gid
== gid
) {
3075 for(i
=0; i
<utok
->ngroups
; i
++) {
3076 if (utok
->groups
[i
] == gid
) {
3086 static bool sid_in_use(const struct user_struct
*user
,
3087 const struct dom_sid
*psid
)
3090 struct security_token
*tok
;
3092 if (user
->session_info
== NULL
) {
3095 tok
= user
->session_info
->security_token
;
3098 * Not sure session_info->security_token can
3099 * ever be NULL. This check might be not
3104 if (security_token_has_sid(tok
, psid
)) {
3112 static bool id_in_use(const struct user_struct
*user
,
3113 const struct id_cache_ref
*id
)
3117 return uid_in_use(user
, id
->id
.uid
);
3119 return gid_in_use(user
, id
->id
.gid
);
3121 return sid_in_use(user
, &id
->id
.sid
);
3128 static void smbd_id_cache_kill(struct messaging_context
*msg_ctx
,
3131 struct server_id server_id
,
3134 const char *msg
= (data
&& data
->data
)
3135 ? (const char *)data
->data
: "<NULL>";
3136 struct id_cache_ref id
;
3137 struct smbd_server_connection
*sconn
=
3138 talloc_get_type_abort(private_data
,
3139 struct smbd_server_connection
);
3141 if (!id_cache_ref_parse(msg
, &id
)) {
3142 DEBUG(0, ("Invalid ?ID: %s\n", msg
));
3146 if (id_in_use(sconn
->users
, &id
)) {
3147 exit_server_cleanly(msg
);
3149 id_cache_delete_from_cache(&id
);
3152 /****************************************************************************
3153 Process commands from the client
3154 ****************************************************************************/
3156 void smbd_process(struct tevent_context
*ev_ctx
,
3157 struct smbd_server_connection
*sconn
)
3159 TALLOC_CTX
*frame
= talloc_stackframe();
3160 struct sockaddr_storage ss
;
3161 struct sockaddr
*sa
= NULL
;
3162 socklen_t sa_socklen
;
3163 struct tsocket_address
*local_address
= NULL
;
3164 struct tsocket_address
*remote_address
= NULL
;
3165 const char *locaddr
= NULL
;
3166 const char *remaddr
= NULL
;
3170 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02
) {
3172 * We're not making the decision here,
3173 * we're just allowing the client
3174 * to decide between SMB1 and SMB2
3175 * with the first negprot
3178 sconn
->using_smb2
= true;
3181 /* Ensure child is set to blocking mode */
3182 set_blocking(sconn
->sock
,True
);
3184 set_socket_options(sconn
->sock
, "SO_KEEPALIVE");
3185 set_socket_options(sconn
->sock
, lp_socket_options());
3187 sa
= (struct sockaddr
*)(void *)&ss
;
3188 sa_socklen
= sizeof(ss
);
3189 ret
= getpeername(sconn
->sock
, sa
, &sa_socklen
);
3191 int level
= (errno
== ENOTCONN
)?2:0;
3192 DEBUG(level
,("getpeername() failed - %s\n", strerror(errno
)));
3193 exit_server_cleanly("getpeername() failed.\n");
3195 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3199 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3200 __location__
, strerror(errno
)));
3201 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3204 sa
= (struct sockaddr
*)(void *)&ss
;
3205 sa_socklen
= sizeof(ss
);
3206 ret
= getsockname(sconn
->sock
, sa
, &sa_socklen
);
3208 int level
= (errno
== ENOTCONN
)?2:0;
3209 DEBUG(level
,("getsockname() failed - %s\n", strerror(errno
)));
3210 exit_server_cleanly("getsockname() failed.\n");
3212 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3216 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3217 __location__
, strerror(errno
)));
3218 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3221 sconn
->local_address
= local_address
;
3222 sconn
->remote_address
= remote_address
;
3224 if (tsocket_address_is_inet(local_address
, "ip")) {
3225 locaddr
= tsocket_address_inet_addr_string(
3226 sconn
->local_address
,
3228 if (locaddr
== NULL
) {
3229 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3230 __location__
, strerror(errno
)));
3231 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3234 locaddr
= "0.0.0.0";
3237 if (tsocket_address_is_inet(remote_address
, "ip")) {
3238 remaddr
= tsocket_address_inet_addr_string(
3239 sconn
->remote_address
,
3241 if (remaddr
== NULL
) {
3242 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3243 __location__
, strerror(errno
)));
3244 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3247 remaddr
= "0.0.0.0";
3250 /* this is needed so that we get decent entries
3251 in smbstatus for port 445 connects */
3252 set_remote_machine_name(remaddr
, false);
3253 reload_services(sconn
, conn_snum_used
, true);
3256 * Before the first packet, check the global hosts allow/ hosts deny
3257 * parameters before doing any parsing of packets passed to us by the
3258 * client. This prevents attacks on our parsing code from hosts not in
3259 * the hosts allow list.
3262 ret
= get_remote_hostname(remote_address
,
3266 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3267 __location__
, strerror(errno
)));
3268 exit_server_cleanly("get_remote_hostname failed.\n");
3270 if (strequal(rhost
, "UNKNOWN")) {
3271 rhost
= talloc_strdup(talloc_tos(), remaddr
);
3273 sconn
->remote_hostname
= talloc_move(sconn
, &rhost
);
3275 sub_set_socket_ids(remaddr
,
3276 sconn
->remote_hostname
,
3279 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3280 sconn
->remote_hostname
,
3283 * send a negative session response "not listening on calling
3286 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3287 DEBUG( 1, ("Connection denied from %s to %s\n",
3288 tsocket_address_string(remote_address
, talloc_tos()),
3289 tsocket_address_string(local_address
, talloc_tos())));
3290 (void)srv_send_smb(sconn
,(char *)buf
, false,
3292 exit_server_cleanly("connection denied");
3295 DEBUG(10, ("Connection allowed from %s to %s\n",
3296 tsocket_address_string(remote_address
, talloc_tos()),
3297 tsocket_address_string(local_address
, talloc_tos())));
3301 smb_perfcount_init();
3303 if (!init_account_policy()) {
3304 exit_server("Could not open account policy tdb.\n");
3307 if (*lp_rootdir()) {
3308 if (chroot(lp_rootdir()) != 0) {
3309 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3310 exit_server("Failed to chroot()");
3312 if (chdir("/") == -1) {
3313 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3314 exit_server("Failed to chroot()");
3316 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3319 if (!srv_init_signing(sconn
)) {
3320 exit_server("Failed to init smb_signing");
3324 if (!init_oplocks(sconn
))
3325 exit_server("Failed to init oplocks");
3327 /* register our message handlers */
3328 messaging_register(sconn
->msg_ctx
, sconn
,
3329 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3330 messaging_register(sconn
->msg_ctx
, sconn
,
3331 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3332 messaging_register(sconn
->msg_ctx
, sconn
,
3333 MSG_SMB_FILE_RENAME
, msg_file_was_renamed
);
3335 id_cache_register_msgs(sconn
->msg_ctx
);
3336 messaging_deregister(sconn
->msg_ctx
, ID_CACHE_KILL
, NULL
);
3337 messaging_register(sconn
->msg_ctx
, sconn
,
3338 ID_CACHE_KILL
, smbd_id_cache_kill
);
3340 messaging_deregister(sconn
->msg_ctx
,
3341 MSG_SMB_CONF_UPDATED
, sconn
->ev_ctx
);
3342 messaging_register(sconn
->msg_ctx
, sconn
,
3343 MSG_SMB_CONF_UPDATED
, smbd_conf_updated
);
3346 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3347 * MSGs to all child processes
3349 messaging_deregister(sconn
->msg_ctx
,
3351 messaging_register(sconn
->msg_ctx
, NULL
,
3352 MSG_DEBUG
, debug_message
);
3354 if ((lp_keepalive() != 0)
3355 && !(event_add_idle(ev_ctx
, NULL
,
3356 timeval_set(lp_keepalive(), 0),
3357 "keepalive", keepalive_fn
,
3359 DEBUG(0, ("Could not add keepalive event\n"));
3363 if (!(event_add_idle(ev_ctx
, NULL
,
3364 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3365 "deadtime", deadtime_fn
, sconn
))) {
3366 DEBUG(0, ("Could not add deadtime event\n"));
3370 if (!(event_add_idle(ev_ctx
, NULL
,
3371 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
3372 "housekeeping", housekeeping_fn
, sconn
))) {
3373 DEBUG(0, ("Could not add housekeeping event\n"));
3377 #ifdef CLUSTER_SUPPORT
3379 if (lp_clustering()) {
3381 * We need to tell ctdb about our client's TCP
3382 * connection, so that for failover ctdbd can send
3383 * tickle acks, triggering a reconnection by the
3387 struct sockaddr_storage srv
, clnt
;
3389 if (client_get_tcp_info(sconn
->sock
, &srv
, &clnt
) == 0) {
3391 status
= smbd_register_ips(sconn
, &srv
, &clnt
);
3392 if (!NT_STATUS_IS_OK(status
)) {
3393 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3394 nt_errstr(status
)));
3398 DEBUG(0,("Unable to get tcp info for "
3399 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3406 sconn
->nbt
.got_session
= false;
3408 sconn
->smb1
.negprot
.max_recv
= MIN(lp_maxxmit(),BUFFER_SIZE
);
3410 sconn
->smb1
.sessions
.done_sesssetup
= false;
3411 sconn
->smb1
.sessions
.max_send
= BUFFER_SIZE
;
3412 sconn
->smb1
.sessions
.last_session_tag
= UID_FIELD_INVALID
;
3413 /* this holds info on user ids that are already validated for this VC */
3414 sconn
->smb1
.sessions
.next_vuid
= VUID_OFFSET
;
3417 if (!init_dptrs(sconn
)) {
3418 exit_server("init_dptrs() failed");
3421 sconn
->smb1
.fde
= event_add_fd(ev_ctx
,
3425 smbd_server_connection_handler
,
3427 if (!sconn
->smb1
.fde
) {
3428 exit_server("failed to create smbd_server_connection fde");
3434 frame
= talloc_stackframe_pool(8192);
3437 if (tevent_loop_once(ev_ctx
) == -1) {
3438 if (errno
!= EINTR
) {
3439 DEBUG(3, ("tevent_loop_once failed: %s,"
3440 " exiting\n", strerror(errno
) ));
3448 exit_server_cleanly(NULL
);
3451 bool req_is_in_chain(struct smb_request
*req
)
3453 if (req
->vwv
!= (const uint16_t *)(req
->inbuf
+smb_vwv
)) {
3455 * We're right now handling a subsequent request, so we must
3461 if (!is_andx_req(req
->cmd
)) {
3467 * Okay, an illegal request, but definitely not chained :-)
3472 return (CVAL(req
->vwv
+0, 0) != 0xFF);