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 "smbd/globals.h"
23 #include "librpc/gen_ndr/netlogon.h"
24 #include "librpc/gen_ndr/messaging.h"
26 extern bool global_machine_password_needs_changing
;
28 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
30 static struct pending_message_list
*get_deferred_open_message_smb(uint64_t mid
);
32 static bool smbd_lock_socket_internal(struct smbd_server_connection
*sconn
)
36 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
40 sconn
->smb1
.echo_handler
.ref_count
++;
42 if (sconn
->smb1
.echo_handler
.ref_count
> 1) {
46 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
48 ok
= fcntl_lock(sconn
->smb1
.echo_handler
.socket_lock_fd
,
49 SMB_F_SETLKW
, 0, 0, F_WRLCK
);
54 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
59 void smbd_lock_socket(struct smbd_server_connection
*sconn
)
61 if (!smbd_lock_socket_internal(sconn
)) {
62 exit_server_cleanly("failed to lock socket");
66 static bool smbd_unlock_socket_internal(struct smbd_server_connection
*sconn
)
70 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
74 sconn
->smb1
.echo_handler
.ref_count
--;
76 if (sconn
->smb1
.echo_handler
.ref_count
> 0) {
80 ok
= fcntl_lock(sconn
->smb1
.echo_handler
.socket_lock_fd
,
81 SMB_F_SETLKW
, 0, 0, F_UNLCK
);
86 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
91 void smbd_unlock_socket(struct smbd_server_connection
*sconn
)
93 if (!smbd_unlock_socket_internal(sconn
)) {
94 exit_server_cleanly("failed to unlock socket");
98 /* Accessor function for smb_read_error for smbd functions. */
100 /****************************************************************************
102 ****************************************************************************/
104 bool srv_send_smb(int fd
, char *buffer
,
105 bool do_signing
, uint32_t seqnum
,
107 struct smb_perfcount_data
*pcd
)
112 char *buf_out
= buffer
;
114 smbd_lock_socket(smbd_server_conn
);
117 /* Sign the outgoing packet if required. */
118 srv_calculate_sign_mac(smbd_server_conn
, buf_out
, seqnum
);
122 NTSTATUS status
= srv_encrypt_buffer(buffer
, &buf_out
);
123 if (!NT_STATUS_IS_OK(status
)) {
124 DEBUG(0, ("send_smb: SMB encryption failed "
125 "on outgoing packet! Error %s\n",
126 nt_errstr(status
) ));
131 len
= smb_len(buf_out
) + 4;
133 ret
= write_data(fd
,buf_out
+nwritten
,len
- nwritten
);
135 DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
136 (int)sys_getpid(), (int)len
,(int)ret
, strerror(errno
) ));
137 srv_free_enc_buffer(buf_out
);
141 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd
, len
);
142 srv_free_enc_buffer(buf_out
);
144 SMB_PERFCOUNT_END(pcd
);
146 smbd_unlock_socket(smbd_server_conn
);
150 /*******************************************************************
151 Setup the word count and byte count for a smb message.
152 ********************************************************************/
154 int srv_set_message(char *buf
,
159 if (zero
&& (num_words
|| num_bytes
)) {
160 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
162 SCVAL(buf
,smb_wct
,num_words
);
163 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
164 smb_setlen(buf
,(smb_size
+ num_words
*2 + num_bytes
- 4));
165 return (smb_size
+ num_words
*2 + num_bytes
);
168 static bool valid_smb_header(const uint8_t *inbuf
)
170 if (is_encrypted_packet(inbuf
)) {
174 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
175 * but it just looks weird to call strncmp for this one.
177 return (IVAL(smb_base(inbuf
), 0) == 0x424D53FF);
180 /* Socket functions for smbd packet processing. */
182 static bool valid_packet_size(size_t len
)
185 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
186 * of header. Don't print the error if this fits.... JRA.
189 if (len
> (BUFFER_SIZE
+ LARGE_WRITEX_HDR_SIZE
)) {
190 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
191 (unsigned long)len
));
197 static NTSTATUS
read_packet_remainder(int fd
, char *buffer
,
198 unsigned int timeout
, ssize_t len
)
204 return read_fd_with_timeout(fd
, buffer
, len
, len
, timeout
, NULL
);
207 /****************************************************************************
208 Attempt a zerocopy writeX read. We know here that len > smb_size-4
209 ****************************************************************************/
212 * Unfortunately, earlier versions of smbclient/libsmbclient
213 * don't send this "standard" writeX header. I've fixed this
214 * for 3.2 but we'll use the old method with earlier versions.
215 * Windows and CIFSFS at least use this standard size. Not
219 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
220 (2*14) + /* word count (including bcc) */ \
223 static NTSTATUS
receive_smb_raw_talloc_partial_read(TALLOC_CTX
*mem_ctx
,
224 const char lenbuf
[4],
225 int fd
, char **buffer
,
226 unsigned int timeout
,
230 /* Size of a WRITEX call (+4 byte len). */
231 char writeX_header
[4 + STANDARD_WRITE_AND_X_HEADER_SIZE
];
232 ssize_t len
= smb_len_large(lenbuf
); /* Could be a UNIX large writeX. */
236 memcpy(writeX_header
, lenbuf
, 4);
238 status
= read_fd_with_timeout(
239 fd
, writeX_header
+ 4,
240 STANDARD_WRITE_AND_X_HEADER_SIZE
,
241 STANDARD_WRITE_AND_X_HEADER_SIZE
,
244 if (!NT_STATUS_IS_OK(status
)) {
249 * Ok - now try and see if this is a possible
253 if (is_valid_writeX_buffer(smbd_server_conn
,
254 (uint8_t *)writeX_header
)) {
256 * If the data offset is beyond what
257 * we've read, drain the extra bytes.
259 uint16_t doff
= SVAL(writeX_header
,smb_vwv11
);
262 if (doff
> STANDARD_WRITE_AND_X_HEADER_SIZE
) {
263 size_t drain
= doff
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
264 if (drain_socket(fd
, drain
) != drain
) {
265 smb_panic("receive_smb_raw_talloc_partial_read:"
266 " failed to drain pending bytes");
269 doff
= STANDARD_WRITE_AND_X_HEADER_SIZE
;
272 /* Spoof down the length and null out the bcc. */
273 set_message_bcc(writeX_header
, 0);
274 newlen
= smb_len(writeX_header
);
276 /* Copy the header we've written. */
278 *buffer
= (char *)TALLOC_MEMDUP(mem_ctx
,
280 sizeof(writeX_header
));
282 if (*buffer
== NULL
) {
283 DEBUG(0, ("Could not allocate inbuf of length %d\n",
284 (int)sizeof(writeX_header
)));
285 return NT_STATUS_NO_MEMORY
;
288 /* Work out the remaining bytes. */
289 *p_unread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
290 *len_ret
= newlen
+ 4;
294 if (!valid_packet_size(len
)) {
295 return NT_STATUS_INVALID_PARAMETER
;
299 * Not a valid writeX call. Just do the standard
303 *buffer
= TALLOC_ARRAY(mem_ctx
, char, len
+4);
305 if (*buffer
== NULL
) {
306 DEBUG(0, ("Could not allocate inbuf of length %d\n",
308 return NT_STATUS_NO_MEMORY
;
311 /* Copy in what we already read. */
314 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
);
315 toread
= len
- STANDARD_WRITE_AND_X_HEADER_SIZE
;
318 status
= read_packet_remainder(
319 fd
, (*buffer
) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE
,
322 if (!NT_STATUS_IS_OK(status
)) {
323 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
333 static NTSTATUS
receive_smb_raw_talloc(TALLOC_CTX
*mem_ctx
, int fd
,
334 char **buffer
, unsigned int timeout
,
335 size_t *p_unread
, size_t *plen
)
339 int min_recv_size
= lp_min_receive_file_size();
344 status
= read_smb_length_return_keepalive(fd
, lenbuf
, timeout
, &len
);
345 if (!NT_STATUS_IS_OK(status
)) {
346 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status
)));
350 if (CVAL(lenbuf
,0) == 0 && min_recv_size
&&
351 (smb_len_large(lenbuf
) > /* Could be a UNIX large writeX. */
352 (min_recv_size
+ STANDARD_WRITE_AND_X_HEADER_SIZE
)) &&
353 !srv_is_signing_active(smbd_server_conn
) &&
354 smbd_server_conn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
356 return receive_smb_raw_talloc_partial_read(
357 mem_ctx
, lenbuf
, fd
, buffer
, timeout
, p_unread
, plen
);
360 if (!valid_packet_size(len
)) {
361 return NT_STATUS_INVALID_PARAMETER
;
365 * The +4 here can't wrap, we've checked the length above already.
368 *buffer
= TALLOC_ARRAY(mem_ctx
, char, len
+4);
370 if (*buffer
== NULL
) {
371 DEBUG(0, ("Could not allocate inbuf of length %d\n",
373 return NT_STATUS_NO_MEMORY
;
376 memcpy(*buffer
, lenbuf
, sizeof(lenbuf
));
378 status
= read_packet_remainder(fd
, (*buffer
)+4, timeout
, len
);
379 if (!NT_STATUS_IS_OK(status
)) {
387 static NTSTATUS
receive_smb_talloc(TALLOC_CTX
*mem_ctx
, int fd
,
388 char **buffer
, unsigned int timeout
,
389 size_t *p_unread
, bool *p_encrypted
,
392 bool trusted_channel
)
397 *p_encrypted
= false;
399 status
= receive_smb_raw_talloc(mem_ctx
, fd
, buffer
, timeout
,
401 if (!NT_STATUS_IS_OK(status
)) {
405 if (is_encrypted_packet((uint8_t *)*buffer
)) {
406 status
= srv_decrypt_buffer(*buffer
);
407 if (!NT_STATUS_IS_OK(status
)) {
408 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
409 "incoming packet! Error %s\n",
410 nt_errstr(status
) ));
416 /* Check the incoming SMB signature. */
417 if (!srv_check_sign_mac(smbd_server_conn
, *buffer
, seqnum
, trusted_channel
)) {
418 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
419 "incoming packet!\n"));
420 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
428 * Initialize a struct smb_request from an inbuf
431 static bool init_smb_request(struct smb_request
*req
,
432 struct smbd_server_connection
*sconn
,
434 size_t unread_bytes
, bool encrypted
,
437 size_t req_size
= smb_len(inbuf
) + 4;
438 /* Ensure we have at least smb_size bytes. */
439 if (req_size
< smb_size
) {
440 DEBUG(0,("init_smb_request: invalid request size %u\n",
441 (unsigned int)req_size
));
444 req
->cmd
= CVAL(inbuf
, smb_com
);
445 req
->flags2
= SVAL(inbuf
, smb_flg2
);
446 req
->smbpid
= SVAL(inbuf
, smb_pid
);
447 req
->mid
= (uint64_t)SVAL(inbuf
, smb_mid
);
448 req
->seqnum
= seqnum
;
449 req
->vuid
= SVAL(inbuf
, smb_uid
);
450 req
->tid
= SVAL(inbuf
, smb_tid
);
451 req
->wct
= CVAL(inbuf
, smb_wct
);
452 req
->vwv
= (uint16_t *)(inbuf
+smb_vwv
);
453 req
->buflen
= smb_buflen(inbuf
);
454 req
->buf
= (const uint8_t *)smb_buf(inbuf
);
455 req
->unread_bytes
= unread_bytes
;
456 req
->encrypted
= encrypted
;
458 req
->conn
= conn_find(sconn
,req
->tid
);
459 req
->chain_fsp
= NULL
;
460 req
->chain_outbuf
= NULL
;
463 smb_init_perfcount_data(&req
->pcd
);
465 /* Ensure we have at least wct words and 2 bytes of bcc. */
466 if (smb_size
+ req
->wct
*2 > req_size
) {
467 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
468 (unsigned int)req
->wct
,
469 (unsigned int)req_size
));
472 /* Ensure bcc is correct. */
473 if (((uint8
*)smb_buf(inbuf
)) + req
->buflen
> inbuf
+ req_size
) {
474 DEBUG(0,("init_smb_request: invalid bcc number %u "
475 "(wct = %u, size %u)\n",
476 (unsigned int)req
->buflen
,
477 (unsigned int)req
->wct
,
478 (unsigned int)req_size
));
486 static void process_smb(struct smbd_server_connection
*conn
,
487 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
488 uint32_t seqnum
, bool encrypted
,
489 struct smb_perfcount_data
*deferred_pcd
);
491 static void smbd_deferred_open_timer(struct event_context
*ev
,
492 struct timed_event
*te
,
493 struct timeval _tval
,
496 struct pending_message_list
*msg
= talloc_get_type(private_data
,
497 struct pending_message_list
);
498 TALLOC_CTX
*mem_ctx
= talloc_tos();
499 uint64_t mid
= (uint64_t)SVAL(msg
->buf
.data
,smb_mid
);
502 inbuf
= (uint8_t *)talloc_memdup(mem_ctx
, msg
->buf
.data
,
505 exit_server("smbd_deferred_open_timer: talloc failed\n");
509 /* We leave this message on the queue so the open code can
510 know this is a retry. */
511 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
512 (unsigned long long)mid
));
514 /* Mark the message as processed so this is not
515 * re-processed in error. */
516 msg
->processed
= true;
518 process_smb(smbd_server_conn
, inbuf
,
520 msg
->seqnum
, msg
->encrypted
, &msg
->pcd
);
522 /* If it's still there and was processed, remove it. */
523 msg
= get_deferred_open_message_smb(mid
);
524 if (msg
&& msg
->processed
) {
525 remove_deferred_open_message_smb(mid
);
529 /****************************************************************************
530 Function to push a message onto the tail of a linked list of smb messages ready
532 ****************************************************************************/
534 static bool push_queued_message(struct smb_request
*req
,
535 struct timeval request_time
,
536 struct timeval end_time
,
537 char *private_data
, size_t private_len
)
539 int msg_len
= smb_len(req
->inbuf
) + 4;
540 struct pending_message_list
*msg
;
542 msg
= TALLOC_ZERO_P(NULL
, struct pending_message_list
);
545 DEBUG(0,("push_message: malloc fail (1)\n"));
549 msg
->buf
= data_blob_talloc(msg
, req
->inbuf
, msg_len
);
550 if(msg
->buf
.data
== NULL
) {
551 DEBUG(0,("push_message: malloc fail (2)\n"));
556 msg
->request_time
= request_time
;
557 msg
->seqnum
= req
->seqnum
;
558 msg
->encrypted
= req
->encrypted
;
559 msg
->processed
= false;
560 SMB_PERFCOUNT_DEFER_OP(&req
->pcd
, &msg
->pcd
);
563 msg
->private_data
= data_blob_talloc(msg
, private_data
,
565 if (msg
->private_data
.data
== NULL
) {
566 DEBUG(0,("push_message: malloc fail (3)\n"));
572 msg
->te
= event_add_timed(smbd_event_context(),
575 smbd_deferred_open_timer
,
578 DEBUG(0,("push_message: event_add_timed failed\n"));
583 DLIST_ADD_END(deferred_open_queue
, msg
, struct pending_message_list
*);
585 DEBUG(10,("push_message: pushed message length %u on "
586 "deferred_open_queue\n", (unsigned int)msg_len
));
591 /****************************************************************************
592 Function to delete a sharing violation open message by mid.
593 ****************************************************************************/
595 void remove_deferred_open_message_smb(uint64_t mid
)
597 struct pending_message_list
*pml
;
599 if (smbd_server_conn
->using_smb2
) {
600 remove_deferred_open_message_smb2(smbd_server_conn
, mid
);
604 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
605 if (mid
== (uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) {
606 DEBUG(10,("remove_deferred_open_message_smb: "
607 "deleting mid %llu len %u\n",
608 (unsigned long long)mid
,
609 (unsigned int)pml
->buf
.length
));
610 DLIST_REMOVE(deferred_open_queue
, pml
);
617 /****************************************************************************
618 Move a sharing violation open retry message to the front of the list and
619 schedule it for immediate processing.
620 ****************************************************************************/
622 void schedule_deferred_open_message_smb(uint64_t mid
)
624 struct pending_message_list
*pml
;
627 if (smbd_server_conn
->using_smb2
) {
628 schedule_deferred_open_message_smb2(smbd_server_conn
, mid
);
632 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
633 uint64_t msg_mid
= (uint64_t)SVAL(pml
->buf
.data
,smb_mid
);
635 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
638 (unsigned long long)msg_mid
));
640 if (mid
== msg_mid
) {
641 struct timed_event
*te
;
643 if (pml
->processed
) {
644 /* A processed message should not be
646 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
647 "message mid %llu was already processed\n",
648 (unsigned long long)msg_mid
));
652 DEBUG(10,("schedule_deferred_open_message_smb: "
653 "scheduling mid %llu\n",
654 (unsigned long long)mid
));
656 te
= event_add_timed(smbd_event_context(),
659 smbd_deferred_open_timer
,
662 DEBUG(10,("schedule_deferred_open_message_smb: "
663 "event_add_timed() failed, "
664 "skipping mid %llu\n",
665 (unsigned long long)msg_mid
));
668 TALLOC_FREE(pml
->te
);
670 DLIST_PROMOTE(deferred_open_queue
, pml
);
675 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
676 "find message mid %llu\n",
677 (unsigned long long)mid
));
680 /****************************************************************************
681 Return true if this mid is on the deferred queue and was not yet processed.
682 ****************************************************************************/
684 bool open_was_deferred(uint64_t mid
)
686 struct pending_message_list
*pml
;
688 if (smbd_server_conn
->using_smb2
) {
689 return open_was_deferred_smb2(smbd_server_conn
, mid
);
692 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
693 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
&& !pml
->processed
) {
700 /****************************************************************************
701 Return the message queued by this mid.
702 ****************************************************************************/
704 static struct pending_message_list
*get_deferred_open_message_smb(uint64_t mid
)
706 struct pending_message_list
*pml
;
708 for (pml
= deferred_open_queue
; pml
; pml
= pml
->next
) {
709 if (((uint64_t)SVAL(pml
->buf
.data
,smb_mid
)) == mid
) {
716 /****************************************************************************
717 Get the state data queued by this mid.
718 ****************************************************************************/
720 bool get_deferred_open_message_state(struct smb_request
*smbreq
,
721 struct timeval
*p_request_time
,
724 struct pending_message_list
*pml
;
726 if (smbd_server_conn
->using_smb2
) {
727 return get_deferred_open_message_state_smb2(smbreq
->smb2req
,
732 pml
= get_deferred_open_message_smb(smbreq
->mid
);
736 if (p_request_time
) {
737 *p_request_time
= pml
->request_time
;
740 *pp_state
= (void *)pml
->private_data
.data
;
745 /****************************************************************************
746 Function to push a deferred open smb message onto a linked list of local smb
747 messages ready for processing.
748 ****************************************************************************/
750 bool push_deferred_open_message_smb(struct smb_request
*req
,
751 struct timeval request_time
,
752 struct timeval timeout
,
754 char *private_data
, size_t priv_len
)
756 struct timeval end_time
;
759 return push_deferred_open_message_smb2(req
->smb2req
,
767 if (req
->unread_bytes
) {
768 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
769 "unread_bytes = %u\n",
770 (unsigned int)req
->unread_bytes
));
771 smb_panic("push_deferred_open_message_smb: "
772 "logic error unread_bytes != 0" );
775 end_time
= timeval_sum(&request_time
, &timeout
);
777 DEBUG(10,("push_deferred_open_message_smb: pushing message "
778 "len %u mid %llu timeout time [%u.%06u]\n",
779 (unsigned int) smb_len(req
->inbuf
)+4,
780 (unsigned long long)req
->mid
,
781 (unsigned int)end_time
.tv_sec
,
782 (unsigned int)end_time
.tv_usec
));
784 return push_queued_message(req
, request_time
, end_time
,
785 private_data
, priv_len
);
789 struct timed_event
*te
;
790 struct timeval interval
;
792 bool (*handler
)(const struct timeval
*now
, void *private_data
);
796 static void smbd_idle_event_handler(struct event_context
*ctx
,
797 struct timed_event
*te
,
801 struct idle_event
*event
=
802 talloc_get_type_abort(private_data
, struct idle_event
);
804 TALLOC_FREE(event
->te
);
806 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
807 event
->name
, event
->te
));
809 if (!event
->handler(&now
, event
->private_data
)) {
810 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
811 event
->name
, event
->te
));
812 /* Don't repeat, delete ourselves */
817 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
818 event
->name
, event
->te
));
820 event
->te
= event_add_timed(ctx
, event
,
821 timeval_sum(&now
, &event
->interval
),
822 smbd_idle_event_handler
, event
);
824 /* We can't do much but fail here. */
825 SMB_ASSERT(event
->te
!= NULL
);
828 struct idle_event
*event_add_idle(struct event_context
*event_ctx
,
830 struct timeval interval
,
832 bool (*handler
)(const struct timeval
*now
,
836 struct idle_event
*result
;
837 struct timeval now
= timeval_current();
839 result
= TALLOC_P(mem_ctx
, struct idle_event
);
840 if (result
== NULL
) {
841 DEBUG(0, ("talloc failed\n"));
845 result
->interval
= interval
;
846 result
->handler
= handler
;
847 result
->private_data
= private_data
;
849 if (!(result
->name
= talloc_asprintf(result
, "idle_evt(%s)", name
))) {
850 DEBUG(0, ("talloc failed\n"));
855 result
->te
= event_add_timed(event_ctx
, result
,
856 timeval_sum(&now
, &interval
),
857 smbd_idle_event_handler
, result
);
858 if (result
->te
== NULL
) {
859 DEBUG(0, ("event_add_timed failed\n"));
864 DEBUG(10,("event_add_idle: %s %p\n", result
->name
, result
->te
));
868 static void smbd_sig_term_handler(struct tevent_context
*ev
,
869 struct tevent_signal
*se
,
875 exit_server_cleanly("termination signal");
878 void smbd_setup_sig_term_handler(void)
880 struct tevent_signal
*se
;
882 se
= tevent_add_signal(smbd_event_context(),
883 smbd_event_context(),
885 smbd_sig_term_handler
,
888 exit_server("failed to setup SIGTERM handler");
892 static void smbd_sig_hup_handler(struct tevent_context
*ev
,
893 struct tevent_signal
*se
,
899 struct messaging_context
*msg_ctx
= talloc_get_type_abort(
900 private_data
, struct messaging_context
);
901 change_to_root_user();
902 DEBUG(1,("Reloading services after SIGHUP\n"));
903 reload_services(msg_ctx
, False
);
906 void smbd_setup_sig_hup_handler(struct tevent_context
*ev
,
907 struct messaging_context
*msg_ctx
)
909 struct tevent_signal
*se
;
911 se
= tevent_add_signal(ev
, ev
, SIGHUP
, 0, smbd_sig_hup_handler
,
914 exit_server("failed to setup SIGHUP handler");
918 static NTSTATUS
smbd_server_connection_loop_once(struct smbd_server_connection
*conn
)
925 to
.tv_sec
= SMBD_SELECT_TIMEOUT
;
929 * Setup the select fd sets.
936 * Are there any timed events waiting ? If so, ensure we don't
937 * select for longer than it would take to wait for them.
944 event_add_to_select_args(smbd_event_context(), &now
,
945 &r_fds
, &w_fds
, &to
, &maxfd
);
948 /* Process a signal and timed events now... */
949 if (run_events(smbd_event_context(), 0, NULL
, NULL
)) {
950 return NT_STATUS_RETRY
;
955 START_PROFILE(smbd_idle
);
957 selrtn
= sys_select(maxfd
+1,&r_fds
,&w_fds
,NULL
,&to
);
960 END_PROFILE(smbd_idle
);
964 if ((conn
->smb1
.echo_handler
.trusted_fd
!= -1)
965 && FD_ISSET(conn
->sock
, &r_fds
)
966 && FD_ISSET(conn
->smb1
.echo_handler
.trusted_fd
, &r_fds
)) {
968 * Prefer to read pending requests from the echo handler. To
969 * quote Jeremy (da70f8ab1): This is a hack of monstrous
972 FD_CLR(conn
->sock
, &r_fds
);
975 if (run_events(smbd_event_context(), selrtn
, &r_fds
, &w_fds
)) {
976 return NT_STATUS_RETRY
;
981 /* something is wrong. Maybe the socket is dead? */
982 return map_nt_error_from_unix(errno
);
985 /* Did we timeout ? */
987 return NT_STATUS_RETRY
;
990 /* should not be reached */
991 return NT_STATUS_INTERNAL_ERROR
;
995 * Only allow 5 outstanding trans requests. We're allocating memory, so
999 NTSTATUS
allow_new_trans(struct trans_state
*list
, uint64_t mid
)
1002 for (; list
!= NULL
; list
= list
->next
) {
1004 if (list
->mid
== mid
) {
1005 return NT_STATUS_INVALID_PARAMETER
;
1011 return NT_STATUS_INSUFFICIENT_RESOURCES
;
1014 return NT_STATUS_OK
;
1018 These flags determine some of the permissions required to do an operation
1020 Note that I don't set NEED_WRITE on some write operations because they
1021 are used by some brain-dead clients when printing, and I don't want to
1022 force write permissions on print services.
1024 #define AS_USER (1<<0)
1025 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1026 #define TIME_INIT (1<<2)
1027 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1028 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1029 #define DO_CHDIR (1<<6)
1032 define a list of possible SMB messages and their corresponding
1033 functions. Any message that has a NULL function is unimplemented -
1034 please feel free to contribute implementations!
1036 static const struct smb_message_struct
{
1038 void (*fn
)(struct smb_request
*req
);
1040 } smb_messages
[256] = {
1042 /* 0x00 */ { "SMBmkdir",reply_mkdir
,AS_USER
| NEED_WRITE
},
1043 /* 0x01 */ { "SMBrmdir",reply_rmdir
,AS_USER
| NEED_WRITE
},
1044 /* 0x02 */ { "SMBopen",reply_open
,AS_USER
},
1045 /* 0x03 */ { "SMBcreate",reply_mknew
,AS_USER
},
1046 /* 0x04 */ { "SMBclose",reply_close
,AS_USER
| CAN_IPC
},
1047 /* 0x05 */ { "SMBflush",reply_flush
,AS_USER
},
1048 /* 0x06 */ { "SMBunlink",reply_unlink
,AS_USER
| NEED_WRITE
},
1049 /* 0x07 */ { "SMBmv",reply_mv
,AS_USER
| NEED_WRITE
},
1050 /* 0x08 */ { "SMBgetatr",reply_getatr
,AS_USER
},
1051 /* 0x09 */ { "SMBsetatr",reply_setatr
,AS_USER
| NEED_WRITE
},
1052 /* 0x0a */ { "SMBread",reply_read
,AS_USER
},
1053 /* 0x0b */ { "SMBwrite",reply_write
,AS_USER
| CAN_IPC
},
1054 /* 0x0c */ { "SMBlock",reply_lock
,AS_USER
},
1055 /* 0x0d */ { "SMBunlock",reply_unlock
,AS_USER
},
1056 /* 0x0e */ { "SMBctemp",reply_ctemp
,AS_USER
},
1057 /* 0x0f */ { "SMBmknew",reply_mknew
,AS_USER
},
1058 /* 0x10 */ { "SMBcheckpath",reply_checkpath
,AS_USER
},
1059 /* 0x11 */ { "SMBexit",reply_exit
,DO_CHDIR
},
1060 /* 0x12 */ { "SMBlseek",reply_lseek
,AS_USER
},
1061 /* 0x13 */ { "SMBlockread",reply_lockread
,AS_USER
},
1062 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock
,AS_USER
},
1063 /* 0x15 */ { NULL
, NULL
, 0 },
1064 /* 0x16 */ { NULL
, NULL
, 0 },
1065 /* 0x17 */ { NULL
, NULL
, 0 },
1066 /* 0x18 */ { NULL
, NULL
, 0 },
1067 /* 0x19 */ { NULL
, NULL
, 0 },
1068 /* 0x1a */ { "SMBreadbraw",reply_readbraw
,AS_USER
},
1069 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx
,AS_USER
},
1070 /* 0x1c */ { "SMBreadBs",reply_readbs
,AS_USER
},
1071 /* 0x1d */ { "SMBwritebraw",reply_writebraw
,AS_USER
},
1072 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx
,AS_USER
},
1073 /* 0x1f */ { "SMBwriteBs",reply_writebs
,AS_USER
},
1074 /* 0x20 */ { "SMBwritec", NULL
,0},
1075 /* 0x21 */ { NULL
, NULL
, 0 },
1076 /* 0x22 */ { "SMBsetattrE",reply_setattrE
,AS_USER
| NEED_WRITE
},
1077 /* 0x23 */ { "SMBgetattrE",reply_getattrE
,AS_USER
},
1078 /* 0x24 */ { "SMBlockingX",reply_lockingX
,AS_USER
},
1079 /* 0x25 */ { "SMBtrans",reply_trans
,AS_USER
| CAN_IPC
},
1080 /* 0x26 */ { "SMBtranss",reply_transs
,AS_USER
| CAN_IPC
},
1081 /* 0x27 */ { "SMBioctl",reply_ioctl
,0},
1082 /* 0x28 */ { "SMBioctls", NULL
,AS_USER
},
1083 /* 0x29 */ { "SMBcopy",reply_copy
,AS_USER
| NEED_WRITE
},
1084 /* 0x2a */ { "SMBmove", NULL
,AS_USER
| NEED_WRITE
},
1085 /* 0x2b */ { "SMBecho",reply_echo
,0},
1086 /* 0x2c */ { "SMBwriteclose",reply_writeclose
,AS_USER
},
1087 /* 0x2d */ { "SMBopenX",reply_open_and_X
,AS_USER
| CAN_IPC
},
1088 /* 0x2e */ { "SMBreadX",reply_read_and_X
,AS_USER
| CAN_IPC
},
1089 /* 0x2f */ { "SMBwriteX",reply_write_and_X
,AS_USER
| CAN_IPC
},
1090 /* 0x30 */ { NULL
, NULL
, 0 },
1091 /* 0x31 */ { NULL
, NULL
, 0 },
1092 /* 0x32 */ { "SMBtrans2",reply_trans2
, AS_USER
| CAN_IPC
},
1093 /* 0x33 */ { "SMBtranss2",reply_transs2
, AS_USER
| CAN_IPC
},
1094 /* 0x34 */ { "SMBfindclose",reply_findclose
,AS_USER
},
1095 /* 0x35 */ { "SMBfindnclose",reply_findnclose
,AS_USER
},
1096 /* 0x36 */ { NULL
, NULL
, 0 },
1097 /* 0x37 */ { NULL
, NULL
, 0 },
1098 /* 0x38 */ { NULL
, NULL
, 0 },
1099 /* 0x39 */ { NULL
, NULL
, 0 },
1100 /* 0x3a */ { NULL
, NULL
, 0 },
1101 /* 0x3b */ { NULL
, NULL
, 0 },
1102 /* 0x3c */ { NULL
, NULL
, 0 },
1103 /* 0x3d */ { NULL
, NULL
, 0 },
1104 /* 0x3e */ { NULL
, NULL
, 0 },
1105 /* 0x3f */ { NULL
, NULL
, 0 },
1106 /* 0x40 */ { NULL
, NULL
, 0 },
1107 /* 0x41 */ { NULL
, NULL
, 0 },
1108 /* 0x42 */ { NULL
, NULL
, 0 },
1109 /* 0x43 */ { NULL
, NULL
, 0 },
1110 /* 0x44 */ { NULL
, NULL
, 0 },
1111 /* 0x45 */ { NULL
, NULL
, 0 },
1112 /* 0x46 */ { NULL
, NULL
, 0 },
1113 /* 0x47 */ { NULL
, NULL
, 0 },
1114 /* 0x48 */ { NULL
, NULL
, 0 },
1115 /* 0x49 */ { NULL
, NULL
, 0 },
1116 /* 0x4a */ { NULL
, NULL
, 0 },
1117 /* 0x4b */ { NULL
, NULL
, 0 },
1118 /* 0x4c */ { NULL
, NULL
, 0 },
1119 /* 0x4d */ { NULL
, NULL
, 0 },
1120 /* 0x4e */ { NULL
, NULL
, 0 },
1121 /* 0x4f */ { NULL
, NULL
, 0 },
1122 /* 0x50 */ { NULL
, NULL
, 0 },
1123 /* 0x51 */ { NULL
, NULL
, 0 },
1124 /* 0x52 */ { NULL
, NULL
, 0 },
1125 /* 0x53 */ { NULL
, NULL
, 0 },
1126 /* 0x54 */ { NULL
, NULL
, 0 },
1127 /* 0x55 */ { NULL
, NULL
, 0 },
1128 /* 0x56 */ { NULL
, NULL
, 0 },
1129 /* 0x57 */ { NULL
, NULL
, 0 },
1130 /* 0x58 */ { NULL
, NULL
, 0 },
1131 /* 0x59 */ { NULL
, NULL
, 0 },
1132 /* 0x5a */ { NULL
, NULL
, 0 },
1133 /* 0x5b */ { NULL
, NULL
, 0 },
1134 /* 0x5c */ { NULL
, NULL
, 0 },
1135 /* 0x5d */ { NULL
, NULL
, 0 },
1136 /* 0x5e */ { NULL
, NULL
, 0 },
1137 /* 0x5f */ { NULL
, NULL
, 0 },
1138 /* 0x60 */ { NULL
, NULL
, 0 },
1139 /* 0x61 */ { NULL
, NULL
, 0 },
1140 /* 0x62 */ { NULL
, NULL
, 0 },
1141 /* 0x63 */ { NULL
, NULL
, 0 },
1142 /* 0x64 */ { NULL
, NULL
, 0 },
1143 /* 0x65 */ { NULL
, NULL
, 0 },
1144 /* 0x66 */ { NULL
, NULL
, 0 },
1145 /* 0x67 */ { NULL
, NULL
, 0 },
1146 /* 0x68 */ { NULL
, NULL
, 0 },
1147 /* 0x69 */ { NULL
, NULL
, 0 },
1148 /* 0x6a */ { NULL
, NULL
, 0 },
1149 /* 0x6b */ { NULL
, NULL
, 0 },
1150 /* 0x6c */ { NULL
, NULL
, 0 },
1151 /* 0x6d */ { NULL
, NULL
, 0 },
1152 /* 0x6e */ { NULL
, NULL
, 0 },
1153 /* 0x6f */ { NULL
, NULL
, 0 },
1154 /* 0x70 */ { "SMBtcon",reply_tcon
,0},
1155 /* 0x71 */ { "SMBtdis",reply_tdis
,DO_CHDIR
},
1156 /* 0x72 */ { "SMBnegprot",reply_negprot
,0},
1157 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X
,0},
1158 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX
, 0}, /* ulogoff doesn't give a valid TID */
1159 /* 0x75 */ { "SMBtconX",reply_tcon_and_X
,0},
1160 /* 0x76 */ { NULL
, NULL
, 0 },
1161 /* 0x77 */ { NULL
, NULL
, 0 },
1162 /* 0x78 */ { NULL
, NULL
, 0 },
1163 /* 0x79 */ { NULL
, NULL
, 0 },
1164 /* 0x7a */ { NULL
, NULL
, 0 },
1165 /* 0x7b */ { NULL
, NULL
, 0 },
1166 /* 0x7c */ { NULL
, NULL
, 0 },
1167 /* 0x7d */ { NULL
, NULL
, 0 },
1168 /* 0x7e */ { NULL
, NULL
, 0 },
1169 /* 0x7f */ { NULL
, NULL
, 0 },
1170 /* 0x80 */ { "SMBdskattr",reply_dskattr
,AS_USER
},
1171 /* 0x81 */ { "SMBsearch",reply_search
,AS_USER
},
1172 /* 0x82 */ { "SMBffirst",reply_search
,AS_USER
},
1173 /* 0x83 */ { "SMBfunique",reply_search
,AS_USER
},
1174 /* 0x84 */ { "SMBfclose",reply_fclose
,AS_USER
},
1175 /* 0x85 */ { NULL
, NULL
, 0 },
1176 /* 0x86 */ { NULL
, NULL
, 0 },
1177 /* 0x87 */ { NULL
, NULL
, 0 },
1178 /* 0x88 */ { NULL
, NULL
, 0 },
1179 /* 0x89 */ { NULL
, NULL
, 0 },
1180 /* 0x8a */ { NULL
, NULL
, 0 },
1181 /* 0x8b */ { NULL
, NULL
, 0 },
1182 /* 0x8c */ { NULL
, NULL
, 0 },
1183 /* 0x8d */ { NULL
, NULL
, 0 },
1184 /* 0x8e */ { NULL
, NULL
, 0 },
1185 /* 0x8f */ { NULL
, NULL
, 0 },
1186 /* 0x90 */ { NULL
, NULL
, 0 },
1187 /* 0x91 */ { NULL
, NULL
, 0 },
1188 /* 0x92 */ { NULL
, NULL
, 0 },
1189 /* 0x93 */ { NULL
, NULL
, 0 },
1190 /* 0x94 */ { NULL
, NULL
, 0 },
1191 /* 0x95 */ { NULL
, NULL
, 0 },
1192 /* 0x96 */ { NULL
, NULL
, 0 },
1193 /* 0x97 */ { NULL
, NULL
, 0 },
1194 /* 0x98 */ { NULL
, NULL
, 0 },
1195 /* 0x99 */ { NULL
, NULL
, 0 },
1196 /* 0x9a */ { NULL
, NULL
, 0 },
1197 /* 0x9b */ { NULL
, NULL
, 0 },
1198 /* 0x9c */ { NULL
, NULL
, 0 },
1199 /* 0x9d */ { NULL
, NULL
, 0 },
1200 /* 0x9e */ { NULL
, NULL
, 0 },
1201 /* 0x9f */ { NULL
, NULL
, 0 },
1202 /* 0xa0 */ { "SMBnttrans",reply_nttrans
, AS_USER
| CAN_IPC
},
1203 /* 0xa1 */ { "SMBnttranss",reply_nttranss
, AS_USER
| CAN_IPC
},
1204 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X
, AS_USER
| CAN_IPC
},
1205 /* 0xa3 */ { NULL
, NULL
, 0 },
1206 /* 0xa4 */ { "SMBntcancel",reply_ntcancel
, 0 },
1207 /* 0xa5 */ { "SMBntrename",reply_ntrename
, AS_USER
| NEED_WRITE
},
1208 /* 0xa6 */ { NULL
, NULL
, 0 },
1209 /* 0xa7 */ { NULL
, NULL
, 0 },
1210 /* 0xa8 */ { NULL
, NULL
, 0 },
1211 /* 0xa9 */ { NULL
, NULL
, 0 },
1212 /* 0xaa */ { NULL
, NULL
, 0 },
1213 /* 0xab */ { NULL
, NULL
, 0 },
1214 /* 0xac */ { NULL
, NULL
, 0 },
1215 /* 0xad */ { NULL
, NULL
, 0 },
1216 /* 0xae */ { NULL
, NULL
, 0 },
1217 /* 0xaf */ { NULL
, NULL
, 0 },
1218 /* 0xb0 */ { NULL
, NULL
, 0 },
1219 /* 0xb1 */ { NULL
, NULL
, 0 },
1220 /* 0xb2 */ { NULL
, NULL
, 0 },
1221 /* 0xb3 */ { NULL
, NULL
, 0 },
1222 /* 0xb4 */ { NULL
, NULL
, 0 },
1223 /* 0xb5 */ { NULL
, NULL
, 0 },
1224 /* 0xb6 */ { NULL
, NULL
, 0 },
1225 /* 0xb7 */ { NULL
, NULL
, 0 },
1226 /* 0xb8 */ { NULL
, NULL
, 0 },
1227 /* 0xb9 */ { NULL
, NULL
, 0 },
1228 /* 0xba */ { NULL
, NULL
, 0 },
1229 /* 0xbb */ { NULL
, NULL
, 0 },
1230 /* 0xbc */ { NULL
, NULL
, 0 },
1231 /* 0xbd */ { NULL
, NULL
, 0 },
1232 /* 0xbe */ { NULL
, NULL
, 0 },
1233 /* 0xbf */ { NULL
, NULL
, 0 },
1234 /* 0xc0 */ { "SMBsplopen",reply_printopen
,AS_USER
},
1235 /* 0xc1 */ { "SMBsplwr",reply_printwrite
,AS_USER
},
1236 /* 0xc2 */ { "SMBsplclose",reply_printclose
,AS_USER
},
1237 /* 0xc3 */ { "SMBsplretq",reply_printqueue
,AS_USER
},
1238 /* 0xc4 */ { NULL
, NULL
, 0 },
1239 /* 0xc5 */ { NULL
, NULL
, 0 },
1240 /* 0xc6 */ { NULL
, NULL
, 0 },
1241 /* 0xc7 */ { NULL
, NULL
, 0 },
1242 /* 0xc8 */ { NULL
, NULL
, 0 },
1243 /* 0xc9 */ { NULL
, NULL
, 0 },
1244 /* 0xca */ { NULL
, NULL
, 0 },
1245 /* 0xcb */ { NULL
, NULL
, 0 },
1246 /* 0xcc */ { NULL
, NULL
, 0 },
1247 /* 0xcd */ { NULL
, NULL
, 0 },
1248 /* 0xce */ { NULL
, NULL
, 0 },
1249 /* 0xcf */ { NULL
, NULL
, 0 },
1250 /* 0xd0 */ { "SMBsends",reply_sends
,AS_GUEST
},
1251 /* 0xd1 */ { "SMBsendb", NULL
,AS_GUEST
},
1252 /* 0xd2 */ { "SMBfwdname", NULL
,AS_GUEST
},
1253 /* 0xd3 */ { "SMBcancelf", NULL
,AS_GUEST
},
1254 /* 0xd4 */ { "SMBgetmac", NULL
,AS_GUEST
},
1255 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt
,AS_GUEST
},
1256 /* 0xd6 */ { "SMBsendend",reply_sendend
,AS_GUEST
},
1257 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt
,AS_GUEST
},
1258 /* 0xd8 */ { NULL
, NULL
, 0 },
1259 /* 0xd9 */ { NULL
, NULL
, 0 },
1260 /* 0xda */ { NULL
, NULL
, 0 },
1261 /* 0xdb */ { NULL
, NULL
, 0 },
1262 /* 0xdc */ { NULL
, NULL
, 0 },
1263 /* 0xdd */ { NULL
, NULL
, 0 },
1264 /* 0xde */ { NULL
, NULL
, 0 },
1265 /* 0xdf */ { NULL
, NULL
, 0 },
1266 /* 0xe0 */ { NULL
, NULL
, 0 },
1267 /* 0xe1 */ { NULL
, NULL
, 0 },
1268 /* 0xe2 */ { NULL
, NULL
, 0 },
1269 /* 0xe3 */ { NULL
, NULL
, 0 },
1270 /* 0xe4 */ { NULL
, NULL
, 0 },
1271 /* 0xe5 */ { NULL
, NULL
, 0 },
1272 /* 0xe6 */ { NULL
, NULL
, 0 },
1273 /* 0xe7 */ { NULL
, NULL
, 0 },
1274 /* 0xe8 */ { NULL
, NULL
, 0 },
1275 /* 0xe9 */ { NULL
, NULL
, 0 },
1276 /* 0xea */ { NULL
, NULL
, 0 },
1277 /* 0xeb */ { NULL
, NULL
, 0 },
1278 /* 0xec */ { NULL
, NULL
, 0 },
1279 /* 0xed */ { NULL
, NULL
, 0 },
1280 /* 0xee */ { NULL
, NULL
, 0 },
1281 /* 0xef */ { NULL
, NULL
, 0 },
1282 /* 0xf0 */ { NULL
, NULL
, 0 },
1283 /* 0xf1 */ { NULL
, NULL
, 0 },
1284 /* 0xf2 */ { NULL
, NULL
, 0 },
1285 /* 0xf3 */ { NULL
, NULL
, 0 },
1286 /* 0xf4 */ { NULL
, NULL
, 0 },
1287 /* 0xf5 */ { NULL
, NULL
, 0 },
1288 /* 0xf6 */ { NULL
, NULL
, 0 },
1289 /* 0xf7 */ { NULL
, NULL
, 0 },
1290 /* 0xf8 */ { NULL
, NULL
, 0 },
1291 /* 0xf9 */ { NULL
, NULL
, 0 },
1292 /* 0xfa */ { NULL
, NULL
, 0 },
1293 /* 0xfb */ { NULL
, NULL
, 0 },
1294 /* 0xfc */ { NULL
, NULL
, 0 },
1295 /* 0xfd */ { NULL
, NULL
, 0 },
1296 /* 0xfe */ { NULL
, NULL
, 0 },
1297 /* 0xff */ { NULL
, NULL
, 0 }
1301 /*******************************************************************
1302 allocate and initialize a reply packet
1303 ********************************************************************/
1305 static bool create_outbuf(TALLOC_CTX
*mem_ctx
, struct smb_request
*req
,
1306 const char *inbuf
, char **outbuf
, uint8_t num_words
,
1310 * Protect against integer wrap
1312 if ((num_bytes
> 0xffffff)
1313 || ((num_bytes
+ smb_size
+ num_words
*2) > 0xffffff)) {
1315 if (asprintf(&msg
, "num_bytes too large: %u",
1316 (unsigned)num_bytes
) == -1) {
1317 msg
= CONST_DISCARD(char *, "num_bytes too large");
1322 *outbuf
= TALLOC_ARRAY(mem_ctx
, char,
1323 smb_size
+ num_words
*2 + num_bytes
);
1324 if (*outbuf
== NULL
) {
1328 construct_reply_common(req
, inbuf
, *outbuf
);
1329 srv_set_message(*outbuf
, num_words
, num_bytes
, false);
1331 * Zero out the word area, the caller has to take care of the bcc area
1334 if (num_words
!= 0) {
1335 memset(*outbuf
+ smb_vwv0
, 0, num_words
*2);
1341 void reply_outbuf(struct smb_request
*req
, uint8 num_words
, uint32 num_bytes
)
1344 if (!create_outbuf(req
, req
, (char *)req
->inbuf
, &outbuf
, num_words
,
1346 smb_panic("could not allocate output buffer\n");
1348 req
->outbuf
= (uint8_t *)outbuf
;
1352 /*******************************************************************
1353 Dump a packet to a file.
1354 ********************************************************************/
1356 static void smb_dump(const char *name
, int type
, const char *data
, ssize_t len
)
1360 if (DEBUGLEVEL
< 50) {
1364 if (len
< 4) len
= smb_len(data
)+4;
1365 for (i
=1;i
<100;i
++) {
1366 if (asprintf(&fname
, "/tmp/%s.%d.%s", name
, i
,
1367 type
? "req" : "resp") == -1) {
1370 fd
= open(fname
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644);
1371 if (fd
!= -1 || errno
!= EEXIST
) break;
1374 ssize_t ret
= write(fd
, data
, len
);
1376 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret
));
1378 DEBUG(0,("created %s len %lu\n", fname
, (unsigned long)len
));
1383 /****************************************************************************
1384 Prepare everything for calling the actual request function, and potentially
1385 call the request function via the "new" interface.
1387 Return False if the "legacy" function needs to be called, everything is
1390 Return True if we're done.
1392 I know this API sucks, but it is the one with the least code change I could
1394 ****************************************************************************/
1396 static connection_struct
*switch_message(uint8 type
, struct smb_request
*req
, int size
)
1400 connection_struct
*conn
= NULL
;
1401 struct smbd_server_connection
*sconn
= req
->sconn
;
1405 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1406 * so subtract 4 from it. */
1407 if (!valid_smb_header(req
->inbuf
)
1408 || (size
< (smb_size
- 4))) {
1409 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1410 smb_len(req
->inbuf
)));
1411 exit_server_cleanly("Non-SMB packet");
1414 if (smb_messages
[type
].fn
== NULL
) {
1415 DEBUG(0,("Unknown message type %d!\n",type
));
1416 smb_dump("Unknown", 1, (char *)req
->inbuf
, size
);
1417 reply_unknown_new(req
, type
);
1421 flags
= smb_messages
[type
].flags
;
1423 /* In share mode security we must ignore the vuid. */
1424 session_tag
= (lp_security() == SEC_SHARE
)
1425 ? UID_FIELD_INVALID
: req
->vuid
;
1428 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type
),
1429 (int)sys_getpid(), (unsigned long)conn
));
1431 smb_dump(smb_fn_name(type
), 1, (char *)req
->inbuf
, size
);
1433 /* Ensure this value is replaced in the incoming packet. */
1434 SSVAL(req
->inbuf
,smb_uid
,session_tag
);
1437 * Ensure the correct username is in current_user_info. This is a
1438 * really ugly bugfix for problems with multiple session_setup_and_X's
1439 * being done and allowing %U and %G substitutions to work correctly.
1440 * There is a reason this code is done here, don't move it unless you
1441 * know what you're doing... :-).
1445 if (session_tag
!= sconn
->smb1
.sessions
.last_session_tag
) {
1446 user_struct
*vuser
= NULL
;
1448 sconn
->smb1
.sessions
.last_session_tag
= session_tag
;
1449 if(session_tag
!= UID_FIELD_INVALID
) {
1450 vuser
= get_valid_user_struct(sconn
, session_tag
);
1452 set_current_user_info(
1453 vuser
->server_info
->sanitized_username
,
1454 vuser
->server_info
->unix_name
,
1455 vuser
->server_info
->info3
->base
.domain
.string
);
1460 /* Does this call need to be run as the connected user? */
1461 if (flags
& AS_USER
) {
1463 /* Does this call need a valid tree connection? */
1466 * Amazingly, the error code depends on the command
1469 if (type
== SMBntcreateX
) {
1470 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1472 reply_nterror(req
, NT_STATUS_NETWORK_NAME_DELETED
);
1477 if (!change_to_user(conn
,session_tag
)) {
1478 DEBUG(0, ("Error: Could not change to user. Removing "
1479 "deferred open, mid=%llu.\n",
1480 (unsigned long long)req
->mid
));
1481 reply_force_doserror(req
, ERRSRV
, ERRbaduid
);
1485 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1487 /* Does it need write permission? */
1488 if ((flags
& NEED_WRITE
) && !CAN_WRITE(conn
)) {
1489 reply_nterror(req
, NT_STATUS_MEDIA_WRITE_PROTECTED
);
1493 /* IPC services are limited */
1494 if (IS_IPC(conn
) && !(flags
& CAN_IPC
)) {
1495 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1499 /* This call needs to be run as root */
1500 change_to_root_user();
1503 /* load service specific parameters */
1505 if (req
->encrypted
) {
1506 conn
->encrypted_tid
= true;
1507 /* encrypted required from now on. */
1508 conn
->encrypt_level
= Required
;
1509 } else if (ENCRYPTION_REQUIRED(conn
)) {
1510 if (req
->cmd
!= SMBtrans2
&& req
->cmd
!= SMBtranss2
) {
1511 exit_server_cleanly("encryption required "
1517 if (!set_current_service(conn
,SVAL(req
->inbuf
,smb_flg
),
1518 (flags
& (AS_USER
|DO_CHDIR
)
1520 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1523 conn
->num_smb_operations
++;
1526 /* does this protocol need to be run as guest? */
1527 if ((flags
& AS_GUEST
)
1528 && (!change_to_guest() ||
1529 !check_access(sconn
->sock
, lp_hostsallow(-1),
1530 lp_hostsdeny(-1)))) {
1531 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1535 smb_messages
[type
].fn(req
);
1539 /****************************************************************************
1540 Construct a reply to the incoming packet.
1541 ****************************************************************************/
1543 static void construct_reply(char *inbuf
, int size
, size_t unread_bytes
,
1544 uint32_t seqnum
, bool encrypted
,
1545 struct smb_perfcount_data
*deferred_pcd
)
1547 connection_struct
*conn
;
1548 struct smb_request
*req
;
1550 if (!(req
= talloc(talloc_tos(), struct smb_request
))) {
1551 smb_panic("could not allocate smb_request");
1554 if (!init_smb_request(req
, smbd_server_conn
, (uint8
*)inbuf
,
1555 unread_bytes
, encrypted
, seqnum
)) {
1556 exit_server_cleanly("Invalid SMB request");
1559 req
->inbuf
= (uint8_t *)talloc_move(req
, &inbuf
);
1561 /* we popped this message off the queue - keep original perf data */
1563 req
->pcd
= *deferred_pcd
;
1565 SMB_PERFCOUNT_START(&req
->pcd
);
1566 SMB_PERFCOUNT_SET_OP(&req
->pcd
, req
->cmd
);
1567 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, size
);
1570 conn
= switch_message(req
->cmd
, req
, size
);
1572 if (req
->unread_bytes
) {
1573 /* writeX failed. drain socket. */
1574 if (drain_socket(req
->sconn
->sock
, req
->unread_bytes
) !=
1575 req
->unread_bytes
) {
1576 smb_panic("failed to drain pending bytes");
1578 req
->unread_bytes
= 0;
1586 if (req
->outbuf
== NULL
) {
1590 if (CVAL(req
->outbuf
,0) == 0) {
1591 show_msg((char *)req
->outbuf
);
1594 if (!srv_send_smb(req
->sconn
->sock
,
1595 (char *)req
->outbuf
,
1596 true, req
->seqnum
+1,
1597 IS_CONN_ENCRYPTED(conn
)||req
->encrypted
,
1599 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1607 /****************************************************************************
1608 Process an smb from the client
1609 ****************************************************************************/
1610 static void process_smb(struct smbd_server_connection
*conn
,
1611 uint8_t *inbuf
, size_t nread
, size_t unread_bytes
,
1612 uint32_t seqnum
, bool encrypted
,
1613 struct smb_perfcount_data
*deferred_pcd
)
1615 int msg_type
= CVAL(inbuf
,0);
1617 DO_PROFILE_INC(smb_count
);
1619 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type
,
1621 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num
,
1623 (unsigned int)unread_bytes
));
1625 if (msg_type
!= 0) {
1627 * NetBIOS session request, keepalive, etc.
1629 reply_special(conn
, (char *)inbuf
);
1633 if (smbd_server_conn
->using_smb2
) {
1634 /* At this point we're not really using smb2,
1635 * we make the decision here.. */
1636 if (smbd_is_smb2_header(inbuf
, nread
)) {
1637 smbd_smb2_first_negprot(smbd_server_conn
, inbuf
, nread
);
1639 } else if (nread
>= smb_size
&& valid_smb_header(inbuf
)
1640 && CVAL(inbuf
, smb_com
) != 0x72) {
1641 /* This is a non-negprot SMB1 packet.
1642 Disable SMB2 from now on. */
1643 smbd_server_conn
->using_smb2
= false;
1647 show_msg((char *)inbuf
);
1649 construct_reply((char *)inbuf
,nread
,unread_bytes
,seqnum
,encrypted
,deferred_pcd
);
1653 conn
->smb1
.num_requests
++;
1655 /* The timeout_processing function isn't run nearly
1656 often enough to implement 'max log size' without
1657 overrunning the size of the file by many megabytes.
1658 This is especially true if we are running at debug
1659 level 10. Checking every 50 SMBs is a nice
1660 tradeoff of performance vs log file size overrun. */
1662 if ((conn
->smb1
.num_requests
% 50) == 0 &&
1663 need_to_check_log_size()) {
1664 change_to_root_user();
1669 /****************************************************************************
1670 Return a string containing the function name of a SMB command.
1671 ****************************************************************************/
1673 const char *smb_fn_name(int type
)
1675 const char *unknown_name
= "SMBunknown";
1677 if (smb_messages
[type
].name
== NULL
)
1678 return(unknown_name
);
1680 return(smb_messages
[type
].name
);
1683 /****************************************************************************
1684 Helper functions for contruct_reply.
1685 ****************************************************************************/
1687 void add_to_common_flags2(uint32 v
)
1692 void remove_from_common_flags2(uint32 v
)
1694 common_flags2
&= ~v
;
1697 static void construct_reply_common(struct smb_request
*req
, const char *inbuf
,
1700 srv_set_message(outbuf
,0,0,false);
1702 SCVAL(outbuf
, smb_com
, req
->cmd
);
1703 SIVAL(outbuf
,smb_rcls
,0);
1704 SCVAL(outbuf
,smb_flg
, FLAG_REPLY
| (CVAL(inbuf
,smb_flg
) & FLAG_CASELESS_PATHNAMES
));
1705 SSVAL(outbuf
,smb_flg2
,
1706 (SVAL(inbuf
,smb_flg2
) & FLAGS2_UNICODE_STRINGS
) |
1708 memset(outbuf
+smb_pidhigh
,'\0',(smb_tid
-smb_pidhigh
));
1710 SSVAL(outbuf
,smb_tid
,SVAL(inbuf
,smb_tid
));
1711 SSVAL(outbuf
,smb_pid
,SVAL(inbuf
,smb_pid
));
1712 SSVAL(outbuf
,smb_uid
,SVAL(inbuf
,smb_uid
));
1713 SSVAL(outbuf
,smb_mid
,SVAL(inbuf
,smb_mid
));
1716 void construct_reply_common_req(struct smb_request
*req
, char *outbuf
)
1718 construct_reply_common(req
, (char *)req
->inbuf
, outbuf
);
1722 * How many bytes have we already accumulated up to the current wct field
1726 size_t req_wct_ofs(struct smb_request
*req
)
1730 if (req
->chain_outbuf
== NULL
) {
1733 buf_size
= talloc_get_size(req
->chain_outbuf
);
1734 if ((buf_size
% 4) != 0) {
1735 buf_size
+= (4 - (buf_size
% 4));
1737 return buf_size
- 4;
1741 * Hack around reply_nterror & friends not being aware of chained requests,
1742 * generating illegal (i.e. wct==0) chain replies.
1745 static void fixup_chain_error_packet(struct smb_request
*req
)
1747 uint8_t *outbuf
= req
->outbuf
;
1749 reply_outbuf(req
, 2, 0);
1750 memcpy(req
->outbuf
, outbuf
, smb_wct
);
1751 TALLOC_FREE(outbuf
);
1752 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
1756 * @brief Find the smb_cmd offset of the last command pushed
1757 * @param[in] buf The buffer we're building up
1758 * @retval Where can we put our next andx cmd?
1760 * While chaining requests, the "next" request we're looking at needs to put
1761 * its SMB_Command before the data the previous request already built up added
1762 * to the chain. Find the offset to the place where we have to put our cmd.
1765 static bool find_andx_cmd_ofs(uint8_t *buf
, size_t *pofs
)
1770 cmd
= CVAL(buf
, smb_com
);
1772 SMB_ASSERT(is_andx_req(cmd
));
1776 while (CVAL(buf
, ofs
) != 0xff) {
1778 if (!is_andx_req(CVAL(buf
, ofs
))) {
1783 * ofs is from start of smb header, so add the 4 length
1784 * bytes. The next cmd is right after the wct field.
1786 ofs
= SVAL(buf
, ofs
+2) + 4 + 1;
1788 SMB_ASSERT(ofs
+4 < talloc_get_size(buf
));
1796 * @brief Do the smb chaining at a buffer level
1797 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1798 * @param[in] smb_command The command that we want to issue
1799 * @param[in] wct How many words?
1800 * @param[in] vwv The words, already in network order
1801 * @param[in] bytes_alignment How shall we align "bytes"?
1802 * @param[in] num_bytes How many bytes?
1803 * @param[in] bytes The data the request ships
1805 * smb_splice_chain() adds the vwv and bytes to the request already present in
1809 static bool smb_splice_chain(uint8_t **poutbuf
, uint8_t smb_command
,
1810 uint8_t wct
, const uint16_t *vwv
,
1811 size_t bytes_alignment
,
1812 uint32_t num_bytes
, const uint8_t *bytes
)
1815 size_t old_size
, new_size
;
1817 size_t chain_padding
= 0;
1818 size_t bytes_padding
= 0;
1821 old_size
= talloc_get_size(*poutbuf
);
1824 * old_size == smb_wct means we're pushing the first request in for
1828 first_request
= (old_size
== smb_wct
);
1830 if (!first_request
&& ((old_size
% 4) != 0)) {
1832 * Align the wct field of subsequent requests to a 4-byte
1835 chain_padding
= 4 - (old_size
% 4);
1839 * After the old request comes the new wct field (1 byte), the vwv's
1840 * and the num_bytes field. After at we might need to align the bytes
1841 * given to us to "bytes_alignment", increasing the num_bytes value.
1844 new_size
= old_size
+ chain_padding
+ 1 + wct
* sizeof(uint16_t) + 2;
1846 if ((bytes_alignment
!= 0) && ((new_size
% bytes_alignment
) != 0)) {
1847 bytes_padding
= bytes_alignment
- (new_size
% bytes_alignment
);
1850 new_size
+= bytes_padding
+ num_bytes
;
1852 if ((smb_command
!= SMBwriteX
) && (new_size
> 0xffff)) {
1853 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1854 (unsigned)new_size
));
1858 outbuf
= TALLOC_REALLOC_ARRAY(NULL
, *poutbuf
, uint8_t, new_size
);
1859 if (outbuf
== NULL
) {
1860 DEBUG(0, ("talloc failed\n"));
1865 if (first_request
) {
1866 SCVAL(outbuf
, smb_com
, smb_command
);
1868 size_t andx_cmd_ofs
;
1870 if (!find_andx_cmd_ofs(outbuf
, &andx_cmd_ofs
)) {
1871 DEBUG(1, ("invalid command chain\n"));
1872 *poutbuf
= TALLOC_REALLOC_ARRAY(
1873 NULL
, *poutbuf
, uint8_t, old_size
);
1877 if (chain_padding
!= 0) {
1878 memset(outbuf
+ old_size
, 0, chain_padding
);
1879 old_size
+= chain_padding
;
1882 SCVAL(outbuf
, andx_cmd_ofs
, smb_command
);
1883 SSVAL(outbuf
, andx_cmd_ofs
+ 2, old_size
- 4);
1889 * Push the chained request:
1894 SCVAL(outbuf
, ofs
, wct
);
1901 memcpy(outbuf
+ ofs
, vwv
, sizeof(uint16_t) * wct
);
1902 ofs
+= sizeof(uint16_t) * wct
;
1908 SSVAL(outbuf
, ofs
, num_bytes
+ bytes_padding
);
1909 ofs
+= sizeof(uint16_t);
1915 if (bytes_padding
!= 0) {
1916 memset(outbuf
+ ofs
, 0, bytes_padding
);
1917 ofs
+= bytes_padding
;
1924 memcpy(outbuf
+ ofs
, bytes
, num_bytes
);
1929 /****************************************************************************
1930 Construct a chained reply and add it to the already made reply
1931 ****************************************************************************/
1933 void chain_reply(struct smb_request
*req
)
1935 size_t smblen
= smb_len(req
->inbuf
);
1936 size_t already_used
, length_needed
;
1938 uint32_t chain_offset
; /* uint32_t to avoid overflow */
1945 if (IVAL(req
->outbuf
, smb_rcls
) != 0) {
1946 fixup_chain_error_packet(req
);
1950 * Any of the AndX requests and replies have at least a wct of
1951 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1952 * beginning of the SMB header to the next wct field.
1954 * None of the AndX requests put anything valuable in vwv[0] and [1],
1955 * so we can overwrite it here to form the chain.
1958 if ((req
->wct
< 2) || (CVAL(req
->outbuf
, smb_wct
) < 2)) {
1959 if (req
->chain_outbuf
== NULL
) {
1960 req
->chain_outbuf
= TALLOC_REALLOC_ARRAY(
1961 req
, req
->outbuf
, uint8_t,
1962 smb_len(req
->outbuf
) + 4);
1963 if (req
->chain_outbuf
== NULL
) {
1964 smb_panic("talloc failed");
1972 * Here we assume that this is the end of the chain. For that we need
1973 * to set "next command" to 0xff and the offset to 0. If we later find
1974 * more commands in the chain, this will be overwritten again.
1977 SCVAL(req
->outbuf
, smb_vwv0
, 0xff);
1978 SCVAL(req
->outbuf
, smb_vwv0
+1, 0);
1979 SSVAL(req
->outbuf
, smb_vwv1
, 0);
1981 if (req
->chain_outbuf
== NULL
) {
1983 * In req->chain_outbuf we collect all the replies. Start the
1984 * chain by copying in the first reply.
1986 * We do the realloc because later on we depend on
1987 * talloc_get_size to determine the length of
1988 * chain_outbuf. The reply_xxx routines might have
1989 * over-allocated (reply_pipe_read_and_X used to be such an
1992 req
->chain_outbuf
= TALLOC_REALLOC_ARRAY(
1993 req
, req
->outbuf
, uint8_t, smb_len(req
->outbuf
) + 4);
1994 if (req
->chain_outbuf
== NULL
) {
1995 smb_panic("talloc failed");
2000 * Update smb headers where subsequent chained commands
2001 * may have updated them.
2003 SCVAL(req
->chain_outbuf
, smb_tid
, CVAL(req
->outbuf
, smb_tid
));
2004 SCVAL(req
->chain_outbuf
, smb_uid
, CVAL(req
->outbuf
, smb_uid
));
2006 if (!smb_splice_chain(&req
->chain_outbuf
,
2007 CVAL(req
->outbuf
, smb_com
),
2008 CVAL(req
->outbuf
, smb_wct
),
2009 (uint16_t *)(req
->outbuf
+ smb_vwv
),
2010 0, smb_buflen(req
->outbuf
),
2011 (uint8_t *)smb_buf(req
->outbuf
))) {
2014 TALLOC_FREE(req
->outbuf
);
2018 * We use the old request's vwv field to grab the next chained command
2019 * and offset into the chained fields.
2022 chain_cmd
= CVAL(req
->vwv
+0, 0);
2023 chain_offset
= SVAL(req
->vwv
+1, 0);
2025 if (chain_cmd
== 0xff) {
2027 * End of chain, no more requests from the client. So ship the
2030 smb_setlen((char *)(req
->chain_outbuf
),
2031 talloc_get_size(req
->chain_outbuf
) - 4);
2033 if (!srv_send_smb(req
->sconn
->sock
, (char *)req
->chain_outbuf
,
2034 true, req
->seqnum
+1,
2035 IS_CONN_ENCRYPTED(req
->conn
)
2038 exit_server_cleanly("chain_reply: srv_send_smb "
2041 TALLOC_FREE(req
->chain_outbuf
);
2046 /* add a new perfcounter for this element of chain */
2047 SMB_PERFCOUNT_ADD(&req
->pcd
);
2048 SMB_PERFCOUNT_SET_OP(&req
->pcd
, chain_cmd
);
2049 SMB_PERFCOUNT_SET_MSGLEN_IN(&req
->pcd
, smblen
);
2052 * Check if the client tries to fool us. The request so far uses the
2053 * space to the end of the byte buffer in the request just
2054 * processed. The chain_offset can't point into that area. If that was
2055 * the case, we could end up with an endless processing of the chain,
2056 * we would always handle the same request.
2059 already_used
= PTR_DIFF(req
->buf
+req
->buflen
, smb_base(req
->inbuf
));
2060 if (chain_offset
< already_used
) {
2065 * Next check: Make sure the chain offset does not point beyond the
2066 * overall smb request length.
2069 length_needed
= chain_offset
+1; /* wct */
2070 if (length_needed
> smblen
) {
2075 * Now comes the pointer magic. Goal here is to set up req->vwv and
2076 * req->buf correctly again to be able to call the subsequent
2077 * switch_message(). The chain offset (the former vwv[1]) points at
2078 * the new wct field.
2081 wct
= CVAL(smb_base(req
->inbuf
), chain_offset
);
2084 * Next consistency check: Make the new vwv array fits in the overall
2088 length_needed
+= (wct
+1)*sizeof(uint16_t); /* vwv+buflen */
2089 if (length_needed
> smblen
) {
2092 vwv
= (uint16_t *)(smb_base(req
->inbuf
) + chain_offset
+ 1);
2095 * Now grab the new byte buffer....
2098 buflen
= SVAL(vwv
+wct
, 0);
2101 * .. and check that it fits.
2104 length_needed
+= buflen
;
2105 if (length_needed
> smblen
) {
2108 buf
= (uint8_t *)(vwv
+wct
+1);
2110 req
->cmd
= chain_cmd
;
2113 req
->buflen
= buflen
;
2116 switch_message(chain_cmd
, req
, smblen
);
2118 if (req
->outbuf
== NULL
) {
2120 * This happens if the chained command has suspended itself or
2121 * if it has called srv_send_smb() itself.
2127 * We end up here if the chained command was not itself chained or
2128 * suspended, but for example a close() command. We now need to splice
2129 * the chained commands' outbuf into the already built up chain_outbuf
2130 * and ship the result.
2136 * We end up here if there's any error in the chain syntax. Report a
2137 * DOS error, just like Windows does.
2139 reply_force_doserror(req
, ERRSRV
, ERRerror
);
2140 fixup_chain_error_packet(req
);
2144 * This scary statement intends to set the
2145 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2146 * to the value req->outbuf carries
2148 SSVAL(req
->chain_outbuf
, smb_flg2
,
2149 (SVAL(req
->chain_outbuf
, smb_flg2
) & ~FLAGS2_32_BIT_ERROR_CODES
)
2150 | (SVAL(req
->outbuf
, smb_flg2
) & FLAGS2_32_BIT_ERROR_CODES
));
2153 * Transfer the error codes from the subrequest to the main one
2155 SSVAL(req
->chain_outbuf
, smb_rcls
, SVAL(req
->outbuf
, smb_rcls
));
2156 SSVAL(req
->chain_outbuf
, smb_err
, SVAL(req
->outbuf
, smb_err
));
2158 if (!smb_splice_chain(&req
->chain_outbuf
,
2159 CVAL(req
->outbuf
, smb_com
),
2160 CVAL(req
->outbuf
, smb_wct
),
2161 (uint16_t *)(req
->outbuf
+ smb_vwv
),
2162 0, smb_buflen(req
->outbuf
),
2163 (uint8_t *)smb_buf(req
->outbuf
))) {
2164 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2166 TALLOC_FREE(req
->outbuf
);
2168 smb_setlen((char *)(req
->chain_outbuf
),
2169 talloc_get_size(req
->chain_outbuf
) - 4);
2171 show_msg((char *)(req
->chain_outbuf
));
2173 if (!srv_send_smb(req
->sconn
->sock
, (char *)req
->chain_outbuf
,
2174 true, req
->seqnum
+1,
2175 IS_CONN_ENCRYPTED(req
->conn
)||req
->encrypted
,
2177 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2179 TALLOC_FREE(req
->chain_outbuf
);
2183 /****************************************************************************
2184 Check if services need reloading.
2185 ****************************************************************************/
2187 static void check_reload(struct messaging_context
*msg_ctx
, time_t t
)
2189 time_t printcap_cache_time
= (time_t)lp_printcap_cache_time();
2191 if(last_smb_conf_reload_time
== 0) {
2192 last_smb_conf_reload_time
= t
;
2193 /* Our printing subsystem might not be ready at smbd start up.
2194 Then no printer is available till the first printers check
2195 is performed. A lower initial interval circumvents this. */
2196 if ( printcap_cache_time
> 60 )
2197 last_printer_reload_time
= t
- printcap_cache_time
+ 60;
2199 last_printer_reload_time
= t
;
2202 if (mypid
!= getpid()) { /* First time or fork happened meanwhile */
2203 /* randomize over 60 second the printcap reload to avoid all
2204 * process hitting cupsd at the same time */
2205 int time_range
= 60;
2207 last_printer_reload_time
+= random() % time_range
;
2211 if (t
>= last_smb_conf_reload_time
+SMBD_RELOAD_CHECK
) {
2212 reload_services(msg_ctx
, True
);
2213 last_smb_conf_reload_time
= t
;
2216 /* 'printcap cache time = 0' disable the feature */
2218 if ( printcap_cache_time
!= 0 )
2220 /* see if it's time to reload or if the clock has been set back */
2222 if ( (t
>= last_printer_reload_time
+printcap_cache_time
)
2223 || (t
-last_printer_reload_time
< 0) )
2225 DEBUG( 3,( "Printcap cache time expired.\n"));
2226 reload_printers(msg_ctx
);
2227 last_printer_reload_time
= t
;
2232 static bool fd_is_readable(int fd
)
2235 struct timeval timeout
= {0, };
2241 ret
= sys_select(fd
+1, &fds
, NULL
, NULL
, &timeout
);
2245 return FD_ISSET(fd
, &fds
);
2248 static void smbd_server_connection_write_handler(struct smbd_server_connection
*conn
)
2250 /* TODO: make write nonblocking */
2253 static void smbd_server_connection_read_handler(
2254 struct smbd_server_connection
*conn
, int fd
)
2256 uint8_t *inbuf
= NULL
;
2257 size_t inbuf_len
= 0;
2258 size_t unread_bytes
= 0;
2259 bool encrypted
= false;
2260 TALLOC_CTX
*mem_ctx
= talloc_tos();
2264 bool from_client
= (conn
->sock
== fd
);
2267 smbd_lock_socket(conn
);
2269 if (!fd_is_readable(fd
)) {
2270 DEBUG(10,("the echo listener was faster\n"));
2271 smbd_unlock_socket(conn
);
2275 /* TODO: make this completely nonblocking */
2276 status
= receive_smb_talloc(mem_ctx
, fd
,
2277 (char **)(void *)&inbuf
,
2281 &inbuf_len
, &seqnum
,
2282 false /* trusted channel */);
2283 smbd_unlock_socket(conn
);
2285 /* TODO: make this completely nonblocking */
2286 status
= receive_smb_talloc(mem_ctx
, fd
,
2287 (char **)(void *)&inbuf
,
2291 &inbuf_len
, &seqnum
,
2292 true /* trusted channel */);
2295 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
2298 if (NT_STATUS_IS_ERR(status
)) {
2299 exit_server_cleanly("failed to receive smb request");
2301 if (!NT_STATUS_IS_OK(status
)) {
2306 process_smb(conn
, inbuf
, inbuf_len
, unread_bytes
,
2307 seqnum
, encrypted
, NULL
);
2310 static void smbd_server_connection_handler(struct event_context
*ev
,
2311 struct fd_event
*fde
,
2315 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2316 struct smbd_server_connection
);
2318 if (flags
& EVENT_FD_WRITE
) {
2319 smbd_server_connection_write_handler(conn
);
2322 if (flags
& EVENT_FD_READ
) {
2323 smbd_server_connection_read_handler(conn
, conn
->sock
);
2328 static void smbd_server_echo_handler(struct event_context
*ev
,
2329 struct fd_event
*fde
,
2333 struct smbd_server_connection
*conn
= talloc_get_type(private_data
,
2334 struct smbd_server_connection
);
2336 if (flags
& EVENT_FD_WRITE
) {
2337 smbd_server_connection_write_handler(conn
);
2340 if (flags
& EVENT_FD_READ
) {
2341 smbd_server_connection_read_handler(
2342 conn
, conn
->smb1
.echo_handler
.trusted_fd
);
2347 /****************************************************************************
2348 received when we should release a specific IP
2349 ****************************************************************************/
2350 static void release_ip(const char *ip
, void *priv
)
2352 char addr
[INET6_ADDRSTRLEN
];
2355 client_socket_addr(smbd_server_fd(),addr
,sizeof(addr
));
2357 if (strncmp("::ffff:", addr
, 7) == 0) {
2361 if ((strcmp(p
, ip
) == 0) || ((p
!= addr
) && strcmp(addr
, ip
) == 0)) {
2362 /* we can't afford to do a clean exit - that involves
2363 database writes, which would potentially mean we
2364 are still running after the failover has finished -
2365 we have to get rid of this process ID straight
2367 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2369 /* note we must exit with non-zero status so the unclean handler gets
2370 called in the parent, so that the brl database is tickled */
2375 static void msg_release_ip(struct messaging_context
*msg_ctx
, void *private_data
,
2376 uint32_t msg_type
, struct server_id server_id
, DATA_BLOB
*data
)
2378 release_ip((char *)data
->data
, NULL
);
2381 #ifdef CLUSTER_SUPPORT
2382 static int client_get_tcp_info(struct sockaddr_storage
*server
,
2383 struct sockaddr_storage
*client
)
2386 if (server_fd
== -1) {
2389 length
= sizeof(*server
);
2390 if (getsockname(server_fd
, (struct sockaddr
*)server
, &length
) != 0) {
2393 length
= sizeof(*client
);
2394 if (getpeername(server_fd
, (struct sockaddr
*)client
, &length
) != 0) {
2402 * Send keepalive packets to our client
2404 static bool keepalive_fn(const struct timeval
*now
, void *private_data
)
2406 struct smbd_server_connection
*sconn
= smbd_server_conn
;
2409 if (sconn
->using_smb2
) {
2410 /* Don't do keepalives on an SMB2 connection. */
2414 smbd_lock_socket(smbd_server_conn
);
2415 ret
= send_keepalive(sconn
->sock
);
2416 smbd_unlock_socket(smbd_server_conn
);
2419 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2426 * Do the recurring check if we're idle
2428 static bool deadtime_fn(const struct timeval
*now
, void *private_data
)
2430 struct smbd_server_connection
*sconn
=
2431 (struct smbd_server_connection
*)private_data
;
2433 if (sconn
->using_smb2
) {
2434 /* TODO: implement real idle check */
2435 if (sconn
->smb2
.sessions
.list
) {
2438 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2439 messaging_send(sconn
->msg_ctx
, procid_self(),
2440 MSG_SHUTDOWN
, &data_blob_null
);
2444 if ((conn_num_open(sconn
) == 0)
2445 || (conn_idle_all(sconn
, now
->tv_sec
))) {
2446 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2447 messaging_send(sconn
->msg_ctx
, procid_self(),
2448 MSG_SHUTDOWN
, &data_blob_null
);
2456 * Do the recurring log file and smb.conf reload checks.
2459 static bool housekeeping_fn(const struct timeval
*now
, void *private_data
)
2461 struct messaging_context
*msg_ctx
= talloc_get_type_abort(
2462 private_data
, struct messaging_context
);
2463 change_to_root_user();
2465 /* update printer queue caches if necessary */
2466 update_monitored_printq_cache(msg_ctx
);
2468 /* check if we need to reload services */
2469 check_reload(msg_ctx
, time(NULL
));
2471 /* Change machine password if neccessary. */
2472 attempt_machine_password_change();
2475 * Force a log file check.
2477 force_check_log_size();
2482 static int create_unlink_tmp(const char *dir
)
2487 fname
= talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir
);
2488 if (fname
== NULL
) {
2492 fd
= mkstemp(fname
);
2497 if (unlink(fname
) == -1) {
2498 int sys_errno
= errno
;
2508 struct smbd_echo_state
{
2509 struct tevent_context
*ev
;
2510 struct iovec
*pending
;
2511 struct smbd_server_connection
*sconn
;
2514 struct tevent_fd
*parent_fde
;
2516 struct tevent_fd
*read_fde
;
2517 struct tevent_req
*write_req
;
2520 static void smbd_echo_writer_done(struct tevent_req
*req
);
2522 static void smbd_echo_activate_writer(struct smbd_echo_state
*state
)
2526 if (state
->write_req
!= NULL
) {
2530 num_pending
= talloc_array_length(state
->pending
);
2531 if (num_pending
== 0) {
2535 state
->write_req
= writev_send(state
, state
->ev
, NULL
,
2536 state
->parent_pipe
, false,
2537 state
->pending
, num_pending
);
2538 if (state
->write_req
== NULL
) {
2539 DEBUG(1, ("writev_send failed\n"));
2543 talloc_steal(state
->write_req
, state
->pending
);
2544 state
->pending
= NULL
;
2546 tevent_req_set_callback(state
->write_req
, smbd_echo_writer_done
,
2550 static void smbd_echo_writer_done(struct tevent_req
*req
)
2552 struct smbd_echo_state
*state
= tevent_req_callback_data(
2553 req
, struct smbd_echo_state
);
2557 written
= writev_recv(req
, &err
);
2559 state
->write_req
= NULL
;
2560 if (written
== -1) {
2561 DEBUG(1, ("writev to parent failed: %s\n", strerror(err
)));
2564 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2565 smbd_echo_activate_writer(state
);
2568 static bool smbd_echo_reply(int fd
,
2569 uint8_t *inbuf
, size_t inbuf_len
,
2572 struct smb_request req
;
2573 uint16_t num_replies
;
2578 if (inbuf_len
< smb_size
) {
2579 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len
));
2582 if (!valid_smb_header(inbuf
)) {
2583 DEBUG(10, ("Got invalid SMB header\n"));
2587 if (!init_smb_request(&req
, smbd_server_conn
, inbuf
, 0, false,
2593 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req
.cmd
,
2594 smb_messages
[req
.cmd
].name
2595 ? smb_messages
[req
.cmd
].name
: "unknown"));
2597 if (req
.cmd
!= SMBecho
) {
2604 num_replies
= SVAL(req
.vwv
+0, 0);
2605 if (num_replies
!= 1) {
2606 /* Not a Windows "Hey, you're still there?" request */
2610 if (!create_outbuf(talloc_tos(), &req
, (char *)req
.inbuf
, &outbuf
,
2612 DEBUG(10, ("create_outbuf failed\n"));
2615 req
.outbuf
= (uint8_t *)outbuf
;
2617 SSVAL(req
.outbuf
, smb_vwv0
, num_replies
);
2619 if (req
.buflen
> 0) {
2620 memcpy(smb_buf(req
.outbuf
), req
.buf
, req
.buflen
);
2623 out_len
= smb_len(req
.outbuf
) + 4;
2625 ok
= srv_send_smb(smbd_server_fd(),
2629 TALLOC_FREE(outbuf
);
2637 static void smbd_echo_exit(struct tevent_context
*ev
,
2638 struct tevent_fd
*fde
, uint16_t flags
,
2641 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2645 static void smbd_echo_reader(struct tevent_context
*ev
,
2646 struct tevent_fd
*fde
, uint16_t flags
,
2649 struct smbd_echo_state
*state
= talloc_get_type_abort(
2650 private_data
, struct smbd_echo_state
);
2651 struct smbd_server_connection
*sconn
= state
->sconn
;
2652 size_t unread
, num_pending
;
2655 uint32_t seqnum
= 0;
2658 bool encrypted
= false;
2662 ok
= smbd_lock_socket_internal(sconn
);
2664 DEBUG(0, ("%s: failed to lock socket\n",
2669 if (!fd_is_readable(smbd_server_fd())) {
2670 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2671 (int)sys_getpid()));
2672 ok
= smbd_unlock_socket_internal(sconn
);
2674 DEBUG(1, ("%s: failed to unlock socket in\n",
2681 num_pending
= talloc_array_length(state
->pending
);
2682 tmp
= talloc_realloc(state
, state
->pending
, struct iovec
,
2685 DEBUG(1, ("talloc_realloc failed\n"));
2688 state
->pending
= tmp
;
2690 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2692 status
= receive_smb_talloc(state
->pending
, smbd_server_fd(),
2693 (char **)(void *)&state
->pending
[num_pending
].iov_base
,
2697 &state
->pending
[num_pending
].iov_len
,
2699 false /* trusted_channel*/);
2700 if (!NT_STATUS_IS_OK(status
)) {
2701 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2702 (int)sys_getpid(), nt_errstr(status
)));
2706 ok
= smbd_unlock_socket_internal(sconn
);
2708 DEBUG(1, ("%s: failed to unlock socket in\n",
2714 * place the seqnum in the packet so that the main process can reply
2717 SIVAL((uint8_t *)state
->pending
[num_pending
].iov_base
, smb_ss_field
, seqnum
);
2718 SIVAL((uint8_t *)state
->pending
[num_pending
].iov_base
, smb_ss_field
+4, NT_STATUS_V(NT_STATUS_OK
));
2720 reply
= smbd_echo_reply(smbd_server_fd(),
2721 (uint8_t *)state
->pending
[num_pending
].iov_base
,
2722 state
->pending
[num_pending
].iov_len
,
2725 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2726 /* no check, shrinking by some bytes does not fail */
2727 state
->pending
= talloc_realloc(state
, state
->pending
,
2731 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2732 smbd_echo_activate_writer(state
);
2736 static void smbd_echo_loop(struct smbd_server_connection
*sconn
,
2739 struct smbd_echo_state
*state
;
2741 state
= talloc_zero(sconn
, struct smbd_echo_state
);
2742 if (state
== NULL
) {
2743 DEBUG(1, ("talloc failed\n"));
2746 state
->sconn
= sconn
;
2747 state
->parent_pipe
= parent_pipe
;
2748 state
->ev
= s3_tevent_context_init(state
);
2749 if (state
->ev
== NULL
) {
2750 DEBUG(1, ("tevent_context_init failed\n"));
2754 state
->parent_fde
= tevent_add_fd(state
->ev
, state
, parent_pipe
,
2755 TEVENT_FD_READ
, smbd_echo_exit
,
2757 if (state
->parent_fde
== NULL
) {
2758 DEBUG(1, ("tevent_add_fd failed\n"));
2762 state
->read_fde
= tevent_add_fd(state
->ev
, state
, smbd_server_fd(),
2763 TEVENT_FD_READ
, smbd_echo_reader
,
2765 if (state
->read_fde
== NULL
) {
2766 DEBUG(1, ("tevent_add_fd failed\n"));
2772 if (tevent_loop_once(state
->ev
) == -1) {
2773 DEBUG(1, ("tevent_loop_once failed: %s\n",
2782 * Handle SMBecho requests in a forked child process
2784 static bool fork_echo_handler(struct smbd_server_connection
*sconn
)
2786 int listener_pipe
[2];
2790 res
= pipe(listener_pipe
);
2792 DEBUG(1, ("pipe() failed: %s\n", strerror(errno
)));
2795 sconn
->smb1
.echo_handler
.socket_lock_fd
= create_unlink_tmp(lp_lockdir());
2796 if (sconn
->smb1
.echo_handler
.socket_lock_fd
== -1) {
2797 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno
)));
2805 close(listener_pipe
[0]);
2807 status
= reinit_after_fork(sconn
->msg_ctx
,
2808 smbd_event_context(),
2809 procid_self(), false);
2810 if (!NT_STATUS_IS_OK(status
)) {
2811 DEBUG(1, ("reinit_after_fork failed: %s\n",
2812 nt_errstr(status
)));
2815 smbd_echo_loop(sconn
, listener_pipe
[1]);
2818 close(listener_pipe
[1]);
2819 listener_pipe
[1] = -1;
2820 sconn
->smb1
.echo_handler
.trusted_fd
= listener_pipe
[0];
2822 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child
));
2825 * Without smb signing this is the same as the normal smbd
2826 * listener. This needs to change once signing comes in.
2828 sconn
->smb1
.echo_handler
.trusted_fde
= event_add_fd(smbd_event_context(),
2830 sconn
->smb1
.echo_handler
.trusted_fd
,
2832 smbd_server_echo_handler
,
2834 if (sconn
->smb1
.echo_handler
.trusted_fde
== NULL
) {
2835 DEBUG(1, ("event_add_fd failed\n"));
2842 if (listener_pipe
[0] != -1) {
2843 close(listener_pipe
[0]);
2845 if (listener_pipe
[1] != -1) {
2846 close(listener_pipe
[1]);
2848 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2849 if (sconn
->smb1
.echo_handler
.socket_lock_fd
!= -1) {
2850 close(sconn
->smb1
.echo_handler
.socket_lock_fd
);
2852 sconn
->smb1
.echo_handler
.trusted_fd
= -1;
2853 sconn
->smb1
.echo_handler
.socket_lock_fd
= -1;
2857 /****************************************************************************
2858 Process commands from the client
2859 ****************************************************************************/
2861 void smbd_process(struct smbd_server_connection
*sconn
)
2863 TALLOC_CTX
*frame
= talloc_stackframe();
2864 struct sockaddr_storage ss
;
2865 struct sockaddr
*sa
= NULL
;
2867 struct tsocket_address
*local_address
= NULL
;
2868 struct tsocket_address
*remote_address
= NULL
;
2869 const char *remaddr
= NULL
;
2872 if (lp_maxprotocol() == PROTOCOL_SMB2
&&
2873 lp_security() != SEC_SHARE
&&
2874 !lp_async_smb_echo_handler()) {
2876 * We're not making the desion here,
2877 * we're just allowing the client
2878 * to decide between SMB1 and SMB2
2879 * with the first negprot
2882 sconn
->using_smb2
= true;
2885 /* Ensure child is set to blocking mode */
2886 set_blocking(smbd_server_fd(),True
);
2888 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2889 set_socket_options(smbd_server_fd(), lp_socket_options());
2891 sa
= (struct sockaddr
*)(void *)&ss
;
2892 sa_len
= sizeof(ss
);
2893 ret
= getpeername(smbd_server_fd(), sa
, &sa_len
);
2895 int level
= (errno
== ENOTCONN
)?2:0;
2896 DEBUG(level
,("getpeername() failed - %s\n", strerror(errno
)));
2897 exit_server_cleanly("getpeername() failed.\n");
2899 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
2903 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2904 __location__
, strerror(errno
)));
2905 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2908 sa
= (struct sockaddr
*)(void *)&ss
;
2909 sa_len
= sizeof(ss
);
2910 ret
= getsockname(smbd_server_fd(), sa
, &sa_len
);
2912 int level
= (errno
== ENOTCONN
)?2:0;
2913 DEBUG(level
,("getsockname() failed - %s\n", strerror(errno
)));
2914 exit_server_cleanly("getsockname() failed.\n");
2916 ret
= tsocket_address_bsd_from_sockaddr(sconn
,
2920 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2921 __location__
, strerror(errno
)));
2922 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2925 sconn
->local_address
= local_address
;
2926 sconn
->remote_address
= remote_address
;
2928 if (tsocket_address_is_inet(remote_address
, "ip")) {
2929 remaddr
= tsocket_address_inet_addr_string(
2930 sconn
->remote_address
,
2932 if (remaddr
== NULL
) {
2936 remaddr
= "0.0.0.0";
2939 /* this is needed so that we get decent entries
2940 in smbstatus for port 445 connects */
2941 set_remote_machine_name(remaddr
, false);
2942 reload_services(sconn
->msg_ctx
, true);
2945 * Before the first packet, check the global hosts allow/ hosts deny
2946 * parameters before doing any parsing of packets passed to us by the
2947 * client. This prevents attacks on our parsing code from hosts not in
2948 * the hosts allow list.
2951 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2952 lp_hostsdeny(-1))) {
2954 * send a negative session response "not listening on calling
2957 unsigned char buf
[5] = {0x83, 0, 0, 1, 0x81};
2958 DEBUG( 1, ("Connection denied from %s to %s\n",
2959 tsocket_address_string(remote_address
, talloc_tos()),
2960 tsocket_address_string(local_address
, talloc_tos())));
2961 (void)srv_send_smb(smbd_server_fd(),(char *)buf
, false,
2963 exit_server_cleanly("connection denied");
2966 DEBUG(10, ("Connection allowed from %s to %s\n",
2967 tsocket_address_string(remote_address
, talloc_tos()),
2968 tsocket_address_string(local_address
, talloc_tos())));
2972 smb_perfcount_init();
2974 if (!init_account_policy()) {
2975 exit_server("Could not open account policy tdb.\n");
2978 if (*lp_rootdir()) {
2979 if (chroot(lp_rootdir()) != 0) {
2980 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2981 exit_server("Failed to chroot()");
2983 if (chdir("/") == -1) {
2984 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2985 exit_server("Failed to chroot()");
2987 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2990 if (!srv_init_signing(sconn
)) {
2991 exit_server("Failed to init smb_signing");
2994 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn
)) {
2995 exit_server("Failed to fork echo handler");
2999 if (!init_oplocks(sconn
->msg_ctx
))
3000 exit_server("Failed to init oplocks");
3002 /* register our message handlers */
3003 messaging_register(sconn
->msg_ctx
, NULL
,
3004 MSG_SMB_FORCE_TDIS
, msg_force_tdis
);
3005 messaging_register(sconn
->msg_ctx
, NULL
,
3006 MSG_SMB_RELEASE_IP
, msg_release_ip
);
3007 messaging_register(sconn
->msg_ctx
, NULL
,
3008 MSG_SMB_CLOSE_FILE
, msg_close_file
);
3011 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3012 * MSGs to all child processes
3014 messaging_deregister(sconn
->msg_ctx
,
3016 messaging_register(sconn
->msg_ctx
, NULL
,
3017 MSG_DEBUG
, debug_message
);
3019 if ((lp_keepalive() != 0)
3020 && !(event_add_idle(smbd_event_context(), NULL
,
3021 timeval_set(lp_keepalive(), 0),
3022 "keepalive", keepalive_fn
,
3024 DEBUG(0, ("Could not add keepalive event\n"));
3028 if (!(event_add_idle(smbd_event_context(), NULL
,
3029 timeval_set(IDLE_CLOSED_TIMEOUT
, 0),
3030 "deadtime", deadtime_fn
, sconn
))) {
3031 DEBUG(0, ("Could not add deadtime event\n"));
3035 if (!(event_add_idle(smbd_event_context(), NULL
,
3036 timeval_set(SMBD_SELECT_TIMEOUT
, 0),
3037 "housekeeping", housekeeping_fn
,
3039 DEBUG(0, ("Could not add housekeeping event\n"));
3043 #ifdef CLUSTER_SUPPORT
3045 if (lp_clustering()) {
3047 * We need to tell ctdb about our client's TCP
3048 * connection, so that for failover ctdbd can send
3049 * tickle acks, triggering a reconnection by the
3053 struct sockaddr_storage srv
, clnt
;
3055 if (client_get_tcp_info(&srv
, &clnt
) == 0) {
3059 status
= ctdbd_register_ips(
3060 messaging_ctdbd_connection(procid_self()),
3061 &srv
, &clnt
, release_ip
, NULL
);
3063 if (!NT_STATUS_IS_OK(status
)) {
3064 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3065 nt_errstr(status
)));
3069 DEBUG(0,("Unable to get tcp info for "
3070 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3077 sconn
->nbt
.got_session
= false;
3079 sconn
->smb1
.negprot
.max_recv
= MIN(lp_maxxmit(),BUFFER_SIZE
);
3081 sconn
->smb1
.sessions
.done_sesssetup
= false;
3082 sconn
->smb1
.sessions
.max_send
= BUFFER_SIZE
;
3083 sconn
->smb1
.sessions
.last_session_tag
= UID_FIELD_INVALID
;
3084 /* users from session setup */
3085 sconn
->smb1
.sessions
.session_userlist
= NULL
;
3086 /* workgroup from session setup. */
3087 sconn
->smb1
.sessions
.session_workgroup
= NULL
;
3088 /* this holds info on user ids that are already validated for this VC */
3089 sconn
->smb1
.sessions
.validated_users
= NULL
;
3090 sconn
->smb1
.sessions
.next_vuid
= VUID_OFFSET
;
3091 sconn
->smb1
.sessions
.num_validated_vuids
= 0;
3094 if (!init_dptrs(sconn
)) {
3095 exit_server("init_dptrs() failed");
3098 sconn
->smb1
.fde
= event_add_fd(smbd_event_context(),
3102 smbd_server_connection_handler
,
3104 if (!sconn
->smb1
.fde
) {
3105 exit_server("failed to create smbd_server_connection fde");
3113 frame
= talloc_stackframe_pool(8192);
3117 status
= smbd_server_connection_loop_once(sconn
);
3118 if (!NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
) &&
3119 !NT_STATUS_IS_OK(status
)) {
3120 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3121 " exiting\n", nt_errstr(status
)));
3128 exit_server_cleanly(NULL
);
3131 bool req_is_in_chain(struct smb_request
*req
)
3133 if (req
->vwv
!= (uint16_t *)(req
->inbuf
+smb_vwv
)) {
3135 * We're right now handling a subsequent request, so we must
3141 if (!is_andx_req(req
->cmd
)) {
3147 * Okay, an illegal request, but definitely not chained :-)
3152 return (CVAL(req
->vwv
+0, 0) != 0xFF);