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/pcap.h"
31 #include "system/select.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
39 extern bool global_machine_password_needs_changing
;
41 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
43 static struct pending_message_list
*get_deferred_open_message_smb(uint64_t mid
);
45 static bool smbd_lock_socket_internal(struct smbd_server_connection
*sconn
)
49 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
53 sconn
->smb1
.echo_handler
.ref_count
++;
55 if (sconn
->smb1
.echo_handler
.ref_count
> 1) {
59 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
63 sconn
->smb1
.echo_handler
.socket_lock_fd
,
64 SMB_F_SETLKW
, 0, 0, F_WRLCK
);
65 } while (!ok
&& (errno
== EINTR
));
68 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
72 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
77 void smbd_lock_socket(struct smbd_server_connection
*sconn
)
79 if (!smbd_lock_socket_internal(sconn
)) {
80 exit_server_cleanly("failed to lock socket");
84 static bool smbd_unlock_socket_internal(struct smbd_server_connection
*sconn
)
88 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
92 sconn
->smb1
.echo_handler
.ref_count
--;
94 if (sconn
->smb1
.echo_handler
.ref_count
> 0) {
100 sconn
->smb1
.echo_handler
.socket_lock_fd
,
101 SMB_F_SETLKW
, 0, 0, F_UNLCK
);
102 } while (!ok
&& (errno
== EINTR
));
105 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno
)));
109 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
114 void smbd_unlock_socket(struct smbd_server_connection
*sconn
)
116 if (!smbd_unlock_socket_internal(sconn
)) {
117 exit_server_cleanly("failed to unlock socket");
121 /* Accessor function for smb_read_error for smbd functions. */
123 /****************************************************************************
125 ****************************************************************************/
127 bool srv_send_smb(struct smbd_server_connection
*sconn
, char *buffer
,
128 bool do_signing
, uint32_t seqnum
,
130 struct smb_perfcount_data
*pcd
)
135 char *buf_out
= buffer
;
137 smbd_lock_socket(sconn
);
140 /* Sign the outgoing packet if required. */
141 srv_calculate_sign_mac(sconn
, buf_out
, seqnum
);
145 NTSTATUS status
= srv_encrypt_buffer(buffer
, &buf_out
);
146 if (!NT_STATUS_IS_OK(status
)) {
147 DEBUG(0, ("send_smb: SMB encryption failed "
148 "on outgoing packet! Error %s\n",
149 nt_errstr(status
) ));
154 len
= smb_len(buf_out
) + 4;
156 ret
= write_data(sconn
->sock
, buf_out
+nwritten
, len
- nwritten
);
159 char addr
[INET6_ADDRSTRLEN
];
161 * Try and give an error message saying what
164 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
165 (int)sys_getpid(), (int)len
,
166 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
167 (int)ret
, strerror(errno
) ));
169 srv_free_enc_buffer(buf_out
);
173 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
174 srv_free_enc_buffer(buf_out
);
176 SMB_PERFCOUNT_END(pcd
);
178 smbd_unlock_socket(sconn
);
182 /*******************************************************************
183 Setup the word count and byte count for a smb message.
184 ********************************************************************/
186 int srv_set_message(char *buf
,
191 if (zero
&& (num_words
|| num_bytes
)) {
192 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
194 SCVAL(buf
,smb_wct
,num_words
);
195 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
196 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
197 return (smb_size
+ num_words
*2 + num_bytes
);
200 static bool valid_smb_header(const uint8_t *inbuf
)
202 if (is_encrypted_packet(inbuf
)) {
206 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
207 * but it just looks weird to call strncmp for this one.
209 return (IVAL(smb_base(inbuf
), 0) == 0x424D53FF);
212 /* Socket functions for smbd packet processing. */
214 static bool valid_packet_size(size_t len
)
217 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
218 * of header. Don't print the error if this fits.... JRA.
221 if (len
> (BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
222 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
223 (unsigned long)len
));
229 static NTSTATUS
read_packet_remainder(int fd
, char *buffer
,
230 unsigned int timeout
, ssize_t len
)
238 status
= read_fd_with_timeout(fd
, buffer
, len
, len
, timeout
, NULL
);
239 if (!NT_STATUS_IS_OK(status
)) {
240 char addr
[INET6_ADDRSTRLEN
];
241 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
243 get_peer_addr(fd
, addr
, sizeof(addr
)),
249 /****************************************************************************
250 Attempt a zerocopy writeX read. We know here that len > smb_size-4
251 ****************************************************************************/
254 * Unfortunately, earlier versions of smbclient/libsmbclient
255 * don't send this "standard" writeX header. I've fixed this
256 * for 3.2 but we'll use the old method with earlier versions.
257 * Windows and CIFSFS at least use this standard size. Not
261 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
262 (2*14) + /* word count (including bcc) */ \
265 static NTSTATUS
receive_smb_raw_talloc_partial_read(TALLOC_CTX
*mem_ctx
,
266 const char lenbuf
[4],
267 struct smbd_server_connection
*sconn
,
270 unsigned int timeout
,
274 /* Size of a WRITEX call (+4 byte len). */
275 char writeX_header
[4 + STANDARD_WRITE_AND_X_HEADER_SIZE
];
276 ssize_t len
= smb_len_large(lenbuf
); /* Could be a UNIX large writeX. */
280 memcpy(writeX_header
, lenbuf
, 4);
282 status
= read_fd_with_timeout(
283 sock
, writeX_header
+ 4,
284 STANDARD_WRITE_AND_X_HEADER_SIZE
,
285 STANDARD_WRITE_AND_X_HEADER_SIZE
,
288 if (!NT_STATUS_IS_OK(status
)) {
289 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
290 "error = %s.\n", sconn
->client_id
.addr
,
296 * Ok - now try and see if this is a possible
300 if (is_valid_writeX_buffer(sconn
, (uint8_t *)writeX_header
)) {
302 * If the data offset is beyond what
303 * we've read, drain the extra bytes.
305 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
308 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
309 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
310 if (drain_socket(sock
, drain
) != drain
) {
311 smb_panic("receive_smb_raw_talloc_partial_read:"
312 " failed to drain pending bytes");
315 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
318 /* Spoof down the length and null out the bcc. */
319 set_message_bcc(writeX_header
, 0);
320 newlen
= smb_len(writeX_header
);
322 /* Copy the header we've written. */
324 *buffer
= (char *)TALLOC_MEMDUP(mem_ctx
,
326 sizeof(writeX_header
));
328 if (*buffer
== NULL
) {
329 DEBUG(0, ("Could not allocate inbuf of length %d\n",
330 (int)sizeof(writeX_header
)));
331 return NT_STATUS_NO_MEMORY
;
334 /* Work out the remaining bytes. */
335 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
336 *len_ret
= newlen
+ 4;
340 if (!valid_packet_size(len
)) {
341 return NT_STATUS_INVALID_PARAMETER
;
345 * Not a valid writeX call. Just do the standard
349 *buffer
= TALLOC_ARRAY(mem_ctx
, char, len
+4);
351 if (*buffer
== NULL
) {
352 DEBUG(0, ("Could not allocate inbuf of length %d\n",
354 return NT_STATUS_NO_MEMORY
;
357 /* Copy in what we already read. */
360 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
361 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
364 status
= read_packet_remainder(
366 (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
369 if (!NT_STATUS_IS_OK(status
)) {
370 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
380 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
,
381 struct smbd_server_connection
*sconn
,
383 char **buffer
, unsigned int timeout
,
384 size_t *p_unread
, size_t *plen
)
388 int min_recv_size
= lp_min_receive_file_size();
393 status
= read_smb_length_return_keepalive(sock
, lenbuf
, timeout
,
395 if (!NT_STATUS_IS_OK(status
)) {
399 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
400 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
401 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
402 !srv_is_signing_active(sconn
) &&
403 sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
405 return receive_smb_raw_talloc_partial_read(
406 mem_ctx
, lenbuf
, sconn
, sock
, buffer
, timeout
,
410 if (!valid_packet_size(len
)) {
411 return NT_STATUS_INVALID_PARAMETER
;
415 * The +4 here can't wrap, we've checked the length above already.
418 *buffer
= TALLOC_ARRAY(mem_ctx
, char, len
+4);
420 if (*buffer
== NULL
) {
421 DEBUG(0, ("Could not allocate inbuf of length %d\n",
423 return NT_STATUS_NO_MEMORY
;
426 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
428 status
= read_packet_remainder(sock
, (*buffer
)+4, timeout
, len
);
429 if (!NT_STATUS_IS_OK(status
)) {
437 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
,
438 struct smbd_server_connection
*sconn
,
440 char **buffer
, unsigned int timeout
,
441 size_t *p_unread
, bool *p_encrypted
,
444 bool trusted_channel
)
449 *p_encrypted
= false;
451 status
= receive_smb_raw_talloc(mem_ctx
, sconn
, sock
, buffer
, timeout
,
453 if (!NT_STATUS_IS_OK(status
)) {
454 DEBUG(NT_STATUS_EQUAL(status
, NT_STATUS_END_OF_FILE
)?5:1,
455 ("receive_smb_raw_talloc failed for client %s "
456 "read error = %s.\n",
457 sconn
->client_id
.addr
, nt_errstr(status
)));
461 if (is_encrypted_packet((uint8_t *)*buffer
)) {
462 status
= srv_decrypt_buffer(*buffer
);
463 if (!NT_STATUS_IS_OK(status
)) {
464 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
465 "incoming packet! Error %s\n",
466 nt_errstr(status
) ));
472 /* Check the incoming SMB signature. */
473 if (!srv_check_sign_mac(sconn
, *buffer
, seqnum
, trusted_channel
)) {
474 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
475 "incoming packet!\n"));
476 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
484 * Initialize a struct smb_request from an inbuf
487 static bool init_smb_request(struct smb_request
*req
,
488 struct smbd_server_connection
*sconn
,
490 size_t unread_bytes
, bool encrypted
,
493 size_t req_size
= smb_len(inbuf
) + 4;
494 /* Ensure we have at least smb_size bytes. */
495 if (req_size
< smb_size
) {
496 DEBUG(0,("init_smb_request: invalid request size %u\n",
497 (unsigned int)req_size
));
500 req
->cmd
= CVAL(inbuf
, smb_com
);
501 req
->flags2
= SVAL(inbuf
, smb_flg2
);
502 req
->smbpid
= SVAL(inbuf
, smb_pid
);
503 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
504 req
->seqnum
= seqnum
;
505 req
->vuid
= SVAL(inbuf
, smb_uid
);
506 req
->tid
= SVAL(inbuf
, smb_tid
);
507 req
->wct
= CVAL(inbuf
, smb_wct
);
508 req
->vwv
= (uint16_t *)(inbuf
+smb_vwv
);
509 req
->buflen
= smb_buflen(inbuf
);
510 req
->buf
= (const uint8_t *)smb_buf(inbuf
);
511 req
->unread_bytes
= unread_bytes
;
512 req
->encrypted
= encrypted
;
514 req
->conn
= conn_find(sconn
,req
->tid
);
515 req
->chain_fsp
= NULL
;
516 req
->chain_outbuf
= NULL
;
519 smb_init_perfcount_data(&req
->pcd
);
521 /* Ensure we have at least wct words and 2 bytes of bcc. */
522 if (smb_size
+ req
->wct
*2 > req_size
) {
523 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
524 (unsigned int)req
->wct
,
525 (unsigned int)req_size
));
528 /* Ensure bcc is correct. */
529 if (((uint8
*)smb_buf(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
530 DEBUG(0,("init_smb_request: invalid bcc number %u "
531 "(wct = %u, size %u)\n",
532 (unsigned int)req
->buflen
,
533 (unsigned int)req
->wct
,
534 (unsigned int)req_size
));
542 static void process_smb(struct smbd_server_connection
*conn
,
543 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
544 uint32_t seqnum
, bool encrypted
,
545 struct smb_perfcount_data
*deferred_pcd
);
547 static void smbd_deferred_open_timer(struct event_context
*ev
,
548 struct timed_event
*te
,
549 struct timeval _tval
,
552 struct pending_message_list
*msg
= talloc_get_type(private_data
,
553 struct pending_message_list
);
554 TALLOC_CTX
*mem_ctx
= talloc_tos();
555 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
558 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
561 exit_server("smbd_deferred_open_timer: talloc failed\n");
565 /* We leave this message on the queue so the open code can
566 know this is a retry. */
567 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
568 (unsigned long long)mid
));
570 /* Mark the message as processed so this is not
571 * re-processed in error. */
572 msg
->processed
= true;
574 process_smb(smbd_server_conn
, inbuf
,
576 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
578 /* If it's still there and was processed, remove it. */
579 msg
= get_deferred_open_message_smb(mid
);
580 if (msg
&& msg
->processed
) {
581 remove_deferred_open_message_smb(mid
);
585 /****************************************************************************
586 Function to push a message onto the tail of a linked list of smb messages ready
588 ****************************************************************************/
590 static bool push_queued_message(struct smb_request
*req
,
591 struct timeval request_time
,
592 struct timeval end_time
,
593 char *private_data
, size_t private_len
)
595 int msg_len
= smb_len(req
->inbuf
) + 4;
596 struct pending_message_list
*msg
;
598 msg
= TALLOC_ZERO_P(NULL
, struct pending_message_list
);
601 DEBUG(0,("push_message: malloc fail (1)\n"));
605 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
606 if(msg
->buf
.data
== NULL
) {
607 DEBUG(0,("push_message: malloc fail (2)\n"));
612 msg
->request_time
= request_time
;
613 msg
->seqnum
= req
->seqnum
;
614 msg
->encrypted
= req
->encrypted
;
615 msg
->processed
= false;
616 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
619 msg
->private_data
= data_blob_talloc(msg
, private_data
,
621 if (msg
->private_data
.data
== NULL
) {
622 DEBUG(0,("push_message: malloc fail (3)\n"));
628 msg
->te
= event_add_timed(smbd_event_context(),
631 smbd_deferred_open_timer
,
634 DEBUG(0,("push_message: event_add_timed failed\n"));
639 DLIST_ADD_END(deferred_open_queue
, msg
, struct pending_message_list
*);
641 DEBUG(10,("push_message: pushed message length %u on "
642 "deferred_open_queue\n", (unsigned int)msg_len
));
647 /****************************************************************************
648 Function to delete a sharing violation open message by mid.
649 ****************************************************************************/
651 void remove_deferred_open_message_smb(uint64_t mid
)
653 struct pending_message_list
*pml
;
655 if (smbd_server_conn
->using_smb2
) {
656 remove_deferred_open_message_smb2(smbd_server_conn
, mid
);
660 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
661 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
662 DEBUG(10,("remove_deferred_open_message_smb: "
663 "deleting mid %llu len %u\n",
664 (unsigned long long)mid
,
665 (unsigned int)pml
->buf
.length
));
666 DLIST_REMOVE(deferred_open_queue
, pml
);
673 /****************************************************************************
674 Move a sharing violation open retry message to the front of the list and
675 schedule it for immediate processing.
676 ****************************************************************************/
678 void schedule_deferred_open_message_smb(uint64_t mid
)
680 struct pending_message_list
*pml
;
683 if (smbd_server_conn
->using_smb2
) {
684 schedule_deferred_open_message_smb2(smbd_server_conn
, mid
);
688 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
689 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
691 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
694 (unsigned long long)msg_mid
));
696 if (mid
== msg_mid
) {
697 struct timed_event
*te
;
699 if (pml
->processed
) {
700 /* A processed message should not be
702 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
703 "message mid %llu was already processed\n",
704 (unsigned long long)msg_mid
));
708 DEBUG(10,("schedule_deferred_open_message_smb: "
709 "scheduling mid %llu\n",
710 (unsigned long long)mid
));
712 te
= event_add_timed(smbd_event_context(),
715 smbd_deferred_open_timer
,
718 DEBUG(10,("schedule_deferred_open_message_smb: "
719 "event_add_timed() failed, "
720 "skipping mid %llu\n",
721 (unsigned long long)msg_mid
));
724 TALLOC_FREE(pml
->te
);
726 DLIST_PROMOTE(deferred_open_queue
, pml
);
731 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
732 "find message mid %llu\n",
733 (unsigned long long)mid
));
736 /****************************************************************************
737 Return true if this mid is on the deferred queue and was not yet processed.
738 ****************************************************************************/
740 bool open_was_deferred(uint64_t mid
)
742 struct pending_message_list
*pml
;
744 if (smbd_server_conn
->using_smb2
) {
745 return open_was_deferred_smb2(smbd_server_conn
, mid
);
748 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
749 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
756 /****************************************************************************
757 Return the message queued by this mid.
758 ****************************************************************************/
760 static struct pending_message_list
*get_deferred_open_message_smb(uint64_t mid
)
762 struct pending_message_list
*pml
;
764 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
765 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
772 /****************************************************************************
773 Get the state data queued by this mid.
774 ****************************************************************************/
776 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
777 struct timeval
*p_request_time
,
780 struct pending_message_list
*pml
;
782 if (smbd_server_conn
->using_smb2
) {
783 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
788 pml
= get_deferred_open_message_smb(smbreq
->mid
);
792 if (p_request_time
) {
793 *p_request_time
= pml
->request_time
;
796 *pp_state
= (void *)pml
->private_data
.data
;
801 /****************************************************************************
802 Function to push a deferred open smb message onto a linked list of local smb
803 messages ready for processing.
804 ****************************************************************************/
806 bool push_deferred_open_message_smb(struct smb_request
*req
,
807 struct timeval request_time
,
808 struct timeval timeout
,
810 char *private_data
, size_t priv_len
)
812 struct timeval end_time
;
815 return push_deferred_open_message_smb2(req
->smb2req
,
823 if (req
->unread_bytes
) {
824 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
825 "unread_bytes = %u\n",
826 (unsigned int)req
->unread_bytes
));
827 smb_panic("push_deferred_open_message_smb: "
828 "logic error unread_bytes != 0" );
831 end_time
= timeval_sum(&request_time
, &timeout
);
833 DEBUG(10,("push_deferred_open_message_smb: pushing message "
834 "len %u mid %llu timeout time [%u.%06u]\n",
835 (unsigned int) smb_len(req
->inbuf
)+4,
836 (unsigned long long)req
->mid
,
837 (unsigned int)end_time
.tv_sec
,
838 (unsigned int)end_time
.tv_usec
));
840 return push_queued_message(req
, request_time
, end_time
,
841 private_data
, priv_len
);
845 struct timed_event
*te
;
846 struct timeval interval
;
848 bool (*handler
)(const struct timeval
*now
, void *private_data
);
852 static void smbd_idle_event_handler(struct event_context
*ctx
,
853 struct timed_event
*te
,
857 struct idle_event
*event
=
858 talloc_get_type_abort(private_data
, struct idle_event
);
860 TALLOC_FREE(event
->te
);
862 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
863 event
->name
, event
->te
));
865 if (!event
->handler(&now
, event
->private_data
)) {
866 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
867 event
->name
, event
->te
));
868 /* Don't repeat, delete ourselves */
873 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
874 event
->name
, event
->te
));
876 event
->te
= event_add_timed(ctx
, event
,
877 timeval_sum(&now
, &event
->interval
),
878 smbd_idle_event_handler
, event
);
880 /* We can't do much but fail here. */
881 SMB_ASSERT(event
->te
!= NULL
);
884 struct idle_event
*event_add_idle(struct event_context
*event_ctx
,
886 struct timeval interval
,
888 bool (*handler
)(const struct timeval
*now
,
892 struct idle_event
*result
;
893 struct timeval now
= timeval_current();
895 result
= TALLOC_P(mem_ctx
, struct idle_event
);
896 if (result
== NULL
) {
897 DEBUG(0, ("talloc failed\n"));
901 result
->interval
= interval
;
902 result
->handler
= handler
;
903 result
->private_data
= private_data
;
905 if (!(result
->name
= talloc_asprintf(result
, "idle_evt(%s)", name
))) {
906 DEBUG(0, ("talloc failed\n"));
911 result
->te
= event_add_timed(event_ctx
, result
,
912 timeval_sum(&now
, &interval
),
913 smbd_idle_event_handler
, result
);
914 if (result
->te
== NULL
) {
915 DEBUG(0, ("event_add_timed failed\n"));
920 DEBUG(10,("event_add_idle: %s %p\n", result
->name
, result
->te
));
924 static void smbd_sig_term_handler(struct tevent_context
*ev
,
925 struct tevent_signal
*se
,
931 exit_server_cleanly("termination signal");
934 void smbd_setup_sig_term_handler(void)
936 struct tevent_signal
*se
;
938 se
= tevent_add_signal(smbd_event_context(),
939 smbd_event_context(),
941 smbd_sig_term_handler
,
944 exit_server("failed to setup SIGTERM handler");
948 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
949 struct tevent_signal
*se
,
955 struct messaging_context
*msg_ctx
= talloc_get_type_abort(
956 private_data
, struct messaging_context
);
957 change_to_root_user();
958 DEBUG(1,("Reloading services after SIGHUP\n"));
959 reload_services(msg_ctx
, smbd_server_conn
->sock
, False
);
961 pcap_cache_reload(ev
, msg_ctx
, &reload_pcap_change_notify
);
965 void smbd_setup_sig_hup_handler(struct tevent_context
*ev
,
966 struct messaging_context
*msg_ctx
)
968 struct tevent_signal
*se
;
970 se
= tevent_add_signal(ev
, ev
, SIGHUP
, 0, smbd_sig_hup_handler
,
973 exit_server("failed to setup SIGHUP handler");
977 static NTSTATUS
smbd_server_connection_loop_once(struct smbd_server_connection
*conn
)
984 timeout
= SMBD_SELECT_TIMEOUT
* 1000;
987 * Are there any timed events waiting ? If so, ensure we don't
988 * select for longer than it would take to wait for them.
991 event_add_to_poll_args(smbd_event_context(), conn
,
992 &conn
->pfds
, &num_pfds
, &timeout
);
994 /* Process a signal and timed events now... */
995 if (run_events_poll(smbd_event_context(), 0, NULL
, 0)) {
996 return NT_STATUS_RETRY
;
1001 START_PROFILE(smbd_idle
);
1003 ret
= sys_poll(conn
->pfds
, num_pfds
, timeout
);
1006 END_PROFILE(smbd_idle
);
1011 if (errno
== EINTR
) {
1012 return NT_STATUS_RETRY
;
1014 return map_nt_error_from_unix(errno
);
1017 retry
= run_events_poll(smbd_event_context(), ret
, conn
->pfds
,
1020 return NT_STATUS_RETRY
;
1023 /* Did we timeout ? */
1025 return NT_STATUS_RETRY
;
1028 /* should not be reached */
1029 return NT_STATUS_INTERNAL_ERROR
;
1033 * Only allow 5 outstanding trans requests. We're allocating memory, so
1037 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
1040 for (; list
!= NULL
; list
= list
->next
) {
1042 if (list
->mid
== mid
) {
1043 return NT_STATUS_INVALID_PARAMETER
;
1049 return NT_STATUS_INSUFFICIENT_RESOURCES
;
1052 return NT_STATUS_OK
;
1056 These flags determine some of the permissions required to do an operation
1058 Note that I don't set NEED_WRITE on some write operations because they
1059 are used by some brain-dead clients when printing, and I don't want to
1060 force write permissions on print services.
1062 #define AS_USER (1<<0)
1063 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1064 #define TIME_INIT (1<<2)
1065 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1066 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1067 #define DO_CHDIR (1<<6)
1070 define a list of possible SMB messages and their corresponding
1071 functions. Any message that has a NULL function is unimplemented -
1072 please feel free to contribute implementations!
1074 static const struct smb_message_struct
{
1076 void (*fn
)(struct smb_request
*req
);
1078 } smb_messages
[256] = {
1080 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1081 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1082 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1083 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1084 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1085 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1086 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1087 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1088 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1089 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1090 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1091 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1092 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1093 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1094 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1095 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1096 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1097 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1098 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1099 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1100 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1101 /* 0x15 */ { NULL
, NULL
, 0 },
1102 /* 0x16 */ { NULL
, NULL
, 0 },
1103 /* 0x17 */ { NULL
, NULL
, 0 },
1104 /* 0x18 */ { NULL
, NULL
, 0 },
1105 /* 0x19 */ { NULL
, NULL
, 0 },
1106 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1107 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1108 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1109 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1110 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1111 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1112 /* 0x20 */ { "SMBwritec", NULL
,0},
1113 /* 0x21 */ { NULL
, NULL
, 0 },
1114 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1115 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1116 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1117 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1118 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1119 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1120 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1121 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1122 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1123 /* 0x2b */ { "SMBecho",reply_echo
,0},
1124 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1125 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1126 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1127 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1128 /* 0x30 */ { NULL
, NULL
, 0 },
1129 /* 0x31 */ { NULL
, NULL
, 0 },
1130 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1131 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1132 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1133 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1134 /* 0x36 */ { NULL
, NULL
, 0 },
1135 /* 0x37 */ { NULL
, NULL
, 0 },
1136 /* 0x38 */ { NULL
, NULL
, 0 },
1137 /* 0x39 */ { NULL
, NULL
, 0 },
1138 /* 0x3a */ { NULL
, NULL
, 0 },
1139 /* 0x3b */ { NULL
, NULL
, 0 },
1140 /* 0x3c */ { NULL
, NULL
, 0 },
1141 /* 0x3d */ { NULL
, NULL
, 0 },
1142 /* 0x3e */ { NULL
, NULL
, 0 },
1143 /* 0x3f */ { NULL
, NULL
, 0 },
1144 /* 0x40 */ { NULL
, NULL
, 0 },
1145 /* 0x41 */ { NULL
, NULL
, 0 },
1146 /* 0x42 */ { NULL
, NULL
, 0 },
1147 /* 0x43 */ { NULL
, NULL
, 0 },
1148 /* 0x44 */ { NULL
, NULL
, 0 },
1149 /* 0x45 */ { NULL
, NULL
, 0 },
1150 /* 0x46 */ { NULL
, NULL
, 0 },
1151 /* 0x47 */ { NULL
, NULL
, 0 },
1152 /* 0x48 */ { NULL
, NULL
, 0 },
1153 /* 0x49 */ { NULL
, NULL
, 0 },
1154 /* 0x4a */ { NULL
, NULL
, 0 },
1155 /* 0x4b */ { NULL
, NULL
, 0 },
1156 /* 0x4c */ { NULL
, NULL
, 0 },
1157 /* 0x4d */ { NULL
, NULL
, 0 },
1158 /* 0x4e */ { NULL
, NULL
, 0 },
1159 /* 0x4f */ { NULL
, NULL
, 0 },
1160 /* 0x50 */ { NULL
, NULL
, 0 },
1161 /* 0x51 */ { NULL
, NULL
, 0 },
1162 /* 0x52 */ { NULL
, NULL
, 0 },
1163 /* 0x53 */ { NULL
, NULL
, 0 },
1164 /* 0x54 */ { NULL
, NULL
, 0 },
1165 /* 0x55 */ { NULL
, NULL
, 0 },
1166 /* 0x56 */ { NULL
, NULL
, 0 },
1167 /* 0x57 */ { NULL
, NULL
, 0 },
1168 /* 0x58 */ { NULL
, NULL
, 0 },
1169 /* 0x59 */ { NULL
, NULL
, 0 },
1170 /* 0x5a */ { NULL
, NULL
, 0 },
1171 /* 0x5b */ { NULL
, NULL
, 0 },
1172 /* 0x5c */ { NULL
, NULL
, 0 },
1173 /* 0x5d */ { NULL
, NULL
, 0 },
1174 /* 0x5e */ { NULL
, NULL
, 0 },
1175 /* 0x5f */ { NULL
, NULL
, 0 },
1176 /* 0x60 */ { NULL
, NULL
, 0 },
1177 /* 0x61 */ { NULL
, NULL
, 0 },
1178 /* 0x62 */ { NULL
, NULL
, 0 },
1179 /* 0x63 */ { NULL
, NULL
, 0 },
1180 /* 0x64 */ { NULL
, NULL
, 0 },
1181 /* 0x65 */ { NULL
, NULL
, 0 },
1182 /* 0x66 */ { NULL
, NULL
, 0 },
1183 /* 0x67 */ { NULL
, NULL
, 0 },
1184 /* 0x68 */ { NULL
, NULL
, 0 },
1185 /* 0x69 */ { NULL
, NULL
, 0 },
1186 /* 0x6a */ { NULL
, NULL
, 0 },
1187 /* 0x6b */ { NULL
, NULL
, 0 },
1188 /* 0x6c */ { NULL
, NULL
, 0 },
1189 /* 0x6d */ { NULL
, NULL
, 0 },
1190 /* 0x6e */ { NULL
, NULL
, 0 },
1191 /* 0x6f */ { NULL
, NULL
, 0 },
1192 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1193 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1194 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1195 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1196 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1197 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1198 /* 0x76 */ { NULL
, NULL
, 0 },
1199 /* 0x77 */ { NULL
, NULL
, 0 },
1200 /* 0x78 */ { NULL
, NULL
, 0 },
1201 /* 0x79 */ { NULL
, NULL
, 0 },
1202 /* 0x7a */ { NULL
, NULL
, 0 },
1203 /* 0x7b */ { NULL
, NULL
, 0 },
1204 /* 0x7c */ { NULL
, NULL
, 0 },
1205 /* 0x7d */ { NULL
, NULL
, 0 },
1206 /* 0x7e */ { NULL
, NULL
, 0 },
1207 /* 0x7f */ { NULL
, NULL
, 0 },
1208 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1209 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1210 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1211 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1212 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1213 /* 0x85 */ { NULL
, NULL
, 0 },
1214 /* 0x86 */ { NULL
, NULL
, 0 },
1215 /* 0x87 */ { NULL
, NULL
, 0 },
1216 /* 0x88 */ { NULL
, NULL
, 0 },
1217 /* 0x89 */ { NULL
, NULL
, 0 },
1218 /* 0x8a */ { NULL
, NULL
, 0 },
1219 /* 0x8b */ { NULL
, NULL
, 0 },
1220 /* 0x8c */ { NULL
, NULL
, 0 },
1221 /* 0x8d */ { NULL
, NULL
, 0 },
1222 /* 0x8e */ { NULL
, NULL
, 0 },
1223 /* 0x8f */ { NULL
, NULL
, 0 },
1224 /* 0x90 */ { NULL
, NULL
, 0 },
1225 /* 0x91 */ { NULL
, NULL
, 0 },
1226 /* 0x92 */ { NULL
, NULL
, 0 },
1227 /* 0x93 */ { NULL
, NULL
, 0 },
1228 /* 0x94 */ { NULL
, NULL
, 0 },
1229 /* 0x95 */ { NULL
, NULL
, 0 },
1230 /* 0x96 */ { NULL
, NULL
, 0 },
1231 /* 0x97 */ { NULL
, NULL
, 0 },
1232 /* 0x98 */ { NULL
, NULL
, 0 },
1233 /* 0x99 */ { NULL
, NULL
, 0 },
1234 /* 0x9a */ { NULL
, NULL
, 0 },
1235 /* 0x9b */ { NULL
, NULL
, 0 },
1236 /* 0x9c */ { NULL
, NULL
, 0 },
1237 /* 0x9d */ { NULL
, NULL
, 0 },
1238 /* 0x9e */ { NULL
, NULL
, 0 },
1239 /* 0x9f */ { NULL
, NULL
, 0 },
1240 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1241 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1242 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1243 /* 0xa3 */ { NULL
, NULL
, 0 },
1244 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1245 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1246 /* 0xa6 */ { NULL
, NULL
, 0 },
1247 /* 0xa7 */ { NULL
, NULL
, 0 },
1248 /* 0xa8 */ { NULL
, NULL
, 0 },
1249 /* 0xa9 */ { NULL
, NULL
, 0 },
1250 /* 0xaa */ { NULL
, NULL
, 0 },
1251 /* 0xab */ { NULL
, NULL
, 0 },
1252 /* 0xac */ { NULL
, NULL
, 0 },
1253 /* 0xad */ { NULL
, NULL
, 0 },
1254 /* 0xae */ { NULL
, NULL
, 0 },
1255 /* 0xaf */ { NULL
, NULL
, 0 },
1256 /* 0xb0 */ { NULL
, NULL
, 0 },
1257 /* 0xb1 */ { NULL
, NULL
, 0 },
1258 /* 0xb2 */ { NULL
, NULL
, 0 },
1259 /* 0xb3 */ { NULL
, NULL
, 0 },
1260 /* 0xb4 */ { NULL
, NULL
, 0 },
1261 /* 0xb5 */ { NULL
, NULL
, 0 },
1262 /* 0xb6 */ { NULL
, NULL
, 0 },
1263 /* 0xb7 */ { NULL
, NULL
, 0 },
1264 /* 0xb8 */ { NULL
, NULL
, 0 },
1265 /* 0xb9 */ { NULL
, NULL
, 0 },
1266 /* 0xba */ { NULL
, NULL
, 0 },
1267 /* 0xbb */ { NULL
, NULL
, 0 },
1268 /* 0xbc */ { NULL
, NULL
, 0 },
1269 /* 0xbd */ { NULL
, NULL
, 0 },
1270 /* 0xbe */ { NULL
, NULL
, 0 },
1271 /* 0xbf */ { NULL
, NULL
, 0 },
1272 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1273 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1274 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1275 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1276 /* 0xc4 */ { NULL
, NULL
, 0 },
1277 /* 0xc5 */ { NULL
, NULL
, 0 },
1278 /* 0xc6 */ { NULL
, NULL
, 0 },
1279 /* 0xc7 */ { NULL
, NULL
, 0 },
1280 /* 0xc8 */ { NULL
, NULL
, 0 },
1281 /* 0xc9 */ { NULL
, NULL
, 0 },
1282 /* 0xca */ { NULL
, NULL
, 0 },
1283 /* 0xcb */ { NULL
, NULL
, 0 },
1284 /* 0xcc */ { NULL
, NULL
, 0 },
1285 /* 0xcd */ { NULL
, NULL
, 0 },
1286 /* 0xce */ { NULL
, NULL
, 0 },
1287 /* 0xcf */ { NULL
, NULL
, 0 },
1288 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1289 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1290 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1291 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1292 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1293 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1294 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1295 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1296 /* 0xd8 */ { NULL
, NULL
, 0 },
1297 /* 0xd9 */ { NULL
, NULL
, 0 },
1298 /* 0xda */ { NULL
, NULL
, 0 },
1299 /* 0xdb */ { NULL
, NULL
, 0 },
1300 /* 0xdc */ { NULL
, NULL
, 0 },
1301 /* 0xdd */ { NULL
, NULL
, 0 },
1302 /* 0xde */ { NULL
, NULL
, 0 },
1303 /* 0xdf */ { NULL
, NULL
, 0 },
1304 /* 0xe0 */ { NULL
, NULL
, 0 },
1305 /* 0xe1 */ { NULL
, NULL
, 0 },
1306 /* 0xe2 */ { NULL
, NULL
, 0 },
1307 /* 0xe3 */ { NULL
, NULL
, 0 },
1308 /* 0xe4 */ { NULL
, NULL
, 0 },
1309 /* 0xe5 */ { NULL
, NULL
, 0 },
1310 /* 0xe6 */ { NULL
, NULL
, 0 },
1311 /* 0xe7 */ { NULL
, NULL
, 0 },
1312 /* 0xe8 */ { NULL
, NULL
, 0 },
1313 /* 0xe9 */ { NULL
, NULL
, 0 },
1314 /* 0xea */ { NULL
, NULL
, 0 },
1315 /* 0xeb */ { NULL
, NULL
, 0 },
1316 /* 0xec */ { NULL
, NULL
, 0 },
1317 /* 0xed */ { NULL
, NULL
, 0 },
1318 /* 0xee */ { NULL
, NULL
, 0 },
1319 /* 0xef */ { NULL
, NULL
, 0 },
1320 /* 0xf0 */ { NULL
, NULL
, 0 },
1321 /* 0xf1 */ { NULL
, NULL
, 0 },
1322 /* 0xf2 */ { NULL
, NULL
, 0 },
1323 /* 0xf3 */ { NULL
, NULL
, 0 },
1324 /* 0xf4 */ { NULL
, NULL
, 0 },
1325 /* 0xf5 */ { NULL
, NULL
, 0 },
1326 /* 0xf6 */ { NULL
, NULL
, 0 },
1327 /* 0xf7 */ { NULL
, NULL
, 0 },
1328 /* 0xf8 */ { NULL
, NULL
, 0 },
1329 /* 0xf9 */ { NULL
, NULL
, 0 },
1330 /* 0xfa */ { NULL
, NULL
, 0 },
1331 /* 0xfb */ { NULL
, NULL
, 0 },
1332 /* 0xfc */ { NULL
, NULL
, 0 },
1333 /* 0xfd */ { NULL
, NULL
, 0 },
1334 /* 0xfe */ { NULL
, NULL
, 0 },
1335 /* 0xff */ { NULL
, NULL
, 0 }
1339 /*******************************************************************
1340 allocate and initialize a reply packet
1341 ********************************************************************/
1343 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1344 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1348 * Protect against integer wrap
1350 if ((num_bytes
> 0xffffff)
1351 || ((num_bytes
+ smb_size
+ num_words
*2) > 0xffffff)) {
1353 if (asprintf(&msg
, "num_bytes too large: %u",
1354 (unsigned)num_bytes
) == -1) {
1355 msg
= CONST_DISCARD(char *, "num_bytes too large");
1360 *outbuf
= TALLOC_ARRAY(mem_ctx
, char,
1361 smb_size
+ num_words
*2 + num_bytes
);
1362 if (*outbuf
== NULL
) {
1366 construct_reply_common(req
, inbuf
, *outbuf
);
1367 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1369 * Zero out the word area, the caller has to take care of the bcc area
1372 if (num_words
!= 0) {
1373 memset(*outbuf
+ smb_vwv0
, 0, num_words
*2);
1379 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1382 if (!create_outbuf(req
, req
, (char *)req
->inbuf
, &outbuf
, num_words
,
1384 smb_panic("could not allocate output buffer\n");
1386 req
->outbuf
= (uint8_t *)outbuf
;
1390 /*******************************************************************
1391 Dump a packet to a file.
1392 ********************************************************************/
1394 static void smb_dump(const char *name
, int type
, const char *data
, ssize_t len
)
1398 if (DEBUGLEVEL
< 50) {
1402 if (len
< 4) len
= smb_len(data
)+4;
1403 for (i
=1;i
<100;i
++) {
1404 if (asprintf(&fname
, "/tmp/%s.%d.%s", name
, i
,
1405 type
? "req" : "resp") == -1) {
1408 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1409 if (fd
!= -1 || errno
!= EEXIST
) break;
1412 ssize_t ret
= write(fd
, data
, len
);
1414 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1416 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1421 /****************************************************************************
1422 Prepare everything for calling the actual request function, and potentially
1423 call the request function via the "new" interface.
1425 Return False if the "legacy" function needs to be called, everything is
1428 Return True if we're done.
1430 I know this API sucks, but it is the one with the least code change I could
1432 ****************************************************************************/
1434 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
, int size
)
1438 connection_struct
*conn
= NULL
;
1439 struct smbd_server_connection
*sconn
= req
->sconn
;
1443 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1444 * so subtract 4 from it. */
1445 if ((size
< (smb_size
- 4)) ||
1446 !valid_smb_header(req
->inbuf
)) {
1447 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1448 smb_len(req
->inbuf
)));
1449 exit_server_cleanly("Non-SMB packet");
1452 if (smb_messages
[type
].fn
== NULL
) {
1453 DEBUG(0,("Unknown message type %d!\n",type
));
1454 smb_dump("Unknown", 1, (char *)req
->inbuf
, size
);
1455 reply_unknown_new(req
, type
);
1459 flags
= smb_messages
[type
].flags
;
1461 /* In share mode security we must ignore the vuid. */
1462 session_tag
= (lp_security() == SEC_SHARE
)
1463 ? UID_FIELD_INVALID
: req
->vuid
;
1466 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1467 (int)sys_getpid(), (unsigned long)conn
));
1469 smb_dump(smb_fn_name(type
), 1, (char *)req
->inbuf
, size
);
1471 /* Ensure this value is replaced in the incoming packet. */
1472 SSVAL(req
->inbuf
,smb_uid
,session_tag
);
1475 * Ensure the correct username is in current_user_info. This is a
1476 * really ugly bugfix for problems with multiple session_setup_and_X's
1477 * being done and allowing %U and %G substitutions to work correctly.
1478 * There is a reason this code is done here, don't move it unless you
1479 * know what you're doing... :-).
1483 if (session_tag
!= sconn
->smb1
.sessions
.last_session_tag
) {
1484 user_struct
*vuser
= NULL
;
1486 sconn
->smb1
.sessions
.last_session_tag
= session_tag
;
1487 if(session_tag
!= UID_FIELD_INVALID
) {
1488 vuser
= get_valid_user_struct(sconn
, session_tag
);
1490 set_current_user_info(
1491 vuser
->session_info
->sanitized_username
,
1492 vuser
->session_info
->unix_name
,
1493 vuser
->session_info
->info3
->base
.domain
.string
);
1498 /* Does this call need to be run as the connected user? */
1499 if (flags
& AS_USER
) {
1501 /* Does this call need a valid tree connection? */
1504 * Amazingly, the error code depends on the command
1507 if (type
== SMBntcreateX
) {
1508 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1510 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1515 if (!change_to_user(conn
,session_tag
)) {
1516 DEBUG(0, ("Error: Could not change to user. Removing "
1517 "deferred open, mid=%llu.\n",
1518 (unsigned long long)req
->mid
));
1519 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1523 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1525 /* Does it need write permission? */
1526 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1527 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1531 /* IPC services are limited */
1532 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1533 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1537 /* This call needs to be run as root */
1538 change_to_root_user();
1541 /* load service specific parameters */
1543 if (req
->encrypted
) {
1544 conn
->encrypted_tid
= true;
1545 /* encrypted required from now on. */
1546 conn
->encrypt_level
= Required
;
1547 } else if (ENCRYPTION_REQUIRED(conn
)) {
1548 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1549 exit_server_cleanly("encryption required "
1555 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1556 (flags
& (AS_USER
|DO_CHDIR
)
1558 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1561 conn
->num_smb_operations
++;
1564 /* does this protocol need to be run as guest? */
1565 if ((flags
& AS_GUEST
)
1566 && (!change_to_guest() ||
1567 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1568 sconn
->client_id
.name
,
1569 sconn
->client_id
.addr
))) {
1570 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1574 smb_messages
[type
].fn(req
);
1578 /****************************************************************************
1579 Construct a reply to the incoming packet.
1580 ****************************************************************************/
1582 static void construct_reply(struct smbd_server_connection
*sconn
,
1583 char *inbuf
, int size
, size_t unread_bytes
,
1584 uint32_t seqnum
, bool encrypted
,
1585 struct smb_perfcount_data
*deferred_pcd
)
1587 connection_struct
*conn
;
1588 struct smb_request
*req
;
1590 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1591 smb_panic("could not allocate smb_request");
1594 if (!init_smb_request(req
, sconn
, (uint8
*)inbuf
, unread_bytes
,
1595 encrypted
, seqnum
)) {
1596 exit_server_cleanly("Invalid SMB request");
1599 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1601 /* we popped this message off the queue - keep original perf data */
1603 req
->pcd
= *deferred_pcd
;
1605 SMB_PERFCOUNT_START(&req
->pcd
);
1606 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1607 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1610 conn
= switch_message(req
->cmd
, req
, size
);
1612 if (req
->unread_bytes
) {
1613 /* writeX failed. drain socket. */
1614 if (drain_socket(req
->sconn
->sock
, req
->unread_bytes
) !=
1615 req
->unread_bytes
) {
1616 smb_panic("failed to drain pending bytes");
1618 req
->unread_bytes
= 0;
1626 if (req
->outbuf
== NULL
) {
1630 if (CVAL(req
->outbuf
,0) == 0) {
1631 show_msg((char *)req
->outbuf
);
1634 if (!srv_send_smb(req
->sconn
,
1635 (char *)req
->outbuf
,
1636 true, req
->seqnum
+1,
1637 IS_CONN_ENCRYPTED(conn
)||req
->encrypted
,
1639 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1647 /****************************************************************************
1648 Process an smb from the client
1649 ****************************************************************************/
1650 static void process_smb(struct smbd_server_connection
*sconn
,
1651 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1652 uint32_t seqnum
, bool encrypted
,
1653 struct smb_perfcount_data
*deferred_pcd
)
1655 int msg_type
= CVAL(inbuf
,0);
1657 DO_PROFILE_INC(smb_count
);
1659 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1661 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1662 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1664 if (msg_type
!= 0) {
1666 * NetBIOS session request, keepalive, etc.
1668 reply_special(sconn
, (char *)inbuf
, nread
);
1672 if (sconn
->using_smb2
) {
1673 /* At this point we're not really using smb2,
1674 * we make the decision here.. */
1675 if (smbd_is_smb2_header(inbuf
, nread
)) {
1676 smbd_smb2_first_negprot(sconn
, inbuf
, nread
);
1678 } else if (nread
>= smb_size
&& valid_smb_header(inbuf
)
1679 && CVAL(inbuf
, smb_com
) != 0x72) {
1680 /* This is a non-negprot SMB1 packet.
1681 Disable SMB2 from now on. */
1682 sconn
->using_smb2
= false;
1686 show_msg((char *)inbuf
);
1688 construct_reply(sconn
, (char *)inbuf
, nread
, unread_bytes
, seqnum
,
1689 encrypted
, deferred_pcd
);
1693 sconn
->num_requests
++;
1695 /* The timeout_processing function isn't run nearly
1696 often enough to implement 'max log size' without
1697 overrunning the size of the file by many megabytes.
1698 This is especially true if we are running at debug
1699 level 10. Checking every 50 SMBs is a nice
1700 tradeoff of performance vs log file size overrun. */
1702 if ((sconn
->num_requests
% 50) == 0 &&
1703 need_to_check_log_size()) {
1704 change_to_root_user();
1709 /****************************************************************************
1710 Return a string containing the function name of a SMB command.
1711 ****************************************************************************/
1713 const char *smb_fn_name(int type
)
1715 const char *unknown_name
= "SMBunknown";
1717 if (smb_messages
[type
].name
== NULL
)
1718 return(unknown_name
);
1720 return(smb_messages
[type
].name
);
1723 /****************************************************************************
1724 Helper functions for contruct_reply.
1725 ****************************************************************************/
1727 void add_to_common_flags2(uint32 v
)
1732 void remove_from_common_flags2(uint32 v
)
1734 common_flags2
&= ~v
;
1737 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1740 srv_set_message(outbuf
,0,0,false);
1742 SCVAL(outbuf
, smb_com
, req
->cmd
);
1743 SIVAL(outbuf
,smb_rcls
,0);
1744 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1745 SSVAL(outbuf
,smb_flg2
,
1746 (SVAL(inbuf
,smb_flg2
) & FLAGS2_UNICODE_STRINGS
) |
1748 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1750 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
1751 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
1752 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
1753 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
1756 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
1758 construct_reply_common(req
, (char *)req
->inbuf
, outbuf
);
1762 * How many bytes have we already accumulated up to the current wct field
1766 size_t req_wct_ofs(struct smb_request
*req
)
1770 if (req
->chain_outbuf
== NULL
) {
1773 buf_size
= talloc_get_size(req
->chain_outbuf
);
1774 if ((buf_size
% 4) != 0) {
1775 buf_size
+= (4 - (buf_size
% 4));
1777 return buf_size
- 4;
1781 * Hack around reply_nterror & friends not being aware of chained requests,
1782 * generating illegal (i.e. wct==0) chain replies.
1785 static void fixup_chain_error_packet(struct smb_request
*req
)
1787 uint8_t *outbuf
= req
->outbuf
;
1789 reply_outbuf(req
, 2, 0);
1790 memcpy(req
->outbuf
, outbuf
, smb_wct
);
1791 TALLOC_FREE(outbuf
);
1792 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
1796 * @brief Find the smb_cmd offset of the last command pushed
1797 * @param[in] buf The buffer we're building up
1798 * @retval Where can we put our next andx cmd?
1800 * While chaining requests, the "next" request we're looking at needs to put
1801 * its SMB_Command before the data the previous request already built up added
1802 * to the chain. Find the offset to the place where we have to put our cmd.
1805 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
1810 cmd
= CVAL(buf
, smb_com
);
1812 SMB_ASSERT(is_andx_req(cmd
));
1816 while (CVAL(buf
, ofs
) != 0xff) {
1818 if (!is_andx_req(CVAL(buf
, ofs
))) {
1823 * ofs is from start of smb header, so add the 4 length
1824 * bytes. The next cmd is right after the wct field.
1826 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
1828 SMB_ASSERT(ofs
+4 < talloc_get_size(buf
));
1836 * @brief Do the smb chaining at a buffer level
1837 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1838 * @param[in] smb_command The command that we want to issue
1839 * @param[in] wct How many words?
1840 * @param[in] vwv The words, already in network order
1841 * @param[in] bytes_alignment How shall we align "bytes"?
1842 * @param[in] num_bytes How many bytes?
1843 * @param[in] bytes The data the request ships
1845 * smb_splice_chain() adds the vwv and bytes to the request already present in
1849 static bool smb_splice_chain(uint8_t **poutbuf
, uint8_t smb_command
,
1850 uint8_t wct
, const uint16_t *vwv
,
1851 size_t bytes_alignment
,
1852 uint32_t num_bytes
, const uint8_t *bytes
)
1855 size_t old_size
, new_size
;
1857 size_t chain_padding
= 0;
1858 size_t bytes_padding
= 0;
1861 old_size
= talloc_get_size(*poutbuf
);
1864 * old_size == smb_wct means we're pushing the first request in for
1868 first_request
= (old_size
== smb_wct
);
1870 if (!first_request
&& ((old_size
% 4) != 0)) {
1872 * Align the wct field of subsequent requests to a 4-byte
1875 chain_padding
= 4 - (old_size
% 4);
1879 * After the old request comes the new wct field (1 byte), the vwv's
1880 * and the num_bytes field. After at we might need to align the bytes
1881 * given to us to "bytes_alignment", increasing the num_bytes value.
1884 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
1886 if ((bytes_alignment
!= 0) && ((new_size
% bytes_alignment
) != 0)) {
1887 bytes_padding
= bytes_alignment
- (new_size
% bytes_alignment
);
1890 new_size
+= bytes_padding
+ num_bytes
;
1892 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
1893 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1894 (unsigned)new_size
));
1898 outbuf
= TALLOC_REALLOC_ARRAY(NULL
, *poutbuf
, uint8_t, new_size
);
1899 if (outbuf
== NULL
) {
1900 DEBUG(0, ("talloc failed\n"));
1905 if (first_request
) {
1906 SCVAL(outbuf
, smb_com
, smb_command
);
1908 size_t andx_cmd_ofs
;
1910 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
1911 DEBUG(1, ("invalid command chain\n"));
1912 *poutbuf
= TALLOC_REALLOC_ARRAY(
1913 NULL
, *poutbuf
, uint8_t, old_size
);
1917 if (chain_padding
!= 0) {
1918 memset(outbuf
+ old_size
, 0, chain_padding
);
1919 old_size
+= chain_padding
;
1922 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
1923 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
1929 * Push the chained request:
1934 SCVAL(outbuf
, ofs
, wct
);
1941 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
1942 ofs
+= sizeof(uint16_t) * wct
;
1948 SSVAL(outbuf
, ofs
, num_bytes
+ bytes_padding
);
1949 ofs
+= sizeof(uint16_t);
1955 if (bytes_padding
!= 0) {
1956 memset(outbuf
+ ofs
, 0, bytes_padding
);
1957 ofs
+= bytes_padding
;
1964 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
1969 /****************************************************************************
1970 Construct a chained reply and add it to the already made reply
1971 ****************************************************************************/
1973 void chain_reply(struct smb_request
*req
)
1975 size_t smblen
= smb_len(req
->inbuf
);
1976 size_t already_used
, length_needed
;
1978 uint32_t chain_offset
; /* uint32_t to avoid overflow */
1985 if (IVAL(req
->outbuf
, smb_rcls
) != 0) {
1986 fixup_chain_error_packet(req
);
1990 * Any of the AndX requests and replies have at least a wct of
1991 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1992 * beginning of the SMB header to the next wct field.
1994 * None of the AndX requests put anything valuable in vwv[0] and [1],
1995 * so we can overwrite it here to form the chain.
1998 if ((req
->wct
< 2) || (CVAL(req
->outbuf
, smb_wct
) < 2)) {
1999 if (req
->chain_outbuf
== NULL
) {
2000 req
->chain_outbuf
= TALLOC_REALLOC_ARRAY(
2001 req
, req
->outbuf
, uint8_t,
2002 smb_len(req
->outbuf
) + 4);
2003 if (req
->chain_outbuf
== NULL
) {
2004 smb_panic("talloc failed");
2012 * Here we assume that this is the end of the chain. For that we need
2013 * to set "next command" to 0xff and the offset to 0. If we later find
2014 * more commands in the chain, this will be overwritten again.
2017 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
2018 SCVAL(req
->outbuf
, smb_vwv0
+1, 0);
2019 SSVAL(req
->outbuf
, smb_vwv1
, 0);
2021 if (req
->chain_outbuf
== NULL
) {
2023 * In req->chain_outbuf we collect all the replies. Start the
2024 * chain by copying in the first reply.
2026 * We do the realloc because later on we depend on
2027 * talloc_get_size to determine the length of
2028 * chain_outbuf. The reply_xxx routines might have
2029 * over-allocated (reply_pipe_read_and_X used to be such an
2032 req
->chain_outbuf
= TALLOC_REALLOC_ARRAY(
2033 req
, req
->outbuf
, uint8_t, smb_len(req
->outbuf
) + 4);
2034 if (req
->chain_outbuf
== NULL
) {
2035 smb_panic("talloc failed");
2040 * Update smb headers where subsequent chained commands
2041 * may have updated them.
2043 SSVAL(req
->chain_outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
2044 SSVAL(req
->chain_outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
2046 if (!smb_splice_chain(&req
->chain_outbuf
,
2047 CVAL(req
->outbuf
, smb_com
),
2048 CVAL(req
->outbuf
, smb_wct
),
2049 (uint16_t *)(req
->outbuf
+ smb_vwv
),
2050 0, smb_buflen(req
->outbuf
),
2051 (uint8_t *)smb_buf(req
->outbuf
))) {
2054 TALLOC_FREE(req
->outbuf
);
2058 * We use the old request's vwv field to grab the next chained command
2059 * and offset into the chained fields.
2062 chain_cmd
= CVAL(req
->vwv
+0, 0);
2063 chain_offset
= SVAL(req
->vwv
+1, 0);
2065 if (chain_cmd
== 0xff) {
2067 * End of chain, no more requests from the client. So ship the
2070 smb_setlen((char *)(req
->chain_outbuf
),
2071 talloc_get_size(req
->chain_outbuf
) - 4);
2073 if (!srv_send_smb(req
->sconn
, (char *)req
->chain_outbuf
,
2074 true, req
->seqnum
+1,
2075 IS_CONN_ENCRYPTED(req
->conn
)
2078 exit_server_cleanly("chain_reply: srv_send_smb "
2081 TALLOC_FREE(req
->chain_outbuf
);
2086 /* add a new perfcounter for this element of chain */
2087 SMB_PERFCOUNT_ADD(&req
->pcd
);
2088 SMB_PERFCOUNT_SET_OP(&req
->pcd
, chain_cmd
);
2089 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, smblen
);
2092 * Check if the client tries to fool us. The chain offset
2093 * needs to point beyond the current request in the chain, it
2094 * needs to strictly grow. Otherwise we might be tricked into
2095 * an endless loop always processing the same request over and
2096 * over again. We used to assume that vwv and the byte buffer
2097 * array in a chain are always attached, but OS/2 the
2098 * Write&X/Read&X chain puts the Read&X vwv array right behind
2099 * the Write&X vwv chain. The Write&X bcc array is put behind
2100 * the Read&X vwv array. So now we check whether the chain
2101 * offset points strictly behind the previous vwv
2102 * array. req->buf points right after the vwv array of the
2103 * previous request. See
2104 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2108 already_used
= PTR_DIFF(req
->buf
, smb_base(req
->inbuf
));
2109 if (chain_offset
<= already_used
) {
2114 * Next check: Make sure the chain offset does not point beyond the
2115 * overall smb request length.
2118 length_needed
= chain_offset
+1; /* wct */
2119 if (length_needed
> smblen
) {
2124 * Now comes the pointer magic. Goal here is to set up req->vwv and
2125 * req->buf correctly again to be able to call the subsequent
2126 * switch_message(). The chain offset (the former vwv[1]) points at
2127 * the new wct field.
2130 wct
= CVAL(smb_base(req
->inbuf
), chain_offset
);
2133 * Next consistency check: Make the new vwv array fits in the overall
2137 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2138 if (length_needed
> smblen
) {
2141 vwv
= (uint16_t *)(smb_base(req
->inbuf
) + chain_offset
+ 1);
2144 * Now grab the new byte buffer....
2147 buflen
= SVAL(vwv
+wct
, 0);
2150 * .. and check that it fits.
2153 length_needed
+= buflen
;
2154 if (length_needed
> smblen
) {
2157 buf
= (uint8_t *)(vwv
+wct
+1);
2159 req
->cmd
= chain_cmd
;
2162 req
->buflen
= buflen
;
2165 switch_message(chain_cmd
, req
, smblen
);
2167 if (req
->outbuf
== NULL
) {
2169 * This happens if the chained command has suspended itself or
2170 * if it has called srv_send_smb() itself.
2176 * We end up here if the chained command was not itself chained or
2177 * suspended, but for example a close() command. We now need to splice
2178 * the chained commands' outbuf into the already built up chain_outbuf
2179 * and ship the result.
2185 * We end up here if there's any error in the chain syntax. Report a
2186 * DOS error, just like Windows does.
2188 reply_force_doserror(req
, ERRSRV
, ERRerror
);
2189 fixup_chain_error_packet(req
);
2193 * This scary statement intends to set the
2194 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2195 * to the value req->outbuf carries
2197 SSVAL(req
->chain_outbuf
, smb_flg2
,
2198 (SVAL(req
->chain_outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
2199 | (SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
2202 * Transfer the error codes from the subrequest to the main one
2204 SSVAL(req
->chain_outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
2205 SSVAL(req
->chain_outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
2207 if (!smb_splice_chain(&req
->chain_outbuf
,
2208 CVAL(req
->outbuf
, smb_com
),
2209 CVAL(req
->outbuf
, smb_wct
),
2210 (uint16_t *)(req
->outbuf
+ smb_vwv
),
2211 0, smb_buflen(req
->outbuf
),
2212 (uint8_t *)smb_buf(req
->outbuf
))) {
2213 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2215 TALLOC_FREE(req
->outbuf
);
2217 smb_setlen((char *)(req
->chain_outbuf
),
2218 talloc_get_size(req
->chain_outbuf
) - 4);
2220 show_msg((char *)(req
->chain_outbuf
));
2222 if (!srv_send_smb(req
->sconn
, (char *)req
->chain_outbuf
,
2223 true, req
->seqnum
+1,
2224 IS_CONN_ENCRYPTED(req
->conn
)||req
->encrypted
,
2226 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2228 TALLOC_FREE(req
->chain_outbuf
);
2232 /****************************************************************************
2233 Check if services need reloading.
2234 ****************************************************************************/
2236 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2239 if (last_smb_conf_reload_time
== 0) {
2240 last_smb_conf_reload_time
= t
;
2243 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2244 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
2245 last_smb_conf_reload_time
= t
;
2249 static bool fd_is_readable(int fd
)
2253 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2255 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2259 static void smbd_server_connection_write_handler(struct smbd_server_connection
*conn
)
2261 /* TODO: make write nonblocking */
2264 static void smbd_server_connection_read_handler(
2265 struct smbd_server_connection
*conn
, int fd
)
2267 uint8_t *inbuf
= NULL
;
2268 size_t inbuf_len
= 0;
2269 size_t unread_bytes
= 0;
2270 bool encrypted
= false;
2271 TALLOC_CTX
*mem_ctx
= talloc_tos();
2275 bool from_client
= (conn
->sock
== fd
);
2278 smbd_lock_socket(conn
);
2280 if (lp_async_smb_echo_handler() && !fd_is_readable(fd
)) {
2281 DEBUG(10,("the echo listener was faster\n"));
2282 smbd_unlock_socket(conn
);
2286 /* TODO: make this completely nonblocking */
2287 status
= receive_smb_talloc(mem_ctx
, conn
, fd
,
2288 (char **)(void *)&inbuf
,
2292 &inbuf_len
, &seqnum
,
2293 false /* trusted channel */);
2294 smbd_unlock_socket(conn
);
2296 /* TODO: make this completely nonblocking */
2297 status
= receive_smb_talloc(mem_ctx
, conn
, fd
,
2298 (char **)(void *)&inbuf
,
2302 &inbuf_len
, &seqnum
,
2303 true /* trusted channel */);
2306 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2309 if (NT_STATUS_IS_ERR(status
)) {
2310 exit_server_cleanly("failed to receive smb request");
2312 if (!NT_STATUS_IS_OK(status
)) {
2317 process_smb(conn
, inbuf
, inbuf_len
, unread_bytes
,
2318 seqnum
, encrypted
, NULL
);
2321 static void smbd_server_connection_handler(struct event_context
*ev
,
2322 struct fd_event
*fde
,
2326 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2327 struct smbd_server_connection
);
2329 if (flags
& EVENT_FD_WRITE
) {
2330 smbd_server_connection_write_handler(conn
);
2333 if (flags
& EVENT_FD_READ
) {
2334 smbd_server_connection_read_handler(conn
, conn
->sock
);
2339 static void smbd_server_echo_handler(struct event_context
*ev
,
2340 struct fd_event
*fde
,
2344 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2345 struct smbd_server_connection
);
2347 if (flags
& EVENT_FD_WRITE
) {
2348 smbd_server_connection_write_handler(conn
);
2351 if (flags
& EVENT_FD_READ
) {
2352 smbd_server_connection_read_handler(
2353 conn
, conn
->smb1
.echo_handler
.trusted_fd
);
2358 /****************************************************************************
2359 received when we should release a specific IP
2360 ****************************************************************************/
2361 static void release_ip(const char *ip
, void *priv
)
2363 const char *addr
= (const char *)priv
;
2364 const char *p
= addr
;
2366 if (strncmp("::ffff:", addr
, 7) == 0) {
2370 DEBUG(10, ("Got release IP message for %s, "
2371 "our address is %s\n", ip
, p
));
2373 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2374 /* we can't afford to do a clean exit - that involves
2375 database writes, which would potentially mean we
2376 are still running after the failover has finished -
2377 we have to get rid of this process ID straight
2379 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2381 /* note we must exit with non-zero status so the unclean handler gets
2382 called in the parent, so that the brl database is tickled */
2387 static void msg_release_ip(struct messaging_context
*msg_ctx
, void *private_data
,
2388 uint32_t msg_type
, struct server_id server_id
, DATA_BLOB
*data
)
2390 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2391 private_data
, struct smbd_server_connection
);
2393 release_ip((char *)data
->data
, sconn
->client_id
.addr
);
2396 #ifdef CLUSTER_SUPPORT
2397 static int client_get_tcp_info(int sock
, struct sockaddr_storage
*server
,
2398 struct sockaddr_storage
*client
)
2401 length
= sizeof(*server
);
2402 if (getsockname(sock
, (struct sockaddr
*)server
, &length
) != 0) {
2405 length
= sizeof(*client
);
2406 if (getpeername(sock
, (struct sockaddr
*)client
, &length
) != 0) {
2414 * Send keepalive packets to our client
2416 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2418 struct smbd_server_connection
*sconn
= smbd_server_conn
;
2421 if (sconn
->using_smb2
) {
2422 /* Don't do keepalives on an SMB2 connection. */
2426 smbd_lock_socket(smbd_server_conn
);
2427 ret
= send_keepalive(sconn
->sock
);
2428 smbd_unlock_socket(smbd_server_conn
);
2431 char addr
[INET6_ADDRSTRLEN
];
2433 * Try and give an error message saying what
2436 DEBUG(0, ("send_keepalive failed for client %s. "
2437 "Error %s - exiting\n",
2438 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
2446 * Do the recurring check if we're idle
2448 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2450 struct smbd_server_connection
*sconn
=
2451 (struct smbd_server_connection
*)private_data
;
2453 if ((conn_num_open(sconn
) == 0)
2454 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2455 DEBUG( 2, ( "Closing idle connection\n" ) );
2456 messaging_send(sconn
->msg_ctx
,
2457 messaging_server_id(sconn
->msg_ctx
),
2458 MSG_SHUTDOWN
, &data_blob_null
);
2466 * Do the recurring log file and smb.conf reload checks.
2469 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2471 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2472 private_data
, struct smbd_server_connection
);
2474 DEBUG(5, ("housekeeping\n"));
2476 change_to_root_user();
2478 /* update printer queue caches if necessary */
2479 update_monitored_printq_cache(sconn
->msg_ctx
);
2481 /* check if we need to reload services */
2482 check_reload(sconn
, time_mono(NULL
));
2484 /* Change machine password if neccessary. */
2485 attempt_machine_password_change();
2488 * Force a log file check.
2490 force_check_log_size();
2495 static int create_unlink_tmp(const char *dir
)
2500 fname
= talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir
);
2501 if (fname
== NULL
) {
2505 fd
= mkstemp(fname
);
2510 if (unlink(fname
) == -1) {
2511 int sys_errno
= errno
;
2521 struct smbd_echo_state
{
2522 struct tevent_context
*ev
;
2523 struct iovec
*pending
;
2524 struct smbd_server_connection
*sconn
;
2527 struct tevent_fd
*parent_fde
;
2529 struct tevent_fd
*read_fde
;
2530 struct tevent_req
*write_req
;
2533 static void smbd_echo_writer_done(struct tevent_req
*req
);
2535 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2539 if (state
->write_req
!= NULL
) {
2543 num_pending
= talloc_array_length(state
->pending
);
2544 if (num_pending
== 0) {
2548 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
2549 state
->parent_pipe
, false,
2550 state
->pending
, num_pending
);
2551 if (state
->write_req
== NULL
) {
2552 DEBUG(1, ("writev_send failed\n"));
2556 talloc_steal(state
->write_req
, state
->pending
);
2557 state
->pending
= NULL
;
2559 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
2563 static void smbd_echo_writer_done(struct tevent_req
*req
)
2565 struct smbd_echo_state
*state
= tevent_req_callback_data(
2566 req
, struct smbd_echo_state
);
2570 written
= writev_recv(req
, &err
);
2572 state
->write_req
= NULL
;
2573 if (written
== -1) {
2574 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
2577 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2578 smbd_echo_activate_writer(state
);
2581 static bool smbd_echo_reply(uint8_t *inbuf
, size_t inbuf_len
,
2584 struct smb_request req
;
2585 uint16_t num_replies
;
2590 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == SMBkeepalive
)) {
2591 DEBUG(10, ("Got netbios keepalive\n"));
2598 if (inbuf_len
< smb_size
) {
2599 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
2602 if (!valid_smb_header(inbuf
)) {
2603 DEBUG(10, ("Got invalid SMB header\n"));
2607 if (!init_smb_request(&req
, smbd_server_conn
, inbuf
, 0, false,
2613 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
2614 smb_messages
[req
.cmd
].name
2615 ? smb_messages
[req
.cmd
].name
: "unknown"));
2617 if (req
.cmd
!= SMBecho
) {
2624 num_replies
= SVAL(req
.vwv
+0, 0);
2625 if (num_replies
!= 1) {
2626 /* Not a Windows "Hey, you're still there?" request */
2630 if (!create_outbuf(talloc_tos(), &req
, (char *)req
.inbuf
, &outbuf
,
2632 DEBUG(10, ("create_outbuf failed\n"));
2635 req
.outbuf
= (uint8_t *)outbuf
;
2637 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
2639 if (req
.buflen
> 0) {
2640 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
2643 out_len
= smb_len(req
.outbuf
) + 4;
2645 ok
= srv_send_smb(req
.sconn
,
2649 TALLOC_FREE(outbuf
);
2657 static void smbd_echo_exit(struct tevent_context
*ev
,
2658 struct tevent_fd
*fde
, uint16_t flags
,
2661 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2665 static void smbd_echo_reader(struct tevent_context
*ev
,
2666 struct tevent_fd
*fde
, uint16_t flags
,
2669 struct smbd_echo_state
*state
= talloc_get_type_abort(
2670 private_data
, struct smbd_echo_state
);
2671 struct smbd_server_connection
*sconn
= state
->sconn
;
2672 size_t unread
, num_pending
;
2676 uint32_t seqnum
= 0;
2679 bool encrypted
= false;
2683 ok
= smbd_lock_socket_internal(sconn
);
2685 DEBUG(0, ("%s: failed to lock socket\n",
2690 if (!fd_is_readable(sconn
->sock
)) {
2691 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2692 (int)sys_getpid()));
2693 ok
= smbd_unlock_socket_internal(sconn
);
2695 DEBUG(1, ("%s: failed to unlock socket in\n",
2702 num_pending
= talloc_array_length(state
->pending
);
2703 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
2706 DEBUG(1, ("talloc_realloc failed\n"));
2709 state
->pending
= tmp
;
2711 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2713 status
= receive_smb_talloc(state
->pending
, sconn
, sconn
->sock
,
2714 (char **)(void *)&state
->pending
[num_pending
].iov_base
,
2720 false /* trusted_channel*/);
2721 if (!NT_STATUS_IS_OK(status
)) {
2722 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2723 (int)sys_getpid(), nt_errstr(status
)));
2726 state
->pending
[num_pending
].iov_len
= iov_len
;
2728 ok
= smbd_unlock_socket_internal(sconn
);
2730 DEBUG(1, ("%s: failed to unlock socket in\n",
2735 reply
= smbd_echo_reply((uint8_t *)state
->pending
[num_pending
].iov_base
,
2736 state
->pending
[num_pending
].iov_len
,
2739 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2740 /* no check, shrinking by some bytes does not fail */
2741 state
->pending
= talloc_realloc(state
, state
->pending
,
2747 if (state
->pending
[num_pending
].iov_len
>= smb_size
) {
2749 * place the seqnum in the packet so that the main process
2750 * can reply with signing
2752 SIVAL((uint8_t *)state
->pending
[num_pending
].iov_base
,
2753 smb_ss_field
, seqnum
);
2754 SIVAL((uint8_t *)state
->pending
[num_pending
].iov_base
,
2755 smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
2758 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2759 smbd_echo_activate_writer(state
);
2762 static void smbd_echo_loop(struct smbd_server_connection
*sconn
,
2765 struct smbd_echo_state
*state
;
2767 state
= talloc_zero(sconn
, struct smbd_echo_state
);
2768 if (state
== NULL
) {
2769 DEBUG(1, ("talloc failed\n"));
2772 state
->sconn
= sconn
;
2773 state
->parent_pipe
= parent_pipe
;
2774 state
->ev
= s3_tevent_context_init(state
);
2775 if (state
->ev
== NULL
) {
2776 DEBUG(1, ("tevent_context_init failed\n"));
2780 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
2781 TEVENT_FD_READ
, smbd_echo_exit
,
2783 if (state
->parent_fde
== NULL
) {
2784 DEBUG(1, ("tevent_add_fd failed\n"));
2788 state
->read_fde
= tevent_add_fd(state
->ev
, state
, sconn
->sock
,
2789 TEVENT_FD_READ
, smbd_echo_reader
,
2791 if (state
->read_fde
== NULL
) {
2792 DEBUG(1, ("tevent_add_fd failed\n"));
2798 if (tevent_loop_once(state
->ev
) == -1) {
2799 DEBUG(1, ("tevent_loop_once failed: %s\n",
2808 * Handle SMBecho requests in a forked child process
2810 bool fork_echo_handler(struct smbd_server_connection
*sconn
)
2812 int listener_pipe
[2];
2816 res
= pipe(listener_pipe
);
2818 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
2821 sconn
->smb1
.echo_handler
.socket_lock_fd
= create_unlink_tmp(lp_lockdir());
2822 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
2823 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno
)));
2831 close(listener_pipe
[0]);
2832 set_blocking(listener_pipe
[1], false);
2834 status
= reinit_after_fork(sconn
->msg_ctx
,
2835 smbd_event_context(),
2836 procid_self(), false);
2837 if (!NT_STATUS_IS_OK(status
)) {
2838 DEBUG(1, ("reinit_after_fork failed: %s\n",
2839 nt_errstr(status
)));
2842 smbd_echo_loop(sconn
, listener_pipe
[1]);
2845 close(listener_pipe
[1]);
2846 listener_pipe
[1] = -1;
2847 sconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
2849 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child
));
2852 * Without smb signing this is the same as the normal smbd
2853 * listener. This needs to change once signing comes in.
2855 sconn
->smb1
.echo_handler
.trusted_fde
= event_add_fd(smbd_event_context(),
2857 sconn
->smb1
.echo_handler
.trusted_fd
,
2859 smbd_server_echo_handler
,
2861 if (sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
2862 DEBUG(1, ("event_add_fd failed\n"));
2869 if (listener_pipe
[0] != -1) {
2870 close(listener_pipe
[0]);
2872 if (listener_pipe
[1] != -1) {
2873 close(listener_pipe
[1]);
2875 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2876 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
2877 close(sconn
->smb1
.echo_handler
.socket_lock_fd
);
2879 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2880 sconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
2886 static NTSTATUS
smbd_register_ips(struct smbd_server_connection
*sconn
,
2887 struct sockaddr_storage
*srv
,
2888 struct sockaddr_storage
*clnt
)
2890 struct ctdbd_connection
*cconn
;
2891 char tmp_addr
[INET6_ADDRSTRLEN
];
2894 cconn
= messaging_ctdbd_connection();
2895 if (cconn
== NULL
) {
2896 return NT_STATUS_NO_MEMORY
;
2899 client_socket_addr(sconn
->sock
, tmp_addr
, sizeof(tmp_addr
));
2900 addr
= talloc_strdup(cconn
, tmp_addr
);
2902 return NT_STATUS_NO_MEMORY
;
2904 return ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, addr
);
2909 /****************************************************************************
2910 Process commands from the client
2911 ****************************************************************************/
2913 void smbd_process(struct smbd_server_connection
*sconn
)
2915 TALLOC_CTX
*frame
= talloc_stackframe();
2916 struct sockaddr_storage ss
;
2917 struct sockaddr
*sa
= NULL
;
2918 socklen_t sa_socklen
;
2919 struct tsocket_address
*local_address
= NULL
;
2920 struct tsocket_address
*remote_address
= NULL
;
2921 const char *remaddr
= NULL
;
2924 if (lp_maxprotocol() == PROTOCOL_SMB2
) {
2926 * We're not making the decision here,
2927 * we're just allowing the client
2928 * to decide between SMB1 and SMB2
2929 * with the first negprot
2932 sconn
->using_smb2
= true;
2935 /* Ensure child is set to blocking mode */
2936 set_blocking(sconn
->sock
,True
);
2938 set_socket_options(sconn
->sock
, "SO_KEEPALIVE");
2939 set_socket_options(sconn
->sock
, lp_socket_options());
2941 sa
= (struct sockaddr
*)(void *)&ss
;
2942 sa_socklen
= sizeof(ss
);
2943 ret
= getpeername(sconn
->sock
, sa
, &sa_socklen
);
2945 int level
= (errno
== ENOTCONN
)?2:0;
2946 DEBUG(level
,("getpeername() failed - %s\n", strerror(errno
)));
2947 exit_server_cleanly("getpeername() failed.\n");
2949 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
2953 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2954 __location__
, strerror(errno
)));
2955 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2958 sa
= (struct sockaddr
*)(void *)&ss
;
2959 sa_socklen
= sizeof(ss
);
2960 ret
= getsockname(sconn
->sock
, sa
, &sa_socklen
);
2962 int level
= (errno
== ENOTCONN
)?2:0;
2963 DEBUG(level
,("getsockname() failed - %s\n", strerror(errno
)));
2964 exit_server_cleanly("getsockname() failed.\n");
2966 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
2970 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2971 __location__
, strerror(errno
)));
2972 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2975 sconn
->local_address
= local_address
;
2976 sconn
->remote_address
= remote_address
;
2978 if (tsocket_address_is_inet(remote_address
, "ip")) {
2979 remaddr
= tsocket_address_inet_addr_string(
2980 sconn
->remote_address
,
2982 if (remaddr
== NULL
) {
2986 remaddr
= "0.0.0.0";
2989 /* this is needed so that we get decent entries
2990 in smbstatus for port 445 connects */
2991 set_remote_machine_name(remaddr
, false);
2992 reload_services(sconn
->msg_ctx
, sconn
->sock
, true);
2995 * Before the first packet, check the global hosts allow/ hosts deny
2996 * parameters before doing any parsing of packets passed to us by the
2997 * client. This prevents attacks on our parsing code from hosts not in
2998 * the hosts allow list.
3001 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3002 sconn
->client_id
.name
,
3003 sconn
->client_id
.addr
)) {
3005 * send a negative session response "not listening on calling
3008 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
3009 DEBUG( 1, ("Connection denied from %s to %s\n",
3010 tsocket_address_string(remote_address
, talloc_tos()),
3011 tsocket_address_string(local_address
, talloc_tos())));
3012 (void)srv_send_smb(sconn
,(char *)buf
, false,
3014 exit_server_cleanly("connection denied");
3017 DEBUG(10, ("Connection allowed from %s to %s\n",
3018 tsocket_address_string(remote_address
, talloc_tos()),
3019 tsocket_address_string(local_address
, talloc_tos())));
3023 smb_perfcount_init();
3025 if (!init_account_policy()) {
3026 exit_server("Could not open account policy tdb.\n");
3029 if (*lp_rootdir()) {
3030 if (chroot(lp_rootdir()) != 0) {
3031 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3032 exit_server("Failed to chroot()");
3034 if (chdir("/") == -1) {
3035 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3036 exit_server("Failed to chroot()");
3038 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3041 if (!srv_init_signing(sconn
)) {
3042 exit_server("Failed to init smb_signing");
3046 if (!init_oplocks(sconn
->msg_ctx
))
3047 exit_server("Failed to init oplocks");
3049 /* register our message handlers */
3050 messaging_register(sconn
->msg_ctx
, NULL
,
3051 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3052 messaging_register(sconn
->msg_ctx
, sconn
,
3053 MSG_SMB_RELEASE_IP
, msg_release_ip
);
3054 messaging_register(sconn
->msg_ctx
, NULL
,
3055 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3058 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3059 * MSGs to all child processes
3061 messaging_deregister(sconn
->msg_ctx
,
3063 messaging_register(sconn
->msg_ctx
, NULL
,
3064 MSG_DEBUG
, debug_message
);
3066 if ((lp_keepalive() != 0)
3067 && !(event_add_idle(smbd_event_context(), NULL
,
3068 timeval_set(lp_keepalive(), 0),
3069 "keepalive", keepalive_fn
,
3071 DEBUG(0, ("Could not add keepalive event\n"));
3075 if (!(event_add_idle(smbd_event_context(), NULL
,
3076 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3077 "deadtime", deadtime_fn
, sconn
))) {
3078 DEBUG(0, ("Could not add deadtime event\n"));
3082 if (!(event_add_idle(smbd_event_context(), NULL
,
3083 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
3084 "housekeeping", housekeeping_fn
, sconn
))) {
3085 DEBUG(0, ("Could not add housekeeping event\n"));
3089 #ifdef CLUSTER_SUPPORT
3091 if (lp_clustering()) {
3093 * We need to tell ctdb about our client's TCP
3094 * connection, so that for failover ctdbd can send
3095 * tickle acks, triggering a reconnection by the
3099 struct sockaddr_storage srv
, clnt
;
3101 if (client_get_tcp_info(sconn
->sock
, &srv
, &clnt
) == 0) {
3103 status
= smbd_register_ips(sconn
, &srv
, &clnt
);
3104 if (!NT_STATUS_IS_OK(status
)) {
3105 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3106 nt_errstr(status
)));
3110 DEBUG(0,("Unable to get tcp info for "
3111 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3118 sconn
->nbt
.got_session
= false;
3120 sconn
->smb1
.negprot
.max_recv
= MIN(lp_maxxmit(),BUFFER_SIZE
);
3122 sconn
->smb1
.sessions
.done_sesssetup
= false;
3123 sconn
->smb1
.sessions
.max_send
= BUFFER_SIZE
;
3124 sconn
->smb1
.sessions
.last_session_tag
= UID_FIELD_INVALID
;
3125 /* users from session setup */
3126 sconn
->smb1
.sessions
.session_userlist
= NULL
;
3127 /* workgroup from session setup. */
3128 sconn
->smb1
.sessions
.session_workgroup
= NULL
;
3129 /* this holds info on user ids that are already validated for this VC */
3130 sconn
->smb1
.sessions
.validated_users
= NULL
;
3131 sconn
->smb1
.sessions
.next_vuid
= VUID_OFFSET
;
3132 sconn
->smb1
.sessions
.num_validated_vuids
= 0;
3135 if (!init_dptrs(sconn
)) {
3136 exit_server("init_dptrs() failed");
3139 sconn
->smb1
.fde
= event_add_fd(smbd_event_context(),
3143 smbd_server_connection_handler
,
3145 if (!sconn
->smb1
.fde
) {
3146 exit_server("failed to create smbd_server_connection fde");
3154 frame
= talloc_stackframe_pool(8192);
3158 status
= smbd_server_connection_loop_once(sconn
);
3159 if (!NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
) &&
3160 !NT_STATUS_IS_OK(status
)) {
3161 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3162 " exiting\n", nt_errstr(status
)));
3169 exit_server_cleanly(NULL
);
3172 bool req_is_in_chain(struct smb_request
*req
)
3174 if (req
->vwv
!= (uint16_t *)(req
->inbuf
+smb_vwv
)) {
3176 * We're right now handling a subsequent request, so we must
3182 if (!is_andx_req(req
->cmd
)) {
3188 * Okay, an illegal request, but definitely not chained :-)
3193 return (CVAL(req
->vwv
+0, 0) != 0xFF);