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)sys_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)sys_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)sys_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)sys_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
;
541 req
->chain_outbuf
= NULL
;
544 req
->priv_paths
= NULL
;
545 smb_init_perfcount_data(&req
->pcd
);
547 /* Ensure we have at least wct words and 2 bytes of bcc. */
548 if (smb_size
+ req
->wct
*2 > req_size
) {
549 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
550 (unsigned int)req
->wct
,
551 (unsigned int)req_size
));
554 /* Ensure bcc is correct. */
555 if (((const uint8_t *)smb_buf_const(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
556 DEBUG(0,("init_smb_request: invalid bcc number %u "
557 "(wct = %u, size %u)\n",
558 (unsigned int)req
->buflen
,
559 (unsigned int)req
->wct
,
560 (unsigned int)req_size
));
568 static void process_smb(struct smbd_server_connection
*conn
,
569 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
570 uint32_t seqnum
, bool encrypted
,
571 struct smb_perfcount_data
*deferred_pcd
);
573 static void smbd_deferred_open_timer(struct event_context
*ev
,
574 struct timed_event
*te
,
575 struct timeval _tval
,
578 struct pending_message_list
*msg
= talloc_get_type(private_data
,
579 struct pending_message_list
);
580 struct smbd_server_connection
*sconn
= msg
->sconn
;
581 TALLOC_CTX
*mem_ctx
= talloc_tos();
582 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
585 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
588 exit_server("smbd_deferred_open_timer: talloc failed\n");
592 /* We leave this message on the queue so the open code can
593 know this is a retry. */
594 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
595 (unsigned long long)mid
));
597 /* Mark the message as processed so this is not
598 * re-processed in error. */
599 msg
->processed
= true;
601 process_smb(sconn
, inbuf
,
603 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
605 /* If it's still there and was processed, remove it. */
606 msg
= get_deferred_open_message_smb(sconn
, mid
);
607 if (msg
&& msg
->processed
) {
608 remove_deferred_open_message_smb(sconn
, mid
);
612 /****************************************************************************
613 Function to push a message onto the tail of a linked list of smb messages ready
615 ****************************************************************************/
617 static bool push_queued_message(struct smb_request
*req
,
618 struct timeval request_time
,
619 struct timeval end_time
,
620 char *private_data
, size_t private_len
)
622 int msg_len
= smb_len(req
->inbuf
) + 4;
623 struct pending_message_list
*msg
;
625 msg
= talloc_zero(NULL
, struct pending_message_list
);
628 DEBUG(0,("push_message: malloc fail (1)\n"));
631 msg
->sconn
= req
->sconn
;
633 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
634 if(msg
->buf
.data
== NULL
) {
635 DEBUG(0,("push_message: malloc fail (2)\n"));
640 msg
->request_time
= request_time
;
641 msg
->seqnum
= req
->seqnum
;
642 msg
->encrypted
= req
->encrypted
;
643 msg
->processed
= false;
644 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
647 msg
->private_data
= data_blob_talloc(msg
, private_data
,
649 if (msg
->private_data
.data
== NULL
) {
650 DEBUG(0,("push_message: malloc fail (3)\n"));
656 msg
->te
= tevent_add_timer(msg
->sconn
->ev_ctx
,
659 smbd_deferred_open_timer
,
662 DEBUG(0,("push_message: event_add_timed failed\n"));
667 DLIST_ADD_END(req
->sconn
->deferred_open_queue
, msg
,
668 struct pending_message_list
*);
670 DEBUG(10,("push_message: pushed message length %u on "
671 "deferred_open_queue\n", (unsigned int)msg_len
));
676 /****************************************************************************
677 Function to delete a sharing violation open message by mid.
678 ****************************************************************************/
680 void remove_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
683 struct pending_message_list
*pml
;
685 if (sconn
->using_smb2
) {
686 remove_deferred_open_message_smb2(sconn
, mid
);
690 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
691 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
692 DEBUG(10,("remove_deferred_open_message_smb: "
693 "deleting mid %llu len %u\n",
694 (unsigned long long)mid
,
695 (unsigned int)pml
->buf
.length
));
696 DLIST_REMOVE(sconn
->deferred_open_queue
, pml
);
703 /****************************************************************************
704 Move a sharing violation open retry message to the front of the list and
705 schedule it for immediate processing.
706 ****************************************************************************/
708 void schedule_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
711 struct pending_message_list
*pml
;
714 if (sconn
->using_smb2
) {
715 schedule_deferred_open_message_smb2(sconn
, mid
);
719 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
720 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
722 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
725 (unsigned long long)msg_mid
));
727 if (mid
== msg_mid
) {
728 struct timed_event
*te
;
730 if (pml
->processed
) {
731 /* A processed message should not be
733 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
734 "message mid %llu was already processed\n",
735 (unsigned long long)msg_mid
));
739 DEBUG(10,("schedule_deferred_open_message_smb: "
740 "scheduling mid %llu\n",
741 (unsigned long long)mid
));
743 te
= tevent_add_timer(pml
->sconn
->ev_ctx
,
746 smbd_deferred_open_timer
,
749 DEBUG(10,("schedule_deferred_open_message_smb: "
750 "event_add_timed() failed, "
751 "skipping mid %llu\n",
752 (unsigned long long)msg_mid
));
755 TALLOC_FREE(pml
->te
);
757 DLIST_PROMOTE(sconn
->deferred_open_queue
, pml
);
762 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
763 "find message mid %llu\n",
764 (unsigned long long)mid
));
767 /****************************************************************************
768 Return true if this mid is on the deferred queue and was not yet processed.
769 ****************************************************************************/
771 bool open_was_deferred(struct smbd_server_connection
*sconn
, uint64_t mid
)
773 struct pending_message_list
*pml
;
775 if (sconn
->using_smb2
) {
776 return open_was_deferred_smb2(sconn
, mid
);
779 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
780 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
787 /****************************************************************************
788 Return the message queued by this mid.
789 ****************************************************************************/
791 static struct pending_message_list
*get_deferred_open_message_smb(
792 struct smbd_server_connection
*sconn
, uint64_t mid
)
794 struct pending_message_list
*pml
;
796 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
797 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
804 /****************************************************************************
805 Get the state data queued by this mid.
806 ****************************************************************************/
808 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
809 struct timeval
*p_request_time
,
812 struct pending_message_list
*pml
;
814 if (smbreq
->sconn
->using_smb2
) {
815 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
820 pml
= get_deferred_open_message_smb(smbreq
->sconn
, smbreq
->mid
);
824 if (p_request_time
) {
825 *p_request_time
= pml
->request_time
;
828 *pp_state
= (void *)pml
->private_data
.data
;
833 /****************************************************************************
834 Function to push a deferred open smb message onto a linked list of local smb
835 messages ready for processing.
836 ****************************************************************************/
838 bool push_deferred_open_message_smb(struct smb_request
*req
,
839 struct timeval request_time
,
840 struct timeval timeout
,
842 char *private_data
, size_t priv_len
)
844 struct timeval end_time
;
847 return push_deferred_open_message_smb2(req
->smb2req
,
855 if (req
->unread_bytes
) {
856 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
857 "unread_bytes = %u\n",
858 (unsigned int)req
->unread_bytes
));
859 smb_panic("push_deferred_open_message_smb: "
860 "logic error unread_bytes != 0" );
863 end_time
= timeval_sum(&request_time
, &timeout
);
865 DEBUG(10,("push_deferred_open_message_smb: pushing message "
866 "len %u mid %llu timeout time [%u.%06u]\n",
867 (unsigned int) smb_len(req
->inbuf
)+4,
868 (unsigned long long)req
->mid
,
869 (unsigned int)end_time
.tv_sec
,
870 (unsigned int)end_time
.tv_usec
));
872 return push_queued_message(req
, request_time
, end_time
,
873 private_data
, priv_len
);
876 static void smbd_sig_term_handler(struct tevent_context
*ev
,
877 struct tevent_signal
*se
,
883 exit_server_cleanly("termination signal");
886 void smbd_setup_sig_term_handler(struct smbd_server_connection
*sconn
)
888 struct tevent_signal
*se
;
890 se
= tevent_add_signal(sconn
->ev_ctx
,
893 smbd_sig_term_handler
,
896 exit_server("failed to setup SIGTERM handler");
900 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
901 struct tevent_signal
*se
,
907 struct smbd_server_connection
*sconn
=
908 talloc_get_type_abort(private_data
,
909 struct smbd_server_connection
);
911 change_to_root_user();
912 DEBUG(1,("Reloading services after SIGHUP\n"));
913 reload_services(sconn
, conn_snum_used
, false);
916 void smbd_setup_sig_hup_handler(struct smbd_server_connection
*sconn
)
918 struct tevent_signal
*se
;
920 se
= tevent_add_signal(sconn
->ev_ctx
,
923 smbd_sig_hup_handler
,
926 exit_server("failed to setup SIGHUP handler");
930 static void smbd_conf_updated(struct messaging_context
*msg
,
933 struct server_id server_id
,
936 struct smbd_server_connection
*sconn
=
937 talloc_get_type_abort(private_data
,
938 struct smbd_server_connection
);
940 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
941 "updated. Reloading.\n"));
942 change_to_root_user();
943 reload_services(sconn
, conn_snum_used
, false);
947 * Only allow 5 outstanding trans requests. We're allocating memory, so
951 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
954 for (; list
!= NULL
; list
= list
->next
) {
956 if (list
->mid
== mid
) {
957 return NT_STATUS_INVALID_PARAMETER
;
963 return NT_STATUS_INSUFFICIENT_RESOURCES
;
970 These flags determine some of the permissions required to do an operation
972 Note that I don't set NEED_WRITE on some write operations because they
973 are used by some brain-dead clients when printing, and I don't want to
974 force write permissions on print services.
976 #define AS_USER (1<<0)
977 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
978 #define TIME_INIT (1<<2)
979 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
980 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
981 #define DO_CHDIR (1<<6)
984 define a list of possible SMB messages and their corresponding
985 functions. Any message that has a NULL function is unimplemented -
986 please feel free to contribute implementations!
988 static const struct smb_message_struct
{
990 void (*fn
)(struct smb_request
*req
);
992 } smb_messages
[256] = {
994 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
995 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
996 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
997 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
998 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
999 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1000 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1001 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1002 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1003 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1004 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1005 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1006 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1007 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1008 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1009 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1010 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1011 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1012 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1013 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1014 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1015 /* 0x15 */ { NULL
, NULL
, 0 },
1016 /* 0x16 */ { NULL
, NULL
, 0 },
1017 /* 0x17 */ { NULL
, NULL
, 0 },
1018 /* 0x18 */ { NULL
, NULL
, 0 },
1019 /* 0x19 */ { NULL
, NULL
, 0 },
1020 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1021 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1022 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1023 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1024 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1025 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1026 /* 0x20 */ { "SMBwritec", NULL
,0},
1027 /* 0x21 */ { NULL
, NULL
, 0 },
1028 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1029 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1030 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1031 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1032 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1033 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1034 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1035 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1036 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1037 /* 0x2b */ { "SMBecho",reply_echo
,0},
1038 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1039 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1040 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1041 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1042 /* 0x30 */ { NULL
, NULL
, 0 },
1043 /* 0x31 */ { NULL
, NULL
, 0 },
1044 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1045 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1046 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1047 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1048 /* 0x36 */ { NULL
, NULL
, 0 },
1049 /* 0x37 */ { NULL
, NULL
, 0 },
1050 /* 0x38 */ { NULL
, NULL
, 0 },
1051 /* 0x39 */ { NULL
, NULL
, 0 },
1052 /* 0x3a */ { NULL
, NULL
, 0 },
1053 /* 0x3b */ { NULL
, NULL
, 0 },
1054 /* 0x3c */ { NULL
, NULL
, 0 },
1055 /* 0x3d */ { NULL
, NULL
, 0 },
1056 /* 0x3e */ { NULL
, NULL
, 0 },
1057 /* 0x3f */ { NULL
, NULL
, 0 },
1058 /* 0x40 */ { NULL
, NULL
, 0 },
1059 /* 0x41 */ { NULL
, NULL
, 0 },
1060 /* 0x42 */ { NULL
, NULL
, 0 },
1061 /* 0x43 */ { NULL
, NULL
, 0 },
1062 /* 0x44 */ { NULL
, NULL
, 0 },
1063 /* 0x45 */ { NULL
, NULL
, 0 },
1064 /* 0x46 */ { NULL
, NULL
, 0 },
1065 /* 0x47 */ { NULL
, NULL
, 0 },
1066 /* 0x48 */ { NULL
, NULL
, 0 },
1067 /* 0x49 */ { NULL
, NULL
, 0 },
1068 /* 0x4a */ { NULL
, NULL
, 0 },
1069 /* 0x4b */ { NULL
, NULL
, 0 },
1070 /* 0x4c */ { NULL
, NULL
, 0 },
1071 /* 0x4d */ { NULL
, NULL
, 0 },
1072 /* 0x4e */ { NULL
, NULL
, 0 },
1073 /* 0x4f */ { NULL
, NULL
, 0 },
1074 /* 0x50 */ { NULL
, NULL
, 0 },
1075 /* 0x51 */ { NULL
, NULL
, 0 },
1076 /* 0x52 */ { NULL
, NULL
, 0 },
1077 /* 0x53 */ { NULL
, NULL
, 0 },
1078 /* 0x54 */ { NULL
, NULL
, 0 },
1079 /* 0x55 */ { NULL
, NULL
, 0 },
1080 /* 0x56 */ { NULL
, NULL
, 0 },
1081 /* 0x57 */ { NULL
, NULL
, 0 },
1082 /* 0x58 */ { NULL
, NULL
, 0 },
1083 /* 0x59 */ { NULL
, NULL
, 0 },
1084 /* 0x5a */ { NULL
, NULL
, 0 },
1085 /* 0x5b */ { NULL
, NULL
, 0 },
1086 /* 0x5c */ { NULL
, NULL
, 0 },
1087 /* 0x5d */ { NULL
, NULL
, 0 },
1088 /* 0x5e */ { NULL
, NULL
, 0 },
1089 /* 0x5f */ { NULL
, NULL
, 0 },
1090 /* 0x60 */ { NULL
, NULL
, 0 },
1091 /* 0x61 */ { NULL
, NULL
, 0 },
1092 /* 0x62 */ { NULL
, NULL
, 0 },
1093 /* 0x63 */ { NULL
, NULL
, 0 },
1094 /* 0x64 */ { NULL
, NULL
, 0 },
1095 /* 0x65 */ { NULL
, NULL
, 0 },
1096 /* 0x66 */ { NULL
, NULL
, 0 },
1097 /* 0x67 */ { NULL
, NULL
, 0 },
1098 /* 0x68 */ { NULL
, NULL
, 0 },
1099 /* 0x69 */ { NULL
, NULL
, 0 },
1100 /* 0x6a */ { NULL
, NULL
, 0 },
1101 /* 0x6b */ { NULL
, NULL
, 0 },
1102 /* 0x6c */ { NULL
, NULL
, 0 },
1103 /* 0x6d */ { NULL
, NULL
, 0 },
1104 /* 0x6e */ { NULL
, NULL
, 0 },
1105 /* 0x6f */ { NULL
, NULL
, 0 },
1106 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1107 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1108 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1109 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1110 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1111 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1112 /* 0x76 */ { NULL
, NULL
, 0 },
1113 /* 0x77 */ { NULL
, NULL
, 0 },
1114 /* 0x78 */ { NULL
, NULL
, 0 },
1115 /* 0x79 */ { NULL
, NULL
, 0 },
1116 /* 0x7a */ { NULL
, NULL
, 0 },
1117 /* 0x7b */ { NULL
, NULL
, 0 },
1118 /* 0x7c */ { NULL
, NULL
, 0 },
1119 /* 0x7d */ { NULL
, NULL
, 0 },
1120 /* 0x7e */ { NULL
, NULL
, 0 },
1121 /* 0x7f */ { NULL
, NULL
, 0 },
1122 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1123 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1124 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1125 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1126 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1127 /* 0x85 */ { NULL
, NULL
, 0 },
1128 /* 0x86 */ { NULL
, NULL
, 0 },
1129 /* 0x87 */ { NULL
, NULL
, 0 },
1130 /* 0x88 */ { NULL
, NULL
, 0 },
1131 /* 0x89 */ { NULL
, NULL
, 0 },
1132 /* 0x8a */ { NULL
, NULL
, 0 },
1133 /* 0x8b */ { NULL
, NULL
, 0 },
1134 /* 0x8c */ { NULL
, NULL
, 0 },
1135 /* 0x8d */ { NULL
, NULL
, 0 },
1136 /* 0x8e */ { NULL
, NULL
, 0 },
1137 /* 0x8f */ { NULL
, NULL
, 0 },
1138 /* 0x90 */ { NULL
, NULL
, 0 },
1139 /* 0x91 */ { NULL
, NULL
, 0 },
1140 /* 0x92 */ { NULL
, NULL
, 0 },
1141 /* 0x93 */ { NULL
, NULL
, 0 },
1142 /* 0x94 */ { NULL
, NULL
, 0 },
1143 /* 0x95 */ { NULL
, NULL
, 0 },
1144 /* 0x96 */ { NULL
, NULL
, 0 },
1145 /* 0x97 */ { NULL
, NULL
, 0 },
1146 /* 0x98 */ { NULL
, NULL
, 0 },
1147 /* 0x99 */ { NULL
, NULL
, 0 },
1148 /* 0x9a */ { NULL
, NULL
, 0 },
1149 /* 0x9b */ { NULL
, NULL
, 0 },
1150 /* 0x9c */ { NULL
, NULL
, 0 },
1151 /* 0x9d */ { NULL
, NULL
, 0 },
1152 /* 0x9e */ { NULL
, NULL
, 0 },
1153 /* 0x9f */ { NULL
, NULL
, 0 },
1154 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1155 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1156 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1157 /* 0xa3 */ { NULL
, NULL
, 0 },
1158 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1159 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1160 /* 0xa6 */ { NULL
, NULL
, 0 },
1161 /* 0xa7 */ { NULL
, NULL
, 0 },
1162 /* 0xa8 */ { NULL
, NULL
, 0 },
1163 /* 0xa9 */ { NULL
, NULL
, 0 },
1164 /* 0xaa */ { NULL
, NULL
, 0 },
1165 /* 0xab */ { NULL
, NULL
, 0 },
1166 /* 0xac */ { NULL
, NULL
, 0 },
1167 /* 0xad */ { NULL
, NULL
, 0 },
1168 /* 0xae */ { NULL
, NULL
, 0 },
1169 /* 0xaf */ { NULL
, NULL
, 0 },
1170 /* 0xb0 */ { NULL
, NULL
, 0 },
1171 /* 0xb1 */ { NULL
, NULL
, 0 },
1172 /* 0xb2 */ { NULL
, NULL
, 0 },
1173 /* 0xb3 */ { NULL
, NULL
, 0 },
1174 /* 0xb4 */ { NULL
, NULL
, 0 },
1175 /* 0xb5 */ { NULL
, NULL
, 0 },
1176 /* 0xb6 */ { NULL
, NULL
, 0 },
1177 /* 0xb7 */ { NULL
, NULL
, 0 },
1178 /* 0xb8 */ { NULL
, NULL
, 0 },
1179 /* 0xb9 */ { NULL
, NULL
, 0 },
1180 /* 0xba */ { NULL
, NULL
, 0 },
1181 /* 0xbb */ { NULL
, NULL
, 0 },
1182 /* 0xbc */ { NULL
, NULL
, 0 },
1183 /* 0xbd */ { NULL
, NULL
, 0 },
1184 /* 0xbe */ { NULL
, NULL
, 0 },
1185 /* 0xbf */ { NULL
, NULL
, 0 },
1186 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1187 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1188 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1189 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1190 /* 0xc4 */ { NULL
, NULL
, 0 },
1191 /* 0xc5 */ { NULL
, NULL
, 0 },
1192 /* 0xc6 */ { NULL
, NULL
, 0 },
1193 /* 0xc7 */ { NULL
, NULL
, 0 },
1194 /* 0xc8 */ { NULL
, NULL
, 0 },
1195 /* 0xc9 */ { NULL
, NULL
, 0 },
1196 /* 0xca */ { NULL
, NULL
, 0 },
1197 /* 0xcb */ { NULL
, NULL
, 0 },
1198 /* 0xcc */ { NULL
, NULL
, 0 },
1199 /* 0xcd */ { NULL
, NULL
, 0 },
1200 /* 0xce */ { NULL
, NULL
, 0 },
1201 /* 0xcf */ { NULL
, NULL
, 0 },
1202 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1203 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1204 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1205 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1206 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1207 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1208 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1209 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1210 /* 0xd8 */ { NULL
, NULL
, 0 },
1211 /* 0xd9 */ { NULL
, NULL
, 0 },
1212 /* 0xda */ { NULL
, NULL
, 0 },
1213 /* 0xdb */ { NULL
, NULL
, 0 },
1214 /* 0xdc */ { NULL
, NULL
, 0 },
1215 /* 0xdd */ { NULL
, NULL
, 0 },
1216 /* 0xde */ { NULL
, NULL
, 0 },
1217 /* 0xdf */ { NULL
, NULL
, 0 },
1218 /* 0xe0 */ { NULL
, NULL
, 0 },
1219 /* 0xe1 */ { NULL
, NULL
, 0 },
1220 /* 0xe2 */ { NULL
, NULL
, 0 },
1221 /* 0xe3 */ { NULL
, NULL
, 0 },
1222 /* 0xe4 */ { NULL
, NULL
, 0 },
1223 /* 0xe5 */ { NULL
, NULL
, 0 },
1224 /* 0xe6 */ { NULL
, NULL
, 0 },
1225 /* 0xe7 */ { NULL
, NULL
, 0 },
1226 /* 0xe8 */ { NULL
, NULL
, 0 },
1227 /* 0xe9 */ { NULL
, NULL
, 0 },
1228 /* 0xea */ { NULL
, NULL
, 0 },
1229 /* 0xeb */ { NULL
, NULL
, 0 },
1230 /* 0xec */ { NULL
, NULL
, 0 },
1231 /* 0xed */ { NULL
, NULL
, 0 },
1232 /* 0xee */ { NULL
, NULL
, 0 },
1233 /* 0xef */ { NULL
, NULL
, 0 },
1234 /* 0xf0 */ { NULL
, NULL
, 0 },
1235 /* 0xf1 */ { NULL
, NULL
, 0 },
1236 /* 0xf2 */ { NULL
, NULL
, 0 },
1237 /* 0xf3 */ { NULL
, NULL
, 0 },
1238 /* 0xf4 */ { NULL
, NULL
, 0 },
1239 /* 0xf5 */ { NULL
, NULL
, 0 },
1240 /* 0xf6 */ { NULL
, NULL
, 0 },
1241 /* 0xf7 */ { NULL
, NULL
, 0 },
1242 /* 0xf8 */ { NULL
, NULL
, 0 },
1243 /* 0xf9 */ { NULL
, NULL
, 0 },
1244 /* 0xfa */ { NULL
, NULL
, 0 },
1245 /* 0xfb */ { NULL
, NULL
, 0 },
1246 /* 0xfc */ { NULL
, NULL
, 0 },
1247 /* 0xfd */ { NULL
, NULL
, 0 },
1248 /* 0xfe */ { NULL
, NULL
, 0 },
1249 /* 0xff */ { NULL
, NULL
, 0 }
1253 /*******************************************************************
1254 allocate and initialize a reply packet
1255 ********************************************************************/
1257 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1258 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1262 * Protect against integer wrap
1264 if ((num_bytes
> 0xffffff)
1265 || ((num_bytes
+ smb_size
+ num_words
*2) > 0xffffff)) {
1267 if (asprintf(&msg
, "num_bytes too large: %u",
1268 (unsigned)num_bytes
) == -1) {
1269 msg
= discard_const_p(char, "num_bytes too large");
1274 *outbuf
= talloc_array(mem_ctx
, char,
1275 smb_size
+ num_words
*2 + num_bytes
);
1276 if (*outbuf
== NULL
) {
1280 construct_reply_common(req
, inbuf
, *outbuf
);
1281 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1283 * Zero out the word area, the caller has to take care of the bcc area
1286 if (num_words
!= 0) {
1287 memset(*outbuf
+ smb_vwv0
, 0, num_words
*2);
1293 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1296 if (!create_outbuf(req
, req
, (const char *)req
->inbuf
, &outbuf
, num_words
,
1298 smb_panic("could not allocate output buffer\n");
1300 req
->outbuf
= (uint8_t *)outbuf
;
1304 /*******************************************************************
1305 Dump a packet to a file.
1306 ********************************************************************/
1308 static void smb_dump(const char *name
, int type
, const char *data
)
1313 if (DEBUGLEVEL
< 50) {
1317 len
= smb_len_tcp(data
)+4;
1318 for (i
=1;i
<100;i
++) {
1319 if (asprintf(&fname
, "/tmp/%s.%d.%s", name
, i
,
1320 type
? "req" : "resp") == -1) {
1323 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1324 if (fd
!= -1 || errno
!= EEXIST
) break;
1327 ssize_t ret
= write(fd
, data
, len
);
1329 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1331 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1336 /****************************************************************************
1337 Prepare everything for calling the actual request function, and potentially
1338 call the request function via the "new" interface.
1340 Return False if the "legacy" function needs to be called, everything is
1343 Return True if we're done.
1345 I know this API sucks, but it is the one with the least code change I could
1347 ****************************************************************************/
1349 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
)
1353 connection_struct
*conn
= NULL
;
1354 struct smbd_server_connection
*sconn
= req
->sconn
;
1358 if (smb_messages
[type
].fn
== NULL
) {
1359 DEBUG(0,("Unknown message type %d!\n",type
));
1360 smb_dump("Unknown", 1, (const char *)req
->inbuf
);
1361 reply_unknown_new(req
, type
);
1365 flags
= smb_messages
[type
].flags
;
1367 /* In share mode security we must ignore the vuid. */
1368 session_tag
= req
->vuid
;
1371 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1372 (int)sys_getpid(), (unsigned long)conn
));
1374 smb_dump(smb_fn_name(type
), 1, (const char *)req
->inbuf
);
1376 /* Ensure this value is replaced in the incoming packet. */
1377 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_uid
,session_tag
);
1380 * Ensure the correct username is in current_user_info. This is a
1381 * really ugly bugfix for problems with multiple session_setup_and_X's
1382 * being done and allowing %U and %G substitutions to work correctly.
1383 * There is a reason this code is done here, don't move it unless you
1384 * know what you're doing... :-).
1388 if (session_tag
!= sconn
->smb1
.sessions
.last_session_tag
) {
1389 user_struct
*vuser
= NULL
;
1391 sconn
->smb1
.sessions
.last_session_tag
= session_tag
;
1392 if(session_tag
!= UID_FIELD_INVALID
) {
1393 vuser
= get_valid_user_struct(sconn
, session_tag
);
1395 set_current_user_info(
1396 vuser
->session_info
->unix_info
->sanitized_username
,
1397 vuser
->session_info
->unix_info
->unix_name
,
1398 vuser
->session_info
->info
->domain_name
);
1403 /* Does this call need to be run as the connected user? */
1404 if (flags
& AS_USER
) {
1406 /* Does this call need a valid tree connection? */
1409 * Amazingly, the error code depends on the command
1412 if (type
== SMBntcreateX
) {
1413 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1415 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1420 if (!change_to_user(conn
,session_tag
)) {
1421 DEBUG(0, ("Error: Could not change to user. Removing "
1422 "deferred open, mid=%llu.\n",
1423 (unsigned long long)req
->mid
));
1424 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1428 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1430 /* Does it need write permission? */
1431 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1432 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1436 /* IPC services are limited */
1437 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1438 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1442 /* This call needs to be run as root */
1443 change_to_root_user();
1446 /* load service specific parameters */
1448 if (req
->encrypted
) {
1449 conn
->encrypted_tid
= true;
1450 /* encrypted required from now on. */
1451 conn
->encrypt_level
= Required
;
1452 } else if (ENCRYPTION_REQUIRED(conn
)) {
1453 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1454 exit_server_cleanly("encryption required "
1460 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1461 (flags
& (AS_USER
|DO_CHDIR
)
1463 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1466 conn
->num_smb_operations
++;
1470 * Does this protocol need to be run as guest? (Only archane
1471 * messenger service requests have this...)
1473 if (flags
& AS_GUEST
) {
1477 if (!change_to_guest()) {
1478 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1482 raddr
= tsocket_address_inet_addr_string(sconn
->remote_address
,
1484 if (raddr
== NULL
) {
1485 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1490 * Haven't we checked this in smbd_process already???
1493 ok
= allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1494 sconn
->remote_hostname
, raddr
);
1498 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1503 smb_messages
[type
].fn(req
);
1507 /****************************************************************************
1508 Construct a reply to the incoming packet.
1509 ****************************************************************************/
1511 static void construct_reply(struct smbd_server_connection
*sconn
,
1512 char *inbuf
, int size
, size_t unread_bytes
,
1513 uint32_t seqnum
, bool encrypted
,
1514 struct smb_perfcount_data
*deferred_pcd
)
1516 connection_struct
*conn
;
1517 struct smb_request
*req
;
1519 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1520 smb_panic("could not allocate smb_request");
1523 if (!init_smb_request(req
, sconn
, (uint8
*)inbuf
, unread_bytes
,
1524 encrypted
, seqnum
)) {
1525 exit_server_cleanly("Invalid SMB request");
1528 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1530 /* we popped this message off the queue - keep original perf data */
1532 req
->pcd
= *deferred_pcd
;
1534 SMB_PERFCOUNT_START(&req
->pcd
);
1535 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1536 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1539 conn
= switch_message(req
->cmd
, req
);
1546 if (req
->outbuf
== NULL
) {
1550 if (CVAL(req
->outbuf
,0) == 0) {
1551 show_msg((char *)req
->outbuf
);
1554 if (!srv_send_smb(req
->sconn
,
1555 (char *)req
->outbuf
,
1556 true, req
->seqnum
+1,
1557 IS_CONN_ENCRYPTED(conn
)||req
->encrypted
,
1559 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1567 static void construct_reply_chain(struct smbd_server_connection
*sconn
,
1568 char *inbuf
, int size
, uint32_t seqnum
,
1570 struct smb_perfcount_data
*deferred_pcd
)
1572 struct connection_struct
*conn
= NULL
;
1573 struct smb_request
**reqs
= NULL
;
1574 struct smb_request
*req
, *first_req
, *last_req
;
1575 unsigned i
, num_reqs
;
1579 ok
= smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf
, sconn
, encrypted
,
1580 seqnum
, &reqs
, &num_reqs
);
1582 status
= NT_STATUS_INVALID_PARAMETER
;
1586 for (i
=0; i
<num_reqs
; i
++) {
1591 * Get the session and tree ids and chain fsp
1592 * from the previous request into the current
1595 struct smb_request
*prev_req
= reqs
[i
-1];
1596 const uint8_t *prev_outbuf
= prev_req
->outbuf
;
1598 req
->vuid
= SVAL(prev_outbuf
, smb_uid
);
1599 req
->tid
= SVAL(prev_outbuf
, smb_tid
);
1600 req
->conn
= conn_find(req
->sconn
, req
->tid
);
1601 req
->chain_fsp
= prev_req
->chain_fsp
;
1603 req
->inbuf
= (uint8_t *)inbuf
;
1604 conn
= switch_message(req
->cmd
, req
);
1606 if (req
->outbuf
== NULL
) {
1607 if (open_was_deferred(req
->sconn
, req
->mid
)) {
1611 status
= NT_STATUS_INTERNAL_ERROR
;
1614 if (IVAL(req
->outbuf
, smb_rcls
) != 0) {
1619 first_req
= reqs
[0];
1624 * The first request already gave an error, no need to
1630 for (i
=1; i
<next_index
; i
++) {
1633 ok
= smb_splice_chain(&first_req
->outbuf
, req
->outbuf
);
1635 status
= NT_STATUS_INTERNAL_ERROR
;
1638 if (req
== last_req
) {
1643 SSVAL(first_req
->outbuf
, smb_uid
, SVAL(last_req
->outbuf
, smb_uid
));
1644 SSVAL(first_req
->outbuf
, smb_tid
, SVAL(last_req
->outbuf
, smb_tid
));
1647 * This scary statement intends to set the
1648 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1649 * to the value last_req->outbuf carries
1651 SSVAL(first_req
->outbuf
, smb_flg2
,
1652 (SVAL(first_req
->outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
1653 |(SVAL(last_req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
1656 * Transfer the error codes from the subrequest to the main one
1658 SSVAL(first_req
->outbuf
, smb_rcls
, SVAL(last_req
->outbuf
, smb_rcls
));
1659 SSVAL(first_req
->outbuf
, smb_err
, SVAL(last_req
->outbuf
, smb_err
));
1664 _smb_setlen_large(first_req
->outbuf
,
1665 talloc_get_size(first_req
->outbuf
) - 4);
1667 if (!srv_send_smb(first_req
->sconn
,
1668 (char *)first_req
->outbuf
,
1669 true, first_req
->seqnum
+1,
1670 IS_CONN_ENCRYPTED(conn
)||first_req
->encrypted
,
1672 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1680 char errbuf
[smb_size
];
1681 error_packet(errbuf
, 0, 0, status
, __LINE__
, __FILE__
);
1682 if (!srv_send_smb(sconn
, errbuf
, true, seqnum
, encrypted
,
1684 exit_server_cleanly("construct_reply_chain: "
1685 "srv_send_smb failed.");
1691 /****************************************************************************
1692 Process an smb from the client
1693 ****************************************************************************/
1694 static void process_smb(struct smbd_server_connection
*sconn
,
1695 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1696 uint32_t seqnum
, bool encrypted
,
1697 struct smb_perfcount_data
*deferred_pcd
)
1699 int msg_type
= CVAL(inbuf
,0);
1701 DO_PROFILE_INC(smb_count
);
1703 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1705 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1706 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1708 if (msg_type
!= NBSSmessage
) {
1710 * NetBIOS session request, keepalive, etc.
1712 reply_special(sconn
, (char *)inbuf
, nread
);
1716 if (sconn
->using_smb2
) {
1717 /* At this point we're not really using smb2,
1718 * we make the decision here.. */
1719 if (smbd_is_smb2_header(inbuf
, nread
)) {
1720 smbd_smb2_first_negprot(sconn
, inbuf
, nread
);
1722 } else if (nread
>= smb_size
&& valid_smb_header(sconn
, inbuf
)
1723 && CVAL(inbuf
, smb_com
) != 0x72) {
1724 /* This is a non-negprot SMB1 packet.
1725 Disable SMB2 from now on. */
1726 sconn
->using_smb2
= false;
1730 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1731 * so subtract 4 from it. */
1732 if ((nread
< (smb_size
- 4)) || !valid_smb_header(sconn
, inbuf
)) {
1733 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1736 /* special magic for immediate exit */
1738 (IVAL(inbuf
, 4) == 0x74697865) &&
1739 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1740 uint8_t exitcode
= CVAL(inbuf
, 8);
1741 DEBUG(1, ("Exiting immediately with code %d\n",
1746 exit_server_cleanly("Non-SMB packet");
1749 show_msg((char *)inbuf
);
1751 if ((unread_bytes
== 0) && smb1_is_chain(inbuf
)) {
1752 construct_reply_chain(sconn
, (char *)inbuf
, nread
,
1753 seqnum
, encrypted
, deferred_pcd
);
1755 construct_reply(sconn
, (char *)inbuf
, nread
, unread_bytes
,
1756 seqnum
, encrypted
, deferred_pcd
);
1762 sconn
->num_requests
++;
1764 /* The timeout_processing function isn't run nearly
1765 often enough to implement 'max log size' without
1766 overrunning the size of the file by many megabytes.
1767 This is especially true if we are running at debug
1768 level 10. Checking every 50 SMBs is a nice
1769 tradeoff of performance vs log file size overrun. */
1771 if ((sconn
->num_requests
% 50) == 0 &&
1772 need_to_check_log_size()) {
1773 change_to_root_user();
1778 /****************************************************************************
1779 Return a string containing the function name of a SMB command.
1780 ****************************************************************************/
1782 const char *smb_fn_name(int type
)
1784 const char *unknown_name
= "SMBunknown";
1786 if (smb_messages
[type
].name
== NULL
)
1787 return(unknown_name
);
1789 return(smb_messages
[type
].name
);
1792 /****************************************************************************
1793 Helper functions for contruct_reply.
1794 ****************************************************************************/
1796 void add_to_common_flags2(uint32 v
)
1801 void remove_from_common_flags2(uint32 v
)
1803 common_flags2
&= ~v
;
1806 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1809 uint16_t in_flags2
= SVAL(inbuf
,smb_flg2
);
1810 uint16_t out_flags2
= common_flags2
;
1812 out_flags2
|= in_flags2
& FLAGS2_UNICODE_STRINGS
;
1813 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
;
1814 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
;
1816 srv_set_message(outbuf
,0,0,false);
1818 SCVAL(outbuf
, smb_com
, req
->cmd
);
1819 SIVAL(outbuf
,smb_rcls
,0);
1820 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1821 SSVAL(outbuf
,smb_flg2
, out_flags2
);
1822 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1823 memcpy(outbuf
+smb_ss_field
, inbuf
+smb_ss_field
, 8);
1825 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
1826 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
1827 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
1828 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
1831 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
1833 construct_reply_common(req
, (const char *)req
->inbuf
, outbuf
);
1837 * How many bytes have we already accumulated up to the current wct field
1841 size_t req_wct_ofs(struct smb_request
*req
)
1845 if (req
->chain_outbuf
== NULL
) {
1848 buf_size
= talloc_get_size(req
->chain_outbuf
);
1849 if ((buf_size
% 4) != 0) {
1850 buf_size
+= (4 - (buf_size
% 4));
1852 return buf_size
- 4;
1856 * @brief Find the smb_cmd offset of the last command pushed
1857 * @param[in] buf The buffer we're building up
1858 * @retval Where can we put our next andx cmd?
1860 * While chaining requests, the "next" request we're looking at needs to put
1861 * its SMB_Command before the data the previous request already built up added
1862 * to the chain. Find the offset to the place where we have to put our cmd.
1865 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
1870 cmd
= CVAL(buf
, smb_com
);
1872 if (!is_andx_req(cmd
)) {
1878 while (CVAL(buf
, ofs
) != 0xff) {
1880 if (!is_andx_req(CVAL(buf
, ofs
))) {
1885 * ofs is from start of smb header, so add the 4 length
1886 * bytes. The next cmd is right after the wct field.
1888 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
1890 if (ofs
+4 >= talloc_get_size(buf
)) {
1900 * @brief Do the smb chaining at a buffer level
1901 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1902 * @param[in] andx_buf Buffer to be appended
1905 static bool smb_splice_chain(uint8_t **poutbuf
, const uint8_t *andx_buf
)
1907 uint8_t smb_command
= CVAL(andx_buf
, smb_com
);
1908 uint8_t wct
= CVAL(andx_buf
, smb_wct
);
1909 const uint16_t *vwv
= (const uint16_t *)(andx_buf
+ smb_vwv
);
1910 uint32_t num_bytes
= smb_buflen(andx_buf
);
1911 const uint8_t *bytes
= (const uint8_t *)smb_buf_const(andx_buf
);
1914 size_t old_size
, new_size
;
1916 size_t chain_padding
= 0;
1917 size_t andx_cmd_ofs
;
1920 old_size
= talloc_get_size(*poutbuf
);
1922 if ((old_size
% 4) != 0) {
1924 * Align the wct field of subsequent requests to a 4-byte
1927 chain_padding
= 4 - (old_size
% 4);
1931 * After the old request comes the new wct field (1 byte), the vwv's
1932 * and the num_bytes field.
1935 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
1936 new_size
+= num_bytes
;
1938 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
1939 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
1940 (unsigned)new_size
));
1944 outbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, new_size
);
1945 if (outbuf
== NULL
) {
1946 DEBUG(0, ("talloc failed\n"));
1951 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
1952 DEBUG(1, ("invalid command chain\n"));
1953 *poutbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, old_size
);
1957 if (chain_padding
!= 0) {
1958 memset(outbuf
+ old_size
, 0, chain_padding
);
1959 old_size
+= chain_padding
;
1962 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
1963 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
1968 * Push the chained request:
1973 SCVAL(outbuf
, ofs
, wct
);
1980 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
1985 * Read&X has an offset into its data buffer at
1986 * vwv[6]. reply_read_andx has no idea anymore that it's
1987 * running from within a chain, so we have to fix up the
1990 * Although it looks disgusting at this place, I want to keep
1991 * it here. The alternative would be to push knowledge about
1992 * the andx chain down into read&x again.
1995 if (smb_command
== SMBreadX
) {
1996 uint8_t *bytes_addr
;
2000 * Invalid read&x response
2005 bytes_addr
= outbuf
+ ofs
/* vwv start */
2006 + sizeof(uint16_t) * wct
/* vwv array */
2007 + sizeof(uint16_t); /* bcc */
2009 SSVAL(outbuf
+ ofs
, 6 * sizeof(uint16_t),
2010 bytes_addr
- outbuf
- 4);
2013 ofs
+= sizeof(uint16_t) * wct
;
2019 SSVAL(outbuf
, ofs
, num_bytes
);
2020 ofs
+= sizeof(uint16_t);
2026 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
2031 bool smb1_is_chain(const uint8_t *buf
)
2033 uint8_t cmd
, wct
, andx_cmd
;
2035 cmd
= CVAL(buf
, smb_com
);
2036 if (!is_andx_req(cmd
)) {
2039 wct
= CVAL(buf
, smb_wct
);
2043 andx_cmd
= CVAL(buf
, smb_vwv
);
2044 return (andx_cmd
!= 0xFF);
2047 bool smb1_walk_chain(const uint8_t *buf
,
2048 bool (*fn
)(uint8_t cmd
,
2049 uint8_t wct
, const uint16_t *vwv
,
2050 uint16_t num_bytes
, const uint8_t *bytes
,
2051 void *private_data
),
2054 size_t smblen
= smb_len(buf
);
2055 const char *smb_buf
= smb_base(buf
);
2056 uint8_t cmd
, chain_cmd
;
2058 const uint16_t *vwv
;
2060 const uint8_t *bytes
;
2062 cmd
= CVAL(buf
, smb_com
);
2063 wct
= CVAL(buf
, smb_wct
);
2064 vwv
= (const uint16_t *)(buf
+ smb_vwv
);
2065 num_bytes
= smb_buflen(buf
);
2066 bytes
= (uint8_t *)smb_buf_const(buf
);
2068 if (!fn(cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2072 if (!is_andx_req(cmd
)) {
2079 chain_cmd
= CVAL(vwv
, 0);
2081 while (chain_cmd
!= 0xff) {
2082 uint32_t chain_offset
; /* uint32_t to avoid overflow */
2083 size_t length_needed
;
2084 ptrdiff_t vwv_offset
;
2086 chain_offset
= SVAL(vwv
+1, 0);
2089 * Check if the client tries to fool us. The chain
2090 * offset needs to point beyond the current request in
2091 * the chain, it needs to strictly grow. Otherwise we
2092 * might be tricked into an endless loop always
2093 * processing the same request over and over again. We
2094 * used to assume that vwv and the byte buffer array
2095 * in a chain are always attached, but OS/2 the
2096 * Write&X/Read&X chain puts the Read&X vwv array
2097 * right behind the Write&X vwv chain. The Write&X bcc
2098 * array is put behind the Read&X vwv array. So now we
2099 * check whether the chain offset points strictly
2100 * behind the previous vwv array. req->buf points
2101 * right after the vwv array of the previous
2103 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2107 vwv_offset
= ((const char *)vwv
- smb_buf
);
2108 if (chain_offset
<= vwv_offset
) {
2113 * Next check: Make sure the chain offset does not
2114 * point beyond the overall smb request length.
2117 length_needed
= chain_offset
+1; /* wct */
2118 if (length_needed
> smblen
) {
2123 * Now comes the pointer magic. Goal here is to set up
2124 * vwv and buf correctly again. The chain offset (the
2125 * former vwv[1]) points at the new wct field.
2128 wct
= CVAL(smb_buf
, chain_offset
);
2130 if (is_andx_req(chain_cmd
) && (wct
< 2)) {
2135 * Next consistency check: Make the new vwv array fits
2136 * in the overall smb request.
2139 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2140 if (length_needed
> smblen
) {
2143 vwv
= (const uint16_t *)(smb_buf
+ chain_offset
+ 1);
2146 * Now grab the new byte buffer....
2149 num_bytes
= SVAL(vwv
+wct
, 0);
2152 * .. and check that it fits.
2155 length_needed
+= num_bytes
;
2156 if (length_needed
> smblen
) {
2159 bytes
= (const uint8_t *)(vwv
+wct
+1);
2161 if (!fn(chain_cmd
, wct
, vwv
, num_bytes
, bytes
, private_data
)) {
2165 if (!is_andx_req(chain_cmd
)) {
2168 chain_cmd
= CVAL(vwv
, 0);
2173 static bool smb1_chain_length_cb(uint8_t cmd
,
2174 uint8_t wct
, const uint16_t *vwv
,
2175 uint16_t num_bytes
, const uint8_t *bytes
,
2178 unsigned *count
= (unsigned *)private_data
;
2183 unsigned smb1_chain_length(const uint8_t *buf
)
2187 if (!smb1_walk_chain(buf
, smb1_chain_length_cb
, &count
)) {
2193 struct smb1_parse_chain_state
{
2194 TALLOC_CTX
*mem_ctx
;
2196 struct smbd_server_connection
*sconn
;
2200 struct smb_request
**reqs
;
2204 static bool smb1_parse_chain_cb(uint8_t cmd
,
2205 uint8_t wct
, const uint16_t *vwv
,
2206 uint16_t num_bytes
, const uint8_t *bytes
,
2209 struct smb1_parse_chain_state
*state
=
2210 (struct smb1_parse_chain_state
*)private_data
;
2211 struct smb_request
**reqs
;
2212 struct smb_request
*req
;
2215 reqs
= talloc_realloc(state
->mem_ctx
, state
->reqs
,
2216 struct smb_request
*, state
->num_reqs
+1);
2222 req
= talloc(reqs
, struct smb_request
);
2227 ok
= init_smb_request(req
, state
->sconn
, state
->buf
, 0,
2228 state
->encrypted
, state
->seqnum
);
2235 req
->buflen
= num_bytes
;
2238 reqs
[state
->num_reqs
] = req
;
2239 state
->num_reqs
+= 1;
2243 bool smb1_parse_chain(TALLOC_CTX
*mem_ctx
, const uint8_t *buf
,
2244 struct smbd_server_connection
*sconn
,
2245 bool encrypted
, uint32_t seqnum
,
2246 struct smb_request
***reqs
, unsigned *num_reqs
)
2248 struct smb1_parse_chain_state state
;
2250 state
.mem_ctx
= mem_ctx
;
2252 state
.sconn
= sconn
;
2253 state
.encrypted
= encrypted
;
2254 state
.seqnum
= seqnum
;
2258 if (!smb1_walk_chain(buf
, smb1_parse_chain_cb
, &state
)) {
2259 TALLOC_FREE(state
.reqs
);
2263 *num_reqs
= state
.num_reqs
;
2267 /****************************************************************************
2268 Check if services need reloading.
2269 ****************************************************************************/
2271 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2274 if (last_smb_conf_reload_time
== 0) {
2275 last_smb_conf_reload_time
= t
;
2278 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2279 reload_services(sconn
, conn_snum_used
, true);
2280 last_smb_conf_reload_time
= t
;
2284 static bool fd_is_readable(int fd
)
2288 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2290 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2294 static void smbd_server_connection_write_handler(
2295 struct smbd_server_connection
*sconn
)
2297 /* TODO: make write nonblocking */
2300 static void smbd_server_connection_read_handler(
2301 struct smbd_server_connection
*sconn
, int fd
)
2303 uint8_t *inbuf
= NULL
;
2304 size_t inbuf_len
= 0;
2305 size_t unread_bytes
= 0;
2306 bool encrypted
= false;
2307 TALLOC_CTX
*mem_ctx
= talloc_tos();
2313 if (lp_async_smb_echo_handler()
2314 && fd_is_readable(sconn
->smb1
.echo_handler
.trusted_fd
)) {
2316 * This is the super-ugly hack to prefer the packets
2317 * forwarded by the echo handler over the ones by the
2320 fd
= sconn
->smb1
.echo_handler
.trusted_fd
;
2323 from_client
= (sconn
->sock
== fd
);
2326 smbd_lock_socket(sconn
);
2328 if (!fd_is_readable(fd
)) {
2329 DEBUG(10,("the echo listener was faster\n"));
2330 smbd_unlock_socket(sconn
);
2335 /* TODO: make this completely nonblocking */
2336 status
= receive_smb_talloc(mem_ctx
, sconn
, fd
,
2337 (char **)(void *)&inbuf
,
2341 &inbuf_len
, &seqnum
,
2342 false /* trusted channel */);
2345 smbd_unlock_socket(sconn
);
2348 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2351 if (NT_STATUS_IS_ERR(status
)) {
2352 exit_server_cleanly("failed to receive smb request");
2354 if (!NT_STATUS_IS_OK(status
)) {
2359 process_smb(sconn
, inbuf
, inbuf_len
, unread_bytes
,
2360 seqnum
, encrypted
, NULL
);
2363 static void smbd_server_connection_handler(struct event_context
*ev
,
2364 struct fd_event
*fde
,
2368 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2369 struct smbd_server_connection
);
2371 if (flags
& EVENT_FD_WRITE
) {
2372 smbd_server_connection_write_handler(conn
);
2375 if (flags
& EVENT_FD_READ
) {
2376 smbd_server_connection_read_handler(conn
, conn
->sock
);
2381 static void smbd_server_echo_handler(struct event_context
*ev
,
2382 struct fd_event
*fde
,
2386 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2387 struct smbd_server_connection
);
2389 if (flags
& EVENT_FD_WRITE
) {
2390 smbd_server_connection_write_handler(conn
);
2393 if (flags
& EVENT_FD_READ
) {
2394 smbd_server_connection_read_handler(
2395 conn
, conn
->smb1
.echo_handler
.trusted_fd
);
2400 #ifdef CLUSTER_SUPPORT
2401 /****************************************************************************
2402 received when we should release a specific IP
2403 ****************************************************************************/
2404 static void release_ip(const char *ip
, void *priv
)
2406 const char *addr
= (const char *)priv
;
2407 const char *p
= addr
;
2409 if (strncmp("::ffff:", addr
, 7) == 0) {
2413 DEBUG(10, ("Got release IP message for %s, "
2414 "our address is %s\n", ip
, p
));
2416 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2417 /* we can't afford to do a clean exit - that involves
2418 database writes, which would potentially mean we
2419 are still running after the failover has finished -
2420 we have to get rid of this process ID straight
2422 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2424 /* note we must exit with non-zero status so the unclean handler gets
2425 called in the parent, so that the brl database is tickled */
2430 static int client_get_tcp_info(int sock
, struct sockaddr_storage
*server
,
2431 struct sockaddr_storage
*client
)
2434 length
= sizeof(*server
);
2435 if (getsockname(sock
, (struct sockaddr
*)server
, &length
) != 0) {
2438 length
= sizeof(*client
);
2439 if (getpeername(sock
, (struct sockaddr
*)client
, &length
) != 0) {
2447 * Send keepalive packets to our client
2449 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2451 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2452 private_data
, struct smbd_server_connection
);
2455 if (sconn
->using_smb2
) {
2456 /* Don't do keepalives on an SMB2 connection. */
2460 smbd_lock_socket(sconn
);
2461 ret
= send_keepalive(sconn
->sock
);
2462 smbd_unlock_socket(sconn
);
2465 char addr
[INET6_ADDRSTRLEN
];
2467 * Try and give an error message saying what
2470 DEBUG(0, ("send_keepalive failed for client %s. "
2471 "Error %s - exiting\n",
2472 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
2480 * Do the recurring check if we're idle
2482 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2484 struct smbd_server_connection
*sconn
=
2485 (struct smbd_server_connection
*)private_data
;
2487 if ((conn_num_open(sconn
) == 0)
2488 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2489 DEBUG( 2, ( "Closing idle connection\n" ) );
2490 messaging_send(sconn
->msg_ctx
,
2491 messaging_server_id(sconn
->msg_ctx
),
2492 MSG_SHUTDOWN
, &data_blob_null
);
2500 * Do the recurring log file and smb.conf reload checks.
2503 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2505 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2506 private_data
, struct smbd_server_connection
);
2508 DEBUG(5, ("housekeeping\n"));
2510 change_to_root_user();
2512 /* update printer queue caches if necessary */
2513 update_monitored_printq_cache(sconn
->msg_ctx
);
2515 /* check if we need to reload services */
2516 check_reload(sconn
, time_mono(NULL
));
2518 /* Change machine password if neccessary. */
2519 attempt_machine_password_change();
2522 * Force a log file check.
2524 force_check_log_size();
2530 * Read an smb packet in the echo handler child, giving the parent
2531 * smbd one second to react once the socket becomes readable.
2534 struct smbd_echo_read_state
{
2535 struct tevent_context
*ev
;
2536 struct smbd_server_connection
*sconn
;
2543 static void smbd_echo_read_readable(struct tevent_req
*subreq
);
2544 static void smbd_echo_read_waited(struct tevent_req
*subreq
);
2546 static struct tevent_req
*smbd_echo_read_send(
2547 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2548 struct smbd_server_connection
*sconn
)
2550 struct tevent_req
*req
, *subreq
;
2551 struct smbd_echo_read_state
*state
;
2553 req
= tevent_req_create(mem_ctx
, &state
,
2554 struct smbd_echo_read_state
);
2559 state
->sconn
= sconn
;
2561 subreq
= wait_for_read_send(state
, ev
, sconn
->sock
);
2562 if (tevent_req_nomem(subreq
, req
)) {
2563 return tevent_req_post(req
, ev
);
2565 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2569 static void smbd_echo_read_readable(struct tevent_req
*subreq
)
2571 struct tevent_req
*req
= tevent_req_callback_data(
2572 subreq
, struct tevent_req
);
2573 struct smbd_echo_read_state
*state
= tevent_req_data(
2574 req
, struct smbd_echo_read_state
);
2578 ok
= wait_for_read_recv(subreq
, &err
);
2579 TALLOC_FREE(subreq
);
2581 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
2586 * Give the parent smbd one second to step in
2589 subreq
= tevent_wakeup_send(
2590 state
, state
->ev
, timeval_current_ofs(1, 0));
2591 if (tevent_req_nomem(subreq
, req
)) {
2594 tevent_req_set_callback(subreq
, smbd_echo_read_waited
, req
);
2597 static void smbd_echo_read_waited(struct tevent_req
*subreq
)
2599 struct tevent_req
*req
= tevent_req_callback_data(
2600 subreq
, struct tevent_req
);
2601 struct smbd_echo_read_state
*state
= tevent_req_data(
2602 req
, struct smbd_echo_read_state
);
2603 struct smbd_server_connection
*sconn
= state
->sconn
;
2609 ok
= tevent_wakeup_recv(subreq
);
2610 TALLOC_FREE(subreq
);
2612 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2616 ok
= smbd_lock_socket_internal(sconn
);
2618 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2619 DEBUG(0, ("%s: failed to lock socket\n", __location__
));
2623 if (!fd_is_readable(sconn
->sock
)) {
2624 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2625 (int)sys_getpid()));
2627 ok
= smbd_unlock_socket_internal(sconn
);
2629 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2630 DEBUG(1, ("%s: failed to unlock socket\n",
2635 subreq
= wait_for_read_send(state
, state
->ev
, sconn
->sock
);
2636 if (tevent_req_nomem(subreq
, req
)) {
2639 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2643 status
= receive_smb_talloc(state
, sconn
, sconn
->sock
, &state
->buf
,
2649 false /* trusted_channel*/);
2651 if (tevent_req_nterror(req
, status
)) {
2652 tevent_req_nterror(req
, status
);
2653 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2654 (int)sys_getpid(), nt_errstr(status
)));
2658 ok
= smbd_unlock_socket_internal(sconn
);
2660 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2661 DEBUG(1, ("%s: failed to unlock socket\n", __location__
));
2664 tevent_req_done(req
);
2667 static NTSTATUS
smbd_echo_read_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2668 char **pbuf
, size_t *pbuflen
, uint32_t *pseqnum
)
2670 struct smbd_echo_read_state
*state
= tevent_req_data(
2671 req
, struct smbd_echo_read_state
);
2674 if (tevent_req_is_nterror(req
, &status
)) {
2677 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
2678 *pbuflen
= state
->buflen
;
2679 *pseqnum
= state
->seqnum
;
2680 return NT_STATUS_OK
;
2683 struct smbd_echo_state
{
2684 struct tevent_context
*ev
;
2685 struct iovec
*pending
;
2686 struct smbd_server_connection
*sconn
;
2689 struct tevent_fd
*parent_fde
;
2691 struct tevent_req
*write_req
;
2694 static void smbd_echo_writer_done(struct tevent_req
*req
);
2696 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2700 if (state
->write_req
!= NULL
) {
2704 num_pending
= talloc_array_length(state
->pending
);
2705 if (num_pending
== 0) {
2709 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
2710 state
->parent_pipe
, false,
2711 state
->pending
, num_pending
);
2712 if (state
->write_req
== NULL
) {
2713 DEBUG(1, ("writev_send failed\n"));
2717 talloc_steal(state
->write_req
, state
->pending
);
2718 state
->pending
= NULL
;
2720 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
2724 static void smbd_echo_writer_done(struct tevent_req
*req
)
2726 struct smbd_echo_state
*state
= tevent_req_callback_data(
2727 req
, struct smbd_echo_state
);
2731 written
= writev_recv(req
, &err
);
2733 state
->write_req
= NULL
;
2734 if (written
== -1) {
2735 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
2738 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2739 smbd_echo_activate_writer(state
);
2742 static bool smbd_echo_reply(struct smbd_echo_state
*state
,
2743 uint8_t *inbuf
, size_t inbuf_len
,
2746 struct smb_request req
;
2747 uint16_t num_replies
;
2751 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == NBSSkeepalive
)) {
2752 DEBUG(10, ("Got netbios keepalive\n"));
2759 if (inbuf_len
< smb_size
) {
2760 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
2763 if (!valid_smb_header(state
->sconn
, inbuf
)) {
2764 DEBUG(10, ("Got invalid SMB header\n"));
2768 if (!init_smb_request(&req
, state
->sconn
, inbuf
, 0, false,
2774 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
2775 smb_messages
[req
.cmd
].name
2776 ? smb_messages
[req
.cmd
].name
: "unknown"));
2778 if (req
.cmd
!= SMBecho
) {
2785 num_replies
= SVAL(req
.vwv
+0, 0);
2786 if (num_replies
!= 1) {
2787 /* Not a Windows "Hey, you're still there?" request */
2791 if (!create_outbuf(talloc_tos(), &req
, (const char *)req
.inbuf
, &outbuf
,
2793 DEBUG(10, ("create_outbuf failed\n"));
2796 req
.outbuf
= (uint8_t *)outbuf
;
2798 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
2800 if (req
.buflen
> 0) {
2801 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
2804 ok
= srv_send_smb(req
.sconn
,
2808 TALLOC_FREE(outbuf
);
2816 static void smbd_echo_exit(struct tevent_context
*ev
,
2817 struct tevent_fd
*fde
, uint16_t flags
,
2820 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2824 static void smbd_echo_got_packet(struct tevent_req
*req
);
2826 static void smbd_echo_loop(struct smbd_server_connection
*sconn
,
2829 struct smbd_echo_state
*state
;
2830 struct tevent_req
*read_req
;
2832 state
= talloc_zero(sconn
, struct smbd_echo_state
);
2833 if (state
== NULL
) {
2834 DEBUG(1, ("talloc failed\n"));
2837 state
->sconn
= sconn
;
2838 state
->parent_pipe
= parent_pipe
;
2839 state
->ev
= s3_tevent_context_init(state
);
2840 if (state
->ev
== NULL
) {
2841 DEBUG(1, ("tevent_context_init failed\n"));
2845 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
2846 TEVENT_FD_READ
, smbd_echo_exit
,
2848 if (state
->parent_fde
== NULL
) {
2849 DEBUG(1, ("tevent_add_fd failed\n"));
2854 read_req
= smbd_echo_read_send(state
, state
->ev
, sconn
);
2855 if (read_req
== NULL
) {
2856 DEBUG(1, ("smbd_echo_read_send failed\n"));
2860 tevent_req_set_callback(read_req
, smbd_echo_got_packet
, state
);
2863 if (tevent_loop_once(state
->ev
) == -1) {
2864 DEBUG(1, ("tevent_loop_once failed: %s\n",
2872 static void smbd_echo_got_packet(struct tevent_req
*req
)
2874 struct smbd_echo_state
*state
= tevent_req_callback_data(
2875 req
, struct smbd_echo_state
);
2879 uint32_t seqnum
= 0;
2882 status
= smbd_echo_read_recv(req
, state
, &buf
, &buflen
, &seqnum
);
2884 if (!NT_STATUS_IS_OK(status
)) {
2885 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2886 nt_errstr(status
)));
2890 reply
= smbd_echo_reply(state
, (uint8_t *)buf
, buflen
, seqnum
);
2896 num_pending
= talloc_array_length(state
->pending
);
2897 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
2900 DEBUG(1, ("talloc_realloc failed\n"));
2903 state
->pending
= tmp
;
2905 if (buflen
>= smb_size
) {
2907 * place the seqnum in the packet so that the main process
2908 * can reply with signing
2910 SIVAL(buf
, smb_ss_field
, seqnum
);
2911 SIVAL(buf
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
2914 iov
= &state
->pending
[num_pending
];
2915 iov
->iov_base
= buf
;
2916 iov
->iov_len
= buflen
;
2918 DEBUG(10,("echo_handler[%d]: forward to main\n",
2919 (int)sys_getpid()));
2920 smbd_echo_activate_writer(state
);
2923 req
= smbd_echo_read_send(state
, state
->ev
, state
->sconn
);
2925 DEBUG(1, ("smbd_echo_read_send failed\n"));
2928 tevent_req_set_callback(req
, smbd_echo_got_packet
, state
);
2933 * Handle SMBecho requests in a forked child process
2935 bool fork_echo_handler(struct smbd_server_connection
*sconn
)
2937 int listener_pipe
[2];
2941 res
= pipe(listener_pipe
);
2943 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
2946 sconn
->smb1
.echo_handler
.socket_lock_fd
= create_unlink_tmp(lp_lockdir());
2947 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
2948 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno
)));
2956 close(listener_pipe
[0]);
2957 set_blocking(listener_pipe
[1], false);
2959 status
= reinit_after_fork(sconn
->msg_ctx
,
2962 if (!NT_STATUS_IS_OK(status
)) {
2963 DEBUG(1, ("reinit_after_fork failed: %s\n",
2964 nt_errstr(status
)));
2967 smbd_echo_loop(sconn
, listener_pipe
[1]);
2970 close(listener_pipe
[1]);
2971 listener_pipe
[1] = -1;
2972 sconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
2974 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child
));
2977 * Without smb signing this is the same as the normal smbd
2978 * listener. This needs to change once signing comes in.
2980 sconn
->smb1
.echo_handler
.trusted_fde
= tevent_add_fd(sconn
->ev_ctx
,
2982 sconn
->smb1
.echo_handler
.trusted_fd
,
2984 smbd_server_echo_handler
,
2986 if (sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
2987 DEBUG(1, ("event_add_fd failed\n"));
2994 if (listener_pipe
[0] != -1) {
2995 close(listener_pipe
[0]);
2997 if (listener_pipe
[1] != -1) {
2998 close(listener_pipe
[1]);
3000 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
3001 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
3002 close(sconn
->smb1
.echo_handler
.socket_lock_fd
);
3004 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
3005 sconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
3011 static NTSTATUS
smbd_register_ips(struct smbd_server_connection
*sconn
,
3012 struct sockaddr_storage
*srv
,
3013 struct sockaddr_storage
*clnt
)
3015 struct ctdbd_connection
*cconn
;
3016 char tmp_addr
[INET6_ADDRSTRLEN
];
3019 cconn
= messaging_ctdbd_connection();
3020 if (cconn
== NULL
) {
3021 return NT_STATUS_NO_MEMORY
;
3024 client_socket_addr(sconn
->sock
, tmp_addr
, sizeof(tmp_addr
));
3025 addr
= talloc_strdup(cconn
, tmp_addr
);
3027 return NT_STATUS_NO_MEMORY
;
3029 return ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, addr
);
3034 static bool uid_in_use(const struct user_struct
*user
, uid_t uid
)
3037 if (user
->session_info
&&
3038 (user
->session_info
->unix_token
->uid
== uid
)) {
3046 static bool gid_in_use(const struct user_struct
*user
, gid_t gid
)
3049 if (user
->session_info
!= NULL
) {
3051 struct security_unix_token
*utok
;
3053 utok
= user
->session_info
->unix_token
;
3054 if (utok
->gid
== gid
) {
3057 for(i
=0; i
<utok
->ngroups
; i
++) {
3058 if (utok
->groups
[i
] == gid
) {
3068 static bool sid_in_use(const struct user_struct
*user
,
3069 const struct dom_sid
*psid
)
3072 struct security_token
*tok
;
3074 if (user
->session_info
== NULL
) {
3077 tok
= user
->session_info
->security_token
;
3080 * Not sure session_info->security_token can
3081 * ever be NULL. This check might be not
3086 if (security_token_has_sid(tok
, psid
)) {
3094 static bool id_in_use(const struct user_struct
*user
,
3095 const struct id_cache_ref
*id
)
3099 return uid_in_use(user
, id
->id
.uid
);
3101 return gid_in_use(user
, id
->id
.gid
);
3103 return sid_in_use(user
, &id
->id
.sid
);
3110 static void smbd_id_cache_kill(struct messaging_context
*msg_ctx
,
3113 struct server_id server_id
,
3116 const char *msg
= (data
&& data
->data
)
3117 ? (const char *)data
->data
: "<NULL>";
3118 struct id_cache_ref id
;
3119 struct smbd_server_connection
*sconn
=
3120 talloc_get_type_abort(private_data
,
3121 struct smbd_server_connection
);
3123 if (!id_cache_ref_parse(msg
, &id
)) {
3124 DEBUG(0, ("Invalid ?ID: %s\n", msg
));
3128 if (id_in_use(sconn
->users
, &id
)) {
3129 exit_server_cleanly(msg
);
3131 id_cache_delete_from_cache(&id
);
3134 /****************************************************************************
3135 Process commands from the client
3136 ****************************************************************************/
3138 void smbd_process(struct tevent_context
*ev_ctx
,
3139 struct smbd_server_connection
*sconn
)
3141 TALLOC_CTX
*frame
= talloc_stackframe();
3142 struct sockaddr_storage ss
;
3143 struct sockaddr
*sa
= NULL
;
3144 socklen_t sa_socklen
;
3145 struct tsocket_address
*local_address
= NULL
;
3146 struct tsocket_address
*remote_address
= NULL
;
3147 const char *locaddr
= NULL
;
3148 const char *remaddr
= NULL
;
3152 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02
) {
3154 * We're not making the decision here,
3155 * we're just allowing the client
3156 * to decide between SMB1 and SMB2
3157 * with the first negprot
3160 sconn
->using_smb2
= true;
3163 /* Ensure child is set to blocking mode */
3164 set_blocking(sconn
->sock
,True
);
3166 set_socket_options(sconn
->sock
, "SO_KEEPALIVE");
3167 set_socket_options(sconn
->sock
, lp_socket_options());
3169 sa
= (struct sockaddr
*)(void *)&ss
;
3170 sa_socklen
= sizeof(ss
);
3171 ret
= getpeername(sconn
->sock
, sa
, &sa_socklen
);
3173 int level
= (errno
== ENOTCONN
)?2:0;
3174 DEBUG(level
,("getpeername() failed - %s\n", strerror(errno
)));
3175 exit_server_cleanly("getpeername() failed.\n");
3177 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3181 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3182 __location__
, strerror(errno
)));
3183 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3186 sa
= (struct sockaddr
*)(void *)&ss
;
3187 sa_socklen
= sizeof(ss
);
3188 ret
= getsockname(sconn
->sock
, sa
, &sa_socklen
);
3190 int level
= (errno
== ENOTCONN
)?2:0;
3191 DEBUG(level
,("getsockname() failed - %s\n", strerror(errno
)));
3192 exit_server_cleanly("getsockname() failed.\n");
3194 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3198 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3199 __location__
, strerror(errno
)));
3200 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3203 sconn
->local_address
= local_address
;
3204 sconn
->remote_address
= remote_address
;
3206 if (tsocket_address_is_inet(local_address
, "ip")) {
3207 locaddr
= tsocket_address_inet_addr_string(
3208 sconn
->local_address
,
3210 if (locaddr
== NULL
) {
3211 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3212 __location__
, strerror(errno
)));
3213 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3216 locaddr
= "0.0.0.0";
3219 if (tsocket_address_is_inet(remote_address
, "ip")) {
3220 remaddr
= tsocket_address_inet_addr_string(
3221 sconn
->remote_address
,
3223 if (remaddr
== NULL
) {
3224 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3225 __location__
, strerror(errno
)));
3226 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3229 remaddr
= "0.0.0.0";
3232 /* this is needed so that we get decent entries
3233 in smbstatus for port 445 connects */
3234 set_remote_machine_name(remaddr
, false);
3235 reload_services(sconn
, conn_snum_used
, true);
3238 * Before the first packet, check the global hosts allow/ hosts deny
3239 * parameters before doing any parsing of packets passed to us by the
3240 * client. This prevents attacks on our parsing code from hosts not in
3241 * the hosts allow list.
3244 ret
= get_remote_hostname(remote_address
,
3248 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3249 __location__
, strerror(errno
)));
3250 exit_server_cleanly("get_remote_hostname failed.\n");
3252 if (strequal(rhost
, "UNKNOWN")) {
3253 rhost
= talloc_strdup(talloc_tos(), remaddr
);
3255 sconn
->remote_hostname
= talloc_move(sconn
, &rhost
);
3257 sub_set_socket_ids(remaddr
,
3258 sconn
->remote_hostname
,
3261 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3262 sconn
->remote_hostname
,
3265 * send a negative session response "not listening on calling
3268 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3269 DEBUG( 1, ("Connection denied from %s to %s\n",
3270 tsocket_address_string(remote_address
, talloc_tos()),
3271 tsocket_address_string(local_address
, talloc_tos())));
3272 (void)srv_send_smb(sconn
,(char *)buf
, false,
3274 exit_server_cleanly("connection denied");
3277 DEBUG(10, ("Connection allowed from %s to %s\n",
3278 tsocket_address_string(remote_address
, talloc_tos()),
3279 tsocket_address_string(local_address
, talloc_tos())));
3283 smb_perfcount_init();
3285 if (!init_account_policy()) {
3286 exit_server("Could not open account policy tdb.\n");
3289 if (*lp_rootdir()) {
3290 if (chroot(lp_rootdir()) != 0) {
3291 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3292 exit_server("Failed to chroot()");
3294 if (chdir("/") == -1) {
3295 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3296 exit_server("Failed to chroot()");
3298 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3301 if (!srv_init_signing(sconn
)) {
3302 exit_server("Failed to init smb_signing");
3306 if (!init_oplocks(sconn
))
3307 exit_server("Failed to init oplocks");
3309 /* register our message handlers */
3310 messaging_register(sconn
->msg_ctx
, sconn
,
3311 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3312 messaging_register(sconn
->msg_ctx
, sconn
,
3313 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3314 messaging_register(sconn
->msg_ctx
, sconn
,
3315 MSG_SMB_FILE_RENAME
, msg_file_was_renamed
);
3317 id_cache_register_msgs(sconn
->msg_ctx
);
3318 messaging_deregister(sconn
->msg_ctx
, ID_CACHE_KILL
, NULL
);
3319 messaging_register(sconn
->msg_ctx
, sconn
,
3320 ID_CACHE_KILL
, smbd_id_cache_kill
);
3322 messaging_deregister(sconn
->msg_ctx
,
3323 MSG_SMB_CONF_UPDATED
, sconn
->ev_ctx
);
3324 messaging_register(sconn
->msg_ctx
, sconn
,
3325 MSG_SMB_CONF_UPDATED
, smbd_conf_updated
);
3328 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3329 * MSGs to all child processes
3331 messaging_deregister(sconn
->msg_ctx
,
3333 messaging_register(sconn
->msg_ctx
, NULL
,
3334 MSG_DEBUG
, debug_message
);
3336 if ((lp_keepalive() != 0)
3337 && !(event_add_idle(ev_ctx
, NULL
,
3338 timeval_set(lp_keepalive(), 0),
3339 "keepalive", keepalive_fn
,
3341 DEBUG(0, ("Could not add keepalive event\n"));
3345 if (!(event_add_idle(ev_ctx
, NULL
,
3346 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3347 "deadtime", deadtime_fn
, sconn
))) {
3348 DEBUG(0, ("Could not add deadtime event\n"));
3352 if (!(event_add_idle(ev_ctx
, NULL
,
3353 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
3354 "housekeeping", housekeeping_fn
, sconn
))) {
3355 DEBUG(0, ("Could not add housekeeping event\n"));
3359 #ifdef CLUSTER_SUPPORT
3361 if (lp_clustering()) {
3363 * We need to tell ctdb about our client's TCP
3364 * connection, so that for failover ctdbd can send
3365 * tickle acks, triggering a reconnection by the
3369 struct sockaddr_storage srv
, clnt
;
3371 if (client_get_tcp_info(sconn
->sock
, &srv
, &clnt
) == 0) {
3373 status
= smbd_register_ips(sconn
, &srv
, &clnt
);
3374 if (!NT_STATUS_IS_OK(status
)) {
3375 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3376 nt_errstr(status
)));
3380 DEBUG(0,("Unable to get tcp info for "
3381 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3388 sconn
->nbt
.got_session
= false;
3390 sconn
->smb1
.negprot
.max_recv
= MIN(lp_maxxmit(),BUFFER_SIZE
);
3392 sconn
->smb1
.sessions
.done_sesssetup
= false;
3393 sconn
->smb1
.sessions
.max_send
= BUFFER_SIZE
;
3394 sconn
->smb1
.sessions
.last_session_tag
= UID_FIELD_INVALID
;
3395 /* this holds info on user ids that are already validated for this VC */
3396 sconn
->smb1
.sessions
.next_vuid
= VUID_OFFSET
;
3399 if (!init_dptrs(sconn
)) {
3400 exit_server("init_dptrs() failed");
3403 sconn
->smb1
.fde
= event_add_fd(ev_ctx
,
3407 smbd_server_connection_handler
,
3409 if (!sconn
->smb1
.fde
) {
3410 exit_server("failed to create smbd_server_connection fde");
3416 frame
= talloc_stackframe_pool(8192);
3419 if (tevent_loop_once(ev_ctx
) == -1) {
3420 if (errno
!= EINTR
) {
3421 DEBUG(3, ("tevent_loop_once failed: %s,"
3422 " exiting\n", strerror(errno
) ));
3430 exit_server_cleanly(NULL
);
3433 bool req_is_in_chain(struct smb_request
*req
)
3435 if (req
->vwv
!= (const uint16_t *)(req
->inbuf
+smb_vwv
)) {
3437 * We're right now handling a subsequent request, so we must
3443 if (!is_andx_req(req
->cmd
)) {
3449 * Okay, an illegal request, but definitely not chained :-)
3454 return (CVAL(req
->vwv
+0, 0) != 0xFF);