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 "system/filesys.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "librpc/gen_ndr/netlogon.h"
26 #include "librpc/gen_ndr/messaging.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/pcap.h"
31 #include "system/select.h"
35 extern bool global_machine_password_needs_changing
;
37 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
39 static struct pending_message_list
*get_deferred_open_message_smb(uint64_t mid
);
41 static bool smbd_lock_socket_internal(struct smbd_server_connection
*sconn
)
45 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
49 sconn
->smb1
.echo_handler
.ref_count
++;
51 if (sconn
->smb1
.echo_handler
.ref_count
> 1) {
55 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
59 sconn
->smb1
.echo_handler
.socket_lock_fd
,
60 SMB_F_SETLKW
, 0, 0, F_WRLCK
);
61 } while (!ok
&& (errno
== EINTR
));
64 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
68 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
73 void smbd_lock_socket(struct smbd_server_connection
*sconn
)
75 if (!smbd_lock_socket_internal(sconn
)) {
76 exit_server_cleanly("failed to lock socket");
80 static bool smbd_unlock_socket_internal(struct smbd_server_connection
*sconn
)
84 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
88 sconn
->smb1
.echo_handler
.ref_count
--;
90 if (sconn
->smb1
.echo_handler
.ref_count
> 0) {
96 sconn
->smb1
.echo_handler
.socket_lock_fd
,
97 SMB_F_SETLKW
, 0, 0, F_UNLCK
);
98 } while (!ok
&& (errno
== EINTR
));
101 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
105 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
110 void smbd_unlock_socket(struct smbd_server_connection
*sconn
)
112 if (!smbd_unlock_socket_internal(sconn
)) {
113 exit_server_cleanly("failed to unlock socket");
117 /* Accessor function for smb_read_error for smbd functions. */
119 /****************************************************************************
121 ****************************************************************************/
123 bool srv_send_smb(struct smbd_server_connection
*sconn
, char *buffer
,
124 bool do_signing
, uint32_t seqnum
,
126 struct smb_perfcount_data
*pcd
)
131 char *buf_out
= buffer
;
133 smbd_lock_socket(sconn
);
136 /* Sign the outgoing packet if required. */
137 srv_calculate_sign_mac(sconn
, buf_out
, seqnum
);
141 NTSTATUS status
= srv_encrypt_buffer(buffer
, &buf_out
);
142 if (!NT_STATUS_IS_OK(status
)) {
143 DEBUG(0, ("send_smb: SMB encryption failed "
144 "on outgoing packet! Error %s\n",
145 nt_errstr(status
) ));
150 len
= smb_len(buf_out
) + 4;
152 ret
= write_data(sconn
->sock
, buf_out
+nwritten
, len
- nwritten
);
155 char addr
[INET6_ADDRSTRLEN
];
157 * Try and give an error message saying what
160 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
161 (int)sys_getpid(), (int)len
,
162 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
163 (int)ret
, strerror(errno
) ));
165 srv_free_enc_buffer(buf_out
);
169 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
170 srv_free_enc_buffer(buf_out
);
172 SMB_PERFCOUNT_END(pcd
);
174 smbd_unlock_socket(sconn
);
178 /*******************************************************************
179 Setup the word count and byte count for a smb message.
180 ********************************************************************/
182 int srv_set_message(char *buf
,
187 if (zero
&& (num_words
|| num_bytes
)) {
188 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
190 SCVAL(buf
,smb_wct
,num_words
);
191 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
192 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
193 return (smb_size
+ num_words
*2 + num_bytes
);
196 static bool valid_smb_header(const uint8_t *inbuf
)
198 if (is_encrypted_packet(inbuf
)) {
202 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
203 * but it just looks weird to call strncmp for this one.
205 return (IVAL(smb_base(inbuf
), 0) == 0x424D53FF);
208 /* Socket functions for smbd packet processing. */
210 static bool valid_packet_size(size_t len
)
213 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
214 * of header. Don't print the error if this fits.... JRA.
217 if (len
> (BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
218 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
219 (unsigned long)len
));
225 static NTSTATUS
read_packet_remainder(int fd
, char *buffer
,
226 unsigned int timeout
, ssize_t len
)
234 status
= read_fd_with_timeout(fd
, buffer
, len
, len
, timeout
, NULL
);
235 if (!NT_STATUS_IS_OK(status
)) {
236 char addr
[INET6_ADDRSTRLEN
];
237 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
239 get_peer_addr(fd
, addr
, sizeof(addr
)),
245 /****************************************************************************
246 Attempt a zerocopy writeX read. We know here that len > smb_size-4
247 ****************************************************************************/
250 * Unfortunately, earlier versions of smbclient/libsmbclient
251 * don't send this "standard" writeX header. I've fixed this
252 * for 3.2 but we'll use the old method with earlier versions.
253 * Windows and CIFSFS at least use this standard size. Not
257 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
258 (2*14) + /* word count (including bcc) */ \
261 static NTSTATUS
receive_smb_raw_talloc_partial_read(TALLOC_CTX
*mem_ctx
,
262 const char lenbuf
[4],
263 struct smbd_server_connection
*sconn
,
265 unsigned int timeout
,
269 /* Size of a WRITEX call (+4 byte len). */
270 char writeX_header
[4 + STANDARD_WRITE_AND_X_HEADER_SIZE
];
271 ssize_t len
= smb_len_large(lenbuf
); /* Could be a UNIX large writeX. */
275 memcpy(writeX_header
, lenbuf
, 4);
277 status
= read_fd_with_timeout(
278 sconn
->sock
, writeX_header
+ 4,
279 STANDARD_WRITE_AND_X_HEADER_SIZE
,
280 STANDARD_WRITE_AND_X_HEADER_SIZE
,
283 if (!NT_STATUS_IS_OK(status
)) {
284 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
285 "error = %s.\n", sconn
->client_id
.addr
,
291 * Ok - now try and see if this is a possible
295 if (is_valid_writeX_buffer(sconn
, (uint8_t *)writeX_header
)) {
297 * If the data offset is beyond what
298 * we've read, drain the extra bytes.
300 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
303 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
304 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
305 if (drain_socket(sconn
->sock
, drain
) != drain
) {
306 smb_panic("receive_smb_raw_talloc_partial_read:"
307 " failed to drain pending bytes");
310 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
313 /* Spoof down the length and null out the bcc. */
314 set_message_bcc(writeX_header
, 0);
315 newlen
= smb_len(writeX_header
);
317 /* Copy the header we've written. */
319 *buffer
= (char *)TALLOC_MEMDUP(mem_ctx
,
321 sizeof(writeX_header
));
323 if (*buffer
== NULL
) {
324 DEBUG(0, ("Could not allocate inbuf of length %d\n",
325 (int)sizeof(writeX_header
)));
326 return NT_STATUS_NO_MEMORY
;
329 /* Work out the remaining bytes. */
330 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
331 *len_ret
= newlen
+ 4;
335 if (!valid_packet_size(len
)) {
336 return NT_STATUS_INVALID_PARAMETER
;
340 * Not a valid writeX call. Just do the standard
344 *buffer
= TALLOC_ARRAY(mem_ctx
, char, len
+4);
346 if (*buffer
== NULL
) {
347 DEBUG(0, ("Could not allocate inbuf of length %d\n",
349 return NT_STATUS_NO_MEMORY
;
352 /* Copy in what we already read. */
355 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
356 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
359 status
= read_packet_remainder(
361 (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
364 if (!NT_STATUS_IS_OK(status
)) {
365 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
375 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
,
376 struct smbd_server_connection
*sconn
,
377 char **buffer
, unsigned int timeout
,
378 size_t *p_unread
, size_t *plen
)
382 int min_recv_size
= lp_min_receive_file_size();
387 status
= read_smb_length_return_keepalive(sconn
->sock
, lenbuf
, timeout
,
389 if (!NT_STATUS_IS_OK(status
)) {
393 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
394 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
395 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
396 !srv_is_signing_active(sconn
) &&
397 sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
399 return receive_smb_raw_talloc_partial_read(
400 mem_ctx
, lenbuf
, sconn
, buffer
, timeout
,
404 if (!valid_packet_size(len
)) {
405 return NT_STATUS_INVALID_PARAMETER
;
409 * The +4 here can't wrap, we've checked the length above already.
412 *buffer
= TALLOC_ARRAY(mem_ctx
, char, len
+4);
414 if (*buffer
== NULL
) {
415 DEBUG(0, ("Could not allocate inbuf of length %d\n",
417 return NT_STATUS_NO_MEMORY
;
420 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
422 status
= read_packet_remainder(sconn
->sock
, (*buffer
)+4, timeout
, len
);
423 if (!NT_STATUS_IS_OK(status
)) {
431 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
,
432 struct smbd_server_connection
*sconn
,
433 char **buffer
, unsigned int timeout
,
434 size_t *p_unread
, bool *p_encrypted
,
437 bool trusted_channel
)
442 *p_encrypted
= false;
444 status
= receive_smb_raw_talloc(mem_ctx
, sconn
, buffer
, timeout
,
446 if (!NT_STATUS_IS_OK(status
)) {
447 DEBUG(1, ("read_smb_length_return_keepalive failed for "
448 "client %s read error = %s.\n",
449 sconn
->client_id
.addr
, nt_errstr(status
)));
453 if (is_encrypted_packet((uint8_t *)*buffer
)) {
454 status
= srv_decrypt_buffer(*buffer
);
455 if (!NT_STATUS_IS_OK(status
)) {
456 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
457 "incoming packet! Error %s\n",
458 nt_errstr(status
) ));
464 /* Check the incoming SMB signature. */
465 if (!srv_check_sign_mac(sconn
, *buffer
, seqnum
, trusted_channel
)) {
466 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
467 "incoming packet!\n"));
468 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
476 * Initialize a struct smb_request from an inbuf
479 static bool init_smb_request(struct smb_request
*req
,
480 struct smbd_server_connection
*sconn
,
482 size_t unread_bytes
, bool encrypted
,
485 size_t req_size
= smb_len(inbuf
) + 4;
486 /* Ensure we have at least smb_size bytes. */
487 if (req_size
< smb_size
) {
488 DEBUG(0,("init_smb_request: invalid request size %u\n",
489 (unsigned int)req_size
));
492 req
->cmd
= CVAL(inbuf
, smb_com
);
493 req
->flags2
= SVAL(inbuf
, smb_flg2
);
494 req
->smbpid
= SVAL(inbuf
, smb_pid
);
495 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
496 req
->seqnum
= seqnum
;
497 req
->vuid
= SVAL(inbuf
, smb_uid
);
498 req
->tid
= SVAL(inbuf
, smb_tid
);
499 req
->wct
= CVAL(inbuf
, smb_wct
);
500 req
->vwv
= (uint16_t *)(inbuf
+smb_vwv
);
501 req
->buflen
= smb_buflen(inbuf
);
502 req
->buf
= (const uint8_t *)smb_buf(inbuf
);
503 req
->unread_bytes
= unread_bytes
;
504 req
->encrypted
= encrypted
;
506 req
->conn
= conn_find(sconn
,req
->tid
);
507 req
->chain_fsp
= NULL
;
508 req
->chain_outbuf
= NULL
;
511 smb_init_perfcount_data(&req
->pcd
);
513 /* Ensure we have at least wct words and 2 bytes of bcc. */
514 if (smb_size
+ req
->wct
*2 > req_size
) {
515 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
516 (unsigned int)req
->wct
,
517 (unsigned int)req_size
));
520 /* Ensure bcc is correct. */
521 if (((uint8
*)smb_buf(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
522 DEBUG(0,("init_smb_request: invalid bcc number %u "
523 "(wct = %u, size %u)\n",
524 (unsigned int)req
->buflen
,
525 (unsigned int)req
->wct
,
526 (unsigned int)req_size
));
534 static void process_smb(struct smbd_server_connection
*conn
,
535 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
536 uint32_t seqnum
, bool encrypted
,
537 struct smb_perfcount_data
*deferred_pcd
);
539 static void smbd_deferred_open_timer(struct event_context
*ev
,
540 struct timed_event
*te
,
541 struct timeval _tval
,
544 struct pending_message_list
*msg
= talloc_get_type(private_data
,
545 struct pending_message_list
);
546 TALLOC_CTX
*mem_ctx
= talloc_tos();
547 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
550 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
553 exit_server("smbd_deferred_open_timer: talloc failed\n");
557 /* We leave this message on the queue so the open code can
558 know this is a retry. */
559 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
560 (unsigned long long)mid
));
562 /* Mark the message as processed so this is not
563 * re-processed in error. */
564 msg
->processed
= true;
566 process_smb(smbd_server_conn
, inbuf
,
568 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
570 /* If it's still there and was processed, remove it. */
571 msg
= get_deferred_open_message_smb(mid
);
572 if (msg
&& msg
->processed
) {
573 remove_deferred_open_message_smb(mid
);
577 /****************************************************************************
578 Function to push a message onto the tail of a linked list of smb messages ready
580 ****************************************************************************/
582 static bool push_queued_message(struct smb_request
*req
,
583 struct timeval request_time
,
584 struct timeval end_time
,
585 char *private_data
, size_t private_len
)
587 int msg_len
= smb_len(req
->inbuf
) + 4;
588 struct pending_message_list
*msg
;
590 msg
= TALLOC_ZERO_P(NULL
, struct pending_message_list
);
593 DEBUG(0,("push_message: malloc fail (1)\n"));
597 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
598 if(msg
->buf
.data
== NULL
) {
599 DEBUG(0,("push_message: malloc fail (2)\n"));
604 msg
->request_time
= request_time
;
605 msg
->seqnum
= req
->seqnum
;
606 msg
->encrypted
= req
->encrypted
;
607 msg
->processed
= false;
608 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
611 msg
->private_data
= data_blob_talloc(msg
, private_data
,
613 if (msg
->private_data
.data
== NULL
) {
614 DEBUG(0,("push_message: malloc fail (3)\n"));
620 msg
->te
= event_add_timed(smbd_event_context(),
623 smbd_deferred_open_timer
,
626 DEBUG(0,("push_message: event_add_timed failed\n"));
631 DLIST_ADD_END(deferred_open_queue
, msg
, struct pending_message_list
*);
633 DEBUG(10,("push_message: pushed message length %u on "
634 "deferred_open_queue\n", (unsigned int)msg_len
));
639 /****************************************************************************
640 Function to delete a sharing violation open message by mid.
641 ****************************************************************************/
643 void remove_deferred_open_message_smb(uint64_t mid
)
645 struct pending_message_list
*pml
;
647 if (smbd_server_conn
->using_smb2
) {
648 remove_deferred_open_message_smb2(smbd_server_conn
, mid
);
652 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
653 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
654 DEBUG(10,("remove_deferred_open_message_smb: "
655 "deleting mid %llu len %u\n",
656 (unsigned long long)mid
,
657 (unsigned int)pml
->buf
.length
));
658 DLIST_REMOVE(deferred_open_queue
, pml
);
665 /****************************************************************************
666 Move a sharing violation open retry message to the front of the list and
667 schedule it for immediate processing.
668 ****************************************************************************/
670 void schedule_deferred_open_message_smb(uint64_t mid
)
672 struct pending_message_list
*pml
;
675 if (smbd_server_conn
->using_smb2
) {
676 schedule_deferred_open_message_smb2(smbd_server_conn
, mid
);
680 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
681 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
683 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
686 (unsigned long long)msg_mid
));
688 if (mid
== msg_mid
) {
689 struct timed_event
*te
;
691 if (pml
->processed
) {
692 /* A processed message should not be
694 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
695 "message mid %llu was already processed\n",
696 (unsigned long long)msg_mid
));
700 DEBUG(10,("schedule_deferred_open_message_smb: "
701 "scheduling mid %llu\n",
702 (unsigned long long)mid
));
704 te
= event_add_timed(smbd_event_context(),
707 smbd_deferred_open_timer
,
710 DEBUG(10,("schedule_deferred_open_message_smb: "
711 "event_add_timed() failed, "
712 "skipping mid %llu\n",
713 (unsigned long long)msg_mid
));
716 TALLOC_FREE(pml
->te
);
718 DLIST_PROMOTE(deferred_open_queue
, pml
);
723 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
724 "find message mid %llu\n",
725 (unsigned long long)mid
));
728 /****************************************************************************
729 Return true if this mid is on the deferred queue and was not yet processed.
730 ****************************************************************************/
732 bool open_was_deferred(uint64_t mid
)
734 struct pending_message_list
*pml
;
736 if (smbd_server_conn
->using_smb2
) {
737 return open_was_deferred_smb2(smbd_server_conn
, mid
);
740 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
741 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
748 /****************************************************************************
749 Return the message queued by this mid.
750 ****************************************************************************/
752 static struct pending_message_list
*get_deferred_open_message_smb(uint64_t mid
)
754 struct pending_message_list
*pml
;
756 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
757 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
764 /****************************************************************************
765 Get the state data queued by this mid.
766 ****************************************************************************/
768 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
769 struct timeval
*p_request_time
,
772 struct pending_message_list
*pml
;
774 if (smbd_server_conn
->using_smb2
) {
775 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
780 pml
= get_deferred_open_message_smb(smbreq
->mid
);
784 if (p_request_time
) {
785 *p_request_time
= pml
->request_time
;
788 *pp_state
= (void *)pml
->private_data
.data
;
793 /****************************************************************************
794 Function to push a deferred open smb message onto a linked list of local smb
795 messages ready for processing.
796 ****************************************************************************/
798 bool push_deferred_open_message_smb(struct smb_request
*req
,
799 struct timeval request_time
,
800 struct timeval timeout
,
802 char *private_data
, size_t priv_len
)
804 struct timeval end_time
;
807 return push_deferred_open_message_smb2(req
->smb2req
,
815 if (req
->unread_bytes
) {
816 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
817 "unread_bytes = %u\n",
818 (unsigned int)req
->unread_bytes
));
819 smb_panic("push_deferred_open_message_smb: "
820 "logic error unread_bytes != 0" );
823 end_time
= timeval_sum(&request_time
, &timeout
);
825 DEBUG(10,("push_deferred_open_message_smb: pushing message "
826 "len %u mid %llu timeout time [%u.%06u]\n",
827 (unsigned int) smb_len(req
->inbuf
)+4,
828 (unsigned long long)req
->mid
,
829 (unsigned int)end_time
.tv_sec
,
830 (unsigned int)end_time
.tv_usec
));
832 return push_queued_message(req
, request_time
, end_time
,
833 private_data
, priv_len
);
837 struct timed_event
*te
;
838 struct timeval interval
;
840 bool (*handler
)(const struct timeval
*now
, void *private_data
);
844 static void smbd_idle_event_handler(struct event_context
*ctx
,
845 struct timed_event
*te
,
849 struct idle_event
*event
=
850 talloc_get_type_abort(private_data
, struct idle_event
);
852 TALLOC_FREE(event
->te
);
854 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
855 event
->name
, event
->te
));
857 if (!event
->handler(&now
, event
->private_data
)) {
858 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
859 event
->name
, event
->te
));
860 /* Don't repeat, delete ourselves */
865 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
866 event
->name
, event
->te
));
868 event
->te
= event_add_timed(ctx
, event
,
869 timeval_sum(&now
, &event
->interval
),
870 smbd_idle_event_handler
, event
);
872 /* We can't do much but fail here. */
873 SMB_ASSERT(event
->te
!= NULL
);
876 struct idle_event
*event_add_idle(struct event_context
*event_ctx
,
878 struct timeval interval
,
880 bool (*handler
)(const struct timeval
*now
,
884 struct idle_event
*result
;
885 struct timeval now
= timeval_current();
887 result
= TALLOC_P(mem_ctx
, struct idle_event
);
888 if (result
== NULL
) {
889 DEBUG(0, ("talloc failed\n"));
893 result
->interval
= interval
;
894 result
->handler
= handler
;
895 result
->private_data
= private_data
;
897 if (!(result
->name
= talloc_asprintf(result
, "idle_evt(%s)", name
))) {
898 DEBUG(0, ("talloc failed\n"));
903 result
->te
= event_add_timed(event_ctx
, result
,
904 timeval_sum(&now
, &interval
),
905 smbd_idle_event_handler
, result
);
906 if (result
->te
== NULL
) {
907 DEBUG(0, ("event_add_timed failed\n"));
912 DEBUG(10,("event_add_idle: %s %p\n", result
->name
, result
->te
));
916 static void smbd_sig_term_handler(struct tevent_context
*ev
,
917 struct tevent_signal
*se
,
923 exit_server_cleanly("termination signal");
926 void smbd_setup_sig_term_handler(void)
928 struct tevent_signal
*se
;
930 se
= tevent_add_signal(smbd_event_context(),
931 smbd_event_context(),
933 smbd_sig_term_handler
,
936 exit_server("failed to setup SIGTERM handler");
940 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
941 struct tevent_signal
*se
,
947 struct messaging_context
*msg_ctx
= talloc_get_type_abort(
948 private_data
, struct messaging_context
);
949 change_to_root_user();
950 DEBUG(1,("Reloading services after SIGHUP\n"));
951 reload_services(msg_ctx
, smbd_server_conn
->sock
, False
);
953 pcap_cache_reload(ev
, msg_ctx
, &reload_pcap_change_notify
);
957 void smbd_setup_sig_hup_handler(struct tevent_context
*ev
,
958 struct messaging_context
*msg_ctx
)
960 struct tevent_signal
*se
;
962 se
= tevent_add_signal(ev
, ev
, SIGHUP
, 0, smbd_sig_hup_handler
,
965 exit_server("failed to setup SIGHUP handler");
969 static NTSTATUS
smbd_server_connection_loop_once(struct smbd_server_connection
*conn
)
976 timeout
= SMBD_SELECT_TIMEOUT
* 1000;
979 * Are there any timed events waiting ? If so, ensure we don't
980 * select for longer than it would take to wait for them.
983 event_add_to_poll_args(smbd_event_context(), conn
,
984 &conn
->pfds
, &num_pfds
, &timeout
);
986 /* Process a signal and timed events now... */
987 if (run_events_poll(smbd_event_context(), 0, NULL
, 0)) {
988 return NT_STATUS_RETRY
;
993 START_PROFILE(smbd_idle
);
995 ret
= sys_poll(conn
->pfds
, num_pfds
, timeout
);
998 END_PROFILE(smbd_idle
);
1002 if (ret
== -1 && errno
!= EINTR
) {
1003 return map_nt_error_from_unix(errno
);
1006 retry
= run_events_poll(smbd_event_context(), ret
, conn
->pfds
,
1009 return NT_STATUS_RETRY
;
1012 /* Did we timeout ? */
1014 return NT_STATUS_RETRY
;
1017 /* should not be reached */
1018 return NT_STATUS_INTERNAL_ERROR
;
1022 * Only allow 5 outstanding trans requests. We're allocating memory, so
1026 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
1029 for (; list
!= NULL
; list
= list
->next
) {
1031 if (list
->mid
== mid
) {
1032 return NT_STATUS_INVALID_PARAMETER
;
1038 return NT_STATUS_INSUFFICIENT_RESOURCES
;
1041 return NT_STATUS_OK
;
1045 These flags determine some of the permissions required to do an operation
1047 Note that I don't set NEED_WRITE on some write operations because they
1048 are used by some brain-dead clients when printing, and I don't want to
1049 force write permissions on print services.
1051 #define AS_USER (1<<0)
1052 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1053 #define TIME_INIT (1<<2)
1054 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1055 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1056 #define DO_CHDIR (1<<6)
1059 define a list of possible SMB messages and their corresponding
1060 functions. Any message that has a NULL function is unimplemented -
1061 please feel free to contribute implementations!
1063 static const struct smb_message_struct
{
1065 void (*fn
)(struct smb_request
*req
);
1067 } smb_messages
[256] = {
1069 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1070 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1071 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1072 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1073 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1074 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1075 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1076 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1077 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1078 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1079 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1080 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1081 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1082 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1083 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1084 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1085 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1086 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1087 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1088 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1089 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1090 /* 0x15 */ { NULL
, NULL
, 0 },
1091 /* 0x16 */ { NULL
, NULL
, 0 },
1092 /* 0x17 */ { NULL
, NULL
, 0 },
1093 /* 0x18 */ { NULL
, NULL
, 0 },
1094 /* 0x19 */ { NULL
, NULL
, 0 },
1095 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1096 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1097 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1098 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1099 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1100 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1101 /* 0x20 */ { "SMBwritec", NULL
,0},
1102 /* 0x21 */ { NULL
, NULL
, 0 },
1103 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1104 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1105 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1106 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1107 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1108 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1109 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1110 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1111 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1112 /* 0x2b */ { "SMBecho",reply_echo
,0},
1113 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1114 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1115 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1116 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1117 /* 0x30 */ { NULL
, NULL
, 0 },
1118 /* 0x31 */ { NULL
, NULL
, 0 },
1119 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1120 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1121 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1122 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1123 /* 0x36 */ { NULL
, NULL
, 0 },
1124 /* 0x37 */ { NULL
, NULL
, 0 },
1125 /* 0x38 */ { NULL
, NULL
, 0 },
1126 /* 0x39 */ { NULL
, NULL
, 0 },
1127 /* 0x3a */ { NULL
, NULL
, 0 },
1128 /* 0x3b */ { NULL
, NULL
, 0 },
1129 /* 0x3c */ { NULL
, NULL
, 0 },
1130 /* 0x3d */ { NULL
, NULL
, 0 },
1131 /* 0x3e */ { NULL
, NULL
, 0 },
1132 /* 0x3f */ { NULL
, NULL
, 0 },
1133 /* 0x40 */ { NULL
, NULL
, 0 },
1134 /* 0x41 */ { NULL
, NULL
, 0 },
1135 /* 0x42 */ { NULL
, NULL
, 0 },
1136 /* 0x43 */ { NULL
, NULL
, 0 },
1137 /* 0x44 */ { NULL
, NULL
, 0 },
1138 /* 0x45 */ { NULL
, NULL
, 0 },
1139 /* 0x46 */ { NULL
, NULL
, 0 },
1140 /* 0x47 */ { NULL
, NULL
, 0 },
1141 /* 0x48 */ { NULL
, NULL
, 0 },
1142 /* 0x49 */ { NULL
, NULL
, 0 },
1143 /* 0x4a */ { NULL
, NULL
, 0 },
1144 /* 0x4b */ { NULL
, NULL
, 0 },
1145 /* 0x4c */ { NULL
, NULL
, 0 },
1146 /* 0x4d */ { NULL
, NULL
, 0 },
1147 /* 0x4e */ { NULL
, NULL
, 0 },
1148 /* 0x4f */ { NULL
, NULL
, 0 },
1149 /* 0x50 */ { NULL
, NULL
, 0 },
1150 /* 0x51 */ { NULL
, NULL
, 0 },
1151 /* 0x52 */ { NULL
, NULL
, 0 },
1152 /* 0x53 */ { NULL
, NULL
, 0 },
1153 /* 0x54 */ { NULL
, NULL
, 0 },
1154 /* 0x55 */ { NULL
, NULL
, 0 },
1155 /* 0x56 */ { NULL
, NULL
, 0 },
1156 /* 0x57 */ { NULL
, NULL
, 0 },
1157 /* 0x58 */ { NULL
, NULL
, 0 },
1158 /* 0x59 */ { NULL
, NULL
, 0 },
1159 /* 0x5a */ { NULL
, NULL
, 0 },
1160 /* 0x5b */ { NULL
, NULL
, 0 },
1161 /* 0x5c */ { NULL
, NULL
, 0 },
1162 /* 0x5d */ { NULL
, NULL
, 0 },
1163 /* 0x5e */ { NULL
, NULL
, 0 },
1164 /* 0x5f */ { NULL
, NULL
, 0 },
1165 /* 0x60 */ { NULL
, NULL
, 0 },
1166 /* 0x61 */ { NULL
, NULL
, 0 },
1167 /* 0x62 */ { NULL
, NULL
, 0 },
1168 /* 0x63 */ { NULL
, NULL
, 0 },
1169 /* 0x64 */ { NULL
, NULL
, 0 },
1170 /* 0x65 */ { NULL
, NULL
, 0 },
1171 /* 0x66 */ { NULL
, NULL
, 0 },
1172 /* 0x67 */ { NULL
, NULL
, 0 },
1173 /* 0x68 */ { NULL
, NULL
, 0 },
1174 /* 0x69 */ { NULL
, NULL
, 0 },
1175 /* 0x6a */ { NULL
, NULL
, 0 },
1176 /* 0x6b */ { NULL
, NULL
, 0 },
1177 /* 0x6c */ { NULL
, NULL
, 0 },
1178 /* 0x6d */ { NULL
, NULL
, 0 },
1179 /* 0x6e */ { NULL
, NULL
, 0 },
1180 /* 0x6f */ { NULL
, NULL
, 0 },
1181 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1182 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1183 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1184 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1185 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1186 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1187 /* 0x76 */ { NULL
, NULL
, 0 },
1188 /* 0x77 */ { NULL
, NULL
, 0 },
1189 /* 0x78 */ { NULL
, NULL
, 0 },
1190 /* 0x79 */ { NULL
, NULL
, 0 },
1191 /* 0x7a */ { NULL
, NULL
, 0 },
1192 /* 0x7b */ { NULL
, NULL
, 0 },
1193 /* 0x7c */ { NULL
, NULL
, 0 },
1194 /* 0x7d */ { NULL
, NULL
, 0 },
1195 /* 0x7e */ { NULL
, NULL
, 0 },
1196 /* 0x7f */ { NULL
, NULL
, 0 },
1197 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1198 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1199 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1200 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1201 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1202 /* 0x85 */ { NULL
, NULL
, 0 },
1203 /* 0x86 */ { NULL
, NULL
, 0 },
1204 /* 0x87 */ { NULL
, NULL
, 0 },
1205 /* 0x88 */ { NULL
, NULL
, 0 },
1206 /* 0x89 */ { NULL
, NULL
, 0 },
1207 /* 0x8a */ { NULL
, NULL
, 0 },
1208 /* 0x8b */ { NULL
, NULL
, 0 },
1209 /* 0x8c */ { NULL
, NULL
, 0 },
1210 /* 0x8d */ { NULL
, NULL
, 0 },
1211 /* 0x8e */ { NULL
, NULL
, 0 },
1212 /* 0x8f */ { NULL
, NULL
, 0 },
1213 /* 0x90 */ { NULL
, NULL
, 0 },
1214 /* 0x91 */ { NULL
, NULL
, 0 },
1215 /* 0x92 */ { NULL
, NULL
, 0 },
1216 /* 0x93 */ { NULL
, NULL
, 0 },
1217 /* 0x94 */ { NULL
, NULL
, 0 },
1218 /* 0x95 */ { NULL
, NULL
, 0 },
1219 /* 0x96 */ { NULL
, NULL
, 0 },
1220 /* 0x97 */ { NULL
, NULL
, 0 },
1221 /* 0x98 */ { NULL
, NULL
, 0 },
1222 /* 0x99 */ { NULL
, NULL
, 0 },
1223 /* 0x9a */ { NULL
, NULL
, 0 },
1224 /* 0x9b */ { NULL
, NULL
, 0 },
1225 /* 0x9c */ { NULL
, NULL
, 0 },
1226 /* 0x9d */ { NULL
, NULL
, 0 },
1227 /* 0x9e */ { NULL
, NULL
, 0 },
1228 /* 0x9f */ { NULL
, NULL
, 0 },
1229 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1230 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1231 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1232 /* 0xa3 */ { NULL
, NULL
, 0 },
1233 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1234 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1235 /* 0xa6 */ { NULL
, NULL
, 0 },
1236 /* 0xa7 */ { NULL
, NULL
, 0 },
1237 /* 0xa8 */ { NULL
, NULL
, 0 },
1238 /* 0xa9 */ { NULL
, NULL
, 0 },
1239 /* 0xaa */ { NULL
, NULL
, 0 },
1240 /* 0xab */ { NULL
, NULL
, 0 },
1241 /* 0xac */ { NULL
, NULL
, 0 },
1242 /* 0xad */ { NULL
, NULL
, 0 },
1243 /* 0xae */ { NULL
, NULL
, 0 },
1244 /* 0xaf */ { NULL
, NULL
, 0 },
1245 /* 0xb0 */ { NULL
, NULL
, 0 },
1246 /* 0xb1 */ { NULL
, NULL
, 0 },
1247 /* 0xb2 */ { NULL
, NULL
, 0 },
1248 /* 0xb3 */ { NULL
, NULL
, 0 },
1249 /* 0xb4 */ { NULL
, NULL
, 0 },
1250 /* 0xb5 */ { NULL
, NULL
, 0 },
1251 /* 0xb6 */ { NULL
, NULL
, 0 },
1252 /* 0xb7 */ { NULL
, NULL
, 0 },
1253 /* 0xb8 */ { NULL
, NULL
, 0 },
1254 /* 0xb9 */ { NULL
, NULL
, 0 },
1255 /* 0xba */ { NULL
, NULL
, 0 },
1256 /* 0xbb */ { NULL
, NULL
, 0 },
1257 /* 0xbc */ { NULL
, NULL
, 0 },
1258 /* 0xbd */ { NULL
, NULL
, 0 },
1259 /* 0xbe */ { NULL
, NULL
, 0 },
1260 /* 0xbf */ { NULL
, NULL
, 0 },
1261 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1262 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1263 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1264 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1265 /* 0xc4 */ { NULL
, NULL
, 0 },
1266 /* 0xc5 */ { NULL
, NULL
, 0 },
1267 /* 0xc6 */ { NULL
, NULL
, 0 },
1268 /* 0xc7 */ { NULL
, NULL
, 0 },
1269 /* 0xc8 */ { NULL
, NULL
, 0 },
1270 /* 0xc9 */ { NULL
, NULL
, 0 },
1271 /* 0xca */ { NULL
, NULL
, 0 },
1272 /* 0xcb */ { NULL
, NULL
, 0 },
1273 /* 0xcc */ { NULL
, NULL
, 0 },
1274 /* 0xcd */ { NULL
, NULL
, 0 },
1275 /* 0xce */ { NULL
, NULL
, 0 },
1276 /* 0xcf */ { NULL
, NULL
, 0 },
1277 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1278 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1279 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1280 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1281 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1282 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1283 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1284 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1285 /* 0xd8 */ { NULL
, NULL
, 0 },
1286 /* 0xd9 */ { NULL
, NULL
, 0 },
1287 /* 0xda */ { NULL
, NULL
, 0 },
1288 /* 0xdb */ { NULL
, NULL
, 0 },
1289 /* 0xdc */ { NULL
, NULL
, 0 },
1290 /* 0xdd */ { NULL
, NULL
, 0 },
1291 /* 0xde */ { NULL
, NULL
, 0 },
1292 /* 0xdf */ { NULL
, NULL
, 0 },
1293 /* 0xe0 */ { NULL
, NULL
, 0 },
1294 /* 0xe1 */ { NULL
, NULL
, 0 },
1295 /* 0xe2 */ { NULL
, NULL
, 0 },
1296 /* 0xe3 */ { NULL
, NULL
, 0 },
1297 /* 0xe4 */ { NULL
, NULL
, 0 },
1298 /* 0xe5 */ { NULL
, NULL
, 0 },
1299 /* 0xe6 */ { NULL
, NULL
, 0 },
1300 /* 0xe7 */ { NULL
, NULL
, 0 },
1301 /* 0xe8 */ { NULL
, NULL
, 0 },
1302 /* 0xe9 */ { NULL
, NULL
, 0 },
1303 /* 0xea */ { NULL
, NULL
, 0 },
1304 /* 0xeb */ { NULL
, NULL
, 0 },
1305 /* 0xec */ { NULL
, NULL
, 0 },
1306 /* 0xed */ { NULL
, NULL
, 0 },
1307 /* 0xee */ { NULL
, NULL
, 0 },
1308 /* 0xef */ { NULL
, NULL
, 0 },
1309 /* 0xf0 */ { NULL
, NULL
, 0 },
1310 /* 0xf1 */ { NULL
, NULL
, 0 },
1311 /* 0xf2 */ { NULL
, NULL
, 0 },
1312 /* 0xf3 */ { NULL
, NULL
, 0 },
1313 /* 0xf4 */ { NULL
, NULL
, 0 },
1314 /* 0xf5 */ { NULL
, NULL
, 0 },
1315 /* 0xf6 */ { NULL
, NULL
, 0 },
1316 /* 0xf7 */ { NULL
, NULL
, 0 },
1317 /* 0xf8 */ { NULL
, NULL
, 0 },
1318 /* 0xf9 */ { NULL
, NULL
, 0 },
1319 /* 0xfa */ { NULL
, NULL
, 0 },
1320 /* 0xfb */ { NULL
, NULL
, 0 },
1321 /* 0xfc */ { NULL
, NULL
, 0 },
1322 /* 0xfd */ { NULL
, NULL
, 0 },
1323 /* 0xfe */ { NULL
, NULL
, 0 },
1324 /* 0xff */ { NULL
, NULL
, 0 }
1328 /*******************************************************************
1329 allocate and initialize a reply packet
1330 ********************************************************************/
1332 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1333 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1337 * Protect against integer wrap
1339 if ((num_bytes
> 0xffffff)
1340 || ((num_bytes
+ smb_size
+ num_words
*2) > 0xffffff)) {
1342 if (asprintf(&msg
, "num_bytes too large: %u",
1343 (unsigned)num_bytes
) == -1) {
1344 msg
= CONST_DISCARD(char *, "num_bytes too large");
1349 *outbuf
= TALLOC_ARRAY(mem_ctx
, char,
1350 smb_size
+ num_words
*2 + num_bytes
);
1351 if (*outbuf
== NULL
) {
1355 construct_reply_common(req
, inbuf
, *outbuf
);
1356 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1358 * Zero out the word area, the caller has to take care of the bcc area
1361 if (num_words
!= 0) {
1362 memset(*outbuf
+ smb_vwv0
, 0, num_words
*2);
1368 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1371 if (!create_outbuf(req
, req
, (char *)req
->inbuf
, &outbuf
, num_words
,
1373 smb_panic("could not allocate output buffer\n");
1375 req
->outbuf
= (uint8_t *)outbuf
;
1379 /*******************************************************************
1380 Dump a packet to a file.
1381 ********************************************************************/
1383 static void smb_dump(const char *name
, int type
, const char *data
, ssize_t len
)
1387 if (DEBUGLEVEL
< 50) {
1391 if (len
< 4) len
= smb_len(data
)+4;
1392 for (i
=1;i
<100;i
++) {
1393 if (asprintf(&fname
, "/tmp/%s.%d.%s", name
, i
,
1394 type
? "req" : "resp") == -1) {
1397 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1398 if (fd
!= -1 || errno
!= EEXIST
) break;
1401 ssize_t ret
= write(fd
, data
, len
);
1403 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1405 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1410 /****************************************************************************
1411 Prepare everything for calling the actual request function, and potentially
1412 call the request function via the "new" interface.
1414 Return False if the "legacy" function needs to be called, everything is
1417 Return True if we're done.
1419 I know this API sucks, but it is the one with the least code change I could
1421 ****************************************************************************/
1423 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
, int size
)
1427 connection_struct
*conn
= NULL
;
1428 struct smbd_server_connection
*sconn
= req
->sconn
;
1432 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1433 * so subtract 4 from it. */
1434 if (!valid_smb_header(req
->inbuf
)
1435 || (size
< (smb_size
- 4))) {
1436 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1437 smb_len(req
->inbuf
)));
1438 exit_server_cleanly("Non-SMB packet");
1441 if (smb_messages
[type
].fn
== NULL
) {
1442 DEBUG(0,("Unknown message type %d!\n",type
));
1443 smb_dump("Unknown", 1, (char *)req
->inbuf
, size
);
1444 reply_unknown_new(req
, type
);
1448 flags
= smb_messages
[type
].flags
;
1450 /* In share mode security we must ignore the vuid. */
1451 session_tag
= (lp_security() == SEC_SHARE
)
1452 ? UID_FIELD_INVALID
: req
->vuid
;
1455 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1456 (int)sys_getpid(), (unsigned long)conn
));
1458 smb_dump(smb_fn_name(type
), 1, (char *)req
->inbuf
, size
);
1460 /* Ensure this value is replaced in the incoming packet. */
1461 SSVAL(req
->inbuf
,smb_uid
,session_tag
);
1464 * Ensure the correct username is in current_user_info. This is a
1465 * really ugly bugfix for problems with multiple session_setup_and_X's
1466 * being done and allowing %U and %G substitutions to work correctly.
1467 * There is a reason this code is done here, don't move it unless you
1468 * know what you're doing... :-).
1472 if (session_tag
!= sconn
->smb1
.sessions
.last_session_tag
) {
1473 user_struct
*vuser
= NULL
;
1475 sconn
->smb1
.sessions
.last_session_tag
= session_tag
;
1476 if(session_tag
!= UID_FIELD_INVALID
) {
1477 vuser
= get_valid_user_struct(sconn
, session_tag
);
1479 set_current_user_info(
1480 vuser
->session_info
->sanitized_username
,
1481 vuser
->session_info
->unix_name
,
1482 vuser
->session_info
->info3
->base
.domain
.string
);
1487 /* Does this call need to be run as the connected user? */
1488 if (flags
& AS_USER
) {
1490 /* Does this call need a valid tree connection? */
1493 * Amazingly, the error code depends on the command
1496 if (type
== SMBntcreateX
) {
1497 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1499 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1504 if (!change_to_user(conn
,session_tag
)) {
1505 DEBUG(0, ("Error: Could not change to user. Removing "
1506 "deferred open, mid=%llu.\n",
1507 (unsigned long long)req
->mid
));
1508 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1512 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1514 /* Does it need write permission? */
1515 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1516 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1520 /* IPC services are limited */
1521 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1522 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1526 /* This call needs to be run as root */
1527 change_to_root_user();
1530 /* load service specific parameters */
1532 if (req
->encrypted
) {
1533 conn
->encrypted_tid
= true;
1534 /* encrypted required from now on. */
1535 conn
->encrypt_level
= Required
;
1536 } else if (ENCRYPTION_REQUIRED(conn
)) {
1537 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1538 exit_server_cleanly("encryption required "
1544 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1545 (flags
& (AS_USER
|DO_CHDIR
)
1547 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1550 conn
->num_smb_operations
++;
1553 /* does this protocol need to be run as guest? */
1554 if ((flags
& AS_GUEST
)
1555 && (!change_to_guest() ||
1556 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1557 sconn
->client_id
.name
,
1558 sconn
->client_id
.addr
))) {
1559 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1563 smb_messages
[type
].fn(req
);
1567 /****************************************************************************
1568 Construct a reply to the incoming packet.
1569 ****************************************************************************/
1571 static void construct_reply(struct smbd_server_connection
*sconn
,
1572 char *inbuf
, int size
, size_t unread_bytes
,
1573 uint32_t seqnum
, bool encrypted
,
1574 struct smb_perfcount_data
*deferred_pcd
)
1576 connection_struct
*conn
;
1577 struct smb_request
*req
;
1579 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1580 smb_panic("could not allocate smb_request");
1583 if (!init_smb_request(req
, sconn
, (uint8
*)inbuf
, unread_bytes
,
1584 encrypted
, seqnum
)) {
1585 exit_server_cleanly("Invalid SMB request");
1588 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1590 /* we popped this message off the queue - keep original perf data */
1592 req
->pcd
= *deferred_pcd
;
1594 SMB_PERFCOUNT_START(&req
->pcd
);
1595 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1596 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1599 conn
= switch_message(req
->cmd
, req
, size
);
1601 if (req
->unread_bytes
) {
1602 /* writeX failed. drain socket. */
1603 if (drain_socket(req
->sconn
->sock
, req
->unread_bytes
) !=
1604 req
->unread_bytes
) {
1605 smb_panic("failed to drain pending bytes");
1607 req
->unread_bytes
= 0;
1615 if (req
->outbuf
== NULL
) {
1619 if (CVAL(req
->outbuf
,0) == 0) {
1620 show_msg((char *)req
->outbuf
);
1623 if (!srv_send_smb(req
->sconn
,
1624 (char *)req
->outbuf
,
1625 true, req
->seqnum
+1,
1626 IS_CONN_ENCRYPTED(conn
)||req
->encrypted
,
1628 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1636 /****************************************************************************
1637 Process an smb from the client
1638 ****************************************************************************/
1639 static void process_smb(struct smbd_server_connection
*sconn
,
1640 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1641 uint32_t seqnum
, bool encrypted
,
1642 struct smb_perfcount_data
*deferred_pcd
)
1644 int msg_type
= CVAL(inbuf
,0);
1646 DO_PROFILE_INC(smb_count
);
1648 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1650 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1651 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1653 if (msg_type
!= 0) {
1655 * NetBIOS session request, keepalive, etc.
1657 reply_special(sconn
, (char *)inbuf
, nread
);
1661 if (sconn
->using_smb2
) {
1662 /* At this point we're not really using smb2,
1663 * we make the decision here.. */
1664 if (smbd_is_smb2_header(inbuf
, nread
)) {
1665 smbd_smb2_first_negprot(sconn
, inbuf
, nread
);
1667 } else if (nread
>= smb_size
&& valid_smb_header(inbuf
)
1668 && CVAL(inbuf
, smb_com
) != 0x72) {
1669 /* This is a non-negprot SMB1 packet.
1670 Disable SMB2 from now on. */
1671 sconn
->using_smb2
= false;
1675 show_msg((char *)inbuf
);
1677 construct_reply(sconn
, (char *)inbuf
, nread
, unread_bytes
, seqnum
,
1678 encrypted
, deferred_pcd
);
1682 sconn
->smb1
.num_requests
++;
1684 /* The timeout_processing function isn't run nearly
1685 often enough to implement 'max log size' without
1686 overrunning the size of the file by many megabytes.
1687 This is especially true if we are running at debug
1688 level 10. Checking every 50 SMBs is a nice
1689 tradeoff of performance vs log file size overrun. */
1691 if ((sconn
->smb1
.num_requests
% 50) == 0 &&
1692 need_to_check_log_size()) {
1693 change_to_root_user();
1698 /****************************************************************************
1699 Return a string containing the function name of a SMB command.
1700 ****************************************************************************/
1702 const char *smb_fn_name(int type
)
1704 const char *unknown_name
= "SMBunknown";
1706 if (smb_messages
[type
].name
== NULL
)
1707 return(unknown_name
);
1709 return(smb_messages
[type
].name
);
1712 /****************************************************************************
1713 Helper functions for contruct_reply.
1714 ****************************************************************************/
1716 void add_to_common_flags2(uint32 v
)
1721 void remove_from_common_flags2(uint32 v
)
1723 common_flags2
&= ~v
;
1726 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1729 srv_set_message(outbuf
,0,0,false);
1731 SCVAL(outbuf
, smb_com
, req
->cmd
);
1732 SIVAL(outbuf
,smb_rcls
,0);
1733 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1734 SSVAL(outbuf
,smb_flg2
,
1735 (SVAL(inbuf
,smb_flg2
) & FLAGS2_UNICODE_STRINGS
) |
1737 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1739 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
1740 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
1741 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
1742 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
1745 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
1747 construct_reply_common(req
, (char *)req
->inbuf
, outbuf
);
1751 * How many bytes have we already accumulated up to the current wct field
1755 size_t req_wct_ofs(struct smb_request
*req
)
1759 if (req
->chain_outbuf
== NULL
) {
1762 buf_size
= talloc_get_size(req
->chain_outbuf
);
1763 if ((buf_size
% 4) != 0) {
1764 buf_size
+= (4 - (buf_size
% 4));
1766 return buf_size
- 4;
1770 * Hack around reply_nterror & friends not being aware of chained requests,
1771 * generating illegal (i.e. wct==0) chain replies.
1774 static void fixup_chain_error_packet(struct smb_request
*req
)
1776 uint8_t *outbuf
= req
->outbuf
;
1778 reply_outbuf(req
, 2, 0);
1779 memcpy(req
->outbuf
, outbuf
, smb_wct
);
1780 TALLOC_FREE(outbuf
);
1781 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
1785 * @brief Find the smb_cmd offset of the last command pushed
1786 * @param[in] buf The buffer we're building up
1787 * @retval Where can we put our next andx cmd?
1789 * While chaining requests, the "next" request we're looking at needs to put
1790 * its SMB_Command before the data the previous request already built up added
1791 * to the chain. Find the offset to the place where we have to put our cmd.
1794 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
1799 cmd
= CVAL(buf
, smb_com
);
1801 SMB_ASSERT(is_andx_req(cmd
));
1805 while (CVAL(buf
, ofs
) != 0xff) {
1807 if (!is_andx_req(CVAL(buf
, ofs
))) {
1812 * ofs is from start of smb header, so add the 4 length
1813 * bytes. The next cmd is right after the wct field.
1815 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
1817 SMB_ASSERT(ofs
+4 < talloc_get_size(buf
));
1825 * @brief Do the smb chaining at a buffer level
1826 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1827 * @param[in] smb_command The command that we want to issue
1828 * @param[in] wct How many words?
1829 * @param[in] vwv The words, already in network order
1830 * @param[in] bytes_alignment How shall we align "bytes"?
1831 * @param[in] num_bytes How many bytes?
1832 * @param[in] bytes The data the request ships
1834 * smb_splice_chain() adds the vwv and bytes to the request already present in
1838 static bool smb_splice_chain(uint8_t **poutbuf
, uint8_t smb_command
,
1839 uint8_t wct
, const uint16_t *vwv
,
1840 size_t bytes_alignment
,
1841 uint32_t num_bytes
, const uint8_t *bytes
)
1844 size_t old_size
, new_size
;
1846 size_t chain_padding
= 0;
1847 size_t bytes_padding
= 0;
1850 old_size
= talloc_get_size(*poutbuf
);
1853 * old_size == smb_wct means we're pushing the first request in for
1857 first_request
= (old_size
== smb_wct
);
1859 if (!first_request
&& ((old_size
% 4) != 0)) {
1861 * Align the wct field of subsequent requests to a 4-byte
1864 chain_padding
= 4 - (old_size
% 4);
1868 * After the old request comes the new wct field (1 byte), the vwv's
1869 * and the num_bytes field. After at we might need to align the bytes
1870 * given to us to "bytes_alignment", increasing the num_bytes value.
1873 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
1875 if ((bytes_alignment
!= 0) && ((new_size
% bytes_alignment
) != 0)) {
1876 bytes_padding
= bytes_alignment
- (new_size
% bytes_alignment
);
1879 new_size
+= bytes_padding
+ num_bytes
;
1881 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
1882 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1883 (unsigned)new_size
));
1887 outbuf
= TALLOC_REALLOC_ARRAY(NULL
, *poutbuf
, uint8_t, new_size
);
1888 if (outbuf
== NULL
) {
1889 DEBUG(0, ("talloc failed\n"));
1894 if (first_request
) {
1895 SCVAL(outbuf
, smb_com
, smb_command
);
1897 size_t andx_cmd_ofs
;
1899 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
1900 DEBUG(1, ("invalid command chain\n"));
1901 *poutbuf
= TALLOC_REALLOC_ARRAY(
1902 NULL
, *poutbuf
, uint8_t, old_size
);
1906 if (chain_padding
!= 0) {
1907 memset(outbuf
+ old_size
, 0, chain_padding
);
1908 old_size
+= chain_padding
;
1911 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
1912 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
1918 * Push the chained request:
1923 SCVAL(outbuf
, ofs
, wct
);
1930 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
1931 ofs
+= sizeof(uint16_t) * wct
;
1937 SSVAL(outbuf
, ofs
, num_bytes
+ bytes_padding
);
1938 ofs
+= sizeof(uint16_t);
1944 if (bytes_padding
!= 0) {
1945 memset(outbuf
+ ofs
, 0, bytes_padding
);
1946 ofs
+= bytes_padding
;
1953 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
1958 /****************************************************************************
1959 Construct a chained reply and add it to the already made reply
1960 ****************************************************************************/
1962 void chain_reply(struct smb_request
*req
)
1964 size_t smblen
= smb_len(req
->inbuf
);
1965 size_t already_used
, length_needed
;
1967 uint32_t chain_offset
; /* uint32_t to avoid overflow */
1974 if (IVAL(req
->outbuf
, smb_rcls
) != 0) {
1975 fixup_chain_error_packet(req
);
1979 * Any of the AndX requests and replies have at least a wct of
1980 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1981 * beginning of the SMB header to the next wct field.
1983 * None of the AndX requests put anything valuable in vwv[0] and [1],
1984 * so we can overwrite it here to form the chain.
1987 if ((req
->wct
< 2) || (CVAL(req
->outbuf
, smb_wct
) < 2)) {
1988 if (req
->chain_outbuf
== NULL
) {
1989 req
->chain_outbuf
= TALLOC_REALLOC_ARRAY(
1990 req
, req
->outbuf
, uint8_t,
1991 smb_len(req
->outbuf
) + 4);
1992 if (req
->chain_outbuf
== NULL
) {
1993 smb_panic("talloc failed");
2001 * Here we assume that this is the end of the chain. For that we need
2002 * to set "next command" to 0xff and the offset to 0. If we later find
2003 * more commands in the chain, this will be overwritten again.
2006 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
2007 SCVAL(req
->outbuf
, smb_vwv0
+1, 0);
2008 SSVAL(req
->outbuf
, smb_vwv1
, 0);
2010 if (req
->chain_outbuf
== NULL
) {
2012 * In req->chain_outbuf we collect all the replies. Start the
2013 * chain by copying in the first reply.
2015 * We do the realloc because later on we depend on
2016 * talloc_get_size to determine the length of
2017 * chain_outbuf. The reply_xxx routines might have
2018 * over-allocated (reply_pipe_read_and_X used to be such an
2021 req
->chain_outbuf
= TALLOC_REALLOC_ARRAY(
2022 req
, req
->outbuf
, uint8_t, smb_len(req
->outbuf
) + 4);
2023 if (req
->chain_outbuf
== NULL
) {
2024 smb_panic("talloc failed");
2029 * Update smb headers where subsequent chained commands
2030 * may have updated them.
2032 SSVAL(req
->chain_outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
2033 SSVAL(req
->chain_outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
2035 if (!smb_splice_chain(&req
->chain_outbuf
,
2036 CVAL(req
->outbuf
, smb_com
),
2037 CVAL(req
->outbuf
, smb_wct
),
2038 (uint16_t *)(req
->outbuf
+ smb_vwv
),
2039 0, smb_buflen(req
->outbuf
),
2040 (uint8_t *)smb_buf(req
->outbuf
))) {
2043 TALLOC_FREE(req
->outbuf
);
2047 * We use the old request's vwv field to grab the next chained command
2048 * and offset into the chained fields.
2051 chain_cmd
= CVAL(req
->vwv
+0, 0);
2052 chain_offset
= SVAL(req
->vwv
+1, 0);
2054 if (chain_cmd
== 0xff) {
2056 * End of chain, no more requests from the client. So ship the
2059 smb_setlen((char *)(req
->chain_outbuf
),
2060 talloc_get_size(req
->chain_outbuf
) - 4);
2062 if (!srv_send_smb(req
->sconn
, (char *)req
->chain_outbuf
,
2063 true, req
->seqnum
+1,
2064 IS_CONN_ENCRYPTED(req
->conn
)
2067 exit_server_cleanly("chain_reply: srv_send_smb "
2070 TALLOC_FREE(req
->chain_outbuf
);
2075 /* add a new perfcounter for this element of chain */
2076 SMB_PERFCOUNT_ADD(&req
->pcd
);
2077 SMB_PERFCOUNT_SET_OP(&req
->pcd
, chain_cmd
);
2078 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, smblen
);
2081 * Check if the client tries to fool us. The request so far uses the
2082 * space to the end of the byte buffer in the request just
2083 * processed. The chain_offset can't point into that area. If that was
2084 * the case, we could end up with an endless processing of the chain,
2085 * we would always handle the same request.
2088 already_used
= PTR_DIFF(req
->buf
+req
->buflen
, smb_base(req
->inbuf
));
2089 if (chain_offset
< already_used
) {
2094 * Next check: Make sure the chain offset does not point beyond the
2095 * overall smb request length.
2098 length_needed
= chain_offset
+1; /* wct */
2099 if (length_needed
> smblen
) {
2104 * Now comes the pointer magic. Goal here is to set up req->vwv and
2105 * req->buf correctly again to be able to call the subsequent
2106 * switch_message(). The chain offset (the former vwv[1]) points at
2107 * the new wct field.
2110 wct
= CVAL(smb_base(req
->inbuf
), chain_offset
);
2113 * Next consistency check: Make the new vwv array fits in the overall
2117 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2118 if (length_needed
> smblen
) {
2121 vwv
= (uint16_t *)(smb_base(req
->inbuf
) + chain_offset
+ 1);
2124 * Now grab the new byte buffer....
2127 buflen
= SVAL(vwv
+wct
, 0);
2130 * .. and check that it fits.
2133 length_needed
+= buflen
;
2134 if (length_needed
> smblen
) {
2137 buf
= (uint8_t *)(vwv
+wct
+1);
2139 req
->cmd
= chain_cmd
;
2142 req
->buflen
= buflen
;
2145 switch_message(chain_cmd
, req
, smblen
);
2147 if (req
->outbuf
== NULL
) {
2149 * This happens if the chained command has suspended itself or
2150 * if it has called srv_send_smb() itself.
2156 * We end up here if the chained command was not itself chained or
2157 * suspended, but for example a close() command. We now need to splice
2158 * the chained commands' outbuf into the already built up chain_outbuf
2159 * and ship the result.
2165 * We end up here if there's any error in the chain syntax. Report a
2166 * DOS error, just like Windows does.
2168 reply_force_doserror(req
, ERRSRV
, ERRerror
);
2169 fixup_chain_error_packet(req
);
2173 * This scary statement intends to set the
2174 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2175 * to the value req->outbuf carries
2177 SSVAL(req
->chain_outbuf
, smb_flg2
,
2178 (SVAL(req
->chain_outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
2179 | (SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
2182 * Transfer the error codes from the subrequest to the main one
2184 SSVAL(req
->chain_outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
2185 SSVAL(req
->chain_outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
2187 if (!smb_splice_chain(&req
->chain_outbuf
,
2188 CVAL(req
->outbuf
, smb_com
),
2189 CVAL(req
->outbuf
, smb_wct
),
2190 (uint16_t *)(req
->outbuf
+ smb_vwv
),
2191 0, smb_buflen(req
->outbuf
),
2192 (uint8_t *)smb_buf(req
->outbuf
))) {
2193 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2195 TALLOC_FREE(req
->outbuf
);
2197 smb_setlen((char *)(req
->chain_outbuf
),
2198 talloc_get_size(req
->chain_outbuf
) - 4);
2200 show_msg((char *)(req
->chain_outbuf
));
2202 if (!srv_send_smb(req
->sconn
, (char *)req
->chain_outbuf
,
2203 true, req
->seqnum
+1,
2204 IS_CONN_ENCRYPTED(req
->conn
)||req
->encrypted
,
2206 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2208 TALLOC_FREE(req
->chain_outbuf
);
2212 /****************************************************************************
2213 Check if services need reloading.
2214 ****************************************************************************/
2216 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2219 if (last_smb_conf_reload_time
== 0) {
2220 last_smb_conf_reload_time
= t
;
2223 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2224 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
2225 last_smb_conf_reload_time
= t
;
2229 static bool fd_is_readable(int fd
)
2233 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2235 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2239 static void smbd_server_connection_write_handler(struct smbd_server_connection
*conn
)
2241 /* TODO: make write nonblocking */
2244 static void smbd_server_connection_read_handler(
2245 struct smbd_server_connection
*conn
, int fd
)
2247 uint8_t *inbuf
= NULL
;
2248 size_t inbuf_len
= 0;
2249 size_t unread_bytes
= 0;
2250 bool encrypted
= false;
2251 TALLOC_CTX
*mem_ctx
= talloc_tos();
2255 bool from_client
= (conn
->sock
== fd
);
2258 smbd_lock_socket(conn
);
2260 if (lp_async_smb_echo_handler() && !fd_is_readable(fd
)) {
2261 DEBUG(10,("the echo listener was faster\n"));
2262 smbd_unlock_socket(conn
);
2266 /* TODO: make this completely nonblocking */
2267 status
= receive_smb_talloc(mem_ctx
, conn
,
2268 (char **)(void *)&inbuf
,
2272 &inbuf_len
, &seqnum
,
2273 false /* trusted channel */);
2274 smbd_unlock_socket(conn
);
2276 /* TODO: make this completely nonblocking */
2277 status
= receive_smb_talloc(mem_ctx
, conn
,
2278 (char **)(void *)&inbuf
,
2282 &inbuf_len
, &seqnum
,
2283 true /* trusted channel */);
2286 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2289 if (NT_STATUS_IS_ERR(status
)) {
2290 exit_server_cleanly("failed to receive smb request");
2292 if (!NT_STATUS_IS_OK(status
)) {
2297 process_smb(conn
, inbuf
, inbuf_len
, unread_bytes
,
2298 seqnum
, encrypted
, NULL
);
2301 static void smbd_server_connection_handler(struct event_context
*ev
,
2302 struct fd_event
*fde
,
2306 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2307 struct smbd_server_connection
);
2309 if (flags
& EVENT_FD_WRITE
) {
2310 smbd_server_connection_write_handler(conn
);
2313 if (flags
& EVENT_FD_READ
) {
2314 smbd_server_connection_read_handler(conn
, conn
->sock
);
2319 static void smbd_server_echo_handler(struct event_context
*ev
,
2320 struct fd_event
*fde
,
2324 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2325 struct smbd_server_connection
);
2327 if (flags
& EVENT_FD_WRITE
) {
2328 smbd_server_connection_write_handler(conn
);
2331 if (flags
& EVENT_FD_READ
) {
2332 smbd_server_connection_read_handler(
2333 conn
, conn
->smb1
.echo_handler
.trusted_fd
);
2338 /****************************************************************************
2339 received when we should release a specific IP
2340 ****************************************************************************/
2341 static void release_ip(const char *ip
, void *priv
)
2343 const char *addr
= (const char *)priv
;
2344 const char *p
= addr
;
2346 if (strncmp("::ffff:", addr
, 7) == 0) {
2350 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2351 /* we can't afford to do a clean exit - that involves
2352 database writes, which would potentially mean we
2353 are still running after the failover has finished -
2354 we have to get rid of this process ID straight
2356 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2358 /* note we must exit with non-zero status so the unclean handler gets
2359 called in the parent, so that the brl database is tickled */
2364 static void msg_release_ip(struct messaging_context
*msg_ctx
, void *private_data
,
2365 uint32_t msg_type
, struct server_id server_id
, DATA_BLOB
*data
)
2367 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2368 private_data
, struct smbd_server_connection
);
2370 release_ip((char *)data
->data
, sconn
->client_id
.addr
);
2373 #ifdef CLUSTER_SUPPORT
2374 static int client_get_tcp_info(int sock
, struct sockaddr_storage
*server
,
2375 struct sockaddr_storage
*client
)
2378 length
= sizeof(*server
);
2379 if (getsockname(sock
, (struct sockaddr
*)server
, &length
) != 0) {
2382 length
= sizeof(*client
);
2383 if (getpeername(sock
, (struct sockaddr
*)client
, &length
) != 0) {
2391 * Send keepalive packets to our client
2393 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2395 struct smbd_server_connection
*sconn
= smbd_server_conn
;
2398 if (sconn
->using_smb2
) {
2399 /* Don't do keepalives on an SMB2 connection. */
2403 smbd_lock_socket(smbd_server_conn
);
2404 ret
= send_keepalive(sconn
->sock
);
2405 smbd_unlock_socket(smbd_server_conn
);
2408 char addr
[INET6_ADDRSTRLEN
];
2410 * Try and give an error message saying what
2413 DEBUG(0, ("send_keepalive failed for client %s. "
2414 "Error %s - exiting\n",
2415 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
2423 * Do the recurring check if we're idle
2425 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2427 struct smbd_server_connection
*sconn
=
2428 (struct smbd_server_connection
*)private_data
;
2430 if ((conn_num_open(sconn
) == 0)
2431 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2432 DEBUG( 2, ( "Closing idle connection\n" ) );
2433 messaging_send(sconn
->msg_ctx
,
2434 messaging_server_id(sconn
->msg_ctx
),
2435 MSG_SHUTDOWN
, &data_blob_null
);
2443 * Do the recurring log file and smb.conf reload checks.
2446 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2448 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2449 private_data
, struct smbd_server_connection
);
2451 DEBUG(5, ("housekeeping\n"));
2453 change_to_root_user();
2455 /* update printer queue caches if necessary */
2456 update_monitored_printq_cache(sconn
->msg_ctx
);
2458 /* check if we need to reload services */
2459 check_reload(sconn
, time_mono(NULL
));
2461 /* Change machine password if neccessary. */
2462 attempt_machine_password_change();
2465 * Force a log file check.
2467 force_check_log_size();
2472 static int create_unlink_tmp(const char *dir
)
2477 fname
= talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir
);
2478 if (fname
== NULL
) {
2482 fd
= mkstemp(fname
);
2487 if (unlink(fname
) == -1) {
2488 int sys_errno
= errno
;
2498 struct smbd_echo_state
{
2499 struct tevent_context
*ev
;
2500 struct iovec
*pending
;
2501 struct smbd_server_connection
*sconn
;
2504 struct tevent_fd
*parent_fde
;
2506 struct tevent_fd
*read_fde
;
2507 struct tevent_req
*write_req
;
2510 static void smbd_echo_writer_done(struct tevent_req
*req
);
2512 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2516 if (state
->write_req
!= NULL
) {
2520 num_pending
= talloc_array_length(state
->pending
);
2521 if (num_pending
== 0) {
2525 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
2526 state
->parent_pipe
, false,
2527 state
->pending
, num_pending
);
2528 if (state
->write_req
== NULL
) {
2529 DEBUG(1, ("writev_send failed\n"));
2533 talloc_steal(state
->write_req
, state
->pending
);
2534 state
->pending
= NULL
;
2536 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
2540 static void smbd_echo_writer_done(struct tevent_req
*req
)
2542 struct smbd_echo_state
*state
= tevent_req_callback_data(
2543 req
, struct smbd_echo_state
);
2547 written
= writev_recv(req
, &err
);
2549 state
->write_req
= NULL
;
2550 if (written
== -1) {
2551 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
2554 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2555 smbd_echo_activate_writer(state
);
2558 static bool smbd_echo_reply(uint8_t *inbuf
, size_t inbuf_len
,
2561 struct smb_request req
;
2562 uint16_t num_replies
;
2567 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == SMBkeepalive
)) {
2568 DEBUG(10, ("Got netbios keepalive\n"));
2575 if (inbuf_len
< smb_size
) {
2576 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
2579 if (!valid_smb_header(inbuf
)) {
2580 DEBUG(10, ("Got invalid SMB header\n"));
2584 if (!init_smb_request(&req
, smbd_server_conn
, inbuf
, 0, false,
2590 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
2591 smb_messages
[req
.cmd
].name
2592 ? smb_messages
[req
.cmd
].name
: "unknown"));
2594 if (req
.cmd
!= SMBecho
) {
2601 num_replies
= SVAL(req
.vwv
+0, 0);
2602 if (num_replies
!= 1) {
2603 /* Not a Windows "Hey, you're still there?" request */
2607 if (!create_outbuf(talloc_tos(), &req
, (char *)req
.inbuf
, &outbuf
,
2609 DEBUG(10, ("create_outbuf failed\n"));
2612 req
.outbuf
= (uint8_t *)outbuf
;
2614 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
2616 if (req
.buflen
> 0) {
2617 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
2620 out_len
= smb_len(req
.outbuf
) + 4;
2622 ok
= srv_send_smb(req
.sconn
,
2626 TALLOC_FREE(outbuf
);
2634 static void smbd_echo_exit(struct tevent_context
*ev
,
2635 struct tevent_fd
*fde
, uint16_t flags
,
2638 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2642 static void smbd_echo_reader(struct tevent_context
*ev
,
2643 struct tevent_fd
*fde
, uint16_t flags
,
2646 struct smbd_echo_state
*state
= talloc_get_type_abort(
2647 private_data
, struct smbd_echo_state
);
2648 struct smbd_server_connection
*sconn
= state
->sconn
;
2649 size_t unread
, num_pending
;
2653 uint32_t seqnum
= 0;
2656 bool encrypted
= false;
2660 ok
= smbd_lock_socket_internal(sconn
);
2662 DEBUG(0, ("%s: failed to lock socket\n",
2667 if (!fd_is_readable(sconn
->sock
)) {
2668 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2669 (int)sys_getpid()));
2670 ok
= smbd_unlock_socket_internal(sconn
);
2672 DEBUG(1, ("%s: failed to unlock socket in\n",
2679 num_pending
= talloc_array_length(state
->pending
);
2680 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
2683 DEBUG(1, ("talloc_realloc failed\n"));
2686 state
->pending
= tmp
;
2688 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2690 status
= receive_smb_talloc(state
->pending
, sconn
,
2691 (char **)(void *)&state
->pending
[num_pending
].iov_base
,
2697 false /* trusted_channel*/);
2698 if (!NT_STATUS_IS_OK(status
)) {
2699 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2700 (int)sys_getpid(), nt_errstr(status
)));
2703 state
->pending
[num_pending
].iov_len
= iov_len
;
2705 ok
= smbd_unlock_socket_internal(sconn
);
2707 DEBUG(1, ("%s: failed to unlock socket in\n",
2712 reply
= smbd_echo_reply((uint8_t *)state
->pending
[num_pending
].iov_base
,
2713 state
->pending
[num_pending
].iov_len
,
2716 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2717 /* no check, shrinking by some bytes does not fail */
2718 state
->pending
= talloc_realloc(state
, state
->pending
,
2724 if (state
->pending
[num_pending
].iov_len
>= smb_size
) {
2726 * place the seqnum in the packet so that the main process
2727 * can reply with signing
2729 SIVAL((uint8_t *)state
->pending
[num_pending
].iov_base
,
2730 smb_ss_field
, seqnum
);
2731 SIVAL((uint8_t *)state
->pending
[num_pending
].iov_base
,
2732 smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
2735 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2736 smbd_echo_activate_writer(state
);
2739 static void smbd_echo_loop(struct smbd_server_connection
*sconn
,
2742 struct smbd_echo_state
*state
;
2744 state
= talloc_zero(sconn
, struct smbd_echo_state
);
2745 if (state
== NULL
) {
2746 DEBUG(1, ("talloc failed\n"));
2749 state
->sconn
= sconn
;
2750 state
->parent_pipe
= parent_pipe
;
2751 state
->ev
= s3_tevent_context_init(state
);
2752 if (state
->ev
== NULL
) {
2753 DEBUG(1, ("tevent_context_init failed\n"));
2757 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
2758 TEVENT_FD_READ
, smbd_echo_exit
,
2760 if (state
->parent_fde
== NULL
) {
2761 DEBUG(1, ("tevent_add_fd failed\n"));
2765 state
->read_fde
= tevent_add_fd(state
->ev
, state
, sconn
->sock
,
2766 TEVENT_FD_READ
, smbd_echo_reader
,
2768 if (state
->read_fde
== NULL
) {
2769 DEBUG(1, ("tevent_add_fd failed\n"));
2775 if (tevent_loop_once(state
->ev
) == -1) {
2776 DEBUG(1, ("tevent_loop_once failed: %s\n",
2785 * Handle SMBecho requests in a forked child process
2787 static bool fork_echo_handler(struct smbd_server_connection
*sconn
)
2789 int listener_pipe
[2];
2793 res
= pipe(listener_pipe
);
2795 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
2798 sconn
->smb1
.echo_handler
.socket_lock_fd
= create_unlink_tmp(lp_lockdir());
2799 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
2800 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno
)));
2808 close(listener_pipe
[0]);
2809 set_blocking(listener_pipe
[1], false);
2811 status
= reinit_after_fork(sconn
->msg_ctx
,
2812 smbd_event_context(),
2813 procid_self(), false);
2814 if (!NT_STATUS_IS_OK(status
)) {
2815 DEBUG(1, ("reinit_after_fork failed: %s\n",
2816 nt_errstr(status
)));
2819 smbd_echo_loop(sconn
, listener_pipe
[1]);
2822 close(listener_pipe
[1]);
2823 listener_pipe
[1] = -1;
2824 sconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
2826 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child
));
2829 * Without smb signing this is the same as the normal smbd
2830 * listener. This needs to change once signing comes in.
2832 sconn
->smb1
.echo_handler
.trusted_fde
= event_add_fd(smbd_event_context(),
2834 sconn
->smb1
.echo_handler
.trusted_fd
,
2836 smbd_server_echo_handler
,
2838 if (sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
2839 DEBUG(1, ("event_add_fd failed\n"));
2846 if (listener_pipe
[0] != -1) {
2847 close(listener_pipe
[0]);
2849 if (listener_pipe
[1] != -1) {
2850 close(listener_pipe
[1]);
2852 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2853 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
2854 close(sconn
->smb1
.echo_handler
.socket_lock_fd
);
2856 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2857 sconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
2863 static NTSTATUS
smbd_register_ips(struct smbd_server_connection
*sconn
,
2864 struct sockaddr_storage
*srv
,
2865 struct sockaddr_storage
*clnt
)
2867 struct ctdbd_connection
*cconn
;
2868 char tmp_addr
[INET6_ADDRSTRLEN
];
2871 cconn
= messaging_ctdbd_connection();
2872 if (cconn
== NULL
) {
2873 return NT_STATUS_NO_MEMORY
;
2876 client_socket_addr(sconn
->sock
, tmp_addr
, sizeof(tmp_addr
));
2877 addr
= talloc_strdup(cconn
, tmp_addr
);
2879 return NT_STATUS_NO_MEMORY
;
2881 return ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, addr
);
2886 /****************************************************************************
2887 Process commands from the client
2888 ****************************************************************************/
2890 void smbd_process(struct smbd_server_connection
*sconn
)
2892 TALLOC_CTX
*frame
= talloc_stackframe();
2893 struct sockaddr_storage ss
;
2894 struct sockaddr
*sa
= NULL
;
2895 socklen_t sa_socklen
;
2896 struct tsocket_address
*local_address
= NULL
;
2897 struct tsocket_address
*remote_address
= NULL
;
2898 const char *remaddr
= NULL
;
2901 if (lp_maxprotocol() == PROTOCOL_SMB2
&&
2902 !lp_async_smb_echo_handler()) {
2904 * We're not making the desion here,
2905 * we're just allowing the client
2906 * to decide between SMB1 and SMB2
2907 * with the first negprot
2910 sconn
->using_smb2
= true;
2913 /* Ensure child is set to blocking mode */
2914 set_blocking(sconn
->sock
,True
);
2916 set_socket_options(sconn
->sock
, "SO_KEEPALIVE");
2917 set_socket_options(sconn
->sock
, lp_socket_options());
2919 sa
= (struct sockaddr
*)(void *)&ss
;
2920 sa_socklen
= sizeof(ss
);
2921 ret
= getpeername(sconn
->sock
, sa
, &sa_socklen
);
2923 int level
= (errno
== ENOTCONN
)?2:0;
2924 DEBUG(level
,("getpeername() failed - %s\n", strerror(errno
)));
2925 exit_server_cleanly("getpeername() failed.\n");
2927 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
2931 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2932 __location__
, strerror(errno
)));
2933 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2936 sa
= (struct sockaddr
*)(void *)&ss
;
2937 sa_socklen
= sizeof(ss
);
2938 ret
= getsockname(sconn
->sock
, sa
, &sa_socklen
);
2940 int level
= (errno
== ENOTCONN
)?2:0;
2941 DEBUG(level
,("getsockname() failed - %s\n", strerror(errno
)));
2942 exit_server_cleanly("getsockname() failed.\n");
2944 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
2948 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2949 __location__
, strerror(errno
)));
2950 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2953 sconn
->local_address
= local_address
;
2954 sconn
->remote_address
= remote_address
;
2956 if (tsocket_address_is_inet(remote_address
, "ip")) {
2957 remaddr
= tsocket_address_inet_addr_string(
2958 sconn
->remote_address
,
2960 if (remaddr
== NULL
) {
2964 remaddr
= "0.0.0.0";
2967 /* this is needed so that we get decent entries
2968 in smbstatus for port 445 connects */
2969 set_remote_machine_name(remaddr
, false);
2970 reload_services(sconn
->msg_ctx
, sconn
->sock
, true);
2973 * Before the first packet, check the global hosts allow/ hosts deny
2974 * parameters before doing any parsing of packets passed to us by the
2975 * client. This prevents attacks on our parsing code from hosts not in
2976 * the hosts allow list.
2979 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2980 sconn
->client_id
.name
,
2981 sconn
->client_id
.addr
)) {
2983 * send a negative session response "not listening on calling
2986 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
2987 DEBUG( 1, ("Connection denied from %s to %s\n",
2988 tsocket_address_string(remote_address
, talloc_tos()),
2989 tsocket_address_string(local_address
, talloc_tos())));
2990 (void)srv_send_smb(sconn
,(char *)buf
, false,
2992 exit_server_cleanly("connection denied");
2995 DEBUG(10, ("Connection allowed from %s to %s\n",
2996 tsocket_address_string(remote_address
, talloc_tos()),
2997 tsocket_address_string(local_address
, talloc_tos())));
3001 smb_perfcount_init();
3003 if (!init_account_policy()) {
3004 exit_server("Could not open account policy tdb.\n");
3007 if (*lp_rootdir()) {
3008 if (chroot(lp_rootdir()) != 0) {
3009 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3010 exit_server("Failed to chroot()");
3012 if (chdir("/") == -1) {
3013 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3014 exit_server("Failed to chroot()");
3016 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3019 if (!srv_init_signing(sconn
)) {
3020 exit_server("Failed to init smb_signing");
3023 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn
)) {
3024 exit_server("Failed to fork echo handler");
3028 if (!init_oplocks(sconn
->msg_ctx
))
3029 exit_server("Failed to init oplocks");
3031 /* register our message handlers */
3032 messaging_register(sconn
->msg_ctx
, NULL
,
3033 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3034 messaging_register(sconn
->msg_ctx
, sconn
,
3035 MSG_SMB_RELEASE_IP
, msg_release_ip
);
3036 messaging_register(sconn
->msg_ctx
, NULL
,
3037 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3040 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3041 * MSGs to all child processes
3043 messaging_deregister(sconn
->msg_ctx
,
3045 messaging_register(sconn
->msg_ctx
, NULL
,
3046 MSG_DEBUG
, debug_message
);
3048 if ((lp_keepalive() != 0)
3049 && !(event_add_idle(smbd_event_context(), NULL
,
3050 timeval_set(lp_keepalive(), 0),
3051 "keepalive", keepalive_fn
,
3053 DEBUG(0, ("Could not add keepalive event\n"));
3057 if (!(event_add_idle(smbd_event_context(), NULL
,
3058 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3059 "deadtime", deadtime_fn
, sconn
))) {
3060 DEBUG(0, ("Could not add deadtime event\n"));
3064 if (!(event_add_idle(smbd_event_context(), NULL
,
3065 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
3066 "housekeeping", housekeeping_fn
, sconn
))) {
3067 DEBUG(0, ("Could not add housekeeping event\n"));
3071 #ifdef CLUSTER_SUPPORT
3073 if (lp_clustering()) {
3075 * We need to tell ctdb about our client's TCP
3076 * connection, so that for failover ctdbd can send
3077 * tickle acks, triggering a reconnection by the
3081 struct sockaddr_storage srv
, clnt
;
3083 if (client_get_tcp_info(sconn
->sock
, &srv
, &clnt
) == 0) {
3085 status
= smbd_register_ips(sconn
, &srv
, &clnt
);
3086 if (!NT_STATUS_IS_OK(status
)) {
3087 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3088 nt_errstr(status
)));
3092 DEBUG(0,("Unable to get tcp info for "
3093 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3100 sconn
->nbt
.got_session
= false;
3102 sconn
->smb1
.negprot
.max_recv
= MIN(lp_maxxmit(),BUFFER_SIZE
);
3104 sconn
->smb1
.sessions
.done_sesssetup
= false;
3105 sconn
->smb1
.sessions
.max_send
= BUFFER_SIZE
;
3106 sconn
->smb1
.sessions
.last_session_tag
= UID_FIELD_INVALID
;
3107 /* users from session setup */
3108 sconn
->smb1
.sessions
.session_userlist
= NULL
;
3109 /* workgroup from session setup. */
3110 sconn
->smb1
.sessions
.session_workgroup
= NULL
;
3111 /* this holds info on user ids that are already validated for this VC */
3112 sconn
->smb1
.sessions
.validated_users
= NULL
;
3113 sconn
->smb1
.sessions
.next_vuid
= VUID_OFFSET
;
3114 sconn
->smb1
.sessions
.num_validated_vuids
= 0;
3117 if (!init_dptrs(sconn
)) {
3118 exit_server("init_dptrs() failed");
3121 sconn
->smb1
.fde
= event_add_fd(smbd_event_context(),
3125 smbd_server_connection_handler
,
3127 if (!sconn
->smb1
.fde
) {
3128 exit_server("failed to create smbd_server_connection fde");
3136 frame
= talloc_stackframe_pool(8192);
3140 status
= smbd_server_connection_loop_once(sconn
);
3141 if (!NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
) &&
3142 !NT_STATUS_IS_OK(status
)) {
3143 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3144 " exiting\n", nt_errstr(status
)));
3151 exit_server_cleanly(NULL
);
3154 bool req_is_in_chain(struct smb_request
*req
)
3156 if (req
->vwv
!= (uint16_t *)(req
->inbuf
+smb_vwv
)) {
3158 * We're right now handling a subsequent request, so we must
3164 if (!is_andx_req(req
->cmd
)) {
3170 * Okay, an illegal request, but definitely not chained :-)
3175 return (CVAL(req
->vwv
+0, 0) != 0xFF);