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"
40 extern bool global_machine_password_needs_changing
;
42 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
44 static struct pending_message_list
*get_deferred_open_message_smb(
45 struct smbd_server_connection
*sconn
, uint64_t mid
);
47 static bool smbd_lock_socket_internal(struct smbd_server_connection
*sconn
)
51 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
55 sconn
->smb1
.echo_handler
.ref_count
++;
57 if (sconn
->smb1
.echo_handler
.ref_count
> 1) {
61 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
65 sconn
->smb1
.echo_handler
.socket_lock_fd
,
66 SMB_F_SETLKW
, 0, 0, F_WRLCK
);
67 } while (!ok
&& (errno
== EINTR
));
70 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
74 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
79 void smbd_lock_socket(struct smbd_server_connection
*sconn
)
81 if (!smbd_lock_socket_internal(sconn
)) {
82 exit_server_cleanly("failed to lock socket");
86 static bool smbd_unlock_socket_internal(struct smbd_server_connection
*sconn
)
90 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
94 sconn
->smb1
.echo_handler
.ref_count
--;
96 if (sconn
->smb1
.echo_handler
.ref_count
> 0) {
102 sconn
->smb1
.echo_handler
.socket_lock_fd
,
103 SMB_F_SETLKW
, 0, 0, F_UNLCK
);
104 } while (!ok
&& (errno
== EINTR
));
107 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
111 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
116 void smbd_unlock_socket(struct smbd_server_connection
*sconn
)
118 if (!smbd_unlock_socket_internal(sconn
)) {
119 exit_server_cleanly("failed to unlock socket");
123 /* Accessor function for smb_read_error for smbd functions. */
125 /****************************************************************************
127 ****************************************************************************/
129 bool srv_send_smb(struct smbd_server_connection
*sconn
, char *buffer
,
130 bool do_signing
, uint32_t seqnum
,
132 struct smb_perfcount_data
*pcd
)
137 char *buf_out
= buffer
;
139 smbd_lock_socket(sconn
);
142 /* Sign the outgoing packet if required. */
143 srv_calculate_sign_mac(sconn
, buf_out
, seqnum
);
147 NTSTATUS status
= srv_encrypt_buffer(sconn
, buffer
, &buf_out
);
148 if (!NT_STATUS_IS_OK(status
)) {
149 DEBUG(0, ("send_smb: SMB encryption failed "
150 "on outgoing packet! Error %s\n",
151 nt_errstr(status
) ));
156 len
= smb_len(buf_out
) + 4;
158 ret
= write_data(sconn
->sock
, buf_out
+nwritten
, len
- nwritten
);
161 char addr
[INET6_ADDRSTRLEN
];
163 * Try and give an error message saying what
166 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
167 (int)sys_getpid(), (int)len
,
168 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
169 (int)ret
, strerror(errno
) ));
171 srv_free_enc_buffer(sconn
, buf_out
);
175 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
176 srv_free_enc_buffer(sconn
, buf_out
);
178 SMB_PERFCOUNT_END(pcd
);
180 smbd_unlock_socket(sconn
);
184 /*******************************************************************
185 Setup the word count and byte count for a smb message.
186 ********************************************************************/
188 int srv_set_message(char *buf
,
193 if (zero
&& (num_words
|| num_bytes
)) {
194 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
196 SCVAL(buf
,smb_wct
,num_words
);
197 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
198 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
199 return (smb_size
+ num_words
*2 + num_bytes
);
202 static bool valid_smb_header(struct smbd_server_connection
*sconn
,
203 const uint8_t *inbuf
)
205 if (is_encrypted_packet(sconn
, inbuf
)) {
209 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
210 * but it just looks weird to call strncmp for this one.
212 return (IVAL(smb_base(inbuf
), 0) == 0x424D53FF);
215 /* Socket functions for smbd packet processing. */
217 static bool valid_packet_size(size_t len
)
220 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
221 * of header. Don't print the error if this fits.... JRA.
224 if (len
> (BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
225 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
226 (unsigned long)len
));
232 static NTSTATUS
read_packet_remainder(int fd
, char *buffer
,
233 unsigned int timeout
, ssize_t len
)
241 status
= read_fd_with_timeout(fd
, buffer
, len
, len
, timeout
, NULL
);
242 if (!NT_STATUS_IS_OK(status
)) {
243 char addr
[INET6_ADDRSTRLEN
];
244 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
246 get_peer_addr(fd
, addr
, sizeof(addr
)),
252 /****************************************************************************
253 Attempt a zerocopy writeX read. We know here that len > smb_size-4
254 ****************************************************************************/
257 * Unfortunately, earlier versions of smbclient/libsmbclient
258 * don't send this "standard" writeX header. I've fixed this
259 * for 3.2 but we'll use the old method with earlier versions.
260 * Windows and CIFSFS at least use this standard size. Not
264 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
265 (2*14) + /* word count (including bcc) */ \
268 static NTSTATUS
receive_smb_raw_talloc_partial_read(TALLOC_CTX
*mem_ctx
,
269 const char lenbuf
[4],
270 struct smbd_server_connection
*sconn
,
273 unsigned int timeout
,
277 /* Size of a WRITEX call (+4 byte len). */
278 char writeX_header
[4 + STANDARD_WRITE_AND_X_HEADER_SIZE
];
279 ssize_t len
= smb_len_large(lenbuf
); /* Could be a UNIX large writeX. */
283 memcpy(writeX_header
, lenbuf
, 4);
285 status
= read_fd_with_timeout(
286 sock
, writeX_header
+ 4,
287 STANDARD_WRITE_AND_X_HEADER_SIZE
,
288 STANDARD_WRITE_AND_X_HEADER_SIZE
,
291 if (!NT_STATUS_IS_OK(status
)) {
292 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
294 tsocket_address_string(sconn
->remote_address
,
301 * Ok - now try and see if this is a possible
305 if (is_valid_writeX_buffer(sconn
, (uint8_t *)writeX_header
)) {
307 * If the data offset is beyond what
308 * we've read, drain the extra bytes.
310 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
313 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
314 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
315 if (drain_socket(sock
, drain
) != drain
) {
316 smb_panic("receive_smb_raw_talloc_partial_read:"
317 " failed to drain pending bytes");
320 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
323 /* Spoof down the length and null out the bcc. */
324 set_message_bcc(writeX_header
, 0);
325 newlen
= smb_len(writeX_header
);
327 /* Copy the header we've written. */
329 *buffer
= (char *)talloc_memdup(mem_ctx
,
331 sizeof(writeX_header
));
333 if (*buffer
== NULL
) {
334 DEBUG(0, ("Could not allocate inbuf of length %d\n",
335 (int)sizeof(writeX_header
)));
336 return NT_STATUS_NO_MEMORY
;
339 /* Work out the remaining bytes. */
340 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
341 *len_ret
= newlen
+ 4;
345 if (!valid_packet_size(len
)) {
346 return NT_STATUS_INVALID_PARAMETER
;
350 * Not a valid writeX call. Just do the standard
354 *buffer
= talloc_array(mem_ctx
, char, len
+4);
356 if (*buffer
== NULL
) {
357 DEBUG(0, ("Could not allocate inbuf of length %d\n",
359 return NT_STATUS_NO_MEMORY
;
362 /* Copy in what we already read. */
365 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
366 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
369 status
= read_packet_remainder(
371 (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
374 if (!NT_STATUS_IS_OK(status
)) {
375 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
385 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
,
386 struct smbd_server_connection
*sconn
,
388 char **buffer
, unsigned int timeout
,
389 size_t *p_unread
, size_t *plen
)
393 int min_recv_size
= lp_min_receive_file_size();
398 status
= read_smb_length_return_keepalive(sock
, lenbuf
, timeout
,
400 if (!NT_STATUS_IS_OK(status
)) {
404 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
405 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
406 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
407 !srv_is_signing_active(sconn
) &&
408 sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
410 return receive_smb_raw_talloc_partial_read(
411 mem_ctx
, lenbuf
, sconn
, sock
, buffer
, timeout
,
415 if (!valid_packet_size(len
)) {
416 return NT_STATUS_INVALID_PARAMETER
;
420 * The +4 here can't wrap, we've checked the length above already.
423 *buffer
= talloc_array(mem_ctx
, char, len
+4);
425 if (*buffer
== NULL
) {
426 DEBUG(0, ("Could not allocate inbuf of length %d\n",
428 return NT_STATUS_NO_MEMORY
;
431 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
433 status
= read_packet_remainder(sock
, (*buffer
)+4, timeout
, len
);
434 if (!NT_STATUS_IS_OK(status
)) {
442 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
,
443 struct smbd_server_connection
*sconn
,
445 char **buffer
, unsigned int timeout
,
446 size_t *p_unread
, bool *p_encrypted
,
449 bool trusted_channel
)
454 *p_encrypted
= false;
456 status
= receive_smb_raw_talloc(mem_ctx
, sconn
, sock
, buffer
, timeout
,
458 if (!NT_STATUS_IS_OK(status
)) {
459 DEBUG(1, ("read_smb_length_return_keepalive failed for "
460 "client %s read error = %s.\n",
461 tsocket_address_string(sconn
->remote_address
,
467 if (is_encrypted_packet(sconn
, (uint8_t *)*buffer
)) {
468 status
= srv_decrypt_buffer(sconn
, *buffer
);
469 if (!NT_STATUS_IS_OK(status
)) {
470 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
471 "incoming packet! Error %s\n",
472 nt_errstr(status
) ));
478 /* Check the incoming SMB signature. */
479 if (!srv_check_sign_mac(sconn
, *buffer
, seqnum
, trusted_channel
)) {
480 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
481 "incoming packet!\n"));
482 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
490 * Initialize a struct smb_request from an inbuf
493 static bool init_smb_request(struct smb_request
*req
,
494 struct smbd_server_connection
*sconn
,
496 size_t unread_bytes
, bool encrypted
,
499 size_t req_size
= smb_len(inbuf
) + 4;
500 /* Ensure we have at least smb_size bytes. */
501 if (req_size
< smb_size
) {
502 DEBUG(0,("init_smb_request: invalid request size %u\n",
503 (unsigned int)req_size
));
506 req
->cmd
= CVAL(inbuf
, smb_com
);
507 req
->flags2
= SVAL(inbuf
, smb_flg2
);
508 req
->smbpid
= SVAL(inbuf
, smb_pid
);
509 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
510 req
->seqnum
= seqnum
;
511 req
->vuid
= SVAL(inbuf
, smb_uid
);
512 req
->tid
= SVAL(inbuf
, smb_tid
);
513 req
->wct
= CVAL(inbuf
, smb_wct
);
514 req
->vwv
= discard_const_p(uint16_t, (inbuf
+smb_vwv
));
515 req
->buflen
= smb_buflen(inbuf
);
516 req
->buf
= (const uint8_t *)smb_buf_const(inbuf
);
517 req
->unread_bytes
= unread_bytes
;
518 req
->encrypted
= encrypted
;
520 req
->conn
= conn_find(sconn
,req
->tid
);
521 req
->chain_fsp
= NULL
;
522 req
->chain_outbuf
= NULL
;
525 smb_init_perfcount_data(&req
->pcd
);
527 /* Ensure we have at least wct words and 2 bytes of bcc. */
528 if (smb_size
+ req
->wct
*2 > req_size
) {
529 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
530 (unsigned int)req
->wct
,
531 (unsigned int)req_size
));
534 /* Ensure bcc is correct. */
535 if (((const uint8_t *)smb_buf_const(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
536 DEBUG(0,("init_smb_request: invalid bcc number %u "
537 "(wct = %u, size %u)\n",
538 (unsigned int)req
->buflen
,
539 (unsigned int)req
->wct
,
540 (unsigned int)req_size
));
548 static void process_smb(struct smbd_server_connection
*conn
,
549 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
550 uint32_t seqnum
, bool encrypted
,
551 struct smb_perfcount_data
*deferred_pcd
);
553 static void smbd_deferred_open_timer(struct event_context
*ev
,
554 struct timed_event
*te
,
555 struct timeval _tval
,
558 struct pending_message_list
*msg
= talloc_get_type(private_data
,
559 struct pending_message_list
);
560 TALLOC_CTX
*mem_ctx
= talloc_tos();
561 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
564 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
567 exit_server("smbd_deferred_open_timer: talloc failed\n");
571 /* We leave this message on the queue so the open code can
572 know this is a retry. */
573 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
574 (unsigned long long)mid
));
576 /* Mark the message as processed so this is not
577 * re-processed in error. */
578 msg
->processed
= true;
580 process_smb(smbd_server_conn
, inbuf
,
582 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
584 /* If it's still there and was processed, remove it. */
585 msg
= get_deferred_open_message_smb(smbd_server_conn
, mid
);
586 if (msg
&& msg
->processed
) {
587 remove_deferred_open_message_smb(smbd_server_conn
, mid
);
591 /****************************************************************************
592 Function to push a message onto the tail of a linked list of smb messages ready
594 ****************************************************************************/
596 static bool push_queued_message(struct smb_request
*req
,
597 struct timeval request_time
,
598 struct timeval end_time
,
599 char *private_data
, size_t private_len
)
601 int msg_len
= smb_len(req
->inbuf
) + 4;
602 struct pending_message_list
*msg
;
604 msg
= talloc_zero(NULL
, struct pending_message_list
);
607 DEBUG(0,("push_message: malloc fail (1)\n"));
611 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
612 if(msg
->buf
.data
== NULL
) {
613 DEBUG(0,("push_message: malloc fail (2)\n"));
618 msg
->request_time
= request_time
;
619 msg
->seqnum
= req
->seqnum
;
620 msg
->encrypted
= req
->encrypted
;
621 msg
->processed
= false;
622 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
625 msg
->private_data
= data_blob_talloc(msg
, private_data
,
627 if (msg
->private_data
.data
== NULL
) {
628 DEBUG(0,("push_message: malloc fail (3)\n"));
634 msg
->te
= event_add_timed(server_event_context(),
637 smbd_deferred_open_timer
,
640 DEBUG(0,("push_message: event_add_timed failed\n"));
645 DLIST_ADD_END(req
->sconn
->deferred_open_queue
, msg
,
646 struct pending_message_list
*);
648 DEBUG(10,("push_message: pushed message length %u on "
649 "deferred_open_queue\n", (unsigned int)msg_len
));
654 /****************************************************************************
655 Function to delete a sharing violation open message by mid.
656 ****************************************************************************/
658 void remove_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
661 struct pending_message_list
*pml
;
663 if (sconn
->using_smb2
) {
664 remove_deferred_open_message_smb2(sconn
, mid
);
668 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
669 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
670 DEBUG(10,("remove_deferred_open_message_smb: "
671 "deleting mid %llu len %u\n",
672 (unsigned long long)mid
,
673 (unsigned int)pml
->buf
.length
));
674 DLIST_REMOVE(sconn
->deferred_open_queue
, pml
);
681 /****************************************************************************
682 Move a sharing violation open retry message to the front of the list and
683 schedule it for immediate processing.
684 ****************************************************************************/
686 void schedule_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
689 struct pending_message_list
*pml
;
692 if (sconn
->using_smb2
) {
693 schedule_deferred_open_message_smb2(sconn
, mid
);
697 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
698 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
700 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
703 (unsigned long long)msg_mid
));
705 if (mid
== msg_mid
) {
706 struct timed_event
*te
;
708 if (pml
->processed
) {
709 /* A processed message should not be
711 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
712 "message mid %llu was already processed\n",
713 (unsigned long long)msg_mid
));
717 DEBUG(10,("schedule_deferred_open_message_smb: "
718 "scheduling mid %llu\n",
719 (unsigned long long)mid
));
721 te
= event_add_timed(server_event_context(),
724 smbd_deferred_open_timer
,
727 DEBUG(10,("schedule_deferred_open_message_smb: "
728 "event_add_timed() failed, "
729 "skipping mid %llu\n",
730 (unsigned long long)msg_mid
));
733 TALLOC_FREE(pml
->te
);
735 DLIST_PROMOTE(sconn
->deferred_open_queue
, pml
);
740 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
741 "find message mid %llu\n",
742 (unsigned long long)mid
));
745 /****************************************************************************
746 Return true if this mid is on the deferred queue and was not yet processed.
747 ****************************************************************************/
749 bool open_was_deferred(struct smbd_server_connection
*sconn
, uint64_t mid
)
751 struct pending_message_list
*pml
;
753 if (sconn
->using_smb2
) {
754 return open_was_deferred_smb2(sconn
, mid
);
757 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
758 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
765 /****************************************************************************
766 Return the message queued by this mid.
767 ****************************************************************************/
769 static struct pending_message_list
*get_deferred_open_message_smb(
770 struct smbd_server_connection
*sconn
, uint64_t mid
)
772 struct pending_message_list
*pml
;
774 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
775 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
782 /****************************************************************************
783 Get the state data queued by this mid.
784 ****************************************************************************/
786 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
787 struct timeval
*p_request_time
,
790 struct pending_message_list
*pml
;
792 if (smbd_server_conn
->using_smb2
) {
793 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
798 pml
= get_deferred_open_message_smb(smbreq
->sconn
, smbreq
->mid
);
802 if (p_request_time
) {
803 *p_request_time
= pml
->request_time
;
806 *pp_state
= (void *)pml
->private_data
.data
;
811 /****************************************************************************
812 Function to push a deferred open smb message onto a linked list of local smb
813 messages ready for processing.
814 ****************************************************************************/
816 bool push_deferred_open_message_smb(struct smb_request
*req
,
817 struct timeval request_time
,
818 struct timeval timeout
,
820 char *private_data
, size_t priv_len
)
822 struct timeval end_time
;
825 return push_deferred_open_message_smb2(req
->smb2req
,
833 if (req
->unread_bytes
) {
834 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
835 "unread_bytes = %u\n",
836 (unsigned int)req
->unread_bytes
));
837 smb_panic("push_deferred_open_message_smb: "
838 "logic error unread_bytes != 0" );
841 end_time
= timeval_sum(&request_time
, &timeout
);
843 DEBUG(10,("push_deferred_open_message_smb: pushing message "
844 "len %u mid %llu timeout time [%u.%06u]\n",
845 (unsigned int) smb_len(req
->inbuf
)+4,
846 (unsigned long long)req
->mid
,
847 (unsigned int)end_time
.tv_sec
,
848 (unsigned int)end_time
.tv_usec
));
850 return push_queued_message(req
, request_time
, end_time
,
851 private_data
, priv_len
);
854 static void smbd_sig_term_handler(struct tevent_context
*ev
,
855 struct tevent_signal
*se
,
861 exit_server_cleanly("termination signal");
864 void smbd_setup_sig_term_handler(void)
866 struct tevent_signal
*se
;
868 se
= tevent_add_signal(server_event_context(),
869 server_event_context(),
871 smbd_sig_term_handler
,
874 exit_server("failed to setup SIGTERM handler");
878 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
879 struct tevent_signal
*se
,
885 struct messaging_context
*msg_ctx
= talloc_get_type_abort(
886 private_data
, struct messaging_context
);
887 change_to_root_user();
888 DEBUG(1,("Reloading services after SIGHUP\n"));
889 reload_services(msg_ctx
, smbd_server_conn
->sock
, False
);
891 printing_subsystem_update(ev
, msg_ctx
, true);
895 void smbd_setup_sig_hup_handler(struct tevent_context
*ev
,
896 struct messaging_context
*msg_ctx
)
898 struct tevent_signal
*se
;
900 se
= tevent_add_signal(ev
, ev
, SIGHUP
, 0, smbd_sig_hup_handler
,
903 exit_server("failed to setup SIGHUP handler");
907 static NTSTATUS
smbd_server_connection_loop_once(struct tevent_context
*ev_ctx
,
908 struct smbd_server_connection
*conn
)
915 timeout
= SMBD_SELECT_TIMEOUT
* 1000;
918 * Are there any timed events waiting ? If so, ensure we don't
919 * select for longer than it would take to wait for them.
922 event_add_to_poll_args(ev_ctx
, conn
, &conn
->pfds
, &num_pfds
, &timeout
);
924 /* Process a signal and timed events now... */
925 if (run_events_poll(ev_ctx
, 0, NULL
, 0)) {
926 return NT_STATUS_RETRY
;
931 START_PROFILE(smbd_idle
);
933 ret
= sys_poll(conn
->pfds
, num_pfds
, timeout
);
936 END_PROFILE(smbd_idle
);
941 if (errno
== EINTR
) {
942 return NT_STATUS_RETRY
;
944 return map_nt_error_from_unix(errno
);
947 retry
= run_events_poll(ev_ctx
, ret
, conn
->pfds
, num_pfds
);
949 return NT_STATUS_RETRY
;
952 /* Did we timeout ? */
954 return NT_STATUS_RETRY
;
957 /* should not be reached */
958 return NT_STATUS_INTERNAL_ERROR
;
962 * Only allow 5 outstanding trans requests. We're allocating memory, so
966 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
969 for (; list
!= NULL
; list
= list
->next
) {
971 if (list
->mid
== mid
) {
972 return NT_STATUS_INVALID_PARAMETER
;
978 return NT_STATUS_INSUFFICIENT_RESOURCES
;
985 These flags determine some of the permissions required to do an operation
987 Note that I don't set NEED_WRITE on some write operations because they
988 are used by some brain-dead clients when printing, and I don't want to
989 force write permissions on print services.
991 #define AS_USER (1<<0)
992 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
993 #define TIME_INIT (1<<2)
994 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
995 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
996 #define DO_CHDIR (1<<6)
999 define a list of possible SMB messages and their corresponding
1000 functions. Any message that has a NULL function is unimplemented -
1001 please feel free to contribute implementations!
1003 static const struct smb_message_struct
{
1005 void (*fn
)(struct smb_request
*req
);
1007 } smb_messages
[256] = {
1009 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1010 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1011 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1012 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1013 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1014 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1015 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1016 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1017 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1018 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1019 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1020 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1021 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1022 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1023 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1024 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1025 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1026 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1027 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1028 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1029 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1030 /* 0x15 */ { NULL
, NULL
, 0 },
1031 /* 0x16 */ { NULL
, NULL
, 0 },
1032 /* 0x17 */ { NULL
, NULL
, 0 },
1033 /* 0x18 */ { NULL
, NULL
, 0 },
1034 /* 0x19 */ { NULL
, NULL
, 0 },
1035 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1036 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1037 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1038 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1039 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1040 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1041 /* 0x20 */ { "SMBwritec", NULL
,0},
1042 /* 0x21 */ { NULL
, NULL
, 0 },
1043 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1044 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1045 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1046 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1047 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1048 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1049 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1050 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1051 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1052 /* 0x2b */ { "SMBecho",reply_echo
,0},
1053 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1054 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1055 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1056 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1057 /* 0x30 */ { NULL
, NULL
, 0 },
1058 /* 0x31 */ { NULL
, NULL
, 0 },
1059 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1060 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1061 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1062 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1063 /* 0x36 */ { NULL
, NULL
, 0 },
1064 /* 0x37 */ { NULL
, NULL
, 0 },
1065 /* 0x38 */ { NULL
, NULL
, 0 },
1066 /* 0x39 */ { NULL
, NULL
, 0 },
1067 /* 0x3a */ { NULL
, NULL
, 0 },
1068 /* 0x3b */ { NULL
, NULL
, 0 },
1069 /* 0x3c */ { NULL
, NULL
, 0 },
1070 /* 0x3d */ { NULL
, NULL
, 0 },
1071 /* 0x3e */ { NULL
, NULL
, 0 },
1072 /* 0x3f */ { NULL
, NULL
, 0 },
1073 /* 0x40 */ { NULL
, NULL
, 0 },
1074 /* 0x41 */ { NULL
, NULL
, 0 },
1075 /* 0x42 */ { NULL
, NULL
, 0 },
1076 /* 0x43 */ { NULL
, NULL
, 0 },
1077 /* 0x44 */ { NULL
, NULL
, 0 },
1078 /* 0x45 */ { NULL
, NULL
, 0 },
1079 /* 0x46 */ { NULL
, NULL
, 0 },
1080 /* 0x47 */ { NULL
, NULL
, 0 },
1081 /* 0x48 */ { NULL
, NULL
, 0 },
1082 /* 0x49 */ { NULL
, NULL
, 0 },
1083 /* 0x4a */ { NULL
, NULL
, 0 },
1084 /* 0x4b */ { NULL
, NULL
, 0 },
1085 /* 0x4c */ { NULL
, NULL
, 0 },
1086 /* 0x4d */ { NULL
, NULL
, 0 },
1087 /* 0x4e */ { NULL
, NULL
, 0 },
1088 /* 0x4f */ { NULL
, NULL
, 0 },
1089 /* 0x50 */ { NULL
, NULL
, 0 },
1090 /* 0x51 */ { NULL
, NULL
, 0 },
1091 /* 0x52 */ { NULL
, NULL
, 0 },
1092 /* 0x53 */ { NULL
, NULL
, 0 },
1093 /* 0x54 */ { NULL
, NULL
, 0 },
1094 /* 0x55 */ { NULL
, NULL
, 0 },
1095 /* 0x56 */ { NULL
, NULL
, 0 },
1096 /* 0x57 */ { NULL
, NULL
, 0 },
1097 /* 0x58 */ { NULL
, NULL
, 0 },
1098 /* 0x59 */ { NULL
, NULL
, 0 },
1099 /* 0x5a */ { NULL
, NULL
, 0 },
1100 /* 0x5b */ { NULL
, NULL
, 0 },
1101 /* 0x5c */ { NULL
, NULL
, 0 },
1102 /* 0x5d */ { NULL
, NULL
, 0 },
1103 /* 0x5e */ { NULL
, NULL
, 0 },
1104 /* 0x5f */ { NULL
, NULL
, 0 },
1105 /* 0x60 */ { NULL
, NULL
, 0 },
1106 /* 0x61 */ { NULL
, NULL
, 0 },
1107 /* 0x62 */ { NULL
, NULL
, 0 },
1108 /* 0x63 */ { NULL
, NULL
, 0 },
1109 /* 0x64 */ { NULL
, NULL
, 0 },
1110 /* 0x65 */ { NULL
, NULL
, 0 },
1111 /* 0x66 */ { NULL
, NULL
, 0 },
1112 /* 0x67 */ { NULL
, NULL
, 0 },
1113 /* 0x68 */ { NULL
, NULL
, 0 },
1114 /* 0x69 */ { NULL
, NULL
, 0 },
1115 /* 0x6a */ { NULL
, NULL
, 0 },
1116 /* 0x6b */ { NULL
, NULL
, 0 },
1117 /* 0x6c */ { NULL
, NULL
, 0 },
1118 /* 0x6d */ { NULL
, NULL
, 0 },
1119 /* 0x6e */ { NULL
, NULL
, 0 },
1120 /* 0x6f */ { NULL
, NULL
, 0 },
1121 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1122 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1123 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1124 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1125 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1126 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1127 /* 0x76 */ { NULL
, NULL
, 0 },
1128 /* 0x77 */ { NULL
, NULL
, 0 },
1129 /* 0x78 */ { NULL
, NULL
, 0 },
1130 /* 0x79 */ { NULL
, NULL
, 0 },
1131 /* 0x7a */ { NULL
, NULL
, 0 },
1132 /* 0x7b */ { NULL
, NULL
, 0 },
1133 /* 0x7c */ { NULL
, NULL
, 0 },
1134 /* 0x7d */ { NULL
, NULL
, 0 },
1135 /* 0x7e */ { NULL
, NULL
, 0 },
1136 /* 0x7f */ { NULL
, NULL
, 0 },
1137 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1138 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1139 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1140 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1141 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1142 /* 0x85 */ { NULL
, NULL
, 0 },
1143 /* 0x86 */ { NULL
, NULL
, 0 },
1144 /* 0x87 */ { NULL
, NULL
, 0 },
1145 /* 0x88 */ { NULL
, NULL
, 0 },
1146 /* 0x89 */ { NULL
, NULL
, 0 },
1147 /* 0x8a */ { NULL
, NULL
, 0 },
1148 /* 0x8b */ { NULL
, NULL
, 0 },
1149 /* 0x8c */ { NULL
, NULL
, 0 },
1150 /* 0x8d */ { NULL
, NULL
, 0 },
1151 /* 0x8e */ { NULL
, NULL
, 0 },
1152 /* 0x8f */ { NULL
, NULL
, 0 },
1153 /* 0x90 */ { NULL
, NULL
, 0 },
1154 /* 0x91 */ { NULL
, NULL
, 0 },
1155 /* 0x92 */ { NULL
, NULL
, 0 },
1156 /* 0x93 */ { NULL
, NULL
, 0 },
1157 /* 0x94 */ { NULL
, NULL
, 0 },
1158 /* 0x95 */ { NULL
, NULL
, 0 },
1159 /* 0x96 */ { NULL
, NULL
, 0 },
1160 /* 0x97 */ { NULL
, NULL
, 0 },
1161 /* 0x98 */ { NULL
, NULL
, 0 },
1162 /* 0x99 */ { NULL
, NULL
, 0 },
1163 /* 0x9a */ { NULL
, NULL
, 0 },
1164 /* 0x9b */ { NULL
, NULL
, 0 },
1165 /* 0x9c */ { NULL
, NULL
, 0 },
1166 /* 0x9d */ { NULL
, NULL
, 0 },
1167 /* 0x9e */ { NULL
, NULL
, 0 },
1168 /* 0x9f */ { NULL
, NULL
, 0 },
1169 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1170 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1171 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1172 /* 0xa3 */ { NULL
, NULL
, 0 },
1173 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1174 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1175 /* 0xa6 */ { NULL
, NULL
, 0 },
1176 /* 0xa7 */ { NULL
, NULL
, 0 },
1177 /* 0xa8 */ { NULL
, NULL
, 0 },
1178 /* 0xa9 */ { NULL
, NULL
, 0 },
1179 /* 0xaa */ { NULL
, NULL
, 0 },
1180 /* 0xab */ { NULL
, NULL
, 0 },
1181 /* 0xac */ { NULL
, NULL
, 0 },
1182 /* 0xad */ { NULL
, NULL
, 0 },
1183 /* 0xae */ { NULL
, NULL
, 0 },
1184 /* 0xaf */ { NULL
, NULL
, 0 },
1185 /* 0xb0 */ { NULL
, NULL
, 0 },
1186 /* 0xb1 */ { NULL
, NULL
, 0 },
1187 /* 0xb2 */ { NULL
, NULL
, 0 },
1188 /* 0xb3 */ { NULL
, NULL
, 0 },
1189 /* 0xb4 */ { NULL
, NULL
, 0 },
1190 /* 0xb5 */ { NULL
, NULL
, 0 },
1191 /* 0xb6 */ { NULL
, NULL
, 0 },
1192 /* 0xb7 */ { NULL
, NULL
, 0 },
1193 /* 0xb8 */ { NULL
, NULL
, 0 },
1194 /* 0xb9 */ { NULL
, NULL
, 0 },
1195 /* 0xba */ { NULL
, NULL
, 0 },
1196 /* 0xbb */ { NULL
, NULL
, 0 },
1197 /* 0xbc */ { NULL
, NULL
, 0 },
1198 /* 0xbd */ { NULL
, NULL
, 0 },
1199 /* 0xbe */ { NULL
, NULL
, 0 },
1200 /* 0xbf */ { NULL
, NULL
, 0 },
1201 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1202 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1203 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1204 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1205 /* 0xc4 */ { NULL
, NULL
, 0 },
1206 /* 0xc5 */ { NULL
, NULL
, 0 },
1207 /* 0xc6 */ { NULL
, NULL
, 0 },
1208 /* 0xc7 */ { NULL
, NULL
, 0 },
1209 /* 0xc8 */ { NULL
, NULL
, 0 },
1210 /* 0xc9 */ { NULL
, NULL
, 0 },
1211 /* 0xca */ { NULL
, NULL
, 0 },
1212 /* 0xcb */ { NULL
, NULL
, 0 },
1213 /* 0xcc */ { NULL
, NULL
, 0 },
1214 /* 0xcd */ { NULL
, NULL
, 0 },
1215 /* 0xce */ { NULL
, NULL
, 0 },
1216 /* 0xcf */ { NULL
, NULL
, 0 },
1217 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1218 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1219 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1220 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1221 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1222 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1223 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1224 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1225 /* 0xd8 */ { NULL
, NULL
, 0 },
1226 /* 0xd9 */ { NULL
, NULL
, 0 },
1227 /* 0xda */ { NULL
, NULL
, 0 },
1228 /* 0xdb */ { NULL
, NULL
, 0 },
1229 /* 0xdc */ { NULL
, NULL
, 0 },
1230 /* 0xdd */ { NULL
, NULL
, 0 },
1231 /* 0xde */ { NULL
, NULL
, 0 },
1232 /* 0xdf */ { NULL
, NULL
, 0 },
1233 /* 0xe0 */ { NULL
, NULL
, 0 },
1234 /* 0xe1 */ { NULL
, NULL
, 0 },
1235 /* 0xe2 */ { NULL
, NULL
, 0 },
1236 /* 0xe3 */ { NULL
, NULL
, 0 },
1237 /* 0xe4 */ { NULL
, NULL
, 0 },
1238 /* 0xe5 */ { NULL
, NULL
, 0 },
1239 /* 0xe6 */ { NULL
, NULL
, 0 },
1240 /* 0xe7 */ { NULL
, NULL
, 0 },
1241 /* 0xe8 */ { NULL
, NULL
, 0 },
1242 /* 0xe9 */ { NULL
, NULL
, 0 },
1243 /* 0xea */ { NULL
, NULL
, 0 },
1244 /* 0xeb */ { NULL
, NULL
, 0 },
1245 /* 0xec */ { NULL
, NULL
, 0 },
1246 /* 0xed */ { NULL
, NULL
, 0 },
1247 /* 0xee */ { NULL
, NULL
, 0 },
1248 /* 0xef */ { NULL
, NULL
, 0 },
1249 /* 0xf0 */ { NULL
, NULL
, 0 },
1250 /* 0xf1 */ { NULL
, NULL
, 0 },
1251 /* 0xf2 */ { NULL
, NULL
, 0 },
1252 /* 0xf3 */ { NULL
, NULL
, 0 },
1253 /* 0xf4 */ { NULL
, NULL
, 0 },
1254 /* 0xf5 */ { NULL
, NULL
, 0 },
1255 /* 0xf6 */ { NULL
, NULL
, 0 },
1256 /* 0xf7 */ { NULL
, NULL
, 0 },
1257 /* 0xf8 */ { NULL
, NULL
, 0 },
1258 /* 0xf9 */ { NULL
, NULL
, 0 },
1259 /* 0xfa */ { NULL
, NULL
, 0 },
1260 /* 0xfb */ { NULL
, NULL
, 0 },
1261 /* 0xfc */ { NULL
, NULL
, 0 },
1262 /* 0xfd */ { NULL
, NULL
, 0 },
1263 /* 0xfe */ { NULL
, NULL
, 0 },
1264 /* 0xff */ { NULL
, NULL
, 0 }
1268 /*******************************************************************
1269 allocate and initialize a reply packet
1270 ********************************************************************/
1272 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1273 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1277 * Protect against integer wrap
1279 if ((num_bytes
> 0xffffff)
1280 || ((num_bytes
+ smb_size
+ num_words
*2) > 0xffffff)) {
1282 if (asprintf(&msg
, "num_bytes too large: %u",
1283 (unsigned)num_bytes
) == -1) {
1284 msg
= discard_const_p(char, "num_bytes too large");
1289 *outbuf
= talloc_array(mem_ctx
, char,
1290 smb_size
+ num_words
*2 + num_bytes
);
1291 if (*outbuf
== NULL
) {
1295 construct_reply_common(req
, inbuf
, *outbuf
);
1296 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1298 * Zero out the word area, the caller has to take care of the bcc area
1301 if (num_words
!= 0) {
1302 memset(*outbuf
+ smb_vwv0
, 0, num_words
*2);
1308 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1311 if (!create_outbuf(req
, req
, (const char *)req
->inbuf
, &outbuf
, num_words
,
1313 smb_panic("could not allocate output buffer\n");
1315 req
->outbuf
= (uint8_t *)outbuf
;
1319 /*******************************************************************
1320 Dump a packet to a file.
1321 ********************************************************************/
1323 static void smb_dump(const char *name
, int type
, const char *data
, ssize_t len
)
1327 if (DEBUGLEVEL
< 50) {
1331 if (len
< 4) len
= smb_len(data
)+4;
1332 for (i
=1;i
<100;i
++) {
1333 if (asprintf(&fname
, "/tmp/%s.%d.%s", name
, i
,
1334 type
? "req" : "resp") == -1) {
1337 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1338 if (fd
!= -1 || errno
!= EEXIST
) break;
1341 ssize_t ret
= write(fd
, data
, len
);
1343 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1345 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1350 /****************************************************************************
1351 Prepare everything for calling the actual request function, and potentially
1352 call the request function via the "new" interface.
1354 Return False if the "legacy" function needs to be called, everything is
1357 Return True if we're done.
1359 I know this API sucks, but it is the one with the least code change I could
1361 ****************************************************************************/
1363 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
, int size
)
1367 connection_struct
*conn
= NULL
;
1368 struct smbd_server_connection
*sconn
= req
->sconn
;
1373 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1374 * so subtract 4 from it. */
1375 if (!valid_smb_header(sconn
, req
->inbuf
)
1376 || (size
< (smb_size
- 4))) {
1377 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1378 smb_len(req
->inbuf
)));
1379 exit_server_cleanly("Non-SMB packet");
1382 if (smb_messages
[type
].fn
== NULL
) {
1383 DEBUG(0,("Unknown message type %d!\n",type
));
1384 smb_dump("Unknown", 1, (const char *)req
->inbuf
, size
);
1385 reply_unknown_new(req
, type
);
1389 flags
= smb_messages
[type
].flags
;
1391 /* In share mode security we must ignore the vuid. */
1392 session_tag
= (lp_security() == SEC_SHARE
)
1393 ? UID_FIELD_INVALID
: req
->vuid
;
1396 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1397 (int)sys_getpid(), (unsigned long)conn
));
1399 smb_dump(smb_fn_name(type
), 1, (const char *)req
->inbuf
, size
);
1401 /* Ensure this value is replaced in the incoming packet. */
1402 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_uid
,session_tag
);
1405 * Ensure the correct username is in current_user_info. This is a
1406 * really ugly bugfix for problems with multiple session_setup_and_X's
1407 * being done and allowing %U and %G substitutions to work correctly.
1408 * There is a reason this code is done here, don't move it unless you
1409 * know what you're doing... :-).
1413 if (session_tag
!= sconn
->smb1
.sessions
.last_session_tag
) {
1414 user_struct
*vuser
= NULL
;
1416 sconn
->smb1
.sessions
.last_session_tag
= session_tag
;
1417 if(session_tag
!= UID_FIELD_INVALID
) {
1418 vuser
= get_valid_user_struct(sconn
, session_tag
);
1420 set_current_user_info(
1421 vuser
->session_info
->unix_info
->sanitized_username
,
1422 vuser
->session_info
->unix_info
->unix_name
,
1423 vuser
->session_info
->info
->domain_name
);
1428 /* Does this call need to be run as the connected user? */
1429 if (flags
& AS_USER
) {
1431 /* Does this call need a valid tree connection? */
1434 * Amazingly, the error code depends on the command
1437 if (type
== SMBntcreateX
) {
1438 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1440 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1445 if (!change_to_user(conn
,session_tag
)) {
1446 DEBUG(0, ("Error: Could not change to user. Removing "
1447 "deferred open, mid=%llu.\n",
1448 (unsigned long long)req
->mid
));
1449 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1453 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1455 /* Does it need write permission? */
1456 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1457 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1461 /* IPC services are limited */
1462 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1463 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1467 /* This call needs to be run as root */
1468 change_to_root_user();
1471 /* load service specific parameters */
1473 if (req
->encrypted
) {
1474 conn
->encrypted_tid
= true;
1475 /* encrypted required from now on. */
1476 conn
->encrypt_level
= Required
;
1477 } else if (ENCRYPTION_REQUIRED(conn
)) {
1478 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1479 exit_server_cleanly("encryption required "
1485 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1486 (flags
& (AS_USER
|DO_CHDIR
)
1488 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1491 conn
->num_smb_operations
++;
1494 raddr
= tsocket_address_inet_addr_string(sconn
->remote_address
,
1496 if (raddr
== NULL
) {
1497 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1501 /* does this protocol need to be run as guest? */
1502 if ((flags
& AS_GUEST
)
1503 && (!change_to_guest() ||
1504 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1505 sconn
->remote_hostname
,
1507 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1511 smb_messages
[type
].fn(req
);
1515 /****************************************************************************
1516 Construct a reply to the incoming packet.
1517 ****************************************************************************/
1519 static void construct_reply(struct smbd_server_connection
*sconn
,
1520 char *inbuf
, int size
, size_t unread_bytes
,
1521 uint32_t seqnum
, bool encrypted
,
1522 struct smb_perfcount_data
*deferred_pcd
)
1524 connection_struct
*conn
;
1525 struct smb_request
*req
;
1527 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1528 smb_panic("could not allocate smb_request");
1531 if (!init_smb_request(req
, sconn
, (uint8
*)inbuf
, unread_bytes
,
1532 encrypted
, seqnum
)) {
1533 exit_server_cleanly("Invalid SMB request");
1536 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1538 /* we popped this message off the queue - keep original perf data */
1540 req
->pcd
= *deferred_pcd
;
1542 SMB_PERFCOUNT_START(&req
->pcd
);
1543 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1544 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1547 conn
= switch_message(req
->cmd
, req
, size
);
1549 if (req
->unread_bytes
) {
1550 /* writeX failed. drain socket. */
1551 if (drain_socket(req
->sconn
->sock
, req
->unread_bytes
) !=
1552 req
->unread_bytes
) {
1553 smb_panic("failed to drain pending bytes");
1555 req
->unread_bytes
= 0;
1563 if (req
->outbuf
== NULL
) {
1567 if (CVAL(req
->outbuf
,0) == 0) {
1568 show_msg((char *)req
->outbuf
);
1571 if (!srv_send_smb(req
->sconn
,
1572 (char *)req
->outbuf
,
1573 true, req
->seqnum
+1,
1574 IS_CONN_ENCRYPTED(conn
)||req
->encrypted
,
1576 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1584 /****************************************************************************
1585 Process an smb from the client
1586 ****************************************************************************/
1587 static void process_smb(struct smbd_server_connection
*sconn
,
1588 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1589 uint32_t seqnum
, bool encrypted
,
1590 struct smb_perfcount_data
*deferred_pcd
)
1592 int msg_type
= CVAL(inbuf
,0);
1594 DO_PROFILE_INC(smb_count
);
1596 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1598 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1599 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1601 if (msg_type
!= NBSSmessage
) {
1603 * NetBIOS session request, keepalive, etc.
1605 reply_special(sconn
, (char *)inbuf
, nread
);
1609 if (sconn
->using_smb2
) {
1610 /* At this point we're not really using smb2,
1611 * we make the decision here.. */
1612 if (smbd_is_smb2_header(inbuf
, nread
)) {
1613 smbd_smb2_first_negprot(sconn
, inbuf
, nread
);
1615 } else if (nread
>= smb_size
&& valid_smb_header(sconn
, inbuf
)
1616 && CVAL(inbuf
, smb_com
) != 0x72) {
1617 /* This is a non-negprot SMB1 packet.
1618 Disable SMB2 from now on. */
1619 sconn
->using_smb2
= false;
1623 show_msg((char *)inbuf
);
1625 construct_reply(sconn
, (char *)inbuf
, nread
, unread_bytes
, seqnum
,
1626 encrypted
, deferred_pcd
);
1630 sconn
->num_requests
++;
1632 /* The timeout_processing function isn't run nearly
1633 often enough to implement 'max log size' without
1634 overrunning the size of the file by many megabytes.
1635 This is especially true if we are running at debug
1636 level 10. Checking every 50 SMBs is a nice
1637 tradeoff of performance vs log file size overrun. */
1639 if ((sconn
->num_requests
% 50) == 0 &&
1640 need_to_check_log_size()) {
1641 change_to_root_user();
1646 /****************************************************************************
1647 Return a string containing the function name of a SMB command.
1648 ****************************************************************************/
1650 const char *smb_fn_name(int type
)
1652 const char *unknown_name
= "SMBunknown";
1654 if (smb_messages
[type
].name
== NULL
)
1655 return(unknown_name
);
1657 return(smb_messages
[type
].name
);
1660 /****************************************************************************
1661 Helper functions for contruct_reply.
1662 ****************************************************************************/
1664 void add_to_common_flags2(uint32 v
)
1669 void remove_from_common_flags2(uint32 v
)
1671 common_flags2
&= ~v
;
1674 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1677 uint16_t in_flags2
= SVAL(inbuf
,smb_flg2
);
1678 uint16_t out_flags2
= common_flags2
;
1680 out_flags2
|= in_flags2
& FLAGS2_UNICODE_STRINGS
;
1681 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
;
1682 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
;
1684 srv_set_message(outbuf
,0,0,false);
1686 SCVAL(outbuf
, smb_com
, req
->cmd
);
1687 SIVAL(outbuf
,smb_rcls
,0);
1688 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1689 SSVAL(outbuf
,smb_flg2
, out_flags2
);
1690 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1691 memcpy(outbuf
+smb_ss_field
, inbuf
+smb_ss_field
, 8);
1693 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
1694 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
1695 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
1696 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
1699 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
1701 construct_reply_common(req
, (const char *)req
->inbuf
, outbuf
);
1705 * How many bytes have we already accumulated up to the current wct field
1709 size_t req_wct_ofs(struct smb_request
*req
)
1713 if (req
->chain_outbuf
== NULL
) {
1716 buf_size
= talloc_get_size(req
->chain_outbuf
);
1717 if ((buf_size
% 4) != 0) {
1718 buf_size
+= (4 - (buf_size
% 4));
1720 return buf_size
- 4;
1724 * Hack around reply_nterror & friends not being aware of chained requests,
1725 * generating illegal (i.e. wct==0) chain replies.
1728 static void fixup_chain_error_packet(struct smb_request
*req
)
1730 uint8_t *outbuf
= req
->outbuf
;
1732 reply_outbuf(req
, 2, 0);
1733 memcpy(req
->outbuf
, outbuf
, smb_wct
);
1734 TALLOC_FREE(outbuf
);
1735 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
1739 * @brief Find the smb_cmd offset of the last command pushed
1740 * @param[in] buf The buffer we're building up
1741 * @retval Where can we put our next andx cmd?
1743 * While chaining requests, the "next" request we're looking at needs to put
1744 * its SMB_Command before the data the previous request already built up added
1745 * to the chain. Find the offset to the place where we have to put our cmd.
1748 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
1753 cmd
= CVAL(buf
, smb_com
);
1755 SMB_ASSERT(is_andx_req(cmd
));
1759 while (CVAL(buf
, ofs
) != 0xff) {
1761 if (!is_andx_req(CVAL(buf
, ofs
))) {
1766 * ofs is from start of smb header, so add the 4 length
1767 * bytes. The next cmd is right after the wct field.
1769 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
1771 SMB_ASSERT(ofs
+4 < talloc_get_size(buf
));
1779 * @brief Do the smb chaining at a buffer level
1780 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1781 * @param[in] smb_command The command that we want to issue
1782 * @param[in] wct How many words?
1783 * @param[in] vwv The words, already in network order
1784 * @param[in] bytes_alignment How shall we align "bytes"?
1785 * @param[in] num_bytes How many bytes?
1786 * @param[in] bytes The data the request ships
1788 * smb_splice_chain() adds the vwv and bytes to the request already present in
1792 static bool smb_splice_chain(uint8_t **poutbuf
, uint8_t smb_command
,
1793 uint8_t wct
, const uint16_t *vwv
,
1794 size_t bytes_alignment
,
1795 uint32_t num_bytes
, const uint8_t *bytes
)
1798 size_t old_size
, new_size
;
1800 size_t chain_padding
= 0;
1801 size_t bytes_padding
= 0;
1804 old_size
= talloc_get_size(*poutbuf
);
1807 * old_size == smb_wct means we're pushing the first request in for
1811 first_request
= (old_size
== smb_wct
);
1813 if (!first_request
&& ((old_size
% 4) != 0)) {
1815 * Align the wct field of subsequent requests to a 4-byte
1818 chain_padding
= 4 - (old_size
% 4);
1822 * After the old request comes the new wct field (1 byte), the vwv's
1823 * and the num_bytes field. After at we might need to align the bytes
1824 * given to us to "bytes_alignment", increasing the num_bytes value.
1827 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
1829 if ((bytes_alignment
!= 0) && ((new_size
% bytes_alignment
) != 0)) {
1830 bytes_padding
= bytes_alignment
- (new_size
% bytes_alignment
);
1833 new_size
+= bytes_padding
+ num_bytes
;
1835 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
1836 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1837 (unsigned)new_size
));
1841 outbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, new_size
);
1842 if (outbuf
== NULL
) {
1843 DEBUG(0, ("talloc failed\n"));
1848 if (first_request
) {
1849 SCVAL(outbuf
, smb_com
, smb_command
);
1851 size_t andx_cmd_ofs
;
1853 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
1854 DEBUG(1, ("invalid command chain\n"));
1855 *poutbuf
= talloc_realloc(
1856 NULL
, *poutbuf
, uint8_t, old_size
);
1860 if (chain_padding
!= 0) {
1861 memset(outbuf
+ old_size
, 0, chain_padding
);
1862 old_size
+= chain_padding
;
1865 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
1866 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
1872 * Push the chained request:
1877 SCVAL(outbuf
, ofs
, wct
);
1884 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
1885 ofs
+= sizeof(uint16_t) * wct
;
1891 SSVAL(outbuf
, ofs
, num_bytes
+ bytes_padding
);
1892 ofs
+= sizeof(uint16_t);
1898 if (bytes_padding
!= 0) {
1899 memset(outbuf
+ ofs
, 0, bytes_padding
);
1900 ofs
+= bytes_padding
;
1907 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
1912 /****************************************************************************
1913 Construct a chained reply and add it to the already made reply
1914 ****************************************************************************/
1916 void chain_reply(struct smb_request
*req
)
1918 size_t smblen
= smb_len(req
->inbuf
);
1919 size_t already_used
, length_needed
;
1921 uint32_t chain_offset
; /* uint32_t to avoid overflow */
1924 const uint16_t *vwv
;
1928 if (IVAL(req
->outbuf
, smb_rcls
) != 0) {
1929 fixup_chain_error_packet(req
);
1933 * Any of the AndX requests and replies have at least a wct of
1934 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1935 * beginning of the SMB header to the next wct field.
1937 * None of the AndX requests put anything valuable in vwv[0] and [1],
1938 * so we can overwrite it here to form the chain.
1941 if ((req
->wct
< 2) || (CVAL(req
->outbuf
, smb_wct
) < 2)) {
1942 if (req
->chain_outbuf
== NULL
) {
1943 req
->chain_outbuf
= talloc_realloc(
1944 req
, req
->outbuf
, uint8_t,
1945 smb_len(req
->outbuf
) + 4);
1946 if (req
->chain_outbuf
== NULL
) {
1947 smb_panic("talloc failed");
1955 * Here we assume that this is the end of the chain. For that we need
1956 * to set "next command" to 0xff and the offset to 0. If we later find
1957 * more commands in the chain, this will be overwritten again.
1960 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
1961 SCVAL(req
->outbuf
, smb_vwv0
+1, 0);
1962 SSVAL(req
->outbuf
, smb_vwv1
, 0);
1964 if (req
->chain_outbuf
== NULL
) {
1966 * In req->chain_outbuf we collect all the replies. Start the
1967 * chain by copying in the first reply.
1969 * We do the realloc because later on we depend on
1970 * talloc_get_size to determine the length of
1971 * chain_outbuf. The reply_xxx routines might have
1972 * over-allocated (reply_pipe_read_and_X used to be such an
1975 req
->chain_outbuf
= talloc_realloc(
1976 req
, req
->outbuf
, uint8_t, smb_len(req
->outbuf
) + 4);
1977 if (req
->chain_outbuf
== NULL
) {
1978 smb_panic("talloc failed");
1983 * Update smb headers where subsequent chained commands
1984 * may have updated them.
1986 SSVAL(req
->chain_outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
1987 SSVAL(req
->chain_outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
1989 if (!smb_splice_chain(&req
->chain_outbuf
,
1990 CVAL(req
->outbuf
, smb_com
),
1991 CVAL(req
->outbuf
, smb_wct
),
1992 (uint16_t *)(req
->outbuf
+ smb_vwv
),
1993 0, smb_buflen(req
->outbuf
),
1994 (uint8_t *)smb_buf(req
->outbuf
))) {
1997 TALLOC_FREE(req
->outbuf
);
2001 * We use the old request's vwv field to grab the next chained command
2002 * and offset into the chained fields.
2005 chain_cmd
= CVAL(req
->vwv
+0, 0);
2006 chain_offset
= SVAL(req
->vwv
+1, 0);
2008 if (chain_cmd
== 0xff) {
2010 * End of chain, no more requests from the client. So ship the
2013 smb_setlen((char *)(req
->chain_outbuf
),
2014 talloc_get_size(req
->chain_outbuf
) - 4);
2016 if (!srv_send_smb(req
->sconn
, (char *)req
->chain_outbuf
,
2017 true, req
->seqnum
+1,
2018 IS_CONN_ENCRYPTED(req
->conn
)
2021 exit_server_cleanly("chain_reply: srv_send_smb "
2024 TALLOC_FREE(req
->chain_outbuf
);
2029 /* add a new perfcounter for this element of chain */
2030 SMB_PERFCOUNT_ADD(&req
->pcd
);
2031 SMB_PERFCOUNT_SET_OP(&req
->pcd
, chain_cmd
);
2032 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, smblen
);
2035 * Check if the client tries to fool us. The chain offset
2036 * needs to point beyond the current request in the chain, it
2037 * needs to strictly grow. Otherwise we might be tricked into
2038 * an endless loop always processing the same request over and
2039 * over again. We used to assume that vwv and the byte buffer
2040 * array in a chain are always attached, but OS/2 the
2041 * Write&X/Read&X chain puts the Read&X vwv array right behind
2042 * the Write&X vwv chain. The Write&X bcc array is put behind
2043 * the Read&X vwv array. So now we check whether the chain
2044 * offset points strictly behind the previous vwv
2045 * array. req->buf points right after the vwv array of the
2046 * previous request. See
2047 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2051 already_used
= PTR_DIFF(req
->buf
, smb_base(req
->inbuf
));
2052 if (chain_offset
<= already_used
) {
2057 * Next check: Make sure the chain offset does not point beyond the
2058 * overall smb request length.
2061 length_needed
= chain_offset
+1; /* wct */
2062 if (length_needed
> smblen
) {
2067 * Now comes the pointer magic. Goal here is to set up req->vwv and
2068 * req->buf correctly again to be able to call the subsequent
2069 * switch_message(). The chain offset (the former vwv[1]) points at
2070 * the new wct field.
2073 wct
= CVAL(smb_base(req
->inbuf
), chain_offset
);
2076 * Next consistency check: Make the new vwv array fits in the overall
2080 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2081 if (length_needed
> smblen
) {
2084 vwv
= (const uint16_t *)(smb_base(req
->inbuf
) + chain_offset
+ 1);
2087 * Now grab the new byte buffer....
2090 buflen
= SVAL(vwv
+wct
, 0);
2093 * .. and check that it fits.
2096 length_needed
+= buflen
;
2097 if (length_needed
> smblen
) {
2100 buf
= (const uint8_t *)(vwv
+wct
+1);
2102 req
->cmd
= chain_cmd
;
2104 req
->vwv
= discard_const_p(uint16_t, vwv
);
2105 req
->buflen
= buflen
;
2108 switch_message(chain_cmd
, req
, smblen
);
2110 if (req
->outbuf
== NULL
) {
2112 * This happens if the chained command has suspended itself or
2113 * if it has called srv_send_smb() itself.
2119 * We end up here if the chained command was not itself chained or
2120 * suspended, but for example a close() command. We now need to splice
2121 * the chained commands' outbuf into the already built up chain_outbuf
2122 * and ship the result.
2128 * We end up here if there's any error in the chain syntax. Report a
2129 * DOS error, just like Windows does.
2131 reply_force_doserror(req
, ERRSRV
, ERRerror
);
2132 fixup_chain_error_packet(req
);
2136 * This scary statement intends to set the
2137 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2138 * to the value req->outbuf carries
2140 SSVAL(req
->chain_outbuf
, smb_flg2
,
2141 (SVAL(req
->chain_outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
2142 | (SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
2145 * Transfer the error codes from the subrequest to the main one
2147 SSVAL(req
->chain_outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
2148 SSVAL(req
->chain_outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
2150 if (!smb_splice_chain(&req
->chain_outbuf
,
2151 CVAL(req
->outbuf
, smb_com
),
2152 CVAL(req
->outbuf
, smb_wct
),
2153 (uint16_t *)(req
->outbuf
+ smb_vwv
),
2154 0, smb_buflen(req
->outbuf
),
2155 (uint8_t *)smb_buf(req
->outbuf
))) {
2156 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2158 TALLOC_FREE(req
->outbuf
);
2160 smb_setlen((char *)(req
->chain_outbuf
),
2161 talloc_get_size(req
->chain_outbuf
) - 4);
2163 show_msg((char *)(req
->chain_outbuf
));
2165 if (!srv_send_smb(req
->sconn
, (char *)req
->chain_outbuf
,
2166 true, req
->seqnum
+1,
2167 IS_CONN_ENCRYPTED(req
->conn
)||req
->encrypted
,
2169 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2171 TALLOC_FREE(req
->chain_outbuf
);
2175 /****************************************************************************
2176 Check if services need reloading.
2177 ****************************************************************************/
2179 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2182 if (last_smb_conf_reload_time
== 0) {
2183 last_smb_conf_reload_time
= t
;
2186 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2187 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
2188 last_smb_conf_reload_time
= t
;
2192 static bool fd_is_readable(int fd
)
2196 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2198 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2202 static void smbd_server_connection_write_handler(
2203 struct smbd_server_connection
*sconn
)
2205 /* TODO: make write nonblocking */
2208 static void smbd_server_connection_read_handler(
2209 struct smbd_server_connection
*sconn
, int fd
)
2211 uint8_t *inbuf
= NULL
;
2212 size_t inbuf_len
= 0;
2213 size_t unread_bytes
= 0;
2214 bool encrypted
= false;
2215 TALLOC_CTX
*mem_ctx
= talloc_tos();
2219 bool from_client
= (sconn
->sock
== fd
);
2222 smbd_lock_socket(sconn
);
2224 if (lp_async_smb_echo_handler()) {
2226 if (fd_is_readable(sconn
->smb1
.echo_handler
.trusted_fd
)) {
2228 * This is the super-ugly hack to
2229 * prefer the packets forwarded by the
2230 * echo handler over the ones by the
2233 fd
= sconn
->smb1
.echo_handler
.trusted_fd
;
2234 } else if (!fd_is_readable(fd
)) {
2235 DEBUG(10,("the echo listener was faster\n"));
2236 smbd_unlock_socket(sconn
);
2241 /* TODO: make this completely nonblocking */
2242 status
= receive_smb_talloc(mem_ctx
, sconn
, fd
,
2243 (char **)(void *)&inbuf
,
2247 &inbuf_len
, &seqnum
,
2248 false /* trusted channel */);
2249 smbd_unlock_socket(sconn
);
2251 /* TODO: make this completely nonblocking */
2252 status
= receive_smb_talloc(mem_ctx
, sconn
, fd
,
2253 (char **)(void *)&inbuf
,
2257 &inbuf_len
, &seqnum
,
2258 true /* trusted channel */);
2261 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2264 if (NT_STATUS_IS_ERR(status
)) {
2265 exit_server_cleanly("failed to receive smb request");
2267 if (!NT_STATUS_IS_OK(status
)) {
2272 process_smb(sconn
, inbuf
, inbuf_len
, unread_bytes
,
2273 seqnum
, encrypted
, NULL
);
2276 static void smbd_server_connection_handler(struct event_context
*ev
,
2277 struct fd_event
*fde
,
2281 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2282 struct smbd_server_connection
);
2284 if (flags
& EVENT_FD_WRITE
) {
2285 smbd_server_connection_write_handler(conn
);
2288 if (flags
& EVENT_FD_READ
) {
2289 smbd_server_connection_read_handler(conn
, conn
->sock
);
2294 static void smbd_server_echo_handler(struct event_context
*ev
,
2295 struct fd_event
*fde
,
2299 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2300 struct smbd_server_connection
);
2302 if (flags
& EVENT_FD_WRITE
) {
2303 smbd_server_connection_write_handler(conn
);
2306 if (flags
& EVENT_FD_READ
) {
2307 smbd_server_connection_read_handler(
2308 conn
, conn
->smb1
.echo_handler
.trusted_fd
);
2313 #ifdef CLUSTER_SUPPORT
2314 /****************************************************************************
2315 received when we should release a specific IP
2316 ****************************************************************************/
2317 static void release_ip(const char *ip
, void *priv
)
2319 const char *addr
= (const char *)priv
;
2320 const char *p
= addr
;
2322 if (strncmp("::ffff:", addr
, 7) == 0) {
2326 DEBUG(10, ("Got release IP message for %s, "
2327 "our address is %s\n", ip
, p
));
2329 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2330 /* we can't afford to do a clean exit - that involves
2331 database writes, which would potentially mean we
2332 are still running after the failover has finished -
2333 we have to get rid of this process ID straight
2335 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2337 /* note we must exit with non-zero status so the unclean handler gets
2338 called in the parent, so that the brl database is tickled */
2343 static int client_get_tcp_info(int sock
, struct sockaddr_storage
*server
,
2344 struct sockaddr_storage
*client
)
2347 length
= sizeof(*server
);
2348 if (getsockname(sock
, (struct sockaddr
*)server
, &length
) != 0) {
2351 length
= sizeof(*client
);
2352 if (getpeername(sock
, (struct sockaddr
*)client
, &length
) != 0) {
2360 * Send keepalive packets to our client
2362 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2364 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2365 private_data
, struct smbd_server_connection
);
2368 if (sconn
->using_smb2
) {
2369 /* Don't do keepalives on an SMB2 connection. */
2373 smbd_lock_socket(smbd_server_conn
);
2374 ret
= send_keepalive(sconn
->sock
);
2375 smbd_unlock_socket(smbd_server_conn
);
2378 char addr
[INET6_ADDRSTRLEN
];
2380 * Try and give an error message saying what
2383 DEBUG(0, ("send_keepalive failed for client %s. "
2384 "Error %s - exiting\n",
2385 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
2393 * Do the recurring check if we're idle
2395 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2397 struct smbd_server_connection
*sconn
=
2398 (struct smbd_server_connection
*)private_data
;
2400 if ((conn_num_open(sconn
) == 0)
2401 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2402 DEBUG( 2, ( "Closing idle connection\n" ) );
2403 messaging_send(sconn
->msg_ctx
,
2404 messaging_server_id(sconn
->msg_ctx
),
2405 MSG_SHUTDOWN
, &data_blob_null
);
2413 * Do the recurring log file and smb.conf reload checks.
2416 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2418 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2419 private_data
, struct smbd_server_connection
);
2421 DEBUG(5, ("housekeeping\n"));
2423 change_to_root_user();
2425 /* update printer queue caches if necessary */
2426 update_monitored_printq_cache(sconn
->msg_ctx
);
2428 /* check if we need to reload services */
2429 check_reload(sconn
, time_mono(NULL
));
2431 /* Change machine password if neccessary. */
2432 attempt_machine_password_change();
2435 * Force a log file check.
2437 force_check_log_size();
2443 * Read an smb packet in the echo handler child, giving the parent
2444 * smbd one second to react once the socket becomes readable.
2447 struct smbd_echo_read_state
{
2448 struct tevent_context
*ev
;
2449 struct smbd_server_connection
*sconn
;
2456 static void smbd_echo_read_readable(struct tevent_req
*subreq
);
2457 static void smbd_echo_read_waited(struct tevent_req
*subreq
);
2459 static struct tevent_req
*smbd_echo_read_send(
2460 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2461 struct smbd_server_connection
*sconn
)
2463 struct tevent_req
*req
, *subreq
;
2464 struct smbd_echo_read_state
*state
;
2466 req
= tevent_req_create(mem_ctx
, &state
,
2467 struct smbd_echo_read_state
);
2472 state
->sconn
= sconn
;
2474 subreq
= wait_for_read_send(state
, ev
, sconn
->sock
);
2475 if (tevent_req_nomem(subreq
, req
)) {
2476 return tevent_req_post(req
, ev
);
2478 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2482 static void smbd_echo_read_readable(struct tevent_req
*subreq
)
2484 struct tevent_req
*req
= tevent_req_callback_data(
2485 subreq
, struct tevent_req
);
2486 struct smbd_echo_read_state
*state
= tevent_req_data(
2487 req
, struct smbd_echo_read_state
);
2491 ok
= wait_for_read_recv(subreq
, &err
);
2492 TALLOC_FREE(subreq
);
2494 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
2499 * Give the parent smbd one second to step in
2502 subreq
= tevent_wakeup_send(
2503 state
, state
->ev
, timeval_current_ofs(1, 0));
2504 if (tevent_req_nomem(subreq
, req
)) {
2507 tevent_req_set_callback(subreq
, smbd_echo_read_waited
, req
);
2510 static void smbd_echo_read_waited(struct tevent_req
*subreq
)
2512 struct tevent_req
*req
= tevent_req_callback_data(
2513 subreq
, struct tevent_req
);
2514 struct smbd_echo_read_state
*state
= tevent_req_data(
2515 req
, struct smbd_echo_read_state
);
2516 struct smbd_server_connection
*sconn
= state
->sconn
;
2522 ok
= tevent_wakeup_recv(subreq
);
2523 TALLOC_FREE(subreq
);
2525 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2529 ok
= smbd_lock_socket_internal(sconn
);
2531 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2532 DEBUG(0, ("%s: failed to lock socket\n", __location__
));
2536 if (!fd_is_readable(sconn
->sock
)) {
2537 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2538 (int)sys_getpid()));
2540 ok
= smbd_unlock_socket_internal(sconn
);
2542 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2543 DEBUG(1, ("%s: failed to unlock socket\n",
2548 subreq
= wait_for_read_send(state
, state
->ev
, sconn
->sock
);
2549 if (tevent_req_nomem(subreq
, req
)) {
2552 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2556 status
= receive_smb_talloc(state
, sconn
, sconn
->sock
, &state
->buf
,
2562 false /* trusted_channel*/);
2564 if (tevent_req_nterror(req
, status
)) {
2565 tevent_req_nterror(req
, status
);
2566 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2567 (int)sys_getpid(), nt_errstr(status
)));
2571 ok
= smbd_unlock_socket_internal(sconn
);
2573 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2574 DEBUG(1, ("%s: failed to unlock socket\n", __location__
));
2577 tevent_req_done(req
);
2580 static NTSTATUS
smbd_echo_read_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2581 char **pbuf
, size_t *pbuflen
, uint32_t *pseqnum
)
2583 struct smbd_echo_read_state
*state
= tevent_req_data(
2584 req
, struct smbd_echo_read_state
);
2587 if (tevent_req_is_nterror(req
, &status
)) {
2590 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
2591 *pbuflen
= state
->buflen
;
2592 *pseqnum
= state
->seqnum
;
2593 return NT_STATUS_OK
;
2596 struct smbd_echo_state
{
2597 struct tevent_context
*ev
;
2598 struct iovec
*pending
;
2599 struct smbd_server_connection
*sconn
;
2602 struct tevent_fd
*parent_fde
;
2604 struct tevent_req
*write_req
;
2607 static void smbd_echo_writer_done(struct tevent_req
*req
);
2609 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2613 if (state
->write_req
!= NULL
) {
2617 num_pending
= talloc_array_length(state
->pending
);
2618 if (num_pending
== 0) {
2622 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
2623 state
->parent_pipe
, false,
2624 state
->pending
, num_pending
);
2625 if (state
->write_req
== NULL
) {
2626 DEBUG(1, ("writev_send failed\n"));
2630 talloc_steal(state
->write_req
, state
->pending
);
2631 state
->pending
= NULL
;
2633 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
2637 static void smbd_echo_writer_done(struct tevent_req
*req
)
2639 struct smbd_echo_state
*state
= tevent_req_callback_data(
2640 req
, struct smbd_echo_state
);
2644 written
= writev_recv(req
, &err
);
2646 state
->write_req
= NULL
;
2647 if (written
== -1) {
2648 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
2651 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2652 smbd_echo_activate_writer(state
);
2655 static bool smbd_echo_reply(uint8_t *inbuf
, size_t inbuf_len
,
2658 struct smb_request req
;
2659 uint16_t num_replies
;
2664 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == NBSSkeepalive
)) {
2665 DEBUG(10, ("Got netbios keepalive\n"));
2672 if (inbuf_len
< smb_size
) {
2673 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
2676 if (!valid_smb_header(smbd_server_conn
, inbuf
)) {
2677 DEBUG(10, ("Got invalid SMB header\n"));
2681 if (!init_smb_request(&req
, smbd_server_conn
, inbuf
, 0, false,
2687 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
2688 smb_messages
[req
.cmd
].name
2689 ? smb_messages
[req
.cmd
].name
: "unknown"));
2691 if (req
.cmd
!= SMBecho
) {
2698 num_replies
= SVAL(req
.vwv
+0, 0);
2699 if (num_replies
!= 1) {
2700 /* Not a Windows "Hey, you're still there?" request */
2704 if (!create_outbuf(talloc_tos(), &req
, (const char *)req
.inbuf
, &outbuf
,
2706 DEBUG(10, ("create_outbuf failed\n"));
2709 req
.outbuf
= (uint8_t *)outbuf
;
2711 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
2713 if (req
.buflen
> 0) {
2714 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
2717 out_len
= smb_len(req
.outbuf
) + 4;
2719 ok
= srv_send_smb(req
.sconn
,
2723 TALLOC_FREE(outbuf
);
2731 static void smbd_echo_exit(struct tevent_context
*ev
,
2732 struct tevent_fd
*fde
, uint16_t flags
,
2735 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2739 static void smbd_echo_got_packet(struct tevent_req
*req
);
2741 static void smbd_echo_loop(struct smbd_server_connection
*sconn
,
2744 struct smbd_echo_state
*state
;
2745 struct tevent_req
*read_req
;
2747 state
= talloc_zero(sconn
, struct smbd_echo_state
);
2748 if (state
== NULL
) {
2749 DEBUG(1, ("talloc failed\n"));
2752 state
->sconn
= sconn
;
2753 state
->parent_pipe
= parent_pipe
;
2754 state
->ev
= s3_tevent_context_init(state
);
2755 if (state
->ev
== NULL
) {
2756 DEBUG(1, ("tevent_context_init failed\n"));
2760 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
2761 TEVENT_FD_READ
, smbd_echo_exit
,
2763 if (state
->parent_fde
== NULL
) {
2764 DEBUG(1, ("tevent_add_fd failed\n"));
2769 read_req
= smbd_echo_read_send(state
, state
->ev
, sconn
);
2770 if (read_req
== NULL
) {
2771 DEBUG(1, ("smbd_echo_read_send failed\n"));
2775 tevent_req_set_callback(read_req
, smbd_echo_got_packet
, state
);
2778 if (tevent_loop_once(state
->ev
) == -1) {
2779 DEBUG(1, ("tevent_loop_once failed: %s\n",
2787 static void smbd_echo_got_packet(struct tevent_req
*req
)
2789 struct smbd_echo_state
*state
= tevent_req_callback_data(
2790 req
, struct smbd_echo_state
);
2794 uint32_t seqnum
= 0;
2797 status
= smbd_echo_read_recv(req
, state
, &buf
, &buflen
, &seqnum
);
2799 if (!NT_STATUS_IS_OK(status
)) {
2800 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2801 nt_errstr(status
)));
2805 reply
= smbd_echo_reply((uint8_t *)buf
, buflen
, seqnum
);
2811 num_pending
= talloc_array_length(state
->pending
);
2812 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
2815 DEBUG(1, ("talloc_realloc failed\n"));
2818 state
->pending
= tmp
;
2820 if (buflen
>= smb_size
) {
2822 * place the seqnum in the packet so that the main process
2823 * can reply with signing
2825 SIVAL(buf
, smb_ss_field
, seqnum
);
2826 SIVAL(buf
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
2829 iov
= &state
->pending
[num_pending
];
2830 iov
->iov_base
= buf
;
2831 iov
->iov_len
= buflen
;
2833 DEBUG(10,("echo_handler[%d]: forward to main\n",
2834 (int)sys_getpid()));
2835 smbd_echo_activate_writer(state
);
2838 req
= smbd_echo_read_send(state
, state
->ev
, state
->sconn
);
2840 DEBUG(1, ("smbd_echo_read_send failed\n"));
2843 tevent_req_set_callback(req
, smbd_echo_got_packet
, state
);
2848 * Handle SMBecho requests in a forked child process
2850 bool fork_echo_handler(struct smbd_server_connection
*sconn
)
2852 int listener_pipe
[2];
2856 res
= pipe(listener_pipe
);
2858 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
2861 sconn
->smb1
.echo_handler
.socket_lock_fd
= create_unlink_tmp(lp_lockdir());
2862 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
2863 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno
)));
2871 close(listener_pipe
[0]);
2872 set_blocking(listener_pipe
[1], false);
2874 status
= reinit_after_fork(sconn
->msg_ctx
,
2875 server_event_context(),
2876 procid_self(), false);
2877 if (!NT_STATUS_IS_OK(status
)) {
2878 DEBUG(1, ("reinit_after_fork failed: %s\n",
2879 nt_errstr(status
)));
2882 smbd_echo_loop(sconn
, listener_pipe
[1]);
2885 close(listener_pipe
[1]);
2886 listener_pipe
[1] = -1;
2887 sconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
2889 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child
));
2892 * Without smb signing this is the same as the normal smbd
2893 * listener. This needs to change once signing comes in.
2895 sconn
->smb1
.echo_handler
.trusted_fde
= event_add_fd(server_event_context(),
2897 sconn
->smb1
.echo_handler
.trusted_fd
,
2899 smbd_server_echo_handler
,
2901 if (sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
2902 DEBUG(1, ("event_add_fd failed\n"));
2909 if (listener_pipe
[0] != -1) {
2910 close(listener_pipe
[0]);
2912 if (listener_pipe
[1] != -1) {
2913 close(listener_pipe
[1]);
2915 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2916 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
2917 close(sconn
->smb1
.echo_handler
.socket_lock_fd
);
2919 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2920 sconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
2926 static NTSTATUS
smbd_register_ips(struct smbd_server_connection
*sconn
,
2927 struct sockaddr_storage
*srv
,
2928 struct sockaddr_storage
*clnt
)
2930 struct ctdbd_connection
*cconn
;
2931 char tmp_addr
[INET6_ADDRSTRLEN
];
2934 cconn
= messaging_ctdbd_connection();
2935 if (cconn
== NULL
) {
2936 return NT_STATUS_NO_MEMORY
;
2939 client_socket_addr(sconn
->sock
, tmp_addr
, sizeof(tmp_addr
));
2940 addr
= talloc_strdup(cconn
, tmp_addr
);
2942 return NT_STATUS_NO_MEMORY
;
2944 return ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, addr
);
2949 /****************************************************************************
2950 Process commands from the client
2951 ****************************************************************************/
2953 void smbd_process(struct tevent_context
*ev_ctx
,
2954 struct smbd_server_connection
*sconn
)
2956 TALLOC_CTX
*frame
= talloc_stackframe();
2957 struct sockaddr_storage ss
;
2958 struct sockaddr
*sa
= NULL
;
2959 socklen_t sa_socklen
;
2960 struct tsocket_address
*local_address
= NULL
;
2961 struct tsocket_address
*remote_address
= NULL
;
2962 const char *remaddr
= NULL
;
2966 if (lp_maxprotocol() >= PROTOCOL_SMB2_02
) {
2968 * We're not making the decision here,
2969 * we're just allowing the client
2970 * to decide between SMB1 and SMB2
2971 * with the first negprot
2974 sconn
->using_smb2
= true;
2977 /* Ensure child is set to blocking mode */
2978 set_blocking(sconn
->sock
,True
);
2980 set_socket_options(sconn
->sock
, "SO_KEEPALIVE");
2981 set_socket_options(sconn
->sock
, lp_socket_options());
2983 sa
= (struct sockaddr
*)(void *)&ss
;
2984 sa_socklen
= sizeof(ss
);
2985 ret
= getpeername(sconn
->sock
, sa
, &sa_socklen
);
2987 int level
= (errno
== ENOTCONN
)?2:0;
2988 DEBUG(level
,("getpeername() failed - %s\n", strerror(errno
)));
2989 exit_server_cleanly("getpeername() failed.\n");
2991 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
2995 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2996 __location__
, strerror(errno
)));
2997 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3000 sa
= (struct sockaddr
*)(void *)&ss
;
3001 sa_socklen
= sizeof(ss
);
3002 ret
= getsockname(sconn
->sock
, sa
, &sa_socklen
);
3004 int level
= (errno
== ENOTCONN
)?2:0;
3005 DEBUG(level
,("getsockname() failed - %s\n", strerror(errno
)));
3006 exit_server_cleanly("getsockname() failed.\n");
3008 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3012 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3013 __location__
, strerror(errno
)));
3014 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3017 sconn
->local_address
= local_address
;
3018 sconn
->remote_address
= remote_address
;
3020 if (tsocket_address_is_inet(remote_address
, "ip")) {
3021 remaddr
= tsocket_address_inet_addr_string(
3022 sconn
->remote_address
,
3024 if (remaddr
== NULL
) {
3025 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3026 __location__
, strerror(errno
)));
3027 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3030 remaddr
= "0.0.0.0";
3033 /* this is needed so that we get decent entries
3034 in smbstatus for port 445 connects */
3035 set_remote_machine_name(remaddr
, false);
3036 reload_services(sconn
->msg_ctx
, sconn
->sock
, true);
3039 * Before the first packet, check the global hosts allow/ hosts deny
3040 * parameters before doing any parsing of packets passed to us by the
3041 * client. This prevents attacks on our parsing code from hosts not in
3042 * the hosts allow list.
3045 ret
= get_remote_hostname(remote_address
,
3049 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3050 __location__
, strerror(errno
)));
3051 exit_server_cleanly("get_remote_hostname failed.\n");
3053 if (strequal(rhost
, "UNKNOWN")) {
3054 rhost
= talloc_strdup(talloc_tos(), remaddr
);
3056 sconn
->remote_hostname
= talloc_move(sconn
, &rhost
);
3058 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3059 sconn
->remote_hostname
,
3062 * send a negative session response "not listening on calling
3065 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3066 DEBUG( 1, ("Connection denied from %s to %s\n",
3067 tsocket_address_string(remote_address
, talloc_tos()),
3068 tsocket_address_string(local_address
, talloc_tos())));
3069 (void)srv_send_smb(sconn
,(char *)buf
, false,
3071 exit_server_cleanly("connection denied");
3074 DEBUG(10, ("Connection allowed from %s to %s\n",
3075 tsocket_address_string(remote_address
, talloc_tos()),
3076 tsocket_address_string(local_address
, talloc_tos())));
3080 smb_perfcount_init();
3082 if (!init_account_policy()) {
3083 exit_server("Could not open account policy tdb.\n");
3086 if (*lp_rootdir()) {
3087 if (chroot(lp_rootdir()) != 0) {
3088 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3089 exit_server("Failed to chroot()");
3091 if (chdir("/") == -1) {
3092 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3093 exit_server("Failed to chroot()");
3095 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3098 if (!srv_init_signing(sconn
)) {
3099 exit_server("Failed to init smb_signing");
3103 if (!init_oplocks(sconn
->msg_ctx
))
3104 exit_server("Failed to init oplocks");
3106 /* register our message handlers */
3107 messaging_register(sconn
->msg_ctx
, NULL
,
3108 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3109 messaging_register(sconn
->msg_ctx
, NULL
,
3110 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3113 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3114 * MSGs to all child processes
3116 messaging_deregister(sconn
->msg_ctx
,
3118 messaging_register(sconn
->msg_ctx
, NULL
,
3119 MSG_DEBUG
, debug_message
);
3121 if ((lp_keepalive() != 0)
3122 && !(event_add_idle(ev_ctx
, NULL
,
3123 timeval_set(lp_keepalive(), 0),
3124 "keepalive", keepalive_fn
,
3126 DEBUG(0, ("Could not add keepalive event\n"));
3130 if (!(event_add_idle(ev_ctx
, NULL
,
3131 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3132 "deadtime", deadtime_fn
, sconn
))) {
3133 DEBUG(0, ("Could not add deadtime event\n"));
3137 if (!(event_add_idle(ev_ctx
, NULL
,
3138 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
3139 "housekeeping", housekeeping_fn
, sconn
))) {
3140 DEBUG(0, ("Could not add housekeeping event\n"));
3144 #ifdef CLUSTER_SUPPORT
3146 if (lp_clustering()) {
3148 * We need to tell ctdb about our client's TCP
3149 * connection, so that for failover ctdbd can send
3150 * tickle acks, triggering a reconnection by the
3154 struct sockaddr_storage srv
, clnt
;
3156 if (client_get_tcp_info(sconn
->sock
, &srv
, &clnt
) == 0) {
3158 status
= smbd_register_ips(sconn
, &srv
, &clnt
);
3159 if (!NT_STATUS_IS_OK(status
)) {
3160 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3161 nt_errstr(status
)));
3165 DEBUG(0,("Unable to get tcp info for "
3166 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3173 sconn
->nbt
.got_session
= false;
3175 sconn
->smb1
.negprot
.max_recv
= MIN(lp_maxxmit(),BUFFER_SIZE
);
3177 sconn
->smb1
.sessions
.done_sesssetup
= false;
3178 sconn
->smb1
.sessions
.max_send
= BUFFER_SIZE
;
3179 sconn
->smb1
.sessions
.last_session_tag
= UID_FIELD_INVALID
;
3180 /* users from session setup */
3181 sconn
->smb1
.sessions
.session_userlist
= NULL
;
3182 /* workgroup from session setup. */
3183 sconn
->smb1
.sessions
.session_workgroup
= NULL
;
3184 /* this holds info on user ids that are already validated for this VC */
3185 sconn
->smb1
.sessions
.validated_users
= NULL
;
3186 sconn
->smb1
.sessions
.next_vuid
= VUID_OFFSET
;
3187 sconn
->smb1
.sessions
.num_validated_vuids
= 0;
3190 if (!init_dptrs(sconn
)) {
3191 exit_server("init_dptrs() failed");
3194 sconn
->smb1
.fde
= event_add_fd(ev_ctx
,
3198 smbd_server_connection_handler
,
3200 if (!sconn
->smb1
.fde
) {
3201 exit_server("failed to create smbd_server_connection fde");
3209 frame
= talloc_stackframe_pool(8192);
3213 status
= smbd_server_connection_loop_once(ev_ctx
, sconn
);
3214 if (!NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
) &&
3215 !NT_STATUS_IS_OK(status
)) {
3216 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3217 " exiting\n", nt_errstr(status
)));
3224 exit_server_cleanly(NULL
);
3227 bool req_is_in_chain(struct smb_request
*req
)
3229 if (req
->vwv
!= (const uint16_t *)(req
->inbuf
+smb_vwv
)) {
3231 * We're right now handling a subsequent request, so we must
3237 if (!is_andx_req(req
->cmd
)) {
3243 * Okay, an illegal request, but definitely not chained :-)
3248 return (CVAL(req
->vwv
+0, 0) != 0xFF);