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(1, ("read_smb_length_return_keepalive failed for "
455 "client %s read error = %s.\n",
456 sconn
->client_id
.addr
, nt_errstr(status
)));
460 if (is_encrypted_packet((uint8_t *)*buffer
)) {
461 status
= srv_decrypt_buffer(*buffer
);
462 if (!NT_STATUS_IS_OK(status
)) {
463 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
464 "incoming packet! Error %s\n",
465 nt_errstr(status
) ));
471 /* Check the incoming SMB signature. */
472 if (!srv_check_sign_mac(sconn
, *buffer
, seqnum
, trusted_channel
)) {
473 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
474 "incoming packet!\n"));
475 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
483 * Initialize a struct smb_request from an inbuf
486 static bool init_smb_request(struct smb_request
*req
,
487 struct smbd_server_connection
*sconn
,
489 size_t unread_bytes
, bool encrypted
,
492 size_t req_size
= smb_len(inbuf
) + 4;
493 /* Ensure we have at least smb_size bytes. */
494 if (req_size
< smb_size
) {
495 DEBUG(0,("init_smb_request: invalid request size %u\n",
496 (unsigned int)req_size
));
499 req
->cmd
= CVAL(inbuf
, smb_com
);
500 req
->flags2
= SVAL(inbuf
, smb_flg2
);
501 req
->smbpid
= SVAL(inbuf
, smb_pid
);
502 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
503 req
->seqnum
= seqnum
;
504 req
->vuid
= SVAL(inbuf
, smb_uid
);
505 req
->tid
= SVAL(inbuf
, smb_tid
);
506 req
->wct
= CVAL(inbuf
, smb_wct
);
507 req
->vwv
= (uint16_t *)(inbuf
+smb_vwv
);
508 req
->buflen
= smb_buflen(inbuf
);
509 req
->buf
= (const uint8_t *)smb_buf(inbuf
);
510 req
->unread_bytes
= unread_bytes
;
511 req
->encrypted
= encrypted
;
513 req
->conn
= conn_find(sconn
,req
->tid
);
514 req
->chain_fsp
= NULL
;
515 req
->chain_outbuf
= NULL
;
518 smb_init_perfcount_data(&req
->pcd
);
520 /* Ensure we have at least wct words and 2 bytes of bcc. */
521 if (smb_size
+ req
->wct
*2 > req_size
) {
522 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
523 (unsigned int)req
->wct
,
524 (unsigned int)req_size
));
527 /* Ensure bcc is correct. */
528 if (((uint8
*)smb_buf(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
529 DEBUG(0,("init_smb_request: invalid bcc number %u "
530 "(wct = %u, size %u)\n",
531 (unsigned int)req
->buflen
,
532 (unsigned int)req
->wct
,
533 (unsigned int)req_size
));
541 static void process_smb(struct smbd_server_connection
*conn
,
542 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
543 uint32_t seqnum
, bool encrypted
,
544 struct smb_perfcount_data
*deferred_pcd
);
546 static void smbd_deferred_open_timer(struct event_context
*ev
,
547 struct timed_event
*te
,
548 struct timeval _tval
,
551 struct pending_message_list
*msg
= talloc_get_type(private_data
,
552 struct pending_message_list
);
553 TALLOC_CTX
*mem_ctx
= talloc_tos();
554 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
557 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
560 exit_server("smbd_deferred_open_timer: talloc failed\n");
564 /* We leave this message on the queue so the open code can
565 know this is a retry. */
566 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
567 (unsigned long long)mid
));
569 /* Mark the message as processed so this is not
570 * re-processed in error. */
571 msg
->processed
= true;
573 process_smb(smbd_server_conn
, inbuf
,
575 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
577 /* If it's still there and was processed, remove it. */
578 msg
= get_deferred_open_message_smb(mid
);
579 if (msg
&& msg
->processed
) {
580 remove_deferred_open_message_smb(mid
);
584 /****************************************************************************
585 Function to push a message onto the tail of a linked list of smb messages ready
587 ****************************************************************************/
589 static bool push_queued_message(struct smb_request
*req
,
590 struct timeval request_time
,
591 struct timeval end_time
,
592 char *private_data
, size_t private_len
)
594 int msg_len
= smb_len(req
->inbuf
) + 4;
595 struct pending_message_list
*msg
;
597 msg
= TALLOC_ZERO_P(NULL
, struct pending_message_list
);
600 DEBUG(0,("push_message: malloc fail (1)\n"));
604 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
605 if(msg
->buf
.data
== NULL
) {
606 DEBUG(0,("push_message: malloc fail (2)\n"));
611 msg
->request_time
= request_time
;
612 msg
->seqnum
= req
->seqnum
;
613 msg
->encrypted
= req
->encrypted
;
614 msg
->processed
= false;
615 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
618 msg
->private_data
= data_blob_talloc(msg
, private_data
,
620 if (msg
->private_data
.data
== NULL
) {
621 DEBUG(0,("push_message: malloc fail (3)\n"));
627 msg
->te
= event_add_timed(smbd_event_context(),
630 smbd_deferred_open_timer
,
633 DEBUG(0,("push_message: event_add_timed failed\n"));
638 DLIST_ADD_END(deferred_open_queue
, msg
, struct pending_message_list
*);
640 DEBUG(10,("push_message: pushed message length %u on "
641 "deferred_open_queue\n", (unsigned int)msg_len
));
646 /****************************************************************************
647 Function to delete a sharing violation open message by mid.
648 ****************************************************************************/
650 void remove_deferred_open_message_smb(uint64_t mid
)
652 struct pending_message_list
*pml
;
654 if (smbd_server_conn
->using_smb2
) {
655 remove_deferred_open_message_smb2(smbd_server_conn
, mid
);
659 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
660 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
661 DEBUG(10,("remove_deferred_open_message_smb: "
662 "deleting mid %llu len %u\n",
663 (unsigned long long)mid
,
664 (unsigned int)pml
->buf
.length
));
665 DLIST_REMOVE(deferred_open_queue
, pml
);
672 /****************************************************************************
673 Move a sharing violation open retry message to the front of the list and
674 schedule it for immediate processing.
675 ****************************************************************************/
677 void schedule_deferred_open_message_smb(uint64_t mid
)
679 struct pending_message_list
*pml
;
682 if (smbd_server_conn
->using_smb2
) {
683 schedule_deferred_open_message_smb2(smbd_server_conn
, mid
);
687 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
688 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
690 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
693 (unsigned long long)msg_mid
));
695 if (mid
== msg_mid
) {
696 struct timed_event
*te
;
698 if (pml
->processed
) {
699 /* A processed message should not be
701 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
702 "message mid %llu was already processed\n",
703 (unsigned long long)msg_mid
));
707 DEBUG(10,("schedule_deferred_open_message_smb: "
708 "scheduling mid %llu\n",
709 (unsigned long long)mid
));
711 te
= event_add_timed(smbd_event_context(),
714 smbd_deferred_open_timer
,
717 DEBUG(10,("schedule_deferred_open_message_smb: "
718 "event_add_timed() failed, "
719 "skipping mid %llu\n",
720 (unsigned long long)msg_mid
));
723 TALLOC_FREE(pml
->te
);
725 DLIST_PROMOTE(deferred_open_queue
, pml
);
730 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
731 "find message mid %llu\n",
732 (unsigned long long)mid
));
735 /****************************************************************************
736 Return true if this mid is on the deferred queue and was not yet processed.
737 ****************************************************************************/
739 bool open_was_deferred(uint64_t mid
)
741 struct pending_message_list
*pml
;
743 if (smbd_server_conn
->using_smb2
) {
744 return open_was_deferred_smb2(smbd_server_conn
, mid
);
747 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
748 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
755 /****************************************************************************
756 Return the message queued by this mid.
757 ****************************************************************************/
759 static struct pending_message_list
*get_deferred_open_message_smb(uint64_t mid
)
761 struct pending_message_list
*pml
;
763 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
764 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
771 /****************************************************************************
772 Get the state data queued by this mid.
773 ****************************************************************************/
775 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
776 struct timeval
*p_request_time
,
779 struct pending_message_list
*pml
;
781 if (smbd_server_conn
->using_smb2
) {
782 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
787 pml
= get_deferred_open_message_smb(smbreq
->mid
);
791 if (p_request_time
) {
792 *p_request_time
= pml
->request_time
;
795 *pp_state
= (void *)pml
->private_data
.data
;
800 /****************************************************************************
801 Function to push a deferred open smb message onto a linked list of local smb
802 messages ready for processing.
803 ****************************************************************************/
805 bool push_deferred_open_message_smb(struct smb_request
*req
,
806 struct timeval request_time
,
807 struct timeval timeout
,
809 char *private_data
, size_t priv_len
)
811 struct timeval end_time
;
814 return push_deferred_open_message_smb2(req
->smb2req
,
822 if (req
->unread_bytes
) {
823 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
824 "unread_bytes = %u\n",
825 (unsigned int)req
->unread_bytes
));
826 smb_panic("push_deferred_open_message_smb: "
827 "logic error unread_bytes != 0" );
830 end_time
= timeval_sum(&request_time
, &timeout
);
832 DEBUG(10,("push_deferred_open_message_smb: pushing message "
833 "len %u mid %llu timeout time [%u.%06u]\n",
834 (unsigned int) smb_len(req
->inbuf
)+4,
835 (unsigned long long)req
->mid
,
836 (unsigned int)end_time
.tv_sec
,
837 (unsigned int)end_time
.tv_usec
));
839 return push_queued_message(req
, request_time
, end_time
,
840 private_data
, priv_len
);
844 struct timed_event
*te
;
845 struct timeval interval
;
847 bool (*handler
)(const struct timeval
*now
, void *private_data
);
851 static void smbd_idle_event_handler(struct event_context
*ctx
,
852 struct timed_event
*te
,
856 struct idle_event
*event
=
857 talloc_get_type_abort(private_data
, struct idle_event
);
859 TALLOC_FREE(event
->te
);
861 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
862 event
->name
, event
->te
));
864 if (!event
->handler(&now
, event
->private_data
)) {
865 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
866 event
->name
, event
->te
));
867 /* Don't repeat, delete ourselves */
872 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
873 event
->name
, event
->te
));
875 event
->te
= event_add_timed(ctx
, event
,
876 timeval_sum(&now
, &event
->interval
),
877 smbd_idle_event_handler
, event
);
879 /* We can't do much but fail here. */
880 SMB_ASSERT(event
->te
!= NULL
);
883 struct idle_event
*event_add_idle(struct event_context
*event_ctx
,
885 struct timeval interval
,
887 bool (*handler
)(const struct timeval
*now
,
891 struct idle_event
*result
;
892 struct timeval now
= timeval_current();
894 result
= TALLOC_P(mem_ctx
, struct idle_event
);
895 if (result
== NULL
) {
896 DEBUG(0, ("talloc failed\n"));
900 result
->interval
= interval
;
901 result
->handler
= handler
;
902 result
->private_data
= private_data
;
904 if (!(result
->name
= talloc_asprintf(result
, "idle_evt(%s)", name
))) {
905 DEBUG(0, ("talloc failed\n"));
910 result
->te
= event_add_timed(event_ctx
, result
,
911 timeval_sum(&now
, &interval
),
912 smbd_idle_event_handler
, result
);
913 if (result
->te
== NULL
) {
914 DEBUG(0, ("event_add_timed failed\n"));
919 DEBUG(10,("event_add_idle: %s %p\n", result
->name
, result
->te
));
923 static void smbd_sig_term_handler(struct tevent_context
*ev
,
924 struct tevent_signal
*se
,
930 exit_server_cleanly("termination signal");
933 void smbd_setup_sig_term_handler(void)
935 struct tevent_signal
*se
;
937 se
= tevent_add_signal(smbd_event_context(),
938 smbd_event_context(),
940 smbd_sig_term_handler
,
943 exit_server("failed to setup SIGTERM handler");
947 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
948 struct tevent_signal
*se
,
954 struct messaging_context
*msg_ctx
= talloc_get_type_abort(
955 private_data
, struct messaging_context
);
956 change_to_root_user();
957 DEBUG(1,("Reloading services after SIGHUP\n"));
958 reload_services(msg_ctx
, smbd_server_conn
->sock
, False
);
960 pcap_cache_reload(ev
, msg_ctx
, &reload_pcap_change_notify
);
964 void smbd_setup_sig_hup_handler(struct tevent_context
*ev
,
965 struct messaging_context
*msg_ctx
)
967 struct tevent_signal
*se
;
969 se
= tevent_add_signal(ev
, ev
, SIGHUP
, 0, smbd_sig_hup_handler
,
972 exit_server("failed to setup SIGHUP handler");
976 static NTSTATUS
smbd_server_connection_loop_once(struct smbd_server_connection
*conn
)
983 timeout
= SMBD_SELECT_TIMEOUT
* 1000;
986 * Are there any timed events waiting ? If so, ensure we don't
987 * select for longer than it would take to wait for them.
990 event_add_to_poll_args(smbd_event_context(), conn
,
991 &conn
->pfds
, &num_pfds
, &timeout
);
993 /* Process a signal and timed events now... */
994 if (run_events_poll(smbd_event_context(), 0, NULL
, 0)) {
995 return NT_STATUS_RETRY
;
1000 START_PROFILE(smbd_idle
);
1002 ret
= sys_poll(conn
->pfds
, num_pfds
, timeout
);
1005 END_PROFILE(smbd_idle
);
1010 if (errno
== EINTR
) {
1011 return NT_STATUS_RETRY
;
1013 return map_nt_error_from_unix(errno
);
1016 retry
= run_events_poll(smbd_event_context(), ret
, conn
->pfds
,
1019 return NT_STATUS_RETRY
;
1022 /* Did we timeout ? */
1024 return NT_STATUS_RETRY
;
1027 /* should not be reached */
1028 return NT_STATUS_INTERNAL_ERROR
;
1032 * Only allow 5 outstanding trans requests. We're allocating memory, so
1036 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
1039 for (; list
!= NULL
; list
= list
->next
) {
1041 if (list
->mid
== mid
) {
1042 return NT_STATUS_INVALID_PARAMETER
;
1048 return NT_STATUS_INSUFFICIENT_RESOURCES
;
1051 return NT_STATUS_OK
;
1055 These flags determine some of the permissions required to do an operation
1057 Note that I don't set NEED_WRITE on some write operations because they
1058 are used by some brain-dead clients when printing, and I don't want to
1059 force write permissions on print services.
1061 #define AS_USER (1<<0)
1062 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1063 #define TIME_INIT (1<<2)
1064 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1065 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1066 #define DO_CHDIR (1<<6)
1069 define a list of possible SMB messages and their corresponding
1070 functions. Any message that has a NULL function is unimplemented -
1071 please feel free to contribute implementations!
1073 static const struct smb_message_struct
{
1075 void (*fn
)(struct smb_request
*req
);
1077 } smb_messages
[256] = {
1079 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1080 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1081 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1082 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1083 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1084 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1085 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1086 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1087 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1088 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1089 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1090 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1091 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1092 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1093 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1094 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1095 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1096 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1097 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1098 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1099 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1100 /* 0x15 */ { NULL
, NULL
, 0 },
1101 /* 0x16 */ { NULL
, NULL
, 0 },
1102 /* 0x17 */ { NULL
, NULL
, 0 },
1103 /* 0x18 */ { NULL
, NULL
, 0 },
1104 /* 0x19 */ { NULL
, NULL
, 0 },
1105 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1106 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1107 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1108 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1109 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1110 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1111 /* 0x20 */ { "SMBwritec", NULL
,0},
1112 /* 0x21 */ { NULL
, NULL
, 0 },
1113 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1114 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1115 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1116 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1117 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1118 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1119 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1120 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1121 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1122 /* 0x2b */ { "SMBecho",reply_echo
,0},
1123 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1124 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1125 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1126 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1127 /* 0x30 */ { NULL
, NULL
, 0 },
1128 /* 0x31 */ { NULL
, NULL
, 0 },
1129 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1130 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1131 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1132 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1133 /* 0x36 */ { NULL
, NULL
, 0 },
1134 /* 0x37 */ { NULL
, NULL
, 0 },
1135 /* 0x38 */ { NULL
, NULL
, 0 },
1136 /* 0x39 */ { NULL
, NULL
, 0 },
1137 /* 0x3a */ { NULL
, NULL
, 0 },
1138 /* 0x3b */ { NULL
, NULL
, 0 },
1139 /* 0x3c */ { NULL
, NULL
, 0 },
1140 /* 0x3d */ { NULL
, NULL
, 0 },
1141 /* 0x3e */ { NULL
, NULL
, 0 },
1142 /* 0x3f */ { NULL
, NULL
, 0 },
1143 /* 0x40 */ { NULL
, NULL
, 0 },
1144 /* 0x41 */ { NULL
, NULL
, 0 },
1145 /* 0x42 */ { NULL
, NULL
, 0 },
1146 /* 0x43 */ { NULL
, NULL
, 0 },
1147 /* 0x44 */ { NULL
, NULL
, 0 },
1148 /* 0x45 */ { NULL
, NULL
, 0 },
1149 /* 0x46 */ { NULL
, NULL
, 0 },
1150 /* 0x47 */ { NULL
, NULL
, 0 },
1151 /* 0x48 */ { NULL
, NULL
, 0 },
1152 /* 0x49 */ { NULL
, NULL
, 0 },
1153 /* 0x4a */ { NULL
, NULL
, 0 },
1154 /* 0x4b */ { NULL
, NULL
, 0 },
1155 /* 0x4c */ { NULL
, NULL
, 0 },
1156 /* 0x4d */ { NULL
, NULL
, 0 },
1157 /* 0x4e */ { NULL
, NULL
, 0 },
1158 /* 0x4f */ { NULL
, NULL
, 0 },
1159 /* 0x50 */ { NULL
, NULL
, 0 },
1160 /* 0x51 */ { NULL
, NULL
, 0 },
1161 /* 0x52 */ { NULL
, NULL
, 0 },
1162 /* 0x53 */ { NULL
, NULL
, 0 },
1163 /* 0x54 */ { NULL
, NULL
, 0 },
1164 /* 0x55 */ { NULL
, NULL
, 0 },
1165 /* 0x56 */ { NULL
, NULL
, 0 },
1166 /* 0x57 */ { NULL
, NULL
, 0 },
1167 /* 0x58 */ { NULL
, NULL
, 0 },
1168 /* 0x59 */ { NULL
, NULL
, 0 },
1169 /* 0x5a */ { NULL
, NULL
, 0 },
1170 /* 0x5b */ { NULL
, NULL
, 0 },
1171 /* 0x5c */ { NULL
, NULL
, 0 },
1172 /* 0x5d */ { NULL
, NULL
, 0 },
1173 /* 0x5e */ { NULL
, NULL
, 0 },
1174 /* 0x5f */ { NULL
, NULL
, 0 },
1175 /* 0x60 */ { NULL
, NULL
, 0 },
1176 /* 0x61 */ { NULL
, NULL
, 0 },
1177 /* 0x62 */ { NULL
, NULL
, 0 },
1178 /* 0x63 */ { NULL
, NULL
, 0 },
1179 /* 0x64 */ { NULL
, NULL
, 0 },
1180 /* 0x65 */ { NULL
, NULL
, 0 },
1181 /* 0x66 */ { NULL
, NULL
, 0 },
1182 /* 0x67 */ { NULL
, NULL
, 0 },
1183 /* 0x68 */ { NULL
, NULL
, 0 },
1184 /* 0x69 */ { NULL
, NULL
, 0 },
1185 /* 0x6a */ { NULL
, NULL
, 0 },
1186 /* 0x6b */ { NULL
, NULL
, 0 },
1187 /* 0x6c */ { NULL
, NULL
, 0 },
1188 /* 0x6d */ { NULL
, NULL
, 0 },
1189 /* 0x6e */ { NULL
, NULL
, 0 },
1190 /* 0x6f */ { NULL
, NULL
, 0 },
1191 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1192 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1193 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1194 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1195 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1196 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1197 /* 0x76 */ { NULL
, NULL
, 0 },
1198 /* 0x77 */ { NULL
, NULL
, 0 },
1199 /* 0x78 */ { NULL
, NULL
, 0 },
1200 /* 0x79 */ { NULL
, NULL
, 0 },
1201 /* 0x7a */ { NULL
, NULL
, 0 },
1202 /* 0x7b */ { NULL
, NULL
, 0 },
1203 /* 0x7c */ { NULL
, NULL
, 0 },
1204 /* 0x7d */ { NULL
, NULL
, 0 },
1205 /* 0x7e */ { NULL
, NULL
, 0 },
1206 /* 0x7f */ { NULL
, NULL
, 0 },
1207 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1208 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1209 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1210 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1211 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1212 /* 0x85 */ { NULL
, NULL
, 0 },
1213 /* 0x86 */ { NULL
, NULL
, 0 },
1214 /* 0x87 */ { NULL
, NULL
, 0 },
1215 /* 0x88 */ { NULL
, NULL
, 0 },
1216 /* 0x89 */ { NULL
, NULL
, 0 },
1217 /* 0x8a */ { NULL
, NULL
, 0 },
1218 /* 0x8b */ { NULL
, NULL
, 0 },
1219 /* 0x8c */ { NULL
, NULL
, 0 },
1220 /* 0x8d */ { NULL
, NULL
, 0 },
1221 /* 0x8e */ { NULL
, NULL
, 0 },
1222 /* 0x8f */ { NULL
, NULL
, 0 },
1223 /* 0x90 */ { NULL
, NULL
, 0 },
1224 /* 0x91 */ { NULL
, NULL
, 0 },
1225 /* 0x92 */ { NULL
, NULL
, 0 },
1226 /* 0x93 */ { NULL
, NULL
, 0 },
1227 /* 0x94 */ { NULL
, NULL
, 0 },
1228 /* 0x95 */ { NULL
, NULL
, 0 },
1229 /* 0x96 */ { NULL
, NULL
, 0 },
1230 /* 0x97 */ { NULL
, NULL
, 0 },
1231 /* 0x98 */ { NULL
, NULL
, 0 },
1232 /* 0x99 */ { NULL
, NULL
, 0 },
1233 /* 0x9a */ { NULL
, NULL
, 0 },
1234 /* 0x9b */ { NULL
, NULL
, 0 },
1235 /* 0x9c */ { NULL
, NULL
, 0 },
1236 /* 0x9d */ { NULL
, NULL
, 0 },
1237 /* 0x9e */ { NULL
, NULL
, 0 },
1238 /* 0x9f */ { NULL
, NULL
, 0 },
1239 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1240 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1241 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1242 /* 0xa3 */ { NULL
, NULL
, 0 },
1243 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1244 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1245 /* 0xa6 */ { NULL
, NULL
, 0 },
1246 /* 0xa7 */ { NULL
, NULL
, 0 },
1247 /* 0xa8 */ { NULL
, NULL
, 0 },
1248 /* 0xa9 */ { NULL
, NULL
, 0 },
1249 /* 0xaa */ { NULL
, NULL
, 0 },
1250 /* 0xab */ { NULL
, NULL
, 0 },
1251 /* 0xac */ { NULL
, NULL
, 0 },
1252 /* 0xad */ { NULL
, NULL
, 0 },
1253 /* 0xae */ { NULL
, NULL
, 0 },
1254 /* 0xaf */ { NULL
, NULL
, 0 },
1255 /* 0xb0 */ { NULL
, NULL
, 0 },
1256 /* 0xb1 */ { NULL
, NULL
, 0 },
1257 /* 0xb2 */ { NULL
, NULL
, 0 },
1258 /* 0xb3 */ { NULL
, NULL
, 0 },
1259 /* 0xb4 */ { NULL
, NULL
, 0 },
1260 /* 0xb5 */ { NULL
, NULL
, 0 },
1261 /* 0xb6 */ { NULL
, NULL
, 0 },
1262 /* 0xb7 */ { NULL
, NULL
, 0 },
1263 /* 0xb8 */ { NULL
, NULL
, 0 },
1264 /* 0xb9 */ { NULL
, NULL
, 0 },
1265 /* 0xba */ { NULL
, NULL
, 0 },
1266 /* 0xbb */ { NULL
, NULL
, 0 },
1267 /* 0xbc */ { NULL
, NULL
, 0 },
1268 /* 0xbd */ { NULL
, NULL
, 0 },
1269 /* 0xbe */ { NULL
, NULL
, 0 },
1270 /* 0xbf */ { NULL
, NULL
, 0 },
1271 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1272 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1273 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1274 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1275 /* 0xc4 */ { NULL
, NULL
, 0 },
1276 /* 0xc5 */ { NULL
, NULL
, 0 },
1277 /* 0xc6 */ { NULL
, NULL
, 0 },
1278 /* 0xc7 */ { NULL
, NULL
, 0 },
1279 /* 0xc8 */ { NULL
, NULL
, 0 },
1280 /* 0xc9 */ { NULL
, NULL
, 0 },
1281 /* 0xca */ { NULL
, NULL
, 0 },
1282 /* 0xcb */ { NULL
, NULL
, 0 },
1283 /* 0xcc */ { NULL
, NULL
, 0 },
1284 /* 0xcd */ { NULL
, NULL
, 0 },
1285 /* 0xce */ { NULL
, NULL
, 0 },
1286 /* 0xcf */ { NULL
, NULL
, 0 },
1287 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1288 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1289 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1290 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1291 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1292 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1293 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1294 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1295 /* 0xd8 */ { NULL
, NULL
, 0 },
1296 /* 0xd9 */ { NULL
, NULL
, 0 },
1297 /* 0xda */ { NULL
, NULL
, 0 },
1298 /* 0xdb */ { NULL
, NULL
, 0 },
1299 /* 0xdc */ { NULL
, NULL
, 0 },
1300 /* 0xdd */ { NULL
, NULL
, 0 },
1301 /* 0xde */ { NULL
, NULL
, 0 },
1302 /* 0xdf */ { NULL
, NULL
, 0 },
1303 /* 0xe0 */ { NULL
, NULL
, 0 },
1304 /* 0xe1 */ { NULL
, NULL
, 0 },
1305 /* 0xe2 */ { NULL
, NULL
, 0 },
1306 /* 0xe3 */ { NULL
, NULL
, 0 },
1307 /* 0xe4 */ { NULL
, NULL
, 0 },
1308 /* 0xe5 */ { NULL
, NULL
, 0 },
1309 /* 0xe6 */ { NULL
, NULL
, 0 },
1310 /* 0xe7 */ { NULL
, NULL
, 0 },
1311 /* 0xe8 */ { NULL
, NULL
, 0 },
1312 /* 0xe9 */ { NULL
, NULL
, 0 },
1313 /* 0xea */ { NULL
, NULL
, 0 },
1314 /* 0xeb */ { NULL
, NULL
, 0 },
1315 /* 0xec */ { NULL
, NULL
, 0 },
1316 /* 0xed */ { NULL
, NULL
, 0 },
1317 /* 0xee */ { NULL
, NULL
, 0 },
1318 /* 0xef */ { NULL
, NULL
, 0 },
1319 /* 0xf0 */ { NULL
, NULL
, 0 },
1320 /* 0xf1 */ { NULL
, NULL
, 0 },
1321 /* 0xf2 */ { NULL
, NULL
, 0 },
1322 /* 0xf3 */ { NULL
, NULL
, 0 },
1323 /* 0xf4 */ { NULL
, NULL
, 0 },
1324 /* 0xf5 */ { NULL
, NULL
, 0 },
1325 /* 0xf6 */ { NULL
, NULL
, 0 },
1326 /* 0xf7 */ { NULL
, NULL
, 0 },
1327 /* 0xf8 */ { NULL
, NULL
, 0 },
1328 /* 0xf9 */ { NULL
, NULL
, 0 },
1329 /* 0xfa */ { NULL
, NULL
, 0 },
1330 /* 0xfb */ { NULL
, NULL
, 0 },
1331 /* 0xfc */ { NULL
, NULL
, 0 },
1332 /* 0xfd */ { NULL
, NULL
, 0 },
1333 /* 0xfe */ { NULL
, NULL
, 0 },
1334 /* 0xff */ { NULL
, NULL
, 0 }
1338 /*******************************************************************
1339 allocate and initialize a reply packet
1340 ********************************************************************/
1342 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1343 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1347 * Protect against integer wrap
1349 if ((num_bytes
> 0xffffff)
1350 || ((num_bytes
+ smb_size
+ num_words
*2) > 0xffffff)) {
1352 if (asprintf(&msg
, "num_bytes too large: %u",
1353 (unsigned)num_bytes
) == -1) {
1354 msg
= CONST_DISCARD(char *, "num_bytes too large");
1359 *outbuf
= TALLOC_ARRAY(mem_ctx
, char,
1360 smb_size
+ num_words
*2 + num_bytes
);
1361 if (*outbuf
== NULL
) {
1365 construct_reply_common(req
, inbuf
, *outbuf
);
1366 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1368 * Zero out the word area, the caller has to take care of the bcc area
1371 if (num_words
!= 0) {
1372 memset(*outbuf
+ smb_vwv0
, 0, num_words
*2);
1378 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1381 if (!create_outbuf(req
, req
, (char *)req
->inbuf
, &outbuf
, num_words
,
1383 smb_panic("could not allocate output buffer\n");
1385 req
->outbuf
= (uint8_t *)outbuf
;
1389 /*******************************************************************
1390 Dump a packet to a file.
1391 ********************************************************************/
1393 static void smb_dump(const char *name
, int type
, const char *data
, ssize_t len
)
1397 if (DEBUGLEVEL
< 50) {
1401 if (len
< 4) len
= smb_len(data
)+4;
1402 for (i
=1;i
<100;i
++) {
1403 if (asprintf(&fname
, "/tmp/%s.%d.%s", name
, i
,
1404 type
? "req" : "resp") == -1) {
1407 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1408 if (fd
!= -1 || errno
!= EEXIST
) break;
1411 ssize_t ret
= write(fd
, data
, len
);
1413 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1415 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1420 /****************************************************************************
1421 Prepare everything for calling the actual request function, and potentially
1422 call the request function via the "new" interface.
1424 Return False if the "legacy" function needs to be called, everything is
1427 Return True if we're done.
1429 I know this API sucks, but it is the one with the least code change I could
1431 ****************************************************************************/
1433 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
, int size
)
1437 connection_struct
*conn
= NULL
;
1438 struct smbd_server_connection
*sconn
= req
->sconn
;
1442 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1443 * so subtract 4 from it. */
1444 if (!valid_smb_header(req
->inbuf
)
1445 || (size
< (smb_size
- 4))) {
1446 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1447 smb_len(req
->inbuf
)));
1448 exit_server_cleanly("Non-SMB packet");
1451 if (smb_messages
[type
].fn
== NULL
) {
1452 DEBUG(0,("Unknown message type %d!\n",type
));
1453 smb_dump("Unknown", 1, (char *)req
->inbuf
, size
);
1454 reply_unknown_new(req
, type
);
1458 flags
= smb_messages
[type
].flags
;
1460 /* In share mode security we must ignore the vuid. */
1461 session_tag
= (lp_security() == SEC_SHARE
)
1462 ? UID_FIELD_INVALID
: req
->vuid
;
1465 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1466 (int)sys_getpid(), (unsigned long)conn
));
1468 smb_dump(smb_fn_name(type
), 1, (char *)req
->inbuf
, size
);
1470 /* Ensure this value is replaced in the incoming packet. */
1471 SSVAL(req
->inbuf
,smb_uid
,session_tag
);
1474 * Ensure the correct username is in current_user_info. This is a
1475 * really ugly bugfix for problems with multiple session_setup_and_X's
1476 * being done and allowing %U and %G substitutions to work correctly.
1477 * There is a reason this code is done here, don't move it unless you
1478 * know what you're doing... :-).
1482 if (session_tag
!= sconn
->smb1
.sessions
.last_session_tag
) {
1483 user_struct
*vuser
= NULL
;
1485 sconn
->smb1
.sessions
.last_session_tag
= session_tag
;
1486 if(session_tag
!= UID_FIELD_INVALID
) {
1487 vuser
= get_valid_user_struct(sconn
, session_tag
);
1489 set_current_user_info(
1490 vuser
->session_info
->sanitized_username
,
1491 vuser
->session_info
->unix_name
,
1492 vuser
->session_info
->info3
->base
.domain
.string
);
1497 /* Does this call need to be run as the connected user? */
1498 if (flags
& AS_USER
) {
1500 /* Does this call need a valid tree connection? */
1503 * Amazingly, the error code depends on the command
1506 if (type
== SMBntcreateX
) {
1507 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1509 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1514 if (!change_to_user(conn
,session_tag
)) {
1515 DEBUG(0, ("Error: Could not change to user. Removing "
1516 "deferred open, mid=%llu.\n",
1517 (unsigned long long)req
->mid
));
1518 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1522 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1524 /* Does it need write permission? */
1525 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1526 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1530 /* IPC services are limited */
1531 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1532 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1536 /* This call needs to be run as root */
1537 change_to_root_user();
1540 /* load service specific parameters */
1542 if (req
->encrypted
) {
1543 conn
->encrypted_tid
= true;
1544 /* encrypted required from now on. */
1545 conn
->encrypt_level
= Required
;
1546 } else if (ENCRYPTION_REQUIRED(conn
)) {
1547 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1548 exit_server_cleanly("encryption required "
1554 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1555 (flags
& (AS_USER
|DO_CHDIR
)
1557 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1560 conn
->num_smb_operations
++;
1563 /* does this protocol need to be run as guest? */
1564 if ((flags
& AS_GUEST
)
1565 && (!change_to_guest() ||
1566 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1567 sconn
->client_id
.name
,
1568 sconn
->client_id
.addr
))) {
1569 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1573 smb_messages
[type
].fn(req
);
1577 /****************************************************************************
1578 Construct a reply to the incoming packet.
1579 ****************************************************************************/
1581 static void construct_reply(struct smbd_server_connection
*sconn
,
1582 char *inbuf
, int size
, size_t unread_bytes
,
1583 uint32_t seqnum
, bool encrypted
,
1584 struct smb_perfcount_data
*deferred_pcd
)
1586 connection_struct
*conn
;
1587 struct smb_request
*req
;
1589 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1590 smb_panic("could not allocate smb_request");
1593 if (!init_smb_request(req
, sconn
, (uint8
*)inbuf
, unread_bytes
,
1594 encrypted
, seqnum
)) {
1595 exit_server_cleanly("Invalid SMB request");
1598 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1600 /* we popped this message off the queue - keep original perf data */
1602 req
->pcd
= *deferred_pcd
;
1604 SMB_PERFCOUNT_START(&req
->pcd
);
1605 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1606 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1609 conn
= switch_message(req
->cmd
, req
, size
);
1611 if (req
->unread_bytes
) {
1612 /* writeX failed. drain socket. */
1613 if (drain_socket(req
->sconn
->sock
, req
->unread_bytes
) !=
1614 req
->unread_bytes
) {
1615 smb_panic("failed to drain pending bytes");
1617 req
->unread_bytes
= 0;
1625 if (req
->outbuf
== NULL
) {
1629 if (CVAL(req
->outbuf
,0) == 0) {
1630 show_msg((char *)req
->outbuf
);
1633 if (!srv_send_smb(req
->sconn
,
1634 (char *)req
->outbuf
,
1635 true, req
->seqnum
+1,
1636 IS_CONN_ENCRYPTED(conn
)||req
->encrypted
,
1638 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1646 /****************************************************************************
1647 Process an smb from the client
1648 ****************************************************************************/
1649 static void process_smb(struct smbd_server_connection
*sconn
,
1650 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1651 uint32_t seqnum
, bool encrypted
,
1652 struct smb_perfcount_data
*deferred_pcd
)
1654 int msg_type
= CVAL(inbuf
,0);
1656 DO_PROFILE_INC(smb_count
);
1658 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1660 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1661 sconn
->trans_num
, (int)nread
, (unsigned int)unread_bytes
));
1663 if (msg_type
!= 0) {
1665 * NetBIOS session request, keepalive, etc.
1667 reply_special(sconn
, (char *)inbuf
, nread
);
1671 if (sconn
->using_smb2
) {
1672 /* At this point we're not really using smb2,
1673 * we make the decision here.. */
1674 if (smbd_is_smb2_header(inbuf
, nread
)) {
1675 smbd_smb2_first_negprot(sconn
, inbuf
, nread
);
1677 } else if (nread
>= smb_size
&& valid_smb_header(inbuf
)
1678 && CVAL(inbuf
, smb_com
) != 0x72) {
1679 /* This is a non-negprot SMB1 packet.
1680 Disable SMB2 from now on. */
1681 sconn
->using_smb2
= false;
1685 show_msg((char *)inbuf
);
1687 construct_reply(sconn
, (char *)inbuf
, nread
, unread_bytes
, seqnum
,
1688 encrypted
, deferred_pcd
);
1692 sconn
->num_requests
++;
1694 /* The timeout_processing function isn't run nearly
1695 often enough to implement 'max log size' without
1696 overrunning the size of the file by many megabytes.
1697 This is especially true if we are running at debug
1698 level 10. Checking every 50 SMBs is a nice
1699 tradeoff of performance vs log file size overrun. */
1701 if ((sconn
->num_requests
% 50) == 0 &&
1702 need_to_check_log_size()) {
1703 change_to_root_user();
1708 /****************************************************************************
1709 Return a string containing the function name of a SMB command.
1710 ****************************************************************************/
1712 const char *smb_fn_name(int type
)
1714 const char *unknown_name
= "SMBunknown";
1716 if (smb_messages
[type
].name
== NULL
)
1717 return(unknown_name
);
1719 return(smb_messages
[type
].name
);
1722 /****************************************************************************
1723 Helper functions for contruct_reply.
1724 ****************************************************************************/
1726 void add_to_common_flags2(uint32 v
)
1731 void remove_from_common_flags2(uint32 v
)
1733 common_flags2
&= ~v
;
1736 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1739 srv_set_message(outbuf
,0,0,false);
1741 SCVAL(outbuf
, smb_com
, req
->cmd
);
1742 SIVAL(outbuf
,smb_rcls
,0);
1743 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1744 SSVAL(outbuf
,smb_flg2
,
1745 (SVAL(inbuf
,smb_flg2
) & FLAGS2_UNICODE_STRINGS
) |
1747 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1749 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
1750 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
1751 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
1752 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
1755 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
1757 construct_reply_common(req
, (char *)req
->inbuf
, outbuf
);
1761 * How many bytes have we already accumulated up to the current wct field
1765 size_t req_wct_ofs(struct smb_request
*req
)
1769 if (req
->chain_outbuf
== NULL
) {
1772 buf_size
= talloc_get_size(req
->chain_outbuf
);
1773 if ((buf_size
% 4) != 0) {
1774 buf_size
+= (4 - (buf_size
% 4));
1776 return buf_size
- 4;
1780 * Hack around reply_nterror & friends not being aware of chained requests,
1781 * generating illegal (i.e. wct==0) chain replies.
1784 static void fixup_chain_error_packet(struct smb_request
*req
)
1786 uint8_t *outbuf
= req
->outbuf
;
1788 reply_outbuf(req
, 2, 0);
1789 memcpy(req
->outbuf
, outbuf
, smb_wct
);
1790 TALLOC_FREE(outbuf
);
1791 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
1795 * @brief Find the smb_cmd offset of the last command pushed
1796 * @param[in] buf The buffer we're building up
1797 * @retval Where can we put our next andx cmd?
1799 * While chaining requests, the "next" request we're looking at needs to put
1800 * its SMB_Command before the data the previous request already built up added
1801 * to the chain. Find the offset to the place where we have to put our cmd.
1804 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
1809 cmd
= CVAL(buf
, smb_com
);
1811 SMB_ASSERT(is_andx_req(cmd
));
1815 while (CVAL(buf
, ofs
) != 0xff) {
1817 if (!is_andx_req(CVAL(buf
, ofs
))) {
1822 * ofs is from start of smb header, so add the 4 length
1823 * bytes. The next cmd is right after the wct field.
1825 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
1827 SMB_ASSERT(ofs
+4 < talloc_get_size(buf
));
1835 * @brief Do the smb chaining at a buffer level
1836 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1837 * @param[in] smb_command The command that we want to issue
1838 * @param[in] wct How many words?
1839 * @param[in] vwv The words, already in network order
1840 * @param[in] bytes_alignment How shall we align "bytes"?
1841 * @param[in] num_bytes How many bytes?
1842 * @param[in] bytes The data the request ships
1844 * smb_splice_chain() adds the vwv and bytes to the request already present in
1848 static bool smb_splice_chain(uint8_t **poutbuf
, uint8_t smb_command
,
1849 uint8_t wct
, const uint16_t *vwv
,
1850 size_t bytes_alignment
,
1851 uint32_t num_bytes
, const uint8_t *bytes
)
1854 size_t old_size
, new_size
;
1856 size_t chain_padding
= 0;
1857 size_t bytes_padding
= 0;
1860 old_size
= talloc_get_size(*poutbuf
);
1863 * old_size == smb_wct means we're pushing the first request in for
1867 first_request
= (old_size
== smb_wct
);
1869 if (!first_request
&& ((old_size
% 4) != 0)) {
1871 * Align the wct field of subsequent requests to a 4-byte
1874 chain_padding
= 4 - (old_size
% 4);
1878 * After the old request comes the new wct field (1 byte), the vwv's
1879 * and the num_bytes field. After at we might need to align the bytes
1880 * given to us to "bytes_alignment", increasing the num_bytes value.
1883 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
1885 if ((bytes_alignment
!= 0) && ((new_size
% bytes_alignment
) != 0)) {
1886 bytes_padding
= bytes_alignment
- (new_size
% bytes_alignment
);
1889 new_size
+= bytes_padding
+ num_bytes
;
1891 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
1892 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1893 (unsigned)new_size
));
1897 outbuf
= TALLOC_REALLOC_ARRAY(NULL
, *poutbuf
, uint8_t, new_size
);
1898 if (outbuf
== NULL
) {
1899 DEBUG(0, ("talloc failed\n"));
1904 if (first_request
) {
1905 SCVAL(outbuf
, smb_com
, smb_command
);
1907 size_t andx_cmd_ofs
;
1909 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
1910 DEBUG(1, ("invalid command chain\n"));
1911 *poutbuf
= TALLOC_REALLOC_ARRAY(
1912 NULL
, *poutbuf
, uint8_t, old_size
);
1916 if (chain_padding
!= 0) {
1917 memset(outbuf
+ old_size
, 0, chain_padding
);
1918 old_size
+= chain_padding
;
1921 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
1922 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
1928 * Push the chained request:
1933 SCVAL(outbuf
, ofs
, wct
);
1940 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
1941 ofs
+= sizeof(uint16_t) * wct
;
1947 SSVAL(outbuf
, ofs
, num_bytes
+ bytes_padding
);
1948 ofs
+= sizeof(uint16_t);
1954 if (bytes_padding
!= 0) {
1955 memset(outbuf
+ ofs
, 0, bytes_padding
);
1956 ofs
+= bytes_padding
;
1963 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
1968 /****************************************************************************
1969 Construct a chained reply and add it to the already made reply
1970 ****************************************************************************/
1972 void chain_reply(struct smb_request
*req
)
1974 size_t smblen
= smb_len(req
->inbuf
);
1975 size_t already_used
, length_needed
;
1977 uint32_t chain_offset
; /* uint32_t to avoid overflow */
1984 if (IVAL(req
->outbuf
, smb_rcls
) != 0) {
1985 fixup_chain_error_packet(req
);
1989 * Any of the AndX requests and replies have at least a wct of
1990 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1991 * beginning of the SMB header to the next wct field.
1993 * None of the AndX requests put anything valuable in vwv[0] and [1],
1994 * so we can overwrite it here to form the chain.
1997 if ((req
->wct
< 2) || (CVAL(req
->outbuf
, smb_wct
) < 2)) {
1998 if (req
->chain_outbuf
== NULL
) {
1999 req
->chain_outbuf
= TALLOC_REALLOC_ARRAY(
2000 req
, req
->outbuf
, uint8_t,
2001 smb_len(req
->outbuf
) + 4);
2002 if (req
->chain_outbuf
== NULL
) {
2003 smb_panic("talloc failed");
2011 * Here we assume that this is the end of the chain. For that we need
2012 * to set "next command" to 0xff and the offset to 0. If we later find
2013 * more commands in the chain, this will be overwritten again.
2016 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
2017 SCVAL(req
->outbuf
, smb_vwv0
+1, 0);
2018 SSVAL(req
->outbuf
, smb_vwv1
, 0);
2020 if (req
->chain_outbuf
== NULL
) {
2022 * In req->chain_outbuf we collect all the replies. Start the
2023 * chain by copying in the first reply.
2025 * We do the realloc because later on we depend on
2026 * talloc_get_size to determine the length of
2027 * chain_outbuf. The reply_xxx routines might have
2028 * over-allocated (reply_pipe_read_and_X used to be such an
2031 req
->chain_outbuf
= TALLOC_REALLOC_ARRAY(
2032 req
, req
->outbuf
, uint8_t, smb_len(req
->outbuf
) + 4);
2033 if (req
->chain_outbuf
== NULL
) {
2034 smb_panic("talloc failed");
2039 * Update smb headers where subsequent chained commands
2040 * may have updated them.
2042 SSVAL(req
->chain_outbuf
, smb_tid
, SVAL(req
->outbuf
, smb_tid
));
2043 SSVAL(req
->chain_outbuf
, smb_uid
, SVAL(req
->outbuf
, smb_uid
));
2045 if (!smb_splice_chain(&req
->chain_outbuf
,
2046 CVAL(req
->outbuf
, smb_com
),
2047 CVAL(req
->outbuf
, smb_wct
),
2048 (uint16_t *)(req
->outbuf
+ smb_vwv
),
2049 0, smb_buflen(req
->outbuf
),
2050 (uint8_t *)smb_buf(req
->outbuf
))) {
2053 TALLOC_FREE(req
->outbuf
);
2057 * We use the old request's vwv field to grab the next chained command
2058 * and offset into the chained fields.
2061 chain_cmd
= CVAL(req
->vwv
+0, 0);
2062 chain_offset
= SVAL(req
->vwv
+1, 0);
2064 if (chain_cmd
== 0xff) {
2066 * End of chain, no more requests from the client. So ship the
2069 smb_setlen((char *)(req
->chain_outbuf
),
2070 talloc_get_size(req
->chain_outbuf
) - 4);
2072 if (!srv_send_smb(req
->sconn
, (char *)req
->chain_outbuf
,
2073 true, req
->seqnum
+1,
2074 IS_CONN_ENCRYPTED(req
->conn
)
2077 exit_server_cleanly("chain_reply: srv_send_smb "
2080 TALLOC_FREE(req
->chain_outbuf
);
2085 /* add a new perfcounter for this element of chain */
2086 SMB_PERFCOUNT_ADD(&req
->pcd
);
2087 SMB_PERFCOUNT_SET_OP(&req
->pcd
, chain_cmd
);
2088 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, smblen
);
2091 * Check if the client tries to fool us. The chain offset
2092 * needs to point beyond the current request in the chain, it
2093 * needs to strictly grow. Otherwise we might be tricked into
2094 * an endless loop always processing the same request over and
2095 * over again. We used to assume that vwv and the byte buffer
2096 * array in a chain are always attached, but OS/2 the
2097 * Write&X/Read&X chain puts the Read&X vwv array right behind
2098 * the Write&X vwv chain. The Write&X bcc array is put behind
2099 * the Read&X vwv array. So now we check whether the chain
2100 * offset points strictly behind the previous vwv
2101 * array. req->buf points right after the vwv array of the
2102 * previous request. See
2103 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2107 already_used
= PTR_DIFF(req
->buf
, smb_base(req
->inbuf
));
2108 if (chain_offset
<= already_used
) {
2113 * Next check: Make sure the chain offset does not point beyond the
2114 * overall smb request length.
2117 length_needed
= chain_offset
+1; /* wct */
2118 if (length_needed
> smblen
) {
2123 * Now comes the pointer magic. Goal here is to set up req->vwv and
2124 * req->buf correctly again to be able to call the subsequent
2125 * switch_message(). The chain offset (the former vwv[1]) points at
2126 * the new wct field.
2129 wct
= CVAL(smb_base(req
->inbuf
), chain_offset
);
2132 * Next consistency check: Make the new vwv array fits in the overall
2136 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2137 if (length_needed
> smblen
) {
2140 vwv
= (uint16_t *)(smb_base(req
->inbuf
) + chain_offset
+ 1);
2143 * Now grab the new byte buffer....
2146 buflen
= SVAL(vwv
+wct
, 0);
2149 * .. and check that it fits.
2152 length_needed
+= buflen
;
2153 if (length_needed
> smblen
) {
2156 buf
= (uint8_t *)(vwv
+wct
+1);
2158 req
->cmd
= chain_cmd
;
2161 req
->buflen
= buflen
;
2164 switch_message(chain_cmd
, req
, smblen
);
2166 if (req
->outbuf
== NULL
) {
2168 * This happens if the chained command has suspended itself or
2169 * if it has called srv_send_smb() itself.
2175 * We end up here if the chained command was not itself chained or
2176 * suspended, but for example a close() command. We now need to splice
2177 * the chained commands' outbuf into the already built up chain_outbuf
2178 * and ship the result.
2184 * We end up here if there's any error in the chain syntax. Report a
2185 * DOS error, just like Windows does.
2187 reply_force_doserror(req
, ERRSRV
, ERRerror
);
2188 fixup_chain_error_packet(req
);
2192 * This scary statement intends to set the
2193 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2194 * to the value req->outbuf carries
2196 SSVAL(req
->chain_outbuf
, smb_flg2
,
2197 (SVAL(req
->chain_outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
2198 | (SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
2201 * Transfer the error codes from the subrequest to the main one
2203 SSVAL(req
->chain_outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
2204 SSVAL(req
->chain_outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
2206 if (!smb_splice_chain(&req
->chain_outbuf
,
2207 CVAL(req
->outbuf
, smb_com
),
2208 CVAL(req
->outbuf
, smb_wct
),
2209 (uint16_t *)(req
->outbuf
+ smb_vwv
),
2210 0, smb_buflen(req
->outbuf
),
2211 (uint8_t *)smb_buf(req
->outbuf
))) {
2212 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2214 TALLOC_FREE(req
->outbuf
);
2216 smb_setlen((char *)(req
->chain_outbuf
),
2217 talloc_get_size(req
->chain_outbuf
) - 4);
2219 show_msg((char *)(req
->chain_outbuf
));
2221 if (!srv_send_smb(req
->sconn
, (char *)req
->chain_outbuf
,
2222 true, req
->seqnum
+1,
2223 IS_CONN_ENCRYPTED(req
->conn
)||req
->encrypted
,
2225 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2227 TALLOC_FREE(req
->chain_outbuf
);
2231 /****************************************************************************
2232 Check if services need reloading.
2233 ****************************************************************************/
2235 static void check_reload(struct smbd_server_connection
*sconn
, time_t t
)
2238 if (last_smb_conf_reload_time
== 0) {
2239 last_smb_conf_reload_time
= t
;
2242 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2243 reload_services(sconn
->msg_ctx
, sconn
->sock
, True
);
2244 last_smb_conf_reload_time
= t
;
2248 static bool fd_is_readable(int fd
)
2252 ret
= poll_one_fd(fd
, POLLIN
|POLLHUP
, 0, &revents
);
2254 return ((ret
> 0) && ((revents
& (POLLIN
|POLLHUP
|POLLERR
)) != 0));
2258 static void smbd_server_connection_write_handler(struct smbd_server_connection
*conn
)
2260 /* TODO: make write nonblocking */
2263 static void smbd_server_connection_read_handler(
2264 struct smbd_server_connection
*conn
, int fd
)
2266 uint8_t *inbuf
= NULL
;
2267 size_t inbuf_len
= 0;
2268 size_t unread_bytes
= 0;
2269 bool encrypted
= false;
2270 TALLOC_CTX
*mem_ctx
= talloc_tos();
2274 bool from_client
= (conn
->sock
== fd
);
2277 smbd_lock_socket(conn
);
2279 if (lp_async_smb_echo_handler() && !fd_is_readable(fd
)) {
2280 DEBUG(10,("the echo listener was faster\n"));
2281 smbd_unlock_socket(conn
);
2285 /* TODO: make this completely nonblocking */
2286 status
= receive_smb_talloc(mem_ctx
, conn
, fd
,
2287 (char **)(void *)&inbuf
,
2291 &inbuf_len
, &seqnum
,
2292 false /* trusted channel */);
2293 smbd_unlock_socket(conn
);
2295 /* TODO: make this completely nonblocking */
2296 status
= receive_smb_talloc(mem_ctx
, conn
, fd
,
2297 (char **)(void *)&inbuf
,
2301 &inbuf_len
, &seqnum
,
2302 true /* trusted channel */);
2305 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2308 if (NT_STATUS_IS_ERR(status
)) {
2309 exit_server_cleanly("failed to receive smb request");
2311 if (!NT_STATUS_IS_OK(status
)) {
2316 process_smb(conn
, inbuf
, inbuf_len
, unread_bytes
,
2317 seqnum
, encrypted
, NULL
);
2320 static void smbd_server_connection_handler(struct event_context
*ev
,
2321 struct fd_event
*fde
,
2325 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2326 struct smbd_server_connection
);
2328 if (flags
& EVENT_FD_WRITE
) {
2329 smbd_server_connection_write_handler(conn
);
2332 if (flags
& EVENT_FD_READ
) {
2333 smbd_server_connection_read_handler(conn
, conn
->sock
);
2338 static void smbd_server_echo_handler(struct event_context
*ev
,
2339 struct fd_event
*fde
,
2343 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2344 struct smbd_server_connection
);
2346 if (flags
& EVENT_FD_WRITE
) {
2347 smbd_server_connection_write_handler(conn
);
2350 if (flags
& EVENT_FD_READ
) {
2351 smbd_server_connection_read_handler(
2352 conn
, conn
->smb1
.echo_handler
.trusted_fd
);
2357 /****************************************************************************
2358 received when we should release a specific IP
2359 ****************************************************************************/
2360 static void release_ip(const char *ip
, void *priv
)
2362 const char *addr
= (const char *)priv
;
2363 const char *p
= addr
;
2365 if (strncmp("::ffff:", addr
, 7) == 0) {
2369 DEBUG(10, ("Got release IP message for %s, "
2370 "our address is %s\n", ip
, p
));
2372 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2373 /* we can't afford to do a clean exit - that involves
2374 database writes, which would potentially mean we
2375 are still running after the failover has finished -
2376 we have to get rid of this process ID straight
2378 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2380 /* note we must exit with non-zero status so the unclean handler gets
2381 called in the parent, so that the brl database is tickled */
2386 static void msg_release_ip(struct messaging_context
*msg_ctx
, void *private_data
,
2387 uint32_t msg_type
, struct server_id server_id
, DATA_BLOB
*data
)
2389 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2390 private_data
, struct smbd_server_connection
);
2392 release_ip((char *)data
->data
, sconn
->client_id
.addr
);
2395 #ifdef CLUSTER_SUPPORT
2396 static int client_get_tcp_info(int sock
, struct sockaddr_storage
*server
,
2397 struct sockaddr_storage
*client
)
2400 length
= sizeof(*server
);
2401 if (getsockname(sock
, (struct sockaddr
*)server
, &length
) != 0) {
2404 length
= sizeof(*client
);
2405 if (getpeername(sock
, (struct sockaddr
*)client
, &length
) != 0) {
2413 * Send keepalive packets to our client
2415 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2417 struct smbd_server_connection
*sconn
= smbd_server_conn
;
2420 if (sconn
->using_smb2
) {
2421 /* Don't do keepalives on an SMB2 connection. */
2425 smbd_lock_socket(smbd_server_conn
);
2426 ret
= send_keepalive(sconn
->sock
);
2427 smbd_unlock_socket(smbd_server_conn
);
2430 char addr
[INET6_ADDRSTRLEN
];
2432 * Try and give an error message saying what
2435 DEBUG(0, ("send_keepalive failed for client %s. "
2436 "Error %s - exiting\n",
2437 get_peer_addr(sconn
->sock
, addr
, sizeof(addr
)),
2445 * Do the recurring check if we're idle
2447 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2449 struct smbd_server_connection
*sconn
=
2450 (struct smbd_server_connection
*)private_data
;
2452 if ((conn_num_open(sconn
) == 0)
2453 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2454 DEBUG( 2, ( "Closing idle connection\n" ) );
2455 messaging_send(sconn
->msg_ctx
,
2456 messaging_server_id(sconn
->msg_ctx
),
2457 MSG_SHUTDOWN
, &data_blob_null
);
2465 * Do the recurring log file and smb.conf reload checks.
2468 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2470 struct smbd_server_connection
*sconn
= talloc_get_type_abort(
2471 private_data
, struct smbd_server_connection
);
2473 DEBUG(5, ("housekeeping\n"));
2475 change_to_root_user();
2477 /* update printer queue caches if necessary */
2478 update_monitored_printq_cache(sconn
->msg_ctx
);
2480 /* check if we need to reload services */
2481 check_reload(sconn
, time_mono(NULL
));
2483 /* Change machine password if neccessary. */
2484 attempt_machine_password_change();
2487 * Force a log file check.
2489 force_check_log_size();
2494 static int create_unlink_tmp(const char *dir
)
2499 fname
= talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir
);
2500 if (fname
== NULL
) {
2504 fd
= mkstemp(fname
);
2509 if (unlink(fname
) == -1) {
2510 int sys_errno
= errno
;
2520 struct smbd_echo_state
{
2521 struct tevent_context
*ev
;
2522 struct iovec
*pending
;
2523 struct smbd_server_connection
*sconn
;
2526 struct tevent_fd
*parent_fde
;
2528 struct tevent_fd
*read_fde
;
2529 struct tevent_req
*write_req
;
2532 static void smbd_echo_writer_done(struct tevent_req
*req
);
2534 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2538 if (state
->write_req
!= NULL
) {
2542 num_pending
= talloc_array_length(state
->pending
);
2543 if (num_pending
== 0) {
2547 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
2548 state
->parent_pipe
, false,
2549 state
->pending
, num_pending
);
2550 if (state
->write_req
== NULL
) {
2551 DEBUG(1, ("writev_send failed\n"));
2555 talloc_steal(state
->write_req
, state
->pending
);
2556 state
->pending
= NULL
;
2558 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
2562 static void smbd_echo_writer_done(struct tevent_req
*req
)
2564 struct smbd_echo_state
*state
= tevent_req_callback_data(
2565 req
, struct smbd_echo_state
);
2569 written
= writev_recv(req
, &err
);
2571 state
->write_req
= NULL
;
2572 if (written
== -1) {
2573 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
2576 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2577 smbd_echo_activate_writer(state
);
2580 static bool smbd_echo_reply(uint8_t *inbuf
, size_t inbuf_len
,
2583 struct smb_request req
;
2584 uint16_t num_replies
;
2589 if ((inbuf_len
== 4) && (CVAL(inbuf
, 0) == SMBkeepalive
)) {
2590 DEBUG(10, ("Got netbios keepalive\n"));
2597 if (inbuf_len
< smb_size
) {
2598 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
2601 if (!valid_smb_header(inbuf
)) {
2602 DEBUG(10, ("Got invalid SMB header\n"));
2606 if (!init_smb_request(&req
, smbd_server_conn
, inbuf
, 0, false,
2612 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
2613 smb_messages
[req
.cmd
].name
2614 ? smb_messages
[req
.cmd
].name
: "unknown"));
2616 if (req
.cmd
!= SMBecho
) {
2623 num_replies
= SVAL(req
.vwv
+0, 0);
2624 if (num_replies
!= 1) {
2625 /* Not a Windows "Hey, you're still there?" request */
2629 if (!create_outbuf(talloc_tos(), &req
, (char *)req
.inbuf
, &outbuf
,
2631 DEBUG(10, ("create_outbuf failed\n"));
2634 req
.outbuf
= (uint8_t *)outbuf
;
2636 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
2638 if (req
.buflen
> 0) {
2639 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
2642 out_len
= smb_len(req
.outbuf
) + 4;
2644 ok
= srv_send_smb(req
.sconn
,
2648 TALLOC_FREE(outbuf
);
2656 static void smbd_echo_exit(struct tevent_context
*ev
,
2657 struct tevent_fd
*fde
, uint16_t flags
,
2660 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2664 static void smbd_echo_reader(struct tevent_context
*ev
,
2665 struct tevent_fd
*fde
, uint16_t flags
,
2668 struct smbd_echo_state
*state
= talloc_get_type_abort(
2669 private_data
, struct smbd_echo_state
);
2670 struct smbd_server_connection
*sconn
= state
->sconn
;
2671 size_t unread
, num_pending
;
2675 uint32_t seqnum
= 0;
2678 bool encrypted
= false;
2682 ok
= smbd_lock_socket_internal(sconn
);
2684 DEBUG(0, ("%s: failed to lock socket\n",
2689 if (!fd_is_readable(sconn
->sock
)) {
2690 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2691 (int)sys_getpid()));
2692 ok
= smbd_unlock_socket_internal(sconn
);
2694 DEBUG(1, ("%s: failed to unlock socket in\n",
2701 num_pending
= talloc_array_length(state
->pending
);
2702 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
2705 DEBUG(1, ("talloc_realloc failed\n"));
2708 state
->pending
= tmp
;
2710 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2712 status
= receive_smb_talloc(state
->pending
, sconn
, sconn
->sock
,
2713 (char **)(void *)&state
->pending
[num_pending
].iov_base
,
2719 false /* trusted_channel*/);
2720 if (!NT_STATUS_IS_OK(status
)) {
2721 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2722 (int)sys_getpid(), nt_errstr(status
)));
2725 state
->pending
[num_pending
].iov_len
= iov_len
;
2727 ok
= smbd_unlock_socket_internal(sconn
);
2729 DEBUG(1, ("%s: failed to unlock socket in\n",
2734 reply
= smbd_echo_reply((uint8_t *)state
->pending
[num_pending
].iov_base
,
2735 state
->pending
[num_pending
].iov_len
,
2738 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2739 /* no check, shrinking by some bytes does not fail */
2740 state
->pending
= talloc_realloc(state
, state
->pending
,
2746 if (state
->pending
[num_pending
].iov_len
>= smb_size
) {
2748 * place the seqnum in the packet so that the main process
2749 * can reply with signing
2751 SIVAL((uint8_t *)state
->pending
[num_pending
].iov_base
,
2752 smb_ss_field
, seqnum
);
2753 SIVAL((uint8_t *)state
->pending
[num_pending
].iov_base
,
2754 smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
2757 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2758 smbd_echo_activate_writer(state
);
2761 static void smbd_echo_loop(struct smbd_server_connection
*sconn
,
2764 struct smbd_echo_state
*state
;
2766 state
= talloc_zero(sconn
, struct smbd_echo_state
);
2767 if (state
== NULL
) {
2768 DEBUG(1, ("talloc failed\n"));
2771 state
->sconn
= sconn
;
2772 state
->parent_pipe
= parent_pipe
;
2773 state
->ev
= s3_tevent_context_init(state
);
2774 if (state
->ev
== NULL
) {
2775 DEBUG(1, ("tevent_context_init failed\n"));
2779 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
2780 TEVENT_FD_READ
, smbd_echo_exit
,
2782 if (state
->parent_fde
== NULL
) {
2783 DEBUG(1, ("tevent_add_fd failed\n"));
2787 state
->read_fde
= tevent_add_fd(state
->ev
, state
, sconn
->sock
,
2788 TEVENT_FD_READ
, smbd_echo_reader
,
2790 if (state
->read_fde
== NULL
) {
2791 DEBUG(1, ("tevent_add_fd failed\n"));
2797 if (tevent_loop_once(state
->ev
) == -1) {
2798 DEBUG(1, ("tevent_loop_once failed: %s\n",
2807 * Handle SMBecho requests in a forked child process
2809 static bool fork_echo_handler(struct smbd_server_connection
*sconn
)
2811 int listener_pipe
[2];
2815 res
= pipe(listener_pipe
);
2817 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
2820 sconn
->smb1
.echo_handler
.socket_lock_fd
= create_unlink_tmp(lp_lockdir());
2821 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
2822 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno
)));
2830 close(listener_pipe
[0]);
2831 set_blocking(listener_pipe
[1], false);
2833 status
= reinit_after_fork(sconn
->msg_ctx
,
2834 smbd_event_context(),
2835 procid_self(), false);
2836 if (!NT_STATUS_IS_OK(status
)) {
2837 DEBUG(1, ("reinit_after_fork failed: %s\n",
2838 nt_errstr(status
)));
2841 smbd_echo_loop(sconn
, listener_pipe
[1]);
2844 close(listener_pipe
[1]);
2845 listener_pipe
[1] = -1;
2846 sconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
2848 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child
));
2851 * Without smb signing this is the same as the normal smbd
2852 * listener. This needs to change once signing comes in.
2854 sconn
->smb1
.echo_handler
.trusted_fde
= event_add_fd(smbd_event_context(),
2856 sconn
->smb1
.echo_handler
.trusted_fd
,
2858 smbd_server_echo_handler
,
2860 if (sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
2861 DEBUG(1, ("event_add_fd failed\n"));
2868 if (listener_pipe
[0] != -1) {
2869 close(listener_pipe
[0]);
2871 if (listener_pipe
[1] != -1) {
2872 close(listener_pipe
[1]);
2874 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2875 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
2876 close(sconn
->smb1
.echo_handler
.socket_lock_fd
);
2878 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2879 sconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
2885 static NTSTATUS
smbd_register_ips(struct smbd_server_connection
*sconn
,
2886 struct sockaddr_storage
*srv
,
2887 struct sockaddr_storage
*clnt
)
2889 struct ctdbd_connection
*cconn
;
2890 char tmp_addr
[INET6_ADDRSTRLEN
];
2893 cconn
= messaging_ctdbd_connection();
2894 if (cconn
== NULL
) {
2895 return NT_STATUS_NO_MEMORY
;
2898 client_socket_addr(sconn
->sock
, tmp_addr
, sizeof(tmp_addr
));
2899 addr
= talloc_strdup(cconn
, tmp_addr
);
2901 return NT_STATUS_NO_MEMORY
;
2903 return ctdbd_register_ips(cconn
, srv
, clnt
, release_ip
, addr
);
2908 /****************************************************************************
2909 Process commands from the client
2910 ****************************************************************************/
2912 void smbd_process(struct smbd_server_connection
*sconn
)
2914 TALLOC_CTX
*frame
= talloc_stackframe();
2915 struct sockaddr_storage ss
;
2916 struct sockaddr
*sa
= NULL
;
2917 socklen_t sa_socklen
;
2918 struct tsocket_address
*local_address
= NULL
;
2919 struct tsocket_address
*remote_address
= NULL
;
2920 const char *remaddr
= NULL
;
2923 if (lp_maxprotocol() == PROTOCOL_SMB2
&&
2924 !lp_async_smb_echo_handler()) {
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");
3045 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn
)) {
3046 exit_server("Failed to fork echo handler");
3050 if (!init_oplocks(sconn
->msg_ctx
))
3051 exit_server("Failed to init oplocks");
3053 /* register our message handlers */
3054 messaging_register(sconn
->msg_ctx
, NULL
,
3055 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3056 messaging_register(sconn
->msg_ctx
, sconn
,
3057 MSG_SMB_RELEASE_IP
, msg_release_ip
);
3058 messaging_register(sconn
->msg_ctx
, NULL
,
3059 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3062 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3063 * MSGs to all child processes
3065 messaging_deregister(sconn
->msg_ctx
,
3067 messaging_register(sconn
->msg_ctx
, NULL
,
3068 MSG_DEBUG
, debug_message
);
3070 if ((lp_keepalive() != 0)
3071 && !(event_add_idle(smbd_event_context(), NULL
,
3072 timeval_set(lp_keepalive(), 0),
3073 "keepalive", keepalive_fn
,
3075 DEBUG(0, ("Could not add keepalive event\n"));
3079 if (!(event_add_idle(smbd_event_context(), NULL
,
3080 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3081 "deadtime", deadtime_fn
, sconn
))) {
3082 DEBUG(0, ("Could not add deadtime event\n"));
3086 if (!(event_add_idle(smbd_event_context(), NULL
,
3087 timeval_set(SMBD_HOUSEKEEPING_INTERVAL
, 0),
3088 "housekeeping", housekeeping_fn
, sconn
))) {
3089 DEBUG(0, ("Could not add housekeeping event\n"));
3093 #ifdef CLUSTER_SUPPORT
3095 if (lp_clustering()) {
3097 * We need to tell ctdb about our client's TCP
3098 * connection, so that for failover ctdbd can send
3099 * tickle acks, triggering a reconnection by the
3103 struct sockaddr_storage srv
, clnt
;
3105 if (client_get_tcp_info(sconn
->sock
, &srv
, &clnt
) == 0) {
3107 status
= smbd_register_ips(sconn
, &srv
, &clnt
);
3108 if (!NT_STATUS_IS_OK(status
)) {
3109 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3110 nt_errstr(status
)));
3114 DEBUG(0,("Unable to get tcp info for "
3115 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3122 sconn
->nbt
.got_session
= false;
3124 sconn
->smb1
.negprot
.max_recv
= MIN(lp_maxxmit(),BUFFER_SIZE
);
3126 sconn
->smb1
.sessions
.done_sesssetup
= false;
3127 sconn
->smb1
.sessions
.max_send
= BUFFER_SIZE
;
3128 sconn
->smb1
.sessions
.last_session_tag
= UID_FIELD_INVALID
;
3129 /* users from session setup */
3130 sconn
->smb1
.sessions
.session_userlist
= NULL
;
3131 /* workgroup from session setup. */
3132 sconn
->smb1
.sessions
.session_workgroup
= NULL
;
3133 /* this holds info on user ids that are already validated for this VC */
3134 sconn
->smb1
.sessions
.validated_users
= NULL
;
3135 sconn
->smb1
.sessions
.next_vuid
= VUID_OFFSET
;
3136 sconn
->smb1
.sessions
.num_validated_vuids
= 0;
3139 if (!init_dptrs(sconn
)) {
3140 exit_server("init_dptrs() failed");
3143 sconn
->smb1
.fde
= event_add_fd(smbd_event_context(),
3147 smbd_server_connection_handler
,
3149 if (!sconn
->smb1
.fde
) {
3150 exit_server("failed to create smbd_server_connection fde");
3158 frame
= talloc_stackframe_pool(8192);
3162 status
= smbd_server_connection_loop_once(sconn
);
3163 if (!NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
) &&
3164 !NT_STATUS_IS_OK(status
)) {
3165 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3166 " exiting\n", nt_errstr(status
)));
3173 exit_server_cleanly(NULL
);
3176 bool req_is_in_chain(struct smb_request
*req
)
3178 if (req
->vwv
!= (uint16_t *)(req
->inbuf
+smb_vwv
)) {
3180 * We're right now handling a subsequent request, so we must
3186 if (!is_andx_req(req
->cmd
)) {
3192 * Okay, an illegal request, but definitely not chained :-)
3197 return (CVAL(req
->vwv
+0, 0) != 0xFF);