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(NT_STATUS_EQUAL(status
, NT_STATUS_END_OF_FILE
)?5:1,
460 ("receive_smb_raw_talloc failed for client %s "
461 "read error = %s.\n",
462 tsocket_address_string(sconn
->remote_address
,
464 nt_errstr(status
)) );
468 if (is_encrypted_packet(sconn
, (uint8_t *)*buffer
)) {
469 status
= srv_decrypt_buffer(sconn
, *buffer
);
470 if (!NT_STATUS_IS_OK(status
)) {
471 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
472 "incoming packet! Error %s\n",
473 nt_errstr(status
) ));
479 /* Check the incoming SMB signature. */
480 if (!srv_check_sign_mac(sconn
, *buffer
, seqnum
, trusted_channel
)) {
481 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
482 "incoming packet!\n"));
483 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
491 * Initialize a struct smb_request from an inbuf
494 static bool init_smb_request(struct smb_request
*req
,
495 struct smbd_server_connection
*sconn
,
497 size_t unread_bytes
, bool encrypted
,
500 size_t req_size
= smb_len(inbuf
) + 4;
501 /* Ensure we have at least smb_size bytes. */
502 if (req_size
< smb_size
) {
503 DEBUG(0,("init_smb_request: invalid request size %u\n",
504 (unsigned int)req_size
));
507 req
->cmd
= CVAL(inbuf
, smb_com
);
508 req
->flags2
= SVAL(inbuf
, smb_flg2
);
509 req
->smbpid
= SVAL(inbuf
, smb_pid
);
510 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
511 req
->seqnum
= seqnum
;
512 req
->vuid
= SVAL(inbuf
, smb_uid
);
513 req
->tid
= SVAL(inbuf
, smb_tid
);
514 req
->wct
= CVAL(inbuf
, smb_wct
);
515 req
->vwv
= discard_const_p(uint16_t, (inbuf
+smb_vwv
));
516 req
->buflen
= smb_buflen(inbuf
);
517 req
->buf
= (const uint8_t *)smb_buf_const(inbuf
);
518 req
->unread_bytes
= unread_bytes
;
519 req
->encrypted
= encrypted
;
521 req
->conn
= conn_find(sconn
,req
->tid
);
522 req
->chain_fsp
= NULL
;
523 req
->chain_outbuf
= NULL
;
526 smb_init_perfcount_data(&req
->pcd
);
528 /* Ensure we have at least wct words and 2 bytes of bcc. */
529 if (smb_size
+ req
->wct
*2 > req_size
) {
530 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
531 (unsigned int)req
->wct
,
532 (unsigned int)req_size
));
535 /* Ensure bcc is correct. */
536 if (((const uint8_t *)smb_buf_const(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
537 DEBUG(0,("init_smb_request: invalid bcc number %u "
538 "(wct = %u, size %u)\n",
539 (unsigned int)req
->buflen
,
540 (unsigned int)req
->wct
,
541 (unsigned int)req_size
));
549 static void process_smb(struct smbd_server_connection
*conn
,
550 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
551 uint32_t seqnum
, bool encrypted
,
552 struct smb_perfcount_data
*deferred_pcd
);
554 static void smbd_deferred_open_timer(struct event_context
*ev
,
555 struct timed_event
*te
,
556 struct timeval _tval
,
559 struct pending_message_list
*msg
= talloc_get_type(private_data
,
560 struct pending_message_list
);
561 TALLOC_CTX
*mem_ctx
= talloc_tos();
562 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
565 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
568 exit_server("smbd_deferred_open_timer: talloc failed\n");
572 /* We leave this message on the queue so the open code can
573 know this is a retry. */
574 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
575 (unsigned long long)mid
));
577 /* Mark the message as processed so this is not
578 * re-processed in error. */
579 msg
->processed
= true;
581 process_smb(smbd_server_conn
, inbuf
,
583 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
585 /* If it's still there and was processed, remove it. */
586 msg
= get_deferred_open_message_smb(smbd_server_conn
, mid
);
587 if (msg
&& msg
->processed
) {
588 remove_deferred_open_message_smb(smbd_server_conn
, mid
);
592 /****************************************************************************
593 Function to push a message onto the tail of a linked list of smb messages ready
595 ****************************************************************************/
597 static bool push_queued_message(struct smb_request
*req
,
598 struct timeval request_time
,
599 struct timeval end_time
,
600 char *private_data
, size_t private_len
)
602 int msg_len
= smb_len(req
->inbuf
) + 4;
603 struct pending_message_list
*msg
;
605 msg
= talloc_zero(NULL
, struct pending_message_list
);
608 DEBUG(0,("push_message: malloc fail (1)\n"));
612 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
613 if(msg
->buf
.data
== NULL
) {
614 DEBUG(0,("push_message: malloc fail (2)\n"));
619 msg
->request_time
= request_time
;
620 msg
->seqnum
= req
->seqnum
;
621 msg
->encrypted
= req
->encrypted
;
622 msg
->processed
= false;
623 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
626 msg
->private_data
= data_blob_talloc(msg
, private_data
,
628 if (msg
->private_data
.data
== NULL
) {
629 DEBUG(0,("push_message: malloc fail (3)\n"));
635 msg
->te
= event_add_timed(server_event_context(),
638 smbd_deferred_open_timer
,
641 DEBUG(0,("push_message: event_add_timed failed\n"));
646 DLIST_ADD_END(req
->sconn
->deferred_open_queue
, msg
,
647 struct pending_message_list
*);
649 DEBUG(10,("push_message: pushed message length %u on "
650 "deferred_open_queue\n", (unsigned int)msg_len
));
655 /****************************************************************************
656 Function to delete a sharing violation open message by mid.
657 ****************************************************************************/
659 void remove_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
662 struct pending_message_list
*pml
;
664 if (sconn
->using_smb2
) {
665 remove_deferred_open_message_smb2(sconn
, mid
);
669 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
670 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
671 DEBUG(10,("remove_deferred_open_message_smb: "
672 "deleting mid %llu len %u\n",
673 (unsigned long long)mid
,
674 (unsigned int)pml
->buf
.length
));
675 DLIST_REMOVE(sconn
->deferred_open_queue
, pml
);
682 /****************************************************************************
683 Move a sharing violation open retry message to the front of the list and
684 schedule it for immediate processing.
685 ****************************************************************************/
687 void schedule_deferred_open_message_smb(struct smbd_server_connection
*sconn
,
690 struct pending_message_list
*pml
;
693 if (sconn
->using_smb2
) {
694 schedule_deferred_open_message_smb2(sconn
, mid
);
698 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
699 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
701 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
704 (unsigned long long)msg_mid
));
706 if (mid
== msg_mid
) {
707 struct timed_event
*te
;
709 if (pml
->processed
) {
710 /* A processed message should not be
712 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
713 "message mid %llu was already processed\n",
714 (unsigned long long)msg_mid
));
718 DEBUG(10,("schedule_deferred_open_message_smb: "
719 "scheduling mid %llu\n",
720 (unsigned long long)mid
));
722 te
= event_add_timed(server_event_context(),
725 smbd_deferred_open_timer
,
728 DEBUG(10,("schedule_deferred_open_message_smb: "
729 "event_add_timed() failed, "
730 "skipping mid %llu\n",
731 (unsigned long long)msg_mid
));
734 TALLOC_FREE(pml
->te
);
736 DLIST_PROMOTE(sconn
->deferred_open_queue
, pml
);
741 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
742 "find message mid %llu\n",
743 (unsigned long long)mid
));
746 /****************************************************************************
747 Return true if this mid is on the deferred queue and was not yet processed.
748 ****************************************************************************/
750 bool open_was_deferred(struct smbd_server_connection
*sconn
, uint64_t mid
)
752 struct pending_message_list
*pml
;
754 if (sconn
->using_smb2
) {
755 return open_was_deferred_smb2(sconn
, mid
);
758 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
759 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
766 /****************************************************************************
767 Return the message queued by this mid.
768 ****************************************************************************/
770 static struct pending_message_list
*get_deferred_open_message_smb(
771 struct smbd_server_connection
*sconn
, uint64_t mid
)
773 struct pending_message_list
*pml
;
775 for (pml
= sconn
->deferred_open_queue
; pml
; pml
= pml
->next
) {
776 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
783 /****************************************************************************
784 Get the state data queued by this mid.
785 ****************************************************************************/
787 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
788 struct timeval
*p_request_time
,
791 struct pending_message_list
*pml
;
793 if (smbd_server_conn
->using_smb2
) {
794 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
799 pml
= get_deferred_open_message_smb(smbreq
->sconn
, smbreq
->mid
);
803 if (p_request_time
) {
804 *p_request_time
= pml
->request_time
;
807 *pp_state
= (void *)pml
->private_data
.data
;
812 /****************************************************************************
813 Function to push a deferred open smb message onto a linked list of local smb
814 messages ready for processing.
815 ****************************************************************************/
817 bool push_deferred_open_message_smb(struct smb_request
*req
,
818 struct timeval request_time
,
819 struct timeval timeout
,
821 char *private_data
, size_t priv_len
)
823 struct timeval end_time
;
826 return push_deferred_open_message_smb2(req
->smb2req
,
834 if (req
->unread_bytes
) {
835 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
836 "unread_bytes = %u\n",
837 (unsigned int)req
->unread_bytes
));
838 smb_panic("push_deferred_open_message_smb: "
839 "logic error unread_bytes != 0" );
842 end_time
= timeval_sum(&request_time
, &timeout
);
844 DEBUG(10,("push_deferred_open_message_smb: pushing message "
845 "len %u mid %llu timeout time [%u.%06u]\n",
846 (unsigned int) smb_len(req
->inbuf
)+4,
847 (unsigned long long)req
->mid
,
848 (unsigned int)end_time
.tv_sec
,
849 (unsigned int)end_time
.tv_usec
));
851 return push_queued_message(req
, request_time
, end_time
,
852 private_data
, priv_len
);
855 static void smbd_sig_term_handler(struct tevent_context
*ev
,
856 struct tevent_signal
*se
,
862 exit_server_cleanly("termination signal");
865 void smbd_setup_sig_term_handler(void)
867 struct tevent_signal
*se
;
869 se
= tevent_add_signal(server_event_context(),
870 server_event_context(),
872 smbd_sig_term_handler
,
875 exit_server("failed to setup SIGTERM handler");
879 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
880 struct tevent_signal
*se
,
886 struct messaging_context
*msg_ctx
= talloc_get_type_abort(
887 private_data
, struct messaging_context
);
888 change_to_root_user();
889 DEBUG(1,("Reloading services after SIGHUP\n"));
890 reload_services(msg_ctx
, smbd_server_conn
->sock
, False
);
892 printing_subsystem_update(ev
, msg_ctx
, true);
896 void smbd_setup_sig_hup_handler(struct tevent_context
*ev
,
897 struct messaging_context
*msg_ctx
)
899 struct tevent_signal
*se
;
901 se
= tevent_add_signal(ev
, ev
, SIGHUP
, 0, smbd_sig_hup_handler
,
904 exit_server("failed to setup SIGHUP handler");
908 static NTSTATUS
smbd_server_connection_loop_once(struct tevent_context
*ev_ctx
,
909 struct smbd_server_connection
*conn
)
916 timeout
= SMBD_SELECT_TIMEOUT
* 1000;
919 * Are there any timed events waiting ? If so, ensure we don't
920 * select for longer than it would take to wait for them.
923 event_add_to_poll_args(ev_ctx
, conn
, &conn
->pfds
, &num_pfds
, &timeout
);
925 /* Process a signal and timed events now... */
926 if (run_events_poll(ev_ctx
, 0, NULL
, 0)) {
927 return NT_STATUS_RETRY
;
932 START_PROFILE(smbd_idle
);
934 ret
= sys_poll(conn
->pfds
, num_pfds
, timeout
);
937 END_PROFILE(smbd_idle
);
942 if (errno
== EINTR
) {
943 return NT_STATUS_RETRY
;
945 return map_nt_error_from_unix(errno
);
948 retry
= run_events_poll(ev_ctx
, ret
, conn
->pfds
, num_pfds
);
950 return NT_STATUS_RETRY
;
953 /* Did we timeout ? */
955 return NT_STATUS_RETRY
;
958 /* should not be reached */
959 return NT_STATUS_INTERNAL_ERROR
;
963 * Only allow 5 outstanding trans requests. We're allocating memory, so
967 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
970 for (; list
!= NULL
; list
= list
->next
) {
972 if (list
->mid
== mid
) {
973 return NT_STATUS_INVALID_PARAMETER
;
979 return NT_STATUS_INSUFFICIENT_RESOURCES
;
986 These flags determine some of the permissions required to do an operation
988 Note that I don't set NEED_WRITE on some write operations because they
989 are used by some brain-dead clients when printing, and I don't want to
990 force write permissions on print services.
992 #define AS_USER (1<<0)
993 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
994 #define TIME_INIT (1<<2)
995 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
996 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
997 #define DO_CHDIR (1<<6)
1000 define a list of possible SMB messages and their corresponding
1001 functions. Any message that has a NULL function is unimplemented -
1002 please feel free to contribute implementations!
1004 static const struct smb_message_struct
{
1006 void (*fn
)(struct smb_request
*req
);
1008 } smb_messages
[256] = {
1010 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1011 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1012 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1013 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1014 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1015 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1016 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1017 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1018 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1019 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1020 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1021 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1022 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1023 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1024 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1025 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1026 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1027 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1028 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1029 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1030 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1031 /* 0x15 */ { NULL
, NULL
, 0 },
1032 /* 0x16 */ { NULL
, NULL
, 0 },
1033 /* 0x17 */ { NULL
, NULL
, 0 },
1034 /* 0x18 */ { NULL
, NULL
, 0 },
1035 /* 0x19 */ { NULL
, NULL
, 0 },
1036 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1037 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1038 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1039 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1040 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1041 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1042 /* 0x20 */ { "SMBwritec", NULL
,0},
1043 /* 0x21 */ { NULL
, NULL
, 0 },
1044 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1045 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1046 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1047 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1048 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1049 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1050 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1051 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1052 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1053 /* 0x2b */ { "SMBecho",reply_echo
,0},
1054 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1055 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1056 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1057 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1058 /* 0x30 */ { NULL
, NULL
, 0 },
1059 /* 0x31 */ { NULL
, NULL
, 0 },
1060 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1061 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1062 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1063 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1064 /* 0x36 */ { NULL
, NULL
, 0 },
1065 /* 0x37 */ { NULL
, NULL
, 0 },
1066 /* 0x38 */ { NULL
, NULL
, 0 },
1067 /* 0x39 */ { NULL
, NULL
, 0 },
1068 /* 0x3a */ { NULL
, NULL
, 0 },
1069 /* 0x3b */ { NULL
, NULL
, 0 },
1070 /* 0x3c */ { NULL
, NULL
, 0 },
1071 /* 0x3d */ { NULL
, NULL
, 0 },
1072 /* 0x3e */ { NULL
, NULL
, 0 },
1073 /* 0x3f */ { NULL
, NULL
, 0 },
1074 /* 0x40 */ { NULL
, NULL
, 0 },
1075 /* 0x41 */ { NULL
, NULL
, 0 },
1076 /* 0x42 */ { NULL
, NULL
, 0 },
1077 /* 0x43 */ { NULL
, NULL
, 0 },
1078 /* 0x44 */ { NULL
, NULL
, 0 },
1079 /* 0x45 */ { NULL
, NULL
, 0 },
1080 /* 0x46 */ { NULL
, NULL
, 0 },
1081 /* 0x47 */ { NULL
, NULL
, 0 },
1082 /* 0x48 */ { NULL
, NULL
, 0 },
1083 /* 0x49 */ { NULL
, NULL
, 0 },
1084 /* 0x4a */ { NULL
, NULL
, 0 },
1085 /* 0x4b */ { NULL
, NULL
, 0 },
1086 /* 0x4c */ { NULL
, NULL
, 0 },
1087 /* 0x4d */ { NULL
, NULL
, 0 },
1088 /* 0x4e */ { NULL
, NULL
, 0 },
1089 /* 0x4f */ { NULL
, NULL
, 0 },
1090 /* 0x50 */ { NULL
, NULL
, 0 },
1091 /* 0x51 */ { NULL
, NULL
, 0 },
1092 /* 0x52 */ { NULL
, NULL
, 0 },
1093 /* 0x53 */ { NULL
, NULL
, 0 },
1094 /* 0x54 */ { NULL
, NULL
, 0 },
1095 /* 0x55 */ { NULL
, NULL
, 0 },
1096 /* 0x56 */ { NULL
, NULL
, 0 },
1097 /* 0x57 */ { NULL
, NULL
, 0 },
1098 /* 0x58 */ { NULL
, NULL
, 0 },
1099 /* 0x59 */ { NULL
, NULL
, 0 },
1100 /* 0x5a */ { NULL
, NULL
, 0 },
1101 /* 0x5b */ { NULL
, NULL
, 0 },
1102 /* 0x5c */ { NULL
, NULL
, 0 },
1103 /* 0x5d */ { NULL
, NULL
, 0 },
1104 /* 0x5e */ { NULL
, NULL
, 0 },
1105 /* 0x5f */ { NULL
, NULL
, 0 },
1106 /* 0x60 */ { NULL
, NULL
, 0 },
1107 /* 0x61 */ { NULL
, NULL
, 0 },
1108 /* 0x62 */ { NULL
, NULL
, 0 },
1109 /* 0x63 */ { NULL
, NULL
, 0 },
1110 /* 0x64 */ { NULL
, NULL
, 0 },
1111 /* 0x65 */ { NULL
, NULL
, 0 },
1112 /* 0x66 */ { NULL
, NULL
, 0 },
1113 /* 0x67 */ { NULL
, NULL
, 0 },
1114 /* 0x68 */ { NULL
, NULL
, 0 },
1115 /* 0x69 */ { NULL
, NULL
, 0 },
1116 /* 0x6a */ { NULL
, NULL
, 0 },
1117 /* 0x6b */ { NULL
, NULL
, 0 },
1118 /* 0x6c */ { NULL
, NULL
, 0 },
1119 /* 0x6d */ { NULL
, NULL
, 0 },
1120 /* 0x6e */ { NULL
, NULL
, 0 },
1121 /* 0x6f */ { NULL
, NULL
, 0 },
1122 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1123 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1124 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1125 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1126 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1127 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1128 /* 0x76 */ { NULL
, NULL
, 0 },
1129 /* 0x77 */ { NULL
, NULL
, 0 },
1130 /* 0x78 */ { NULL
, NULL
, 0 },
1131 /* 0x79 */ { NULL
, NULL
, 0 },
1132 /* 0x7a */ { NULL
, NULL
, 0 },
1133 /* 0x7b */ { NULL
, NULL
, 0 },
1134 /* 0x7c */ { NULL
, NULL
, 0 },
1135 /* 0x7d */ { NULL
, NULL
, 0 },
1136 /* 0x7e */ { NULL
, NULL
, 0 },
1137 /* 0x7f */ { NULL
, NULL
, 0 },
1138 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1139 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1140 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1141 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1142 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1143 /* 0x85 */ { NULL
, NULL
, 0 },
1144 /* 0x86 */ { NULL
, NULL
, 0 },
1145 /* 0x87 */ { NULL
, NULL
, 0 },
1146 /* 0x88 */ { NULL
, NULL
, 0 },
1147 /* 0x89 */ { NULL
, NULL
, 0 },
1148 /* 0x8a */ { NULL
, NULL
, 0 },
1149 /* 0x8b */ { NULL
, NULL
, 0 },
1150 /* 0x8c */ { NULL
, NULL
, 0 },
1151 /* 0x8d */ { NULL
, NULL
, 0 },
1152 /* 0x8e */ { NULL
, NULL
, 0 },
1153 /* 0x8f */ { NULL
, NULL
, 0 },
1154 /* 0x90 */ { NULL
, NULL
, 0 },
1155 /* 0x91 */ { NULL
, NULL
, 0 },
1156 /* 0x92 */ { NULL
, NULL
, 0 },
1157 /* 0x93 */ { NULL
, NULL
, 0 },
1158 /* 0x94 */ { NULL
, NULL
, 0 },
1159 /* 0x95 */ { NULL
, NULL
, 0 },
1160 /* 0x96 */ { NULL
, NULL
, 0 },
1161 /* 0x97 */ { NULL
, NULL
, 0 },
1162 /* 0x98 */ { NULL
, NULL
, 0 },
1163 /* 0x99 */ { NULL
, NULL
, 0 },
1164 /* 0x9a */ { NULL
, NULL
, 0 },
1165 /* 0x9b */ { NULL
, NULL
, 0 },
1166 /* 0x9c */ { NULL
, NULL
, 0 },
1167 /* 0x9d */ { NULL
, NULL
, 0 },
1168 /* 0x9e */ { NULL
, NULL
, 0 },
1169 /* 0x9f */ { NULL
, NULL
, 0 },
1170 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1171 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1172 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1173 /* 0xa3 */ { NULL
, NULL
, 0 },
1174 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1175 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1176 /* 0xa6 */ { NULL
, NULL
, 0 },
1177 /* 0xa7 */ { NULL
, NULL
, 0 },
1178 /* 0xa8 */ { NULL
, NULL
, 0 },
1179 /* 0xa9 */ { NULL
, NULL
, 0 },
1180 /* 0xaa */ { NULL
, NULL
, 0 },
1181 /* 0xab */ { NULL
, NULL
, 0 },
1182 /* 0xac */ { NULL
, NULL
, 0 },
1183 /* 0xad */ { NULL
, NULL
, 0 },
1184 /* 0xae */ { NULL
, NULL
, 0 },
1185 /* 0xaf */ { NULL
, NULL
, 0 },
1186 /* 0xb0 */ { NULL
, NULL
, 0 },
1187 /* 0xb1 */ { NULL
, NULL
, 0 },
1188 /* 0xb2 */ { NULL
, NULL
, 0 },
1189 /* 0xb3 */ { NULL
, NULL
, 0 },
1190 /* 0xb4 */ { NULL
, NULL
, 0 },
1191 /* 0xb5 */ { NULL
, NULL
, 0 },
1192 /* 0xb6 */ { NULL
, NULL
, 0 },
1193 /* 0xb7 */ { NULL
, NULL
, 0 },
1194 /* 0xb8 */ { NULL
, NULL
, 0 },
1195 /* 0xb9 */ { NULL
, NULL
, 0 },
1196 /* 0xba */ { NULL
, NULL
, 0 },
1197 /* 0xbb */ { NULL
, NULL
, 0 },
1198 /* 0xbc */ { NULL
, NULL
, 0 },
1199 /* 0xbd */ { NULL
, NULL
, 0 },
1200 /* 0xbe */ { NULL
, NULL
, 0 },
1201 /* 0xbf */ { NULL
, NULL
, 0 },
1202 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1203 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1204 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1205 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1206 /* 0xc4 */ { NULL
, NULL
, 0 },
1207 /* 0xc5 */ { NULL
, NULL
, 0 },
1208 /* 0xc6 */ { NULL
, NULL
, 0 },
1209 /* 0xc7 */ { NULL
, NULL
, 0 },
1210 /* 0xc8 */ { NULL
, NULL
, 0 },
1211 /* 0xc9 */ { NULL
, NULL
, 0 },
1212 /* 0xca */ { NULL
, NULL
, 0 },
1213 /* 0xcb */ { NULL
, NULL
, 0 },
1214 /* 0xcc */ { NULL
, NULL
, 0 },
1215 /* 0xcd */ { NULL
, NULL
, 0 },
1216 /* 0xce */ { NULL
, NULL
, 0 },
1217 /* 0xcf */ { NULL
, NULL
, 0 },
1218 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1219 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1220 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1221 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1222 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1223 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1224 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1225 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1226 /* 0xd8 */ { NULL
, NULL
, 0 },
1227 /* 0xd9 */ { NULL
, NULL
, 0 },
1228 /* 0xda */ { NULL
, NULL
, 0 },
1229 /* 0xdb */ { NULL
, NULL
, 0 },
1230 /* 0xdc */ { NULL
, NULL
, 0 },
1231 /* 0xdd */ { NULL
, NULL
, 0 },
1232 /* 0xde */ { NULL
, NULL
, 0 },
1233 /* 0xdf */ { NULL
, NULL
, 0 },
1234 /* 0xe0 */ { NULL
, NULL
, 0 },
1235 /* 0xe1 */ { NULL
, NULL
, 0 },
1236 /* 0xe2 */ { NULL
, NULL
, 0 },
1237 /* 0xe3 */ { NULL
, NULL
, 0 },
1238 /* 0xe4 */ { NULL
, NULL
, 0 },
1239 /* 0xe5 */ { NULL
, NULL
, 0 },
1240 /* 0xe6 */ { NULL
, NULL
, 0 },
1241 /* 0xe7 */ { NULL
, NULL
, 0 },
1242 /* 0xe8 */ { NULL
, NULL
, 0 },
1243 /* 0xe9 */ { NULL
, NULL
, 0 },
1244 /* 0xea */ { NULL
, NULL
, 0 },
1245 /* 0xeb */ { NULL
, NULL
, 0 },
1246 /* 0xec */ { NULL
, NULL
, 0 },
1247 /* 0xed */ { NULL
, NULL
, 0 },
1248 /* 0xee */ { NULL
, NULL
, 0 },
1249 /* 0xef */ { NULL
, NULL
, 0 },
1250 /* 0xf0 */ { NULL
, NULL
, 0 },
1251 /* 0xf1 */ { NULL
, NULL
, 0 },
1252 /* 0xf2 */ { NULL
, NULL
, 0 },
1253 /* 0xf3 */ { NULL
, NULL
, 0 },
1254 /* 0xf4 */ { NULL
, NULL
, 0 },
1255 /* 0xf5 */ { NULL
, NULL
, 0 },
1256 /* 0xf6 */ { NULL
, NULL
, 0 },
1257 /* 0xf7 */ { NULL
, NULL
, 0 },
1258 /* 0xf8 */ { NULL
, NULL
, 0 },
1259 /* 0xf9 */ { NULL
, NULL
, 0 },
1260 /* 0xfa */ { NULL
, NULL
, 0 },
1261 /* 0xfb */ { NULL
, NULL
, 0 },
1262 /* 0xfc */ { NULL
, NULL
, 0 },
1263 /* 0xfd */ { NULL
, NULL
, 0 },
1264 /* 0xfe */ { NULL
, NULL
, 0 },
1265 /* 0xff */ { NULL
, NULL
, 0 }
1269 /*******************************************************************
1270 allocate and initialize a reply packet
1271 ********************************************************************/
1273 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1274 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1278 * Protect against integer wrap
1280 if ((num_bytes
> 0xffffff)
1281 || ((num_bytes
+ smb_size
+ num_words
*2) > 0xffffff)) {
1283 if (asprintf(&msg
, "num_bytes too large: %u",
1284 (unsigned)num_bytes
) == -1) {
1285 msg
= discard_const_p(char, "num_bytes too large");
1290 *outbuf
= talloc_array(mem_ctx
, char,
1291 smb_size
+ num_words
*2 + num_bytes
);
1292 if (*outbuf
== NULL
) {
1296 construct_reply_common(req
, inbuf
, *outbuf
);
1297 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1299 * Zero out the word area, the caller has to take care of the bcc area
1302 if (num_words
!= 0) {
1303 memset(*outbuf
+ smb_vwv0
, 0, num_words
*2);
1309 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1312 if (!create_outbuf(req
, req
, (const char *)req
->inbuf
, &outbuf
, num_words
,
1314 smb_panic("could not allocate output buffer\n");
1316 req
->outbuf
= (uint8_t *)outbuf
;
1320 /*******************************************************************
1321 Dump a packet to a file.
1322 ********************************************************************/
1324 static void smb_dump(const char *name
, int type
, const char *data
, ssize_t len
)
1328 if (DEBUGLEVEL
< 50) {
1332 if (len
< 4) len
= smb_len(data
)+4;
1333 for (i
=1;i
<100;i
++) {
1334 if (asprintf(&fname
, "/tmp/%s.%d.%s", name
, i
,
1335 type
? "req" : "resp") == -1) {
1338 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1339 if (fd
!= -1 || errno
!= EEXIST
) break;
1342 ssize_t ret
= write(fd
, data
, len
);
1344 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1346 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1351 /****************************************************************************
1352 Prepare everything for calling the actual request function, and potentially
1353 call the request function via the "new" interface.
1355 Return False if the "legacy" function needs to be called, everything is
1358 Return True if we're done.
1360 I know this API sucks, but it is the one with the least code change I could
1362 ****************************************************************************/
1364 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
, int size
)
1368 connection_struct
*conn
= NULL
;
1369 struct smbd_server_connection
*sconn
= req
->sconn
;
1374 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1375 * so subtract 4 from it. */
1376 if (!valid_smb_header(sconn
, req
->inbuf
)
1377 || (size
< (smb_size
- 4))) {
1378 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1379 smb_len(req
->inbuf
)));
1380 exit_server_cleanly("Non-SMB packet");
1383 if (smb_messages
[type
].fn
== NULL
) {
1384 DEBUG(0,("Unknown message type %d!\n",type
));
1385 smb_dump("Unknown", 1, (const char *)req
->inbuf
, size
);
1386 reply_unknown_new(req
, type
);
1390 flags
= smb_messages
[type
].flags
;
1392 /* In share mode security we must ignore the vuid. */
1393 session_tag
= (lp_security() == SEC_SHARE
)
1394 ? UID_FIELD_INVALID
: req
->vuid
;
1397 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1398 (int)sys_getpid(), (unsigned long)conn
));
1400 smb_dump(smb_fn_name(type
), 1, (const char *)req
->inbuf
, size
);
1402 /* Ensure this value is replaced in the incoming packet. */
1403 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_uid
,session_tag
);
1406 * Ensure the correct username is in current_user_info. This is a
1407 * really ugly bugfix for problems with multiple session_setup_and_X's
1408 * being done and allowing %U and %G substitutions to work correctly.
1409 * There is a reason this code is done here, don't move it unless you
1410 * know what you're doing... :-).
1414 if (session_tag
!= sconn
->smb1
.sessions
.last_session_tag
) {
1415 user_struct
*vuser
= NULL
;
1417 sconn
->smb1
.sessions
.last_session_tag
= session_tag
;
1418 if(session_tag
!= UID_FIELD_INVALID
) {
1419 vuser
= get_valid_user_struct(sconn
, session_tag
);
1421 set_current_user_info(
1422 vuser
->session_info
->unix_info
->sanitized_username
,
1423 vuser
->session_info
->unix_info
->unix_name
,
1424 vuser
->session_info
->info
->domain_name
);
1429 /* Does this call need to be run as the connected user? */
1430 if (flags
& AS_USER
) {
1432 /* Does this call need a valid tree connection? */
1435 * Amazingly, the error code depends on the command
1438 if (type
== SMBntcreateX
) {
1439 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1441 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1446 if (!change_to_user(conn
,session_tag
)) {
1447 DEBUG(0, ("Error: Could not change to user. Removing "
1448 "deferred open, mid=%llu.\n",
1449 (unsigned long long)req
->mid
));
1450 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1454 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1456 /* Does it need write permission? */
1457 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1458 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1462 /* IPC services are limited */
1463 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1464 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1468 /* This call needs to be run as root */
1469 change_to_root_user();
1472 /* load service specific parameters */
1474 if (req
->encrypted
) {
1475 conn
->encrypted_tid
= true;
1476 /* encrypted required from now on. */
1477 conn
->encrypt_level
= Required
;
1478 } else if (ENCRYPTION_REQUIRED(conn
)) {
1479 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1480 exit_server_cleanly("encryption required "
1486 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1487 (flags
& (AS_USER
|DO_CHDIR
)
1489 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1492 conn
->num_smb_operations
++;
1495 raddr
= tsocket_address_inet_addr_string(sconn
->remote_address
,
1497 if (raddr
== NULL
) {
1498 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1502 /* does this protocol need to be run as guest? */
1503 if ((flags
& AS_GUEST
)
1504 && (!change_to_guest() ||
1505 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1506 sconn
->remote_hostname
,
1508 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1512 smb_messages
[type
].fn(req
);
1516 /****************************************************************************
1517 Construct a reply to the incoming packet.
1518 ****************************************************************************/
1520 static void construct_reply(struct smbd_server_connection
*sconn
,
1521 char *inbuf
, int size
, size_t unread_bytes
,
1522 uint32_t seqnum
, bool encrypted
,
1523 struct smb_perfcount_data
*deferred_pcd
)
1525 connection_struct
*conn
;
1526 struct smb_request
*req
;
1528 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1529 smb_panic("could not allocate smb_request");
1532 if (!init_smb_request(req
, sconn
, (uint8
*)inbuf
, unread_bytes
,
1533 encrypted
, seqnum
)) {
1534 exit_server_cleanly("Invalid SMB request");
1537 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1539 /* we popped this message off the queue - keep original perf data */
1541 req
->pcd
= *deferred_pcd
;
1543 SMB_PERFCOUNT_START(&req
->pcd
);
1544 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1545 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1548 conn
= switch_message(req
->cmd
, req
, size
);
1550 if (req
->unread_bytes
) {
1551 /* writeX failed. drain socket. */
1552 if (drain_socket(req
->sconn
->sock
, req
->unread_bytes
) !=
1553 req
->unread_bytes
) {
1554 smb_panic("failed to drain pending bytes");
1556 req
->unread_bytes
= 0;
1564 if (req
->outbuf
== NULL
) {
1568 if (CVAL(req
->outbuf
,0) == 0) {
1569 show_msg((char *)req
->outbuf
);
1572 if (!srv_send_smb(req
->sconn
,
1573 (char *)req
->outbuf
,
1574 true, req
->seqnum
+1,
1575 IS_CONN_ENCRYPTED(conn
)||req
->encrypted
,
1577 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1585 /****************************************************************************
1586 Process an smb from the client
1587 ****************************************************************************/
1588 static void process_smb(struct smbd_server_connection
*sconn
,
1589 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1590 uint32_t seqnum
, bool encrypted
,
1591 struct smb_perfcount_data
*deferred_pcd
)
1593 int msg_type
= CVAL(inbuf
,0);
1595 DO_PROFILE_INC(smb_count
);
1597 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1599 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1600 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1602 if (msg_type
!= NBSSmessage
) {
1604 * NetBIOS session request, keepalive, etc.
1606 reply_special(sconn
, (char *)inbuf
, nread
);
1610 if (sconn
->using_smb2
) {
1611 /* At this point we're not really using smb2,
1612 * we make the decision here.. */
1613 if (smbd_is_smb2_header(inbuf
, nread
)) {
1614 smbd_smb2_first_negprot(sconn
, inbuf
, nread
);
1616 } else if (nread
>= smb_size
&& valid_smb_header(sconn
, inbuf
)
1617 && CVAL(inbuf
, smb_com
) != 0x72) {
1618 /* This is a non-negprot SMB1 packet.
1619 Disable SMB2 from now on. */
1620 sconn
->using_smb2
= false;
1624 show_msg((char *)inbuf
);
1626 construct_reply(sconn
, (char *)inbuf
, nread
, unread_bytes
, seqnum
,
1627 encrypted
, deferred_pcd
);
1631 sconn
->num_requests
++;
1633 /* The timeout_processing function isn't run nearly
1634 often enough to implement 'max log size' without
1635 overrunning the size of the file by many megabytes.
1636 This is especially true if we are running at debug
1637 level 10. Checking every 50 SMBs is a nice
1638 tradeoff of performance vs log file size overrun. */
1640 if ((sconn
->num_requests
% 50) == 0 &&
1641 need_to_check_log_size()) {
1642 change_to_root_user();
1647 /****************************************************************************
1648 Return a string containing the function name of a SMB command.
1649 ****************************************************************************/
1651 const char *smb_fn_name(int type
)
1653 const char *unknown_name
= "SMBunknown";
1655 if (smb_messages
[type
].name
== NULL
)
1656 return(unknown_name
);
1658 return(smb_messages
[type
].name
);
1661 /****************************************************************************
1662 Helper functions for contruct_reply.
1663 ****************************************************************************/
1665 void add_to_common_flags2(uint32 v
)
1670 void remove_from_common_flags2(uint32 v
)
1672 common_flags2
&= ~v
;
1675 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1678 uint16_t in_flags2
= SVAL(inbuf
,smb_flg2
);
1679 uint16_t out_flags2
= common_flags2
;
1681 out_flags2
|= in_flags2
& FLAGS2_UNICODE_STRINGS
;
1682 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES
;
1683 out_flags2
|= in_flags2
& FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
;
1685 srv_set_message(outbuf
,0,0,false);
1687 SCVAL(outbuf
, smb_com
, req
->cmd
);
1688 SIVAL(outbuf
,smb_rcls
,0);
1689 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1690 SSVAL(outbuf
,smb_flg2
, out_flags2
);
1691 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1692 memcpy(outbuf
+smb_ss_field
, inbuf
+smb_ss_field
, 8);
1694 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
1695 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
1696 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
1697 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
1700 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
1702 construct_reply_common(req
, (const char *)req
->inbuf
, outbuf
);
1706 * How many bytes have we already accumulated up to the current wct field
1710 size_t req_wct_ofs(struct smb_request
*req
)
1714 if (req
->chain_outbuf
== NULL
) {
1717 buf_size
= talloc_get_size(req
->chain_outbuf
);
1718 if ((buf_size
% 4) != 0) {
1719 buf_size
+= (4 - (buf_size
% 4));
1721 return buf_size
- 4;
1725 * Hack around reply_nterror & friends not being aware of chained requests,
1726 * generating illegal (i.e. wct==0) chain replies.
1729 static void fixup_chain_error_packet(struct smb_request
*req
)
1731 uint8_t *outbuf
= req
->outbuf
;
1733 reply_outbuf(req
, 2, 0);
1734 memcpy(req
->outbuf
, outbuf
, smb_wct
);
1735 TALLOC_FREE(outbuf
);
1736 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
1740 * @brief Find the smb_cmd offset of the last command pushed
1741 * @param[in] buf The buffer we're building up
1742 * @retval Where can we put our next andx cmd?
1744 * While chaining requests, the "next" request we're looking at needs to put
1745 * its SMB_Command before the data the previous request already built up added
1746 * to the chain. Find the offset to the place where we have to put our cmd.
1749 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
1754 cmd
= CVAL(buf
, smb_com
);
1756 SMB_ASSERT(is_andx_req(cmd
));
1760 while (CVAL(buf
, ofs
) != 0xff) {
1762 if (!is_andx_req(CVAL(buf
, ofs
))) {
1767 * ofs is from start of smb header, so add the 4 length
1768 * bytes. The next cmd is right after the wct field.
1770 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
1772 SMB_ASSERT(ofs
+4 < talloc_get_size(buf
));
1780 * @brief Do the smb chaining at a buffer level
1781 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1782 * @param[in] smb_command The command that we want to issue
1783 * @param[in] wct How many words?
1784 * @param[in] vwv The words, already in network order
1785 * @param[in] bytes_alignment How shall we align "bytes"?
1786 * @param[in] num_bytes How many bytes?
1787 * @param[in] bytes The data the request ships
1789 * smb_splice_chain() adds the vwv and bytes to the request already present in
1793 static bool smb_splice_chain(uint8_t **poutbuf
, uint8_t smb_command
,
1794 uint8_t wct
, const uint16_t *vwv
,
1795 size_t bytes_alignment
,
1796 uint32_t num_bytes
, const uint8_t *bytes
)
1799 size_t old_size
, new_size
;
1801 size_t chain_padding
= 0;
1802 size_t bytes_padding
= 0;
1805 old_size
= talloc_get_size(*poutbuf
);
1808 * old_size == smb_wct means we're pushing the first request in for
1812 first_request
= (old_size
== smb_wct
);
1814 if (!first_request
&& ((old_size
% 4) != 0)) {
1816 * Align the wct field of subsequent requests to a 4-byte
1819 chain_padding
= 4 - (old_size
% 4);
1823 * After the old request comes the new wct field (1 byte), the vwv's
1824 * and the num_bytes field. After at we might need to align the bytes
1825 * given to us to "bytes_alignment", increasing the num_bytes value.
1828 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
1830 if ((bytes_alignment
!= 0) && ((new_size
% bytes_alignment
) != 0)) {
1831 bytes_padding
= bytes_alignment
- (new_size
% bytes_alignment
);
1834 new_size
+= bytes_padding
+ num_bytes
;
1836 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
1837 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1838 (unsigned)new_size
));
1842 outbuf
= talloc_realloc(NULL
, *poutbuf
, uint8_t, new_size
);
1843 if (outbuf
== NULL
) {
1844 DEBUG(0, ("talloc failed\n"));
1849 if (first_request
) {
1850 SCVAL(outbuf
, smb_com
, smb_command
);
1852 size_t andx_cmd_ofs
;
1854 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
1855 DEBUG(1, ("invalid command chain\n"));
1856 *poutbuf
= talloc_realloc(
1857 NULL
, *poutbuf
, uint8_t, old_size
);
1861 if (chain_padding
!= 0) {
1862 memset(outbuf
+ old_size
, 0, chain_padding
);
1863 old_size
+= chain_padding
;
1866 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
1867 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
1873 * Push the chained request:
1878 SCVAL(outbuf
, ofs
, wct
);
1885 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
1886 ofs
+= sizeof(uint16_t) * wct
;
1892 SSVAL(outbuf
, ofs
, num_bytes
+ bytes_padding
);
1893 ofs
+= sizeof(uint16_t);
1899 if (bytes_padding
!= 0) {
1900 memset(outbuf
+ ofs
, 0, bytes_padding
);
1901 ofs
+= bytes_padding
;
1908 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
1913 /****************************************************************************
1914 Construct a chained reply and add it to the already made reply
1915 ****************************************************************************/
1917 void chain_reply(struct smb_request
*req
)
1919 size_t smblen
= smb_len(req
->inbuf
);
1920 size_t already_used
, length_needed
;
1922 uint32_t chain_offset
; /* uint32_t to avoid overflow */
1925 const uint16_t *vwv
;
1929 if (IVAL(req
->outbuf
, smb_rcls
) != 0) {
1930 fixup_chain_error_packet(req
);
1934 * Any of the AndX requests and replies have at least a wct of
1935 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1936 * beginning of the SMB header to the next wct field.
1938 * None of the AndX requests put anything valuable in vwv[0] and [1],
1939 * so we can overwrite it here to form the chain.
1942 if ((req
->wct
< 2) || (CVAL(req
->outbuf
, smb_wct
) < 2)) {
1943 if (req
->chain_outbuf
== NULL
) {
1944 req
->chain_outbuf
= talloc_realloc(
1945 req
, req
->outbuf
, uint8_t,
1946 smb_len(req
->outbuf
) + 4);
1947 if (req
->chain_outbuf
== NULL
) {
1948 smb_panic("talloc failed");
1956 * Here we assume that this is the end of the chain. For that we need
1957 * to set "next command" to 0xff and the offset to 0. If we later find
1958 * more commands in the chain, this will be overwritten again.
1961 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
1962 SCVAL(req
->outbuf
, smb_vwv0
+1, 0);
1963 SSVAL(req
->outbuf
, smb_vwv1
, 0);
1965 if (req
->chain_outbuf
== NULL
) {
1967 * In req->chain_outbuf we collect all the replies. Start the
1968 * chain by copying in the first reply.
1970 * We do the realloc because later on we depend on
1971 * talloc_get_size to determine the length of
1972 * chain_outbuf. The reply_xxx routines might have
1973 * over-allocated (reply_pipe_read_and_X used to be such an
1976 req
->chain_outbuf
= talloc_realloc(
1977 req
, req
->outbuf
, uint8_t, smb_len(req
->outbuf
) + 4);
1978 if (req
->chain_outbuf
== NULL
) {
1979 smb_panic("talloc failed");
1984 * Update smb headers where subsequent chained commands
1985 * may have updated them.
1987 SSVAL(req
->chain_outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
1988 SSVAL(req
->chain_outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
1990 if (!smb_splice_chain(&req
->chain_outbuf
,
1991 CVAL(req
->outbuf
, smb_com
),
1992 CVAL(req
->outbuf
, smb_wct
),
1993 (uint16_t *)(req
->outbuf
+ smb_vwv
),
1994 0, smb_buflen(req
->outbuf
),
1995 (uint8_t *)smb_buf(req
->outbuf
))) {
1998 TALLOC_FREE(req
->outbuf
);
2002 * We use the old request's vwv field to grab the next chained command
2003 * and offset into the chained fields.
2006 chain_cmd
= CVAL(req
->vwv
+0, 0);
2007 chain_offset
= SVAL(req
->vwv
+1, 0);
2009 if (chain_cmd
== 0xff) {
2011 * End of chain, no more requests from the client. So ship the
2014 smb_setlen((char *)(req
->chain_outbuf
),
2015 talloc_get_size(req
->chain_outbuf
) - 4);
2017 if (!srv_send_smb(req
->sconn
, (char *)req
->chain_outbuf
,
2018 true, req
->seqnum
+1,
2019 IS_CONN_ENCRYPTED(req
->conn
)
2022 exit_server_cleanly("chain_reply: srv_send_smb "
2025 TALLOC_FREE(req
->chain_outbuf
);
2030 /* add a new perfcounter for this element of chain */
2031 SMB_PERFCOUNT_ADD(&req
->pcd
);
2032 SMB_PERFCOUNT_SET_OP(&req
->pcd
, chain_cmd
);
2033 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, smblen
);
2036 * Check if the client tries to fool us. The chain offset
2037 * needs to point beyond the current request in the chain, it
2038 * needs to strictly grow. Otherwise we might be tricked into
2039 * an endless loop always processing the same request over and
2040 * over again. We used to assume that vwv and the byte buffer
2041 * array in a chain are always attached, but OS/2 the
2042 * Write&X/Read&X chain puts the Read&X vwv array right behind
2043 * the Write&X vwv chain. The Write&X bcc array is put behind
2044 * the Read&X vwv array. So now we check whether the chain
2045 * offset points strictly behind the previous vwv
2046 * array. req->buf points right after the vwv array of the
2047 * previous request. See
2048 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2052 already_used
= PTR_DIFF(req
->buf
, smb_base(req
->inbuf
));
2053 if (chain_offset
<= already_used
) {
2058 * Next check: Make sure the chain offset does not point beyond the
2059 * overall smb request length.
2062 length_needed
= chain_offset
+1; /* wct */
2063 if (length_needed
> smblen
) {
2068 * Now comes the pointer magic. Goal here is to set up req->vwv and
2069 * req->buf correctly again to be able to call the subsequent
2070 * switch_message(). The chain offset (the former vwv[1]) points at
2071 * the new wct field.
2074 wct
= CVAL(smb_base(req
->inbuf
), chain_offset
);
2077 * Next consistency check: Make the new vwv array fits in the overall
2081 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2082 if (length_needed
> smblen
) {
2085 vwv
= (const uint16_t *)(smb_base(req
->inbuf
) + chain_offset
+ 1);
2088 * Now grab the new byte buffer....
2091 buflen
= SVAL(vwv
+wct
, 0);
2094 * .. and check that it fits.
2097 length_needed
+= buflen
;
2098 if (length_needed
> smblen
) {
2101 buf
= (const uint8_t *)(vwv
+wct
+1);
2103 req
->cmd
= chain_cmd
;
2105 req
->vwv
= discard_const_p(uint16_t, vwv
);
2106 req
->buflen
= buflen
;
2109 switch_message(chain_cmd
, req
, smblen
);
2111 if (req
->outbuf
== NULL
) {
2113 * This happens if the chained command has suspended itself or
2114 * if it has called srv_send_smb() itself.
2120 * We end up here if the chained command was not itself chained or
2121 * suspended, but for example a close() command. We now need to splice
2122 * the chained commands' outbuf into the already built up chain_outbuf
2123 * and ship the result.
2129 * We end up here if there's any error in the chain syntax. Report a
2130 * DOS error, just like Windows does.
2132 reply_force_doserror(req
, ERRSRV
, ERRerror
);
2133 fixup_chain_error_packet(req
);
2137 * This scary statement intends to set the
2138 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2139 * to the value req->outbuf carries
2141 SSVAL(req
->chain_outbuf
, smb_flg2
,
2142 (SVAL(req
->chain_outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
2143 | (SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
2146 * Transfer the error codes from the subrequest to the main one
2148 SSVAL(req
->chain_outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
2149 SSVAL(req
->chain_outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
2151 if (!smb_splice_chain(&req
->chain_outbuf
,
2152 CVAL(req
->outbuf
, smb_com
),
2153 CVAL(req
->outbuf
, smb_wct
),
2154 (uint16_t *)(req
->outbuf
+ smb_vwv
),
2155 0, smb_buflen(req
->outbuf
),
2156 (uint8_t *)smb_buf(req
->outbuf
))) {
2157 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2159 TALLOC_FREE(req
->outbuf
);
2161 smb_setlen((char *)(req
->chain_outbuf
),
2162 talloc_get_size(req
->chain_outbuf
) - 4);
2164 show_msg((char *)(req
->chain_outbuf
));
2166 if (!srv_send_smb(req
->sconn
, (char *)req
->chain_outbuf
,
2167 true, req
->seqnum
+1,
2168 IS_CONN_ENCRYPTED(req
->conn
)||req
->encrypted
,
2170 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2172 TALLOC_FREE(req
->chain_outbuf
);
2176 /****************************************************************************
2177 Check if services need reloading.
2178 ****************************************************************************/
2180 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2183 if (last_smb_conf_reload_time
== 0) {
2184 last_smb_conf_reload_time
= t
;
2187 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2188 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
2189 last_smb_conf_reload_time
= t
;
2193 static bool fd_is_readable(int fd
)
2197 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2199 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2203 static void smbd_server_connection_write_handler(
2204 struct smbd_server_connection
*sconn
)
2206 /* TODO: make write nonblocking */
2209 static void smbd_server_connection_read_handler(
2210 struct smbd_server_connection
*sconn
, int fd
)
2212 uint8_t *inbuf
= NULL
;
2213 size_t inbuf_len
= 0;
2214 size_t unread_bytes
= 0;
2215 bool encrypted
= false;
2216 TALLOC_CTX
*mem_ctx
= talloc_tos();
2222 if (lp_async_smb_echo_handler()
2223 && fd_is_readable(sconn
->smb1
.echo_handler
.trusted_fd
)) {
2225 * This is the super-ugly hack to prefer the packets
2226 * forwarded by the echo handler over the ones by the
2229 fd
= sconn
->smb1
.echo_handler
.trusted_fd
;
2232 from_client
= (sconn
->sock
== fd
);
2235 smbd_lock_socket(sconn
);
2237 if (!fd_is_readable(fd
)) {
2238 DEBUG(10,("the echo listener was faster\n"));
2239 smbd_unlock_socket(sconn
);
2244 /* TODO: make this completely nonblocking */
2245 status
= receive_smb_talloc(mem_ctx
, sconn
, fd
,
2246 (char **)(void *)&inbuf
,
2250 &inbuf_len
, &seqnum
,
2251 false /* trusted channel */);
2254 smbd_unlock_socket(sconn
);
2257 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2260 if (NT_STATUS_IS_ERR(status
)) {
2261 exit_server_cleanly("failed to receive smb request");
2263 if (!NT_STATUS_IS_OK(status
)) {
2268 process_smb(sconn
, inbuf
, inbuf_len
, unread_bytes
,
2269 seqnum
, encrypted
, NULL
);
2272 static void smbd_server_connection_handler(struct event_context
*ev
,
2273 struct fd_event
*fde
,
2277 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2278 struct smbd_server_connection
);
2280 if (flags
& EVENT_FD_WRITE
) {
2281 smbd_server_connection_write_handler(conn
);
2284 if (flags
& EVENT_FD_READ
) {
2285 smbd_server_connection_read_handler(conn
, conn
->sock
);
2290 static void smbd_server_echo_handler(struct event_context
*ev
,
2291 struct fd_event
*fde
,
2295 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2296 struct smbd_server_connection
);
2298 if (flags
& EVENT_FD_WRITE
) {
2299 smbd_server_connection_write_handler(conn
);
2302 if (flags
& EVENT_FD_READ
) {
2303 smbd_server_connection_read_handler(
2304 conn
, conn
->smb1
.echo_handler
.trusted_fd
);
2309 #ifdef CLUSTER_SUPPORT
2310 /****************************************************************************
2311 received when we should release a specific IP
2312 ****************************************************************************/
2313 static void release_ip(const char *ip
, void *priv
)
2315 const char *addr
= (const char *)priv
;
2316 const char *p
= addr
;
2318 if (strncmp("::ffff:", addr
, 7) == 0) {
2322 DEBUG(10, ("Got release IP message for %s, "
2323 "our address is %s\n", ip
, p
));
2325 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2326 /* we can't afford to do a clean exit - that involves
2327 database writes, which would potentially mean we
2328 are still running after the failover has finished -
2329 we have to get rid of this process ID straight
2331 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2333 /* note we must exit with non-zero status so the unclean handler gets
2334 called in the parent, so that the brl database is tickled */
2339 static int client_get_tcp_info(int sock
, struct sockaddr_storage
*server
,
2340 struct sockaddr_storage
*client
)
2343 length
= sizeof(*server
);
2344 if (getsockname(sock
, (struct sockaddr
*)server
, &length
) != 0) {
2347 length
= sizeof(*client
);
2348 if (getpeername(sock
, (struct sockaddr
*)client
, &length
) != 0) {
2356 * Send keepalive packets to our client
2358 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2360 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2361 private_data
, struct smbd_server_connection
);
2364 if (sconn
->using_smb2
) {
2365 /* Don't do keepalives on an SMB2 connection. */
2369 smbd_lock_socket(smbd_server_conn
);
2370 ret
= send_keepalive(sconn
->sock
);
2371 smbd_unlock_socket(smbd_server_conn
);
2374 char addr
[INET6_ADDRSTRLEN
];
2376 * Try and give an error message saying what
2379 DEBUG(0, ("send_keepalive failed for client %s. "
2380 "Error %s - exiting\n",
2381 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
2389 * Do the recurring check if we're idle
2391 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2393 struct smbd_server_connection
*sconn
=
2394 (struct smbd_server_connection
*)private_data
;
2396 if ((conn_num_open(sconn
) == 0)
2397 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2398 DEBUG( 2, ( "Closing idle connection\n" ) );
2399 messaging_send(sconn
->msg_ctx
,
2400 messaging_server_id(sconn
->msg_ctx
),
2401 MSG_SHUTDOWN
, &data_blob_null
);
2409 * Do the recurring log file and smb.conf reload checks.
2412 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2414 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2415 private_data
, struct smbd_server_connection
);
2417 DEBUG(5, ("housekeeping\n"));
2419 change_to_root_user();
2421 /* update printer queue caches if necessary */
2422 update_monitored_printq_cache(sconn
->msg_ctx
);
2424 /* check if we need to reload services */
2425 check_reload(sconn
, time_mono(NULL
));
2427 /* Change machine password if neccessary. */
2428 attempt_machine_password_change();
2431 * Force a log file check.
2433 force_check_log_size();
2439 * Read an smb packet in the echo handler child, giving the parent
2440 * smbd one second to react once the socket becomes readable.
2443 struct smbd_echo_read_state
{
2444 struct tevent_context
*ev
;
2445 struct smbd_server_connection
*sconn
;
2452 static void smbd_echo_read_readable(struct tevent_req
*subreq
);
2453 static void smbd_echo_read_waited(struct tevent_req
*subreq
);
2455 static struct tevent_req
*smbd_echo_read_send(
2456 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2457 struct smbd_server_connection
*sconn
)
2459 struct tevent_req
*req
, *subreq
;
2460 struct smbd_echo_read_state
*state
;
2462 req
= tevent_req_create(mem_ctx
, &state
,
2463 struct smbd_echo_read_state
);
2468 state
->sconn
= sconn
;
2470 subreq
= wait_for_read_send(state
, ev
, sconn
->sock
);
2471 if (tevent_req_nomem(subreq
, req
)) {
2472 return tevent_req_post(req
, ev
);
2474 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2478 static void smbd_echo_read_readable(struct tevent_req
*subreq
)
2480 struct tevent_req
*req
= tevent_req_callback_data(
2481 subreq
, struct tevent_req
);
2482 struct smbd_echo_read_state
*state
= tevent_req_data(
2483 req
, struct smbd_echo_read_state
);
2487 ok
= wait_for_read_recv(subreq
, &err
);
2488 TALLOC_FREE(subreq
);
2490 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
2495 * Give the parent smbd one second to step in
2498 subreq
= tevent_wakeup_send(
2499 state
, state
->ev
, timeval_current_ofs(1, 0));
2500 if (tevent_req_nomem(subreq
, req
)) {
2503 tevent_req_set_callback(subreq
, smbd_echo_read_waited
, req
);
2506 static void smbd_echo_read_waited(struct tevent_req
*subreq
)
2508 struct tevent_req
*req
= tevent_req_callback_data(
2509 subreq
, struct tevent_req
);
2510 struct smbd_echo_read_state
*state
= tevent_req_data(
2511 req
, struct smbd_echo_read_state
);
2512 struct smbd_server_connection
*sconn
= state
->sconn
;
2518 ok
= tevent_wakeup_recv(subreq
);
2519 TALLOC_FREE(subreq
);
2521 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
2525 ok
= smbd_lock_socket_internal(sconn
);
2527 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2528 DEBUG(0, ("%s: failed to lock socket\n", __location__
));
2532 if (!fd_is_readable(sconn
->sock
)) {
2533 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2534 (int)sys_getpid()));
2536 ok
= smbd_unlock_socket_internal(sconn
);
2538 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2539 DEBUG(1, ("%s: failed to unlock socket\n",
2544 subreq
= wait_for_read_send(state
, state
->ev
, sconn
->sock
);
2545 if (tevent_req_nomem(subreq
, req
)) {
2548 tevent_req_set_callback(subreq
, smbd_echo_read_readable
, req
);
2552 status
= receive_smb_talloc(state
, sconn
, sconn
->sock
, &state
->buf
,
2558 false /* trusted_channel*/);
2560 if (tevent_req_nterror(req
, status
)) {
2561 tevent_req_nterror(req
, status
);
2562 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2563 (int)sys_getpid(), nt_errstr(status
)));
2567 ok
= smbd_unlock_socket_internal(sconn
);
2569 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
2570 DEBUG(1, ("%s: failed to unlock socket\n", __location__
));
2573 tevent_req_done(req
);
2576 static NTSTATUS
smbd_echo_read_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
2577 char **pbuf
, size_t *pbuflen
, uint32_t *pseqnum
)
2579 struct smbd_echo_read_state
*state
= tevent_req_data(
2580 req
, struct smbd_echo_read_state
);
2583 if (tevent_req_is_nterror(req
, &status
)) {
2586 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
2587 *pbuflen
= state
->buflen
;
2588 *pseqnum
= state
->seqnum
;
2589 return NT_STATUS_OK
;
2592 struct smbd_echo_state
{
2593 struct tevent_context
*ev
;
2594 struct iovec
*pending
;
2595 struct smbd_server_connection
*sconn
;
2598 struct tevent_fd
*parent_fde
;
2600 struct tevent_req
*write_req
;
2603 static void smbd_echo_writer_done(struct tevent_req
*req
);
2605 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2609 if (state
->write_req
!= NULL
) {
2613 num_pending
= talloc_array_length(state
->pending
);
2614 if (num_pending
== 0) {
2618 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
2619 state
->parent_pipe
, false,
2620 state
->pending
, num_pending
);
2621 if (state
->write_req
== NULL
) {
2622 DEBUG(1, ("writev_send failed\n"));
2626 talloc_steal(state
->write_req
, state
->pending
);
2627 state
->pending
= NULL
;
2629 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
2633 static void smbd_echo_writer_done(struct tevent_req
*req
)
2635 struct smbd_echo_state
*state
= tevent_req_callback_data(
2636 req
, struct smbd_echo_state
);
2640 written
= writev_recv(req
, &err
);
2642 state
->write_req
= NULL
;
2643 if (written
== -1) {
2644 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
2647 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2648 smbd_echo_activate_writer(state
);
2651 static bool smbd_echo_reply(uint8_t *inbuf
, size_t inbuf_len
,
2654 struct smb_request req
;
2655 uint16_t num_replies
;
2660 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == NBSSkeepalive
)) {
2661 DEBUG(10, ("Got netbios keepalive\n"));
2668 if (inbuf_len
< smb_size
) {
2669 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
2672 if (!valid_smb_header(smbd_server_conn
, inbuf
)) {
2673 DEBUG(10, ("Got invalid SMB header\n"));
2677 if (!init_smb_request(&req
, smbd_server_conn
, inbuf
, 0, false,
2683 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
2684 smb_messages
[req
.cmd
].name
2685 ? smb_messages
[req
.cmd
].name
: "unknown"));
2687 if (req
.cmd
!= SMBecho
) {
2694 num_replies
= SVAL(req
.vwv
+0, 0);
2695 if (num_replies
!= 1) {
2696 /* Not a Windows "Hey, you're still there?" request */
2700 if (!create_outbuf(talloc_tos(), &req
, (const char *)req
.inbuf
, &outbuf
,
2702 DEBUG(10, ("create_outbuf failed\n"));
2705 req
.outbuf
= (uint8_t *)outbuf
;
2707 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
2709 if (req
.buflen
> 0) {
2710 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
2713 out_len
= smb_len(req
.outbuf
) + 4;
2715 ok
= srv_send_smb(req
.sconn
,
2719 TALLOC_FREE(outbuf
);
2727 static void smbd_echo_exit(struct tevent_context
*ev
,
2728 struct tevent_fd
*fde
, uint16_t flags
,
2731 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2735 static void smbd_echo_got_packet(struct tevent_req
*req
);
2737 static void smbd_echo_loop(struct smbd_server_connection
*sconn
,
2740 struct smbd_echo_state
*state
;
2741 struct tevent_req
*read_req
;
2743 state
= talloc_zero(sconn
, struct smbd_echo_state
);
2744 if (state
== NULL
) {
2745 DEBUG(1, ("talloc failed\n"));
2748 state
->sconn
= sconn
;
2749 state
->parent_pipe
= parent_pipe
;
2750 state
->ev
= s3_tevent_context_init(state
);
2751 if (state
->ev
== NULL
) {
2752 DEBUG(1, ("tevent_context_init failed\n"));
2756 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
2757 TEVENT_FD_READ
, smbd_echo_exit
,
2759 if (state
->parent_fde
== NULL
) {
2760 DEBUG(1, ("tevent_add_fd failed\n"));
2765 read_req
= smbd_echo_read_send(state
, state
->ev
, sconn
);
2766 if (read_req
== NULL
) {
2767 DEBUG(1, ("smbd_echo_read_send failed\n"));
2771 tevent_req_set_callback(read_req
, smbd_echo_got_packet
, state
);
2774 if (tevent_loop_once(state
->ev
) == -1) {
2775 DEBUG(1, ("tevent_loop_once failed: %s\n",
2783 static void smbd_echo_got_packet(struct tevent_req
*req
)
2785 struct smbd_echo_state
*state
= tevent_req_callback_data(
2786 req
, struct smbd_echo_state
);
2790 uint32_t seqnum
= 0;
2793 status
= smbd_echo_read_recv(req
, state
, &buf
, &buflen
, &seqnum
);
2795 if (!NT_STATUS_IS_OK(status
)) {
2796 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2797 nt_errstr(status
)));
2801 reply
= smbd_echo_reply((uint8_t *)buf
, buflen
, seqnum
);
2807 num_pending
= talloc_array_length(state
->pending
);
2808 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
2811 DEBUG(1, ("talloc_realloc failed\n"));
2814 state
->pending
= tmp
;
2816 if (buflen
>= smb_size
) {
2818 * place the seqnum in the packet so that the main process
2819 * can reply with signing
2821 SIVAL(buf
, smb_ss_field
, seqnum
);
2822 SIVAL(buf
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
2825 iov
= &state
->pending
[num_pending
];
2826 iov
->iov_base
= buf
;
2827 iov
->iov_len
= buflen
;
2829 DEBUG(10,("echo_handler[%d]: forward to main\n",
2830 (int)sys_getpid()));
2831 smbd_echo_activate_writer(state
);
2834 req
= smbd_echo_read_send(state
, state
->ev
, state
->sconn
);
2836 DEBUG(1, ("smbd_echo_read_send failed\n"));
2839 tevent_req_set_callback(req
, smbd_echo_got_packet
, state
);
2844 * Handle SMBecho requests in a forked child process
2846 bool fork_echo_handler(struct smbd_server_connection
*sconn
)
2848 int listener_pipe
[2];
2852 res
= pipe(listener_pipe
);
2854 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
2857 sconn
->smb1
.echo_handler
.socket_lock_fd
= create_unlink_tmp(lp_lockdir());
2858 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
2859 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno
)));
2867 close(listener_pipe
[0]);
2868 set_blocking(listener_pipe
[1], false);
2870 status
= reinit_after_fork(sconn
->msg_ctx
,
2871 server_event_context(),
2872 procid_self(), false);
2873 if (!NT_STATUS_IS_OK(status
)) {
2874 DEBUG(1, ("reinit_after_fork failed: %s\n",
2875 nt_errstr(status
)));
2878 smbd_echo_loop(sconn
, listener_pipe
[1]);
2881 close(listener_pipe
[1]);
2882 listener_pipe
[1] = -1;
2883 sconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
2885 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child
));
2888 * Without smb signing this is the same as the normal smbd
2889 * listener. This needs to change once signing comes in.
2891 sconn
->smb1
.echo_handler
.trusted_fde
= event_add_fd(server_event_context(),
2893 sconn
->smb1
.echo_handler
.trusted_fd
,
2895 smbd_server_echo_handler
,
2897 if (sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
2898 DEBUG(1, ("event_add_fd failed\n"));
2905 if (listener_pipe
[0] != -1) {
2906 close(listener_pipe
[0]);
2908 if (listener_pipe
[1] != -1) {
2909 close(listener_pipe
[1]);
2911 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2912 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
2913 close(sconn
->smb1
.echo_handler
.socket_lock_fd
);
2915 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2916 sconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
2922 static NTSTATUS
smbd_register_ips(struct smbd_server_connection
*sconn
,
2923 struct sockaddr_storage
*srv
,
2924 struct sockaddr_storage
*clnt
)
2926 struct ctdbd_connection
*cconn
;
2927 char tmp_addr
[INET6_ADDRSTRLEN
];
2930 cconn
= messaging_ctdbd_connection();
2931 if (cconn
== NULL
) {
2932 return NT_STATUS_NO_MEMORY
;
2935 client_socket_addr(sconn
->sock
, tmp_addr
, sizeof(tmp_addr
));
2936 addr
= talloc_strdup(cconn
, tmp_addr
);
2938 return NT_STATUS_NO_MEMORY
;
2940 return ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, addr
);
2945 /****************************************************************************
2946 Process commands from the client
2947 ****************************************************************************/
2949 void smbd_process(struct tevent_context
*ev_ctx
,
2950 struct smbd_server_connection
*sconn
)
2952 TALLOC_CTX
*frame
= talloc_stackframe();
2953 struct sockaddr_storage ss
;
2954 struct sockaddr
*sa
= NULL
;
2955 socklen_t sa_socklen
;
2956 struct tsocket_address
*local_address
= NULL
;
2957 struct tsocket_address
*remote_address
= NULL
;
2958 const char *remaddr
= NULL
;
2962 if (lp_maxprotocol() >= PROTOCOL_SMB2_02
) {
2964 * We're not making the decision here,
2965 * we're just allowing the client
2966 * to decide between SMB1 and SMB2
2967 * with the first negprot
2970 sconn
->using_smb2
= true;
2973 /* Ensure child is set to blocking mode */
2974 set_blocking(sconn
->sock
,True
);
2976 set_socket_options(sconn
->sock
, "SO_KEEPALIVE");
2977 set_socket_options(sconn
->sock
, lp_socket_options());
2979 sa
= (struct sockaddr
*)(void *)&ss
;
2980 sa_socklen
= sizeof(ss
);
2981 ret
= getpeername(sconn
->sock
, sa
, &sa_socklen
);
2983 int level
= (errno
== ENOTCONN
)?2:0;
2984 DEBUG(level
,("getpeername() failed - %s\n", strerror(errno
)));
2985 exit_server_cleanly("getpeername() failed.\n");
2987 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
2991 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2992 __location__
, strerror(errno
)));
2993 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2996 sa
= (struct sockaddr
*)(void *)&ss
;
2997 sa_socklen
= sizeof(ss
);
2998 ret
= getsockname(sconn
->sock
, sa
, &sa_socklen
);
3000 int level
= (errno
== ENOTCONN
)?2:0;
3001 DEBUG(level
,("getsockname() failed - %s\n", strerror(errno
)));
3002 exit_server_cleanly("getsockname() failed.\n");
3004 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
3008 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3009 __location__
, strerror(errno
)));
3010 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3013 sconn
->local_address
= local_address
;
3014 sconn
->remote_address
= remote_address
;
3016 if (tsocket_address_is_inet(remote_address
, "ip")) {
3017 remaddr
= tsocket_address_inet_addr_string(
3018 sconn
->remote_address
,
3020 if (remaddr
== NULL
) {
3021 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3022 __location__
, strerror(errno
)));
3023 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3026 remaddr
= "0.0.0.0";
3029 /* this is needed so that we get decent entries
3030 in smbstatus for port 445 connects */
3031 set_remote_machine_name(remaddr
, false);
3032 reload_services(sconn
->msg_ctx
, sconn
->sock
, true);
3035 * Before the first packet, check the global hosts allow/ hosts deny
3036 * parameters before doing any parsing of packets passed to us by the
3037 * client. This prevents attacks on our parsing code from hosts not in
3038 * the hosts allow list.
3041 ret
= get_remote_hostname(remote_address
,
3045 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3046 __location__
, strerror(errno
)));
3047 exit_server_cleanly("get_remote_hostname failed.\n");
3049 if (strequal(rhost
, "UNKNOWN")) {
3050 rhost
= talloc_strdup(talloc_tos(), remaddr
);
3052 sconn
->remote_hostname
= talloc_move(sconn
, &rhost
);
3054 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3055 sconn
->remote_hostname
,
3058 * send a negative session response "not listening on calling
3061 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3062 DEBUG( 1, ("Connection denied from %s to %s\n",
3063 tsocket_address_string(remote_address
, talloc_tos()),
3064 tsocket_address_string(local_address
, talloc_tos())));
3065 (void)srv_send_smb(sconn
,(char *)buf
, false,
3067 exit_server_cleanly("connection denied");
3070 DEBUG(10, ("Connection allowed from %s to %s\n",
3071 tsocket_address_string(remote_address
, talloc_tos()),
3072 tsocket_address_string(local_address
, talloc_tos())));
3076 smb_perfcount_init();
3078 if (!init_account_policy()) {
3079 exit_server("Could not open account policy tdb.\n");
3082 if (*lp_rootdir()) {
3083 if (chroot(lp_rootdir()) != 0) {
3084 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3085 exit_server("Failed to chroot()");
3087 if (chdir("/") == -1) {
3088 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3089 exit_server("Failed to chroot()");
3091 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3094 if (!srv_init_signing(sconn
)) {
3095 exit_server("Failed to init smb_signing");
3099 if (!init_oplocks(sconn
->msg_ctx
))
3100 exit_server("Failed to init oplocks");
3102 /* register our message handlers */
3103 messaging_register(sconn
->msg_ctx
, NULL
,
3104 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3105 messaging_register(sconn
->msg_ctx
, NULL
,
3106 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3109 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3110 * MSGs to all child processes
3112 messaging_deregister(sconn
->msg_ctx
,
3114 messaging_register(sconn
->msg_ctx
, NULL
,
3115 MSG_DEBUG
, debug_message
);
3117 if ((lp_keepalive() != 0)
3118 && !(event_add_idle(ev_ctx
, NULL
,
3119 timeval_set(lp_keepalive(), 0),
3120 "keepalive", keepalive_fn
,
3122 DEBUG(0, ("Could not add keepalive event\n"));
3126 if (!(event_add_idle(ev_ctx
, NULL
,
3127 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3128 "deadtime", deadtime_fn
, sconn
))) {
3129 DEBUG(0, ("Could not add deadtime event\n"));
3133 if (!(event_add_idle(ev_ctx
, NULL
,
3134 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
3135 "housekeeping", housekeeping_fn
, sconn
))) {
3136 DEBUG(0, ("Could not add housekeeping event\n"));
3140 #ifdef CLUSTER_SUPPORT
3142 if (lp_clustering()) {
3144 * We need to tell ctdb about our client's TCP
3145 * connection, so that for failover ctdbd can send
3146 * tickle acks, triggering a reconnection by the
3150 struct sockaddr_storage srv
, clnt
;
3152 if (client_get_tcp_info(sconn
->sock
, &srv
, &clnt
) == 0) {
3154 status
= smbd_register_ips(sconn
, &srv
, &clnt
);
3155 if (!NT_STATUS_IS_OK(status
)) {
3156 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3157 nt_errstr(status
)));
3161 DEBUG(0,("Unable to get tcp info for "
3162 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3169 sconn
->nbt
.got_session
= false;
3171 sconn
->smb1
.negprot
.max_recv
= MIN(lp_maxxmit(),BUFFER_SIZE
);
3173 sconn
->smb1
.sessions
.done_sesssetup
= false;
3174 sconn
->smb1
.sessions
.max_send
= BUFFER_SIZE
;
3175 sconn
->smb1
.sessions
.last_session_tag
= UID_FIELD_INVALID
;
3176 /* users from session setup */
3177 sconn
->smb1
.sessions
.session_userlist
= NULL
;
3178 /* workgroup from session setup. */
3179 sconn
->smb1
.sessions
.session_workgroup
= NULL
;
3180 /* this holds info on user ids that are already validated for this VC */
3181 sconn
->smb1
.sessions
.validated_users
= NULL
;
3182 sconn
->smb1
.sessions
.next_vuid
= VUID_OFFSET
;
3183 sconn
->smb1
.sessions
.num_validated_vuids
= 0;
3186 if (!init_dptrs(sconn
)) {
3187 exit_server("init_dptrs() failed");
3190 sconn
->smb1
.fde
= event_add_fd(ev_ctx
,
3194 smbd_server_connection_handler
,
3196 if (!sconn
->smb1
.fde
) {
3197 exit_server("failed to create smbd_server_connection fde");
3205 frame
= talloc_stackframe_pool(8192);
3209 status
= smbd_server_connection_loop_once(ev_ctx
, sconn
);
3210 if (!NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
) &&
3211 !NT_STATUS_IS_OK(status
)) {
3212 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3213 " exiting\n", nt_errstr(status
)));
3220 exit_server_cleanly(NULL
);
3223 bool req_is_in_chain(struct smb_request
*req
)
3225 if (req
->vwv
!= (const uint16_t *)(req
->inbuf
+smb_vwv
)) {
3227 * We're right now handling a subsequent request, so we must
3233 if (!is_andx_req(req
->cmd
)) {
3239 * Okay, an illegal request, but definitely not chained :-)
3244 return (CVAL(req
->vwv
+0, 0) != 0xFF);