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"
25 #include "../lib/async_req/async_sock.h"
26 #include "ctdbd_conn.h"
28 extern bool global_machine_password_needs_changing;
30 static void construct_reply_common(struct smb_request *req, const char *inbuf,
32 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
34 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
38 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
42 sconn->smb1.echo_handler.ref_count++;
44 if (sconn->smb1.echo_handler.ref_count > 1) {
48 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
50 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
51 SMB_F_SETLKW, 0, 0, F_WRLCK);
56 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
61 void smbd_lock_socket(struct smbd_server_connection *sconn)
63 if (!smbd_lock_socket_internal(sconn)) {
64 exit_server_cleanly("failed to lock socket");
68 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
72 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
76 sconn->smb1.echo_handler.ref_count--;
78 if (sconn->smb1.echo_handler.ref_count > 0) {
82 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
83 SMB_F_SETLKW, 0, 0, F_UNLCK);
88 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
93 void smbd_unlock_socket(struct smbd_server_connection *sconn)
95 if (!smbd_unlock_socket_internal(sconn)) {
96 exit_server_cleanly("failed to unlock socket");
100 /* Accessor function for smb_read_error for smbd functions. */
102 /****************************************************************************
104 ****************************************************************************/
106 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
107 bool do_signing, uint32_t seqnum,
109 struct smb_perfcount_data *pcd)
114 char *buf_out = buffer;
116 smbd_lock_socket(sconn);
119 /* Sign the outgoing packet if required. */
120 srv_calculate_sign_mac(sconn, buf_out, seqnum);
124 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
125 if (!NT_STATUS_IS_OK(status)) {
126 DEBUG(0, ("send_smb: SMB encryption failed "
127 "on outgoing packet! Error %s\n",
128 nt_errstr(status) ));
133 len = smb_len(buf_out) + 4;
135 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
138 char addr[INET6_ADDRSTRLEN];
140 * Try and give an error message saying what
143 DEBUG(0,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
144 (int)sys_getpid(), (int)len,
145 get_peer_addr(sconn->sock, addr, sizeof(addr)),
146 (int)ret, strerror(errno) ));
148 srv_free_enc_buffer(buf_out);
152 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
153 srv_free_enc_buffer(buf_out);
155 SMB_PERFCOUNT_END(pcd);
157 smbd_unlock_socket(sconn);
161 /*******************************************************************
162 Setup the word count and byte count for a smb message.
163 ********************************************************************/
165 int srv_set_message(char *buf,
170 if (zero && (num_words || num_bytes)) {
171 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
173 SCVAL(buf,smb_wct,num_words);
174 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
175 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
176 return (smb_size + num_words*2 + num_bytes);
179 static bool valid_smb_header(const uint8_t *inbuf)
181 if (is_encrypted_packet(inbuf)) {
185 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
186 * but it just looks weird to call strncmp for this one.
188 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
191 /* Socket functions for smbd packet processing. */
193 static bool valid_packet_size(size_t len)
196 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
197 * of header. Don't print the error if this fits.... JRA.
200 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
201 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
202 (unsigned long)len));
208 static NTSTATUS read_packet_remainder(int fd, char *buffer,
209 unsigned int timeout, ssize_t len)
217 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
218 if (!NT_STATUS_IS_OK(status)) {
219 char addr[INET6_ADDRSTRLEN];
220 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
222 get_peer_addr(fd, addr, sizeof(addr)),
228 /****************************************************************************
229 Attempt a zerocopy writeX read. We know here that len > smb_size-4
230 ****************************************************************************/
233 * Unfortunately, earlier versions of smbclient/libsmbclient
234 * don't send this "standard" writeX header. I've fixed this
235 * for 3.2 but we'll use the old method with earlier versions.
236 * Windows and CIFSFS at least use this standard size. Not
240 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
241 (2*14) + /* word count (including bcc) */ \
244 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
245 const char lenbuf[4],
246 int fd, char **buffer,
247 unsigned int timeout,
251 /* Size of a WRITEX call (+4 byte len). */
252 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
253 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
257 memcpy(writeX_header, lenbuf, 4);
259 status = read_fd_with_timeout(
260 fd, writeX_header + 4,
261 STANDARD_WRITE_AND_X_HEADER_SIZE,
262 STANDARD_WRITE_AND_X_HEADER_SIZE,
265 if (!NT_STATUS_IS_OK(status)) {
266 char addr[INET6_ADDRSTRLEN];
267 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
269 get_peer_addr(fd, addr, sizeof(addr)),
275 * Ok - now try and see if this is a possible
279 if (is_valid_writeX_buffer(smbd_server_conn,
280 (uint8_t *)writeX_header)) {
282 * If the data offset is beyond what
283 * we've read, drain the extra bytes.
285 uint16_t doff = SVAL(writeX_header,smb_vwv11);
288 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
289 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
290 if (drain_socket(fd, drain) != drain) {
291 smb_panic("receive_smb_raw_talloc_partial_read:"
292 " failed to drain pending bytes");
295 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
298 /* Spoof down the length and null out the bcc. */
299 set_message_bcc(writeX_header, 0);
300 newlen = smb_len(writeX_header);
302 /* Copy the header we've written. */
304 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
306 sizeof(writeX_header));
308 if (*buffer == NULL) {
309 DEBUG(0, ("Could not allocate inbuf of length %d\n",
310 (int)sizeof(writeX_header)));
311 return NT_STATUS_NO_MEMORY;
314 /* Work out the remaining bytes. */
315 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
316 *len_ret = newlen + 4;
320 if (!valid_packet_size(len)) {
321 return NT_STATUS_INVALID_PARAMETER;
325 * Not a valid writeX call. Just do the standard
329 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
331 if (*buffer == NULL) {
332 DEBUG(0, ("Could not allocate inbuf of length %d\n",
334 return NT_STATUS_NO_MEMORY;
337 /* Copy in what we already read. */
340 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
341 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
344 status = read_packet_remainder(
345 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
348 if (!NT_STATUS_IS_OK(status)) {
349 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
359 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
360 char **buffer, unsigned int timeout,
361 size_t *p_unread, size_t *plen)
365 int min_recv_size = lp_min_receive_file_size();
370 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
371 if (!NT_STATUS_IS_OK(status)) {
375 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
376 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
377 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
378 !srv_is_signing_active(smbd_server_conn) &&
379 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
381 return receive_smb_raw_talloc_partial_read(
382 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
385 if (!valid_packet_size(len)) {
386 return NT_STATUS_INVALID_PARAMETER;
390 * The +4 here can't wrap, we've checked the length above already.
393 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
395 if (*buffer == NULL) {
396 DEBUG(0, ("Could not allocate inbuf of length %d\n",
398 return NT_STATUS_NO_MEMORY;
401 memcpy(*buffer, lenbuf, sizeof(lenbuf));
403 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
404 if (!NT_STATUS_IS_OK(status)) {
412 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
413 char **buffer, unsigned int timeout,
414 size_t *p_unread, bool *p_encrypted,
417 bool trusted_channel)
422 *p_encrypted = false;
424 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
426 if (!NT_STATUS_IS_OK(status)) {
427 char addr[INET6_ADDRSTRLEN];
428 DEBUG(0, ("read_smb_length_return_keepalive failed for "
429 "client %s read error = %s.\n",
430 get_peer_addr(fd, addr, sizeof(addr)),
435 if (is_encrypted_packet((uint8_t *)*buffer)) {
436 status = srv_decrypt_buffer(*buffer);
437 if (!NT_STATUS_IS_OK(status)) {
438 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
439 "incoming packet! Error %s\n",
440 nt_errstr(status) ));
446 /* Check the incoming SMB signature. */
447 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
448 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
449 "incoming packet!\n"));
450 return NT_STATUS_INVALID_NETWORK_RESPONSE;
458 * Initialize a struct smb_request from an inbuf
461 static bool init_smb_request(struct smb_request *req,
462 struct smbd_server_connection *sconn,
464 size_t unread_bytes, bool encrypted,
467 size_t req_size = smb_len(inbuf) + 4;
468 /* Ensure we have at least smb_size bytes. */
469 if (req_size < smb_size) {
470 DEBUG(0,("init_smb_request: invalid request size %u\n",
471 (unsigned int)req_size ));
474 req->cmd = CVAL(inbuf, smb_com);
475 req->flags2 = SVAL(inbuf, smb_flg2);
476 req->smbpid = SVAL(inbuf, smb_pid);
477 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
478 req->seqnum = seqnum;
479 req->vuid = SVAL(inbuf, smb_uid);
480 req->tid = SVAL(inbuf, smb_tid);
481 req->wct = CVAL(inbuf, smb_wct);
482 req->vwv = (uint16_t *)(inbuf+smb_vwv);
483 req->buflen = smb_buflen(inbuf);
484 req->buf = (const uint8_t *)smb_buf(inbuf);
485 req->unread_bytes = unread_bytes;
486 req->encrypted = encrypted;
488 req->conn = conn_find(sconn,req->tid);
489 req->chain_fsp = NULL;
490 req->chain_outbuf = NULL;
493 smb_init_perfcount_data(&req->pcd);
495 /* Ensure we have at least wct words and 2 bytes of bcc. */
496 if (smb_size + req->wct*2 > req_size) {
497 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
498 (unsigned int)req->wct,
499 (unsigned int)req_size));
502 /* Ensure bcc is correct. */
503 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
504 DEBUG(0,("init_smb_request: invalid bcc number %u "
505 "(wct = %u, size %u)\n",
506 (unsigned int)req->buflen,
507 (unsigned int)req->wct,
508 (unsigned int)req_size));
516 static void process_smb(struct smbd_server_connection *conn,
517 uint8_t *inbuf, size_t nread, size_t unread_bytes,
518 uint32_t seqnum, bool encrypted,
519 struct smb_perfcount_data *deferred_pcd);
521 static void smbd_deferred_open_timer(struct event_context *ev,
522 struct timed_event *te,
523 struct timeval _tval,
526 struct pending_message_list *msg = talloc_get_type(private_data,
527 struct pending_message_list);
528 TALLOC_CTX *mem_ctx = talloc_tos();
529 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
532 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
535 exit_server("smbd_deferred_open_timer: talloc failed\n");
539 /* We leave this message on the queue so the open code can
540 know this is a retry. */
541 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
542 (unsigned long long)mid ));
544 /* Mark the message as processed so this is not
545 * re-processed in error. */
546 msg->processed = true;
548 process_smb(smbd_server_conn, inbuf,
550 msg->seqnum, msg->encrypted, &msg->pcd);
552 /* If it's still there and was processed, remove it. */
553 msg = get_deferred_open_message_smb(mid);
554 if (msg && msg->processed) {
555 remove_deferred_open_message_smb(mid);
559 /****************************************************************************
560 Function to push a message onto the tail of a linked list of smb messages ready
562 ****************************************************************************/
564 static bool push_queued_message(struct smb_request *req,
565 struct timeval request_time,
566 struct timeval end_time,
567 char *private_data, size_t private_len)
569 int msg_len = smb_len(req->inbuf) + 4;
570 struct pending_message_list *msg;
572 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
575 DEBUG(0,("push_message: malloc fail (1)\n"));
579 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
580 if(msg->buf.data == NULL) {
581 DEBUG(0,("push_message: malloc fail (2)\n"));
586 msg->request_time = request_time;
587 msg->seqnum = req->seqnum;
588 msg->encrypted = req->encrypted;
589 msg->processed = false;
590 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
593 msg->private_data = data_blob_talloc(msg, private_data,
595 if (msg->private_data.data == NULL) {
596 DEBUG(0,("push_message: malloc fail (3)\n"));
602 msg->te = event_add_timed(smbd_event_context(),
605 smbd_deferred_open_timer,
608 DEBUG(0,("push_message: event_add_timed failed\n"));
613 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
615 DEBUG(10,("push_message: pushed message length %u on "
616 "deferred_open_queue\n", (unsigned int)msg_len));
621 /****************************************************************************
622 Function to delete a sharing violation open message by mid.
623 ****************************************************************************/
625 void remove_deferred_open_message_smb(uint64_t mid)
627 struct pending_message_list *pml;
629 if (smbd_server_conn->using_smb2) {
630 remove_deferred_open_message_smb2(smbd_server_conn, mid);
634 for (pml = deferred_open_queue; pml; pml = pml->next) {
635 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
636 DEBUG(10,("remove_deferred_open_message_smb: "
637 "deleting mid %llu len %u\n",
638 (unsigned long long)mid,
639 (unsigned int)pml->buf.length ));
640 DLIST_REMOVE(deferred_open_queue, pml);
647 /****************************************************************************
648 Move a sharing violation open retry message to the front of the list and
649 schedule it for immediate processing.
650 ****************************************************************************/
652 void schedule_deferred_open_message_smb(uint64_t mid)
654 struct pending_message_list *pml;
657 if (smbd_server_conn->using_smb2) {
658 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
662 for (pml = deferred_open_queue; pml; pml = pml->next) {
663 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
665 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
668 (unsigned long long)msg_mid ));
670 if (mid == msg_mid) {
671 struct timed_event *te;
673 if (pml->processed) {
674 /* A processed message should not be
676 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
677 "message mid %llu was already processed\n",
678 (unsigned long long)msg_mid ));
682 DEBUG(10,("schedule_deferred_open_message_smb: "
683 "scheduling mid %llu\n",
684 (unsigned long long)mid ));
686 te = event_add_timed(smbd_event_context(),
689 smbd_deferred_open_timer,
692 DEBUG(10,("schedule_deferred_open_message_smb: "
693 "event_add_timed() failed, "
694 "skipping mid %llu\n",
695 (unsigned long long)msg_mid ));
698 TALLOC_FREE(pml->te);
700 DLIST_PROMOTE(deferred_open_queue, pml);
705 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
706 "find message mid %llu\n",
707 (unsigned long long)mid ));
710 /****************************************************************************
711 Return true if this mid is on the deferred queue and was not yet processed.
712 ****************************************************************************/
714 bool open_was_deferred(uint64_t mid)
716 struct pending_message_list *pml;
718 if (smbd_server_conn->using_smb2) {
719 return open_was_deferred_smb2(smbd_server_conn, mid);
722 for (pml = deferred_open_queue; pml; pml = pml->next) {
723 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
730 /****************************************************************************
731 Return the message queued by this mid.
732 ****************************************************************************/
734 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
736 struct pending_message_list *pml;
738 for (pml = deferred_open_queue; pml; pml = pml->next) {
739 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
746 /****************************************************************************
747 Get the state data queued by this mid.
748 ****************************************************************************/
750 bool get_deferred_open_message_state(struct smb_request *smbreq,
751 struct timeval *p_request_time,
754 struct pending_message_list *pml;
756 if (smbd_server_conn->using_smb2) {
757 return get_deferred_open_message_state_smb2(smbreq->smb2req,
762 pml = get_deferred_open_message_smb(smbreq->mid);
766 if (p_request_time) {
767 *p_request_time = pml->request_time;
770 *pp_state = (void *)pml->private_data.data;
775 /****************************************************************************
776 Function to push a deferred open smb message onto a linked list of local smb
777 messages ready for processing.
778 ****************************************************************************/
780 bool push_deferred_open_message_smb(struct smb_request *req,
781 struct timeval request_time,
782 struct timeval timeout,
784 char *private_data, size_t priv_len)
786 struct timeval end_time;
789 return push_deferred_open_message_smb2(req->smb2req,
797 if (req->unread_bytes) {
798 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
799 "unread_bytes = %u\n",
800 (unsigned int)req->unread_bytes ));
801 smb_panic("push_deferred_open_message_smb: "
802 "logic error unread_bytes != 0" );
805 end_time = timeval_sum(&request_time, &timeout);
807 DEBUG(10,("push_deferred_open_message_smb: pushing message "
808 "len %u mid %llu timeout time [%u.%06u]\n",
809 (unsigned int) smb_len(req->inbuf)+4,
810 (unsigned long long)req->mid,
811 (unsigned int)end_time.tv_sec,
812 (unsigned int)end_time.tv_usec));
814 return push_queued_message(req, request_time, end_time,
815 private_data, priv_len);
819 struct timed_event *te;
820 struct timeval interval;
822 bool (*handler)(const struct timeval *now, void *private_data);
826 static void smbd_idle_event_handler(struct event_context *ctx,
827 struct timed_event *te,
831 struct idle_event *event =
832 talloc_get_type_abort(private_data, struct idle_event);
834 TALLOC_FREE(event->te);
836 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
837 event->name, event->te));
839 if (!event->handler(&now, event->private_data)) {
840 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
841 event->name, event->te));
842 /* Don't repeat, delete ourselves */
847 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
848 event->name, event->te));
850 event->te = event_add_timed(ctx, event,
851 timeval_sum(&now, &event->interval),
852 smbd_idle_event_handler, event);
854 /* We can't do much but fail here. */
855 SMB_ASSERT(event->te != NULL);
858 struct idle_event *event_add_idle(struct event_context *event_ctx,
860 struct timeval interval,
862 bool (*handler)(const struct timeval *now,
866 struct idle_event *result;
867 struct timeval now = timeval_current();
869 result = TALLOC_P(mem_ctx, struct idle_event);
870 if (result == NULL) {
871 DEBUG(0, ("talloc failed\n"));
875 result->interval = interval;
876 result->handler = handler;
877 result->private_data = private_data;
879 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
880 DEBUG(0, ("talloc failed\n"));
885 result->te = event_add_timed(event_ctx, result,
886 timeval_sum(&now, &interval),
887 smbd_idle_event_handler, result);
888 if (result->te == NULL) {
889 DEBUG(0, ("event_add_timed failed\n"));
894 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
898 static void smbd_sig_term_handler(struct tevent_context *ev,
899 struct tevent_signal *se,
905 exit_server_cleanly("termination signal");
908 void smbd_setup_sig_term_handler(void)
910 struct tevent_signal *se;
912 se = tevent_add_signal(smbd_event_context(),
913 smbd_event_context(),
915 smbd_sig_term_handler,
918 exit_server("failed to setup SIGTERM handler");
922 static void smbd_sig_hup_handler(struct tevent_context *ev,
923 struct tevent_signal *se,
929 struct messaging_context *msg_ctx = talloc_get_type_abort(
930 private_data, struct messaging_context);
931 change_to_root_user();
932 DEBUG(1,("Reloading services after SIGHUP\n"));
933 reload_services(msg_ctx, smbd_server_conn->sock, False);
936 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
937 struct messaging_context *msg_ctx)
939 struct tevent_signal *se;
941 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
944 exit_server("failed to setup SIGHUP handler");
948 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
955 to.tv_sec = SMBD_SELECT_TIMEOUT;
959 * Setup the select fd sets.
966 * Are there any timed events waiting ? If so, ensure we don't
967 * select for longer than it would take to wait for them.
974 event_add_to_select_args(smbd_event_context(), &now,
975 &r_fds, &w_fds, &to, &maxfd);
978 /* Process a signal and timed events now... */
979 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
980 return NT_STATUS_RETRY;
985 START_PROFILE(smbd_idle);
987 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
990 END_PROFILE(smbd_idle);
994 if ((conn->smb1.echo_handler.trusted_fd != -1)
995 && FD_ISSET(conn->sock, &r_fds)
996 && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
998 * Prefer to read pending requests from the echo handler. To
999 * quote Jeremy (da70f8ab1): This is a hack of monstrous
1002 FD_CLR(conn->sock, &r_fds);
1005 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
1006 return NT_STATUS_RETRY;
1009 /* Check if error */
1011 /* something is wrong. Maybe the socket is dead? */
1012 return map_nt_error_from_unix(errno);
1015 /* Did we timeout ? */
1017 return NT_STATUS_RETRY;
1020 /* should not be reached */
1021 return NT_STATUS_INTERNAL_ERROR;
1025 * Only allow 5 outstanding trans requests. We're allocating memory, so
1029 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1032 for (; list != NULL; list = list->next) {
1034 if (list->mid == mid) {
1035 return NT_STATUS_INVALID_PARAMETER;
1041 return NT_STATUS_INSUFFICIENT_RESOURCES;
1044 return NT_STATUS_OK;
1048 These flags determine some of the permissions required to do an operation
1050 Note that I don't set NEED_WRITE on some write operations because they
1051 are used by some brain-dead clients when printing, and I don't want to
1052 force write permissions on print services.
1054 #define AS_USER (1<<0)
1055 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1056 #define TIME_INIT (1<<2)
1057 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1058 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1059 #define DO_CHDIR (1<<6)
1062 define a list of possible SMB messages and their corresponding
1063 functions. Any message that has a NULL function is unimplemented -
1064 please feel free to contribute implementations!
1066 static const struct smb_message_struct {
1068 void (*fn)(struct smb_request *req);
1070 } smb_messages[256] = {
1072 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1073 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1074 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1075 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1076 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1077 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1078 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1079 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1080 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1081 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1082 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1083 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1084 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1085 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1086 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1087 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1088 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1089 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1090 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1091 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1092 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1093 /* 0x15 */ { NULL, NULL, 0 },
1094 /* 0x16 */ { NULL, NULL, 0 },
1095 /* 0x17 */ { NULL, NULL, 0 },
1096 /* 0x18 */ { NULL, NULL, 0 },
1097 /* 0x19 */ { NULL, NULL, 0 },
1098 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1099 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1100 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1101 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1102 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1103 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1104 /* 0x20 */ { "SMBwritec", NULL,0},
1105 /* 0x21 */ { NULL, NULL, 0 },
1106 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1107 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1108 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1109 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1110 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1111 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1112 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1113 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1114 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1115 /* 0x2b */ { "SMBecho",reply_echo,0},
1116 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1117 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1118 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1119 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1120 /* 0x30 */ { NULL, NULL, 0 },
1121 /* 0x31 */ { NULL, NULL, 0 },
1122 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1123 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1124 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1125 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1126 /* 0x36 */ { NULL, NULL, 0 },
1127 /* 0x37 */ { NULL, NULL, 0 },
1128 /* 0x38 */ { NULL, NULL, 0 },
1129 /* 0x39 */ { NULL, NULL, 0 },
1130 /* 0x3a */ { NULL, NULL, 0 },
1131 /* 0x3b */ { NULL, NULL, 0 },
1132 /* 0x3c */ { NULL, NULL, 0 },
1133 /* 0x3d */ { NULL, NULL, 0 },
1134 /* 0x3e */ { NULL, NULL, 0 },
1135 /* 0x3f */ { NULL, NULL, 0 },
1136 /* 0x40 */ { NULL, NULL, 0 },
1137 /* 0x41 */ { NULL, NULL, 0 },
1138 /* 0x42 */ { NULL, NULL, 0 },
1139 /* 0x43 */ { NULL, NULL, 0 },
1140 /* 0x44 */ { NULL, NULL, 0 },
1141 /* 0x45 */ { NULL, NULL, 0 },
1142 /* 0x46 */ { NULL, NULL, 0 },
1143 /* 0x47 */ { NULL, NULL, 0 },
1144 /* 0x48 */ { NULL, NULL, 0 },
1145 /* 0x49 */ { NULL, NULL, 0 },
1146 /* 0x4a */ { NULL, NULL, 0 },
1147 /* 0x4b */ { NULL, NULL, 0 },
1148 /* 0x4c */ { NULL, NULL, 0 },
1149 /* 0x4d */ { NULL, NULL, 0 },
1150 /* 0x4e */ { NULL, NULL, 0 },
1151 /* 0x4f */ { NULL, NULL, 0 },
1152 /* 0x50 */ { NULL, NULL, 0 },
1153 /* 0x51 */ { NULL, NULL, 0 },
1154 /* 0x52 */ { NULL, NULL, 0 },
1155 /* 0x53 */ { NULL, NULL, 0 },
1156 /* 0x54 */ { NULL, NULL, 0 },
1157 /* 0x55 */ { NULL, NULL, 0 },
1158 /* 0x56 */ { NULL, NULL, 0 },
1159 /* 0x57 */ { NULL, NULL, 0 },
1160 /* 0x58 */ { NULL, NULL, 0 },
1161 /* 0x59 */ { NULL, NULL, 0 },
1162 /* 0x5a */ { NULL, NULL, 0 },
1163 /* 0x5b */ { NULL, NULL, 0 },
1164 /* 0x5c */ { NULL, NULL, 0 },
1165 /* 0x5d */ { NULL, NULL, 0 },
1166 /* 0x5e */ { NULL, NULL, 0 },
1167 /* 0x5f */ { NULL, NULL, 0 },
1168 /* 0x60 */ { NULL, NULL, 0 },
1169 /* 0x61 */ { NULL, NULL, 0 },
1170 /* 0x62 */ { NULL, NULL, 0 },
1171 /* 0x63 */ { NULL, NULL, 0 },
1172 /* 0x64 */ { NULL, NULL, 0 },
1173 /* 0x65 */ { NULL, NULL, 0 },
1174 /* 0x66 */ { NULL, NULL, 0 },
1175 /* 0x67 */ { NULL, NULL, 0 },
1176 /* 0x68 */ { NULL, NULL, 0 },
1177 /* 0x69 */ { NULL, NULL, 0 },
1178 /* 0x6a */ { NULL, NULL, 0 },
1179 /* 0x6b */ { NULL, NULL, 0 },
1180 /* 0x6c */ { NULL, NULL, 0 },
1181 /* 0x6d */ { NULL, NULL, 0 },
1182 /* 0x6e */ { NULL, NULL, 0 },
1183 /* 0x6f */ { NULL, NULL, 0 },
1184 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1185 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1186 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1187 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1188 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1189 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1190 /* 0x76 */ { NULL, NULL, 0 },
1191 /* 0x77 */ { NULL, NULL, 0 },
1192 /* 0x78 */ { NULL, NULL, 0 },
1193 /* 0x79 */ { NULL, NULL, 0 },
1194 /* 0x7a */ { NULL, NULL, 0 },
1195 /* 0x7b */ { NULL, NULL, 0 },
1196 /* 0x7c */ { NULL, NULL, 0 },
1197 /* 0x7d */ { NULL, NULL, 0 },
1198 /* 0x7e */ { NULL, NULL, 0 },
1199 /* 0x7f */ { NULL, NULL, 0 },
1200 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1201 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1202 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1203 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1204 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1205 /* 0x85 */ { NULL, NULL, 0 },
1206 /* 0x86 */ { NULL, NULL, 0 },
1207 /* 0x87 */ { NULL, NULL, 0 },
1208 /* 0x88 */ { NULL, NULL, 0 },
1209 /* 0x89 */ { NULL, NULL, 0 },
1210 /* 0x8a */ { NULL, NULL, 0 },
1211 /* 0x8b */ { NULL, NULL, 0 },
1212 /* 0x8c */ { NULL, NULL, 0 },
1213 /* 0x8d */ { NULL, NULL, 0 },
1214 /* 0x8e */ { NULL, NULL, 0 },
1215 /* 0x8f */ { NULL, NULL, 0 },
1216 /* 0x90 */ { NULL, NULL, 0 },
1217 /* 0x91 */ { NULL, NULL, 0 },
1218 /* 0x92 */ { NULL, NULL, 0 },
1219 /* 0x93 */ { NULL, NULL, 0 },
1220 /* 0x94 */ { NULL, NULL, 0 },
1221 /* 0x95 */ { NULL, NULL, 0 },
1222 /* 0x96 */ { NULL, NULL, 0 },
1223 /* 0x97 */ { NULL, NULL, 0 },
1224 /* 0x98 */ { NULL, NULL, 0 },
1225 /* 0x99 */ { NULL, NULL, 0 },
1226 /* 0x9a */ { NULL, NULL, 0 },
1227 /* 0x9b */ { NULL, NULL, 0 },
1228 /* 0x9c */ { NULL, NULL, 0 },
1229 /* 0x9d */ { NULL, NULL, 0 },
1230 /* 0x9e */ { NULL, NULL, 0 },
1231 /* 0x9f */ { NULL, NULL, 0 },
1232 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1233 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1234 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1235 /* 0xa3 */ { NULL, NULL, 0 },
1236 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1237 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1238 /* 0xa6 */ { NULL, NULL, 0 },
1239 /* 0xa7 */ { NULL, NULL, 0 },
1240 /* 0xa8 */ { NULL, NULL, 0 },
1241 /* 0xa9 */ { NULL, NULL, 0 },
1242 /* 0xaa */ { NULL, NULL, 0 },
1243 /* 0xab */ { NULL, NULL, 0 },
1244 /* 0xac */ { NULL, NULL, 0 },
1245 /* 0xad */ { NULL, NULL, 0 },
1246 /* 0xae */ { NULL, NULL, 0 },
1247 /* 0xaf */ { NULL, NULL, 0 },
1248 /* 0xb0 */ { NULL, NULL, 0 },
1249 /* 0xb1 */ { NULL, NULL, 0 },
1250 /* 0xb2 */ { NULL, NULL, 0 },
1251 /* 0xb3 */ { NULL, NULL, 0 },
1252 /* 0xb4 */ { NULL, NULL, 0 },
1253 /* 0xb5 */ { NULL, NULL, 0 },
1254 /* 0xb6 */ { NULL, NULL, 0 },
1255 /* 0xb7 */ { NULL, NULL, 0 },
1256 /* 0xb8 */ { NULL, NULL, 0 },
1257 /* 0xb9 */ { NULL, NULL, 0 },
1258 /* 0xba */ { NULL, NULL, 0 },
1259 /* 0xbb */ { NULL, NULL, 0 },
1260 /* 0xbc */ { NULL, NULL, 0 },
1261 /* 0xbd */ { NULL, NULL, 0 },
1262 /* 0xbe */ { NULL, NULL, 0 },
1263 /* 0xbf */ { NULL, NULL, 0 },
1264 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1265 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1266 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1267 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1268 /* 0xc4 */ { NULL, NULL, 0 },
1269 /* 0xc5 */ { NULL, NULL, 0 },
1270 /* 0xc6 */ { NULL, NULL, 0 },
1271 /* 0xc7 */ { NULL, NULL, 0 },
1272 /* 0xc8 */ { NULL, NULL, 0 },
1273 /* 0xc9 */ { NULL, NULL, 0 },
1274 /* 0xca */ { NULL, NULL, 0 },
1275 /* 0xcb */ { NULL, NULL, 0 },
1276 /* 0xcc */ { NULL, NULL, 0 },
1277 /* 0xcd */ { NULL, NULL, 0 },
1278 /* 0xce */ { NULL, NULL, 0 },
1279 /* 0xcf */ { NULL, NULL, 0 },
1280 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1281 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1282 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1283 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1284 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1285 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1286 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1287 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1288 /* 0xd8 */ { NULL, NULL, 0 },
1289 /* 0xd9 */ { NULL, NULL, 0 },
1290 /* 0xda */ { NULL, NULL, 0 },
1291 /* 0xdb */ { NULL, NULL, 0 },
1292 /* 0xdc */ { NULL, NULL, 0 },
1293 /* 0xdd */ { NULL, NULL, 0 },
1294 /* 0xde */ { NULL, NULL, 0 },
1295 /* 0xdf */ { NULL, NULL, 0 },
1296 /* 0xe0 */ { NULL, NULL, 0 },
1297 /* 0xe1 */ { NULL, NULL, 0 },
1298 /* 0xe2 */ { NULL, NULL, 0 },
1299 /* 0xe3 */ { NULL, NULL, 0 },
1300 /* 0xe4 */ { NULL, NULL, 0 },
1301 /* 0xe5 */ { NULL, NULL, 0 },
1302 /* 0xe6 */ { NULL, NULL, 0 },
1303 /* 0xe7 */ { NULL, NULL, 0 },
1304 /* 0xe8 */ { NULL, NULL, 0 },
1305 /* 0xe9 */ { NULL, NULL, 0 },
1306 /* 0xea */ { NULL, NULL, 0 },
1307 /* 0xeb */ { NULL, NULL, 0 },
1308 /* 0xec */ { NULL, NULL, 0 },
1309 /* 0xed */ { NULL, NULL, 0 },
1310 /* 0xee */ { NULL, NULL, 0 },
1311 /* 0xef */ { NULL, NULL, 0 },
1312 /* 0xf0 */ { NULL, NULL, 0 },
1313 /* 0xf1 */ { NULL, NULL, 0 },
1314 /* 0xf2 */ { NULL, NULL, 0 },
1315 /* 0xf3 */ { NULL, NULL, 0 },
1316 /* 0xf4 */ { NULL, NULL, 0 },
1317 /* 0xf5 */ { NULL, NULL, 0 },
1318 /* 0xf6 */ { NULL, NULL, 0 },
1319 /* 0xf7 */ { NULL, NULL, 0 },
1320 /* 0xf8 */ { NULL, NULL, 0 },
1321 /* 0xf9 */ { NULL, NULL, 0 },
1322 /* 0xfa */ { NULL, NULL, 0 },
1323 /* 0xfb */ { NULL, NULL, 0 },
1324 /* 0xfc */ { NULL, NULL, 0 },
1325 /* 0xfd */ { NULL, NULL, 0 },
1326 /* 0xfe */ { NULL, NULL, 0 },
1327 /* 0xff */ { NULL, NULL, 0 }
1331 /*******************************************************************
1332 allocate and initialize a reply packet
1333 ********************************************************************/
1335 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1336 const char *inbuf, char **outbuf, uint8_t num_words,
1340 * Protect against integer wrap
1342 if ((num_bytes > 0xffffff)
1343 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1345 if (asprintf(&msg, "num_bytes too large: %u",
1346 (unsigned)num_bytes) == -1) {
1347 msg = CONST_DISCARD(char *, "num_bytes too large");
1352 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1353 smb_size + num_words*2 + num_bytes);
1354 if (*outbuf == NULL) {
1358 construct_reply_common(req, inbuf, *outbuf);
1359 srv_set_message(*outbuf, num_words, num_bytes, false);
1361 * Zero out the word area, the caller has to take care of the bcc area
1364 if (num_words != 0) {
1365 memset(*outbuf + smb_vwv0, 0, num_words*2);
1371 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1374 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1376 smb_panic("could not allocate output buffer\n");
1378 req->outbuf = (uint8_t *)outbuf;
1382 /*******************************************************************
1383 Dump a packet to a file.
1384 ********************************************************************/
1386 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1390 if (DEBUGLEVEL < 50) {
1394 if (len < 4) len = smb_len(data)+4;
1395 for (i=1;i<100;i++) {
1396 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1397 type ? "req" : "resp") == -1) {
1400 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1401 if (fd != -1 || errno != EEXIST) break;
1404 ssize_t ret = write(fd, data, len);
1406 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1408 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1413 /****************************************************************************
1414 Prepare everything for calling the actual request function, and potentially
1415 call the request function via the "new" interface.
1417 Return False if the "legacy" function needs to be called, everything is
1420 Return True if we're done.
1422 I know this API sucks, but it is the one with the least code change I could
1424 ****************************************************************************/
1426 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1430 connection_struct *conn = NULL;
1431 struct smbd_server_connection *sconn = req->sconn;
1435 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1436 * so subtract 4 from it. */
1437 if (!valid_smb_header(req->inbuf)
1438 || (size < (smb_size - 4))) {
1439 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1440 smb_len(req->inbuf)));
1441 exit_server_cleanly("Non-SMB packet");
1444 if (smb_messages[type].fn == NULL) {
1445 DEBUG(0,("Unknown message type %d!\n",type));
1446 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1447 reply_unknown_new(req, type);
1451 flags = smb_messages[type].flags;
1453 /* In share mode security we must ignore the vuid. */
1454 session_tag = (lp_security() == SEC_SHARE)
1455 ? UID_FIELD_INVALID : req->vuid;
1458 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1459 (int)sys_getpid(), (unsigned long)conn));
1461 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1463 /* Ensure this value is replaced in the incoming packet. */
1464 SSVAL(req->inbuf,smb_uid,session_tag);
1467 * Ensure the correct username is in current_user_info. This is a
1468 * really ugly bugfix for problems with multiple session_setup_and_X's
1469 * being done and allowing %U and %G substitutions to work correctly.
1470 * There is a reason this code is done here, don't move it unless you
1471 * know what you're doing... :-).
1475 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1476 user_struct *vuser = NULL;
1478 sconn->smb1.sessions.last_session_tag = session_tag;
1479 if(session_tag != UID_FIELD_INVALID) {
1480 vuser = get_valid_user_struct(sconn, session_tag);
1482 set_current_user_info(
1483 vuser->server_info->sanitized_username,
1484 vuser->server_info->unix_name,
1485 vuser->server_info->info3->base.domain.string);
1490 /* Does this call need to be run as the connected user? */
1491 if (flags & AS_USER) {
1493 /* Does this call need a valid tree connection? */
1496 * Amazingly, the error code depends on the command
1499 if (type == SMBntcreateX) {
1500 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1502 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1507 if (!change_to_user(conn,session_tag)) {
1508 DEBUG(0, ("Error: Could not change to user. Removing "
1509 "deferred open, mid=%llu.\n",
1510 (unsigned long long)req->mid));
1511 reply_force_doserror(req, ERRSRV, ERRbaduid);
1515 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1517 /* Does it need write permission? */
1518 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1519 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1523 /* IPC services are limited */
1524 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1525 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1529 /* This call needs to be run as root */
1530 change_to_root_user();
1533 /* load service specific parameters */
1535 if (req->encrypted) {
1536 conn->encrypted_tid = true;
1537 /* encrypted required from now on. */
1538 conn->encrypt_level = Required;
1539 } else if (ENCRYPTION_REQUIRED(conn)) {
1540 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1541 exit_server_cleanly("encryption required "
1547 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1548 (flags & (AS_USER|DO_CHDIR)
1550 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1553 conn->num_smb_operations++;
1556 /* does this protocol need to be run as guest? */
1557 if ((flags & AS_GUEST)
1558 && (!change_to_guest() ||
1559 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1560 sconn->client_id.name,
1561 sconn->client_id.addr))) {
1562 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1566 smb_messages[type].fn(req);
1570 /****************************************************************************
1571 Construct a reply to the incoming packet.
1572 ****************************************************************************/
1574 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1575 uint32_t seqnum, bool encrypted,
1576 struct smb_perfcount_data *deferred_pcd)
1578 connection_struct *conn;
1579 struct smb_request *req;
1581 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1582 smb_panic("could not allocate smb_request");
1585 if (!init_smb_request(req, smbd_server_conn, (uint8 *)inbuf,
1586 unread_bytes, encrypted, seqnum)) {
1587 exit_server_cleanly("Invalid SMB request");
1590 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1592 /* we popped this message off the queue - keep original perf data */
1594 req->pcd = *deferred_pcd;
1596 SMB_PERFCOUNT_START(&req->pcd);
1597 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1598 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1601 conn = switch_message(req->cmd, req, size);
1603 if (req->unread_bytes) {
1604 /* writeX failed. drain socket. */
1605 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1606 req->unread_bytes) {
1607 smb_panic("failed to drain pending bytes");
1609 req->unread_bytes = 0;
1617 if (req->outbuf == NULL) {
1621 if (CVAL(req->outbuf,0) == 0) {
1622 show_msg((char *)req->outbuf);
1625 if (!srv_send_smb(req->sconn,
1626 (char *)req->outbuf,
1627 true, req->seqnum+1,
1628 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1630 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1638 /****************************************************************************
1639 Process an smb from the client
1640 ****************************************************************************/
1641 static void process_smb(struct smbd_server_connection *conn,
1642 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1643 uint32_t seqnum, bool encrypted,
1644 struct smb_perfcount_data *deferred_pcd)
1646 int msg_type = CVAL(inbuf,0);
1648 DO_PROFILE_INC(smb_count);
1650 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1652 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1653 conn->trans_num, (int)nread, (unsigned int)unread_bytes));
1655 if (msg_type != 0) {
1657 * NetBIOS session request, keepalive, etc.
1659 reply_special(conn, (char *)inbuf, nread);
1663 if (smbd_server_conn->using_smb2) {
1664 /* At this point we're not really using smb2,
1665 * we make the decision here.. */
1666 if (smbd_is_smb2_header(inbuf, nread)) {
1667 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1669 } else if (nread >= smb_size && valid_smb_header(inbuf)
1670 && CVAL(inbuf, smb_com) != 0x72) {
1671 /* This is a non-negprot SMB1 packet.
1672 Disable SMB2 from now on. */
1673 smbd_server_conn->using_smb2 = false;
1677 show_msg((char *)inbuf);
1679 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1683 conn->smb1.num_requests++;
1685 /* The timeout_processing function isn't run nearly
1686 often enough to implement 'max log size' without
1687 overrunning the size of the file by many megabytes.
1688 This is especially true if we are running at debug
1689 level 10. Checking every 50 SMBs is a nice
1690 tradeoff of performance vs log file size overrun. */
1692 if ((conn->smb1.num_requests % 50) == 0 &&
1693 need_to_check_log_size()) {
1694 change_to_root_user();
1699 /****************************************************************************
1700 Return a string containing the function name of a SMB command.
1701 ****************************************************************************/
1703 const char *smb_fn_name(int type)
1705 const char *unknown_name = "SMBunknown";
1707 if (smb_messages[type].name == NULL)
1708 return(unknown_name);
1710 return(smb_messages[type].name);
1713 /****************************************************************************
1714 Helper functions for contruct_reply.
1715 ****************************************************************************/
1717 void add_to_common_flags2(uint32 v)
1722 void remove_from_common_flags2(uint32 v)
1724 common_flags2 &= ~v;
1727 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1730 srv_set_message(outbuf,0,0,false);
1732 SCVAL(outbuf, smb_com, req->cmd);
1733 SIVAL(outbuf,smb_rcls,0);
1734 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1735 SSVAL(outbuf,smb_flg2,
1736 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1738 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1740 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1741 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1742 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1743 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1746 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1748 construct_reply_common(req, (char *)req->inbuf, outbuf);
1752 * How many bytes have we already accumulated up to the current wct field
1756 size_t req_wct_ofs(struct smb_request *req)
1760 if (req->chain_outbuf == NULL) {
1763 buf_size = talloc_get_size(req->chain_outbuf);
1764 if ((buf_size % 4) != 0) {
1765 buf_size += (4 - (buf_size % 4));
1767 return buf_size - 4;
1771 * Hack around reply_nterror & friends not being aware of chained requests,
1772 * generating illegal (i.e. wct==0) chain replies.
1775 static void fixup_chain_error_packet(struct smb_request *req)
1777 uint8_t *outbuf = req->outbuf;
1779 reply_outbuf(req, 2, 0);
1780 memcpy(req->outbuf, outbuf, smb_wct);
1781 TALLOC_FREE(outbuf);
1782 SCVAL(req->outbuf, smb_vwv0, 0xff);
1786 * @brief Find the smb_cmd offset of the last command pushed
1787 * @param[in] buf The buffer we're building up
1788 * @retval Where can we put our next andx cmd?
1790 * While chaining requests, the "next" request we're looking at needs to put
1791 * its SMB_Command before the data the previous request already built up added
1792 * to the chain. Find the offset to the place where we have to put our cmd.
1795 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1800 cmd = CVAL(buf, smb_com);
1802 SMB_ASSERT(is_andx_req(cmd));
1806 while (CVAL(buf, ofs) != 0xff) {
1808 if (!is_andx_req(CVAL(buf, ofs))) {
1813 * ofs is from start of smb header, so add the 4 length
1814 * bytes. The next cmd is right after the wct field.
1816 ofs = SVAL(buf, ofs+2) + 4 + 1;
1818 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1826 * @brief Do the smb chaining at a buffer level
1827 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1828 * @param[in] smb_command The command that we want to issue
1829 * @param[in] wct How many words?
1830 * @param[in] vwv The words, already in network order
1831 * @param[in] bytes_alignment How shall we align "bytes"?
1832 * @param[in] num_bytes How many bytes?
1833 * @param[in] bytes The data the request ships
1835 * smb_splice_chain() adds the vwv and bytes to the request already present in
1839 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1840 uint8_t wct, const uint16_t *vwv,
1841 size_t bytes_alignment,
1842 uint32_t num_bytes, const uint8_t *bytes)
1845 size_t old_size, new_size;
1847 size_t chain_padding = 0;
1848 size_t bytes_padding = 0;
1851 old_size = talloc_get_size(*poutbuf);
1854 * old_size == smb_wct means we're pushing the first request in for
1858 first_request = (old_size == smb_wct);
1860 if (!first_request && ((old_size % 4) != 0)) {
1862 * Align the wct field of subsequent requests to a 4-byte
1865 chain_padding = 4 - (old_size % 4);
1869 * After the old request comes the new wct field (1 byte), the vwv's
1870 * and the num_bytes field. After at we might need to align the bytes
1871 * given to us to "bytes_alignment", increasing the num_bytes value.
1874 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1876 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1877 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1880 new_size += bytes_padding + num_bytes;
1882 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1883 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1884 (unsigned)new_size));
1888 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1889 if (outbuf == NULL) {
1890 DEBUG(0, ("talloc failed\n"));
1895 if (first_request) {
1896 SCVAL(outbuf, smb_com, smb_command);
1898 size_t andx_cmd_ofs;
1900 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1901 DEBUG(1, ("invalid command chain\n"));
1902 *poutbuf = TALLOC_REALLOC_ARRAY(
1903 NULL, *poutbuf, uint8_t, old_size);
1907 if (chain_padding != 0) {
1908 memset(outbuf + old_size, 0, chain_padding);
1909 old_size += chain_padding;
1912 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1913 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1919 * Push the chained request:
1924 SCVAL(outbuf, ofs, wct);
1931 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1932 ofs += sizeof(uint16_t) * wct;
1938 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1939 ofs += sizeof(uint16_t);
1945 if (bytes_padding != 0) {
1946 memset(outbuf + ofs, 0, bytes_padding);
1947 ofs += bytes_padding;
1954 memcpy(outbuf + ofs, bytes, num_bytes);
1959 /****************************************************************************
1960 Construct a chained reply and add it to the already made reply
1961 ****************************************************************************/
1963 void chain_reply(struct smb_request *req)
1965 size_t smblen = smb_len(req->inbuf);
1966 size_t already_used, length_needed;
1968 uint32_t chain_offset; /* uint32_t to avoid overflow */
1975 if (IVAL(req->outbuf, smb_rcls) != 0) {
1976 fixup_chain_error_packet(req);
1980 * Any of the AndX requests and replies have at least a wct of
1981 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1982 * beginning of the SMB header to the next wct field.
1984 * None of the AndX requests put anything valuable in vwv[0] and [1],
1985 * so we can overwrite it here to form the chain.
1988 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1989 if (req->chain_outbuf == NULL) {
1990 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1991 req, req->outbuf, uint8_t,
1992 smb_len(req->outbuf) + 4);
1993 if (req->chain_outbuf == NULL) {
1994 smb_panic("talloc failed");
2002 * Here we assume that this is the end of the chain. For that we need
2003 * to set "next command" to 0xff and the offset to 0. If we later find
2004 * more commands in the chain, this will be overwritten again.
2007 SCVAL(req->outbuf, smb_vwv0, 0xff);
2008 SCVAL(req->outbuf, smb_vwv0+1, 0);
2009 SSVAL(req->outbuf, smb_vwv1, 0);
2011 if (req->chain_outbuf == NULL) {
2013 * In req->chain_outbuf we collect all the replies. Start the
2014 * chain by copying in the first reply.
2016 * We do the realloc because later on we depend on
2017 * talloc_get_size to determine the length of
2018 * chain_outbuf. The reply_xxx routines might have
2019 * over-allocated (reply_pipe_read_and_X used to be such an
2022 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2023 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2024 if (req->chain_outbuf == NULL) {
2025 smb_panic("talloc failed");
2030 * Update smb headers where subsequent chained commands
2031 * may have updated them.
2033 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2034 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2036 if (!smb_splice_chain(&req->chain_outbuf,
2037 CVAL(req->outbuf, smb_com),
2038 CVAL(req->outbuf, smb_wct),
2039 (uint16_t *)(req->outbuf + smb_vwv),
2040 0, smb_buflen(req->outbuf),
2041 (uint8_t *)smb_buf(req->outbuf))) {
2044 TALLOC_FREE(req->outbuf);
2048 * We use the old request's vwv field to grab the next chained command
2049 * and offset into the chained fields.
2052 chain_cmd = CVAL(req->vwv+0, 0);
2053 chain_offset = SVAL(req->vwv+1, 0);
2055 if (chain_cmd == 0xff) {
2057 * End of chain, no more requests from the client. So ship the
2060 smb_setlen((char *)(req->chain_outbuf),
2061 talloc_get_size(req->chain_outbuf) - 4);
2063 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2064 true, req->seqnum+1,
2065 IS_CONN_ENCRYPTED(req->conn)
2068 exit_server_cleanly("chain_reply: srv_send_smb "
2071 TALLOC_FREE(req->chain_outbuf);
2076 /* add a new perfcounter for this element of chain */
2077 SMB_PERFCOUNT_ADD(&req->pcd);
2078 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2079 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2082 * Check if the client tries to fool us. The request so far uses the
2083 * space to the end of the byte buffer in the request just
2084 * processed. The chain_offset can't point into that area. If that was
2085 * the case, we could end up with an endless processing of the chain,
2086 * we would always handle the same request.
2089 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2090 if (chain_offset < already_used) {
2095 * Next check: Make sure the chain offset does not point beyond the
2096 * overall smb request length.
2099 length_needed = chain_offset+1; /* wct */
2100 if (length_needed > smblen) {
2105 * Now comes the pointer magic. Goal here is to set up req->vwv and
2106 * req->buf correctly again to be able to call the subsequent
2107 * switch_message(). The chain offset (the former vwv[1]) points at
2108 * the new wct field.
2111 wct = CVAL(smb_base(req->inbuf), chain_offset);
2114 * Next consistency check: Make the new vwv array fits in the overall
2118 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2119 if (length_needed > smblen) {
2122 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2125 * Now grab the new byte buffer....
2128 buflen = SVAL(vwv+wct, 0);
2131 * .. and check that it fits.
2134 length_needed += buflen;
2135 if (length_needed > smblen) {
2138 buf = (uint8_t *)(vwv+wct+1);
2140 req->cmd = chain_cmd;
2143 req->buflen = buflen;
2146 switch_message(chain_cmd, req, smblen);
2148 if (req->outbuf == NULL) {
2150 * This happens if the chained command has suspended itself or
2151 * if it has called srv_send_smb() itself.
2157 * We end up here if the chained command was not itself chained or
2158 * suspended, but for example a close() command. We now need to splice
2159 * the chained commands' outbuf into the already built up chain_outbuf
2160 * and ship the result.
2166 * We end up here if there's any error in the chain syntax. Report a
2167 * DOS error, just like Windows does.
2169 reply_force_doserror(req, ERRSRV, ERRerror);
2170 fixup_chain_error_packet(req);
2174 * This scary statement intends to set the
2175 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2176 * to the value req->outbuf carries
2178 SSVAL(req->chain_outbuf, smb_flg2,
2179 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2180 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2183 * Transfer the error codes from the subrequest to the main one
2185 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2186 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2188 if (!smb_splice_chain(&req->chain_outbuf,
2189 CVAL(req->outbuf, smb_com),
2190 CVAL(req->outbuf, smb_wct),
2191 (uint16_t *)(req->outbuf + smb_vwv),
2192 0, smb_buflen(req->outbuf),
2193 (uint8_t *)smb_buf(req->outbuf))) {
2194 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2196 TALLOC_FREE(req->outbuf);
2198 smb_setlen((char *)(req->chain_outbuf),
2199 talloc_get_size(req->chain_outbuf) - 4);
2201 show_msg((char *)(req->chain_outbuf));
2203 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2204 true, req->seqnum+1,
2205 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2207 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2209 TALLOC_FREE(req->chain_outbuf);
2213 /****************************************************************************
2214 Check if services need reloading.
2215 ****************************************************************************/
2217 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2219 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2221 if(last_smb_conf_reload_time == 0) {
2222 last_smb_conf_reload_time = t;
2223 /* Our printing subsystem might not be ready at smbd start up.
2224 Then no printer is available till the first printers check
2225 is performed. A lower initial interval circumvents this. */
2226 if ( printcap_cache_time > 60 )
2227 last_printer_reload_time = t - printcap_cache_time + 60;
2229 last_printer_reload_time = t;
2232 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2233 /* randomize over 60 second the printcap reload to avoid all
2234 * process hitting cupsd at the same time */
2235 int time_range = 60;
2237 last_printer_reload_time += random() % time_range;
2241 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2242 reload_services(sconn->msg_ctx, sconn->sock, True);
2243 last_smb_conf_reload_time = t;
2246 /* 'printcap cache time = 0' disable the feature */
2248 if ( printcap_cache_time != 0 )
2250 /* see if it's time to reload or if the clock has been set back */
2252 if ( (t >= last_printer_reload_time+printcap_cache_time)
2253 || (t-last_printer_reload_time < 0) )
2255 DEBUG( 3,( "Printcap cache time expired.\n"));
2256 reload_printers(sconn->msg_ctx);
2257 last_printer_reload_time = t;
2262 static bool fd_is_readable(int fd)
2265 struct timeval timeout = {0, };
2271 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2275 return FD_ISSET(fd, &fds);
2278 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2280 /* TODO: make write nonblocking */
2283 static void smbd_server_connection_read_handler(
2284 struct smbd_server_connection *conn, int fd)
2286 uint8_t *inbuf = NULL;
2287 size_t inbuf_len = 0;
2288 size_t unread_bytes = 0;
2289 bool encrypted = false;
2290 TALLOC_CTX *mem_ctx = talloc_tos();
2294 bool from_client = (conn->sock == fd);
2297 smbd_lock_socket(conn);
2299 if (!fd_is_readable(fd)) {
2300 DEBUG(10,("the echo listener was faster\n"));
2301 smbd_unlock_socket(conn);
2305 /* TODO: make this completely nonblocking */
2306 status = receive_smb_talloc(mem_ctx, fd,
2307 (char **)(void *)&inbuf,
2311 &inbuf_len, &seqnum,
2312 false /* trusted channel */);
2313 smbd_unlock_socket(conn);
2315 /* TODO: make this completely nonblocking */
2316 status = receive_smb_talloc(mem_ctx, fd,
2317 (char **)(void *)&inbuf,
2321 &inbuf_len, &seqnum,
2322 true /* trusted channel */);
2325 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2328 if (NT_STATUS_IS_ERR(status)) {
2329 exit_server_cleanly("failed to receive smb request");
2331 if (!NT_STATUS_IS_OK(status)) {
2336 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2337 seqnum, encrypted, NULL);
2340 static void smbd_server_connection_handler(struct event_context *ev,
2341 struct fd_event *fde,
2345 struct smbd_server_connection *conn = talloc_get_type(private_data,
2346 struct smbd_server_connection);
2348 if (flags & EVENT_FD_WRITE) {
2349 smbd_server_connection_write_handler(conn);
2352 if (flags & EVENT_FD_READ) {
2353 smbd_server_connection_read_handler(conn, conn->sock);
2358 static void smbd_server_echo_handler(struct event_context *ev,
2359 struct fd_event *fde,
2363 struct smbd_server_connection *conn = talloc_get_type(private_data,
2364 struct smbd_server_connection);
2366 if (flags & EVENT_FD_WRITE) {
2367 smbd_server_connection_write_handler(conn);
2370 if (flags & EVENT_FD_READ) {
2371 smbd_server_connection_read_handler(
2372 conn, conn->smb1.echo_handler.trusted_fd);
2377 /****************************************************************************
2378 received when we should release a specific IP
2379 ****************************************************************************/
2380 static void release_ip(const char *ip, void *priv)
2382 const char *addr = (const char *)priv;
2383 const char *p = addr;
2385 if (strncmp("::ffff:", addr, 7) == 0) {
2389 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2390 /* we can't afford to do a clean exit - that involves
2391 database writes, which would potentially mean we
2392 are still running after the failover has finished -
2393 we have to get rid of this process ID straight
2395 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2397 /* note we must exit with non-zero status so the unclean handler gets
2398 called in the parent, so that the brl database is tickled */
2403 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2404 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2406 struct smbd_server_connection *sconn = talloc_get_type_abort(
2407 private_data, struct smbd_server_connection);
2409 release_ip((char *)data->data, sconn->client_id.addr);
2412 #ifdef CLUSTER_SUPPORT
2413 static int client_get_tcp_info(struct sockaddr_storage *server,
2414 struct sockaddr_storage *client)
2417 if (server_fd == -1) {
2420 length = sizeof(*server);
2421 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2424 length = sizeof(*client);
2425 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2433 * Send keepalive packets to our client
2435 static bool keepalive_fn(const struct timeval *now, void *private_data)
2437 struct smbd_server_connection *sconn = smbd_server_conn;
2440 if (sconn->using_smb2) {
2441 /* Don't do keepalives on an SMB2 connection. */
2445 smbd_lock_socket(smbd_server_conn);
2446 ret = send_keepalive(sconn->sock);
2447 smbd_unlock_socket(smbd_server_conn);
2450 char addr[INET6_ADDRSTRLEN];
2452 * Try and give an error message saying what
2455 DEBUG(0, ("send_keepalive failed for client %s. "
2456 "Error %s - exiting\n",
2457 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2465 * Do the recurring check if we're idle
2467 static bool deadtime_fn(const struct timeval *now, void *private_data)
2469 struct smbd_server_connection *sconn =
2470 (struct smbd_server_connection *)private_data;
2472 if (sconn->using_smb2) {
2473 /* TODO: implement real idle check */
2474 if (sconn->smb2.sessions.list) {
2477 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2478 messaging_send(sconn->msg_ctx, procid_self(),
2479 MSG_SHUTDOWN, &data_blob_null);
2483 if ((conn_num_open(sconn) == 0)
2484 || (conn_idle_all(sconn, now->tv_sec))) {
2485 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2486 messaging_send(sconn->msg_ctx, procid_self(),
2487 MSG_SHUTDOWN, &data_blob_null);
2495 * Do the recurring log file and smb.conf reload checks.
2498 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2500 struct smbd_server_connection *sconn = talloc_get_type_abort(
2501 private_data, struct smbd_server_connection);
2502 change_to_root_user();
2504 /* update printer queue caches if necessary */
2505 update_monitored_printq_cache(sconn->msg_ctx);
2507 /* check if we need to reload services */
2508 check_reload(sconn, time(NULL));
2510 /* Change machine password if neccessary. */
2511 attempt_machine_password_change();
2514 * Force a log file check.
2516 force_check_log_size();
2521 static int create_unlink_tmp(const char *dir)
2526 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2527 if (fname == NULL) {
2531 fd = mkstemp(fname);
2536 if (unlink(fname) == -1) {
2537 int sys_errno = errno;
2547 struct smbd_echo_state {
2548 struct tevent_context *ev;
2549 struct iovec *pending;
2550 struct smbd_server_connection *sconn;
2553 struct tevent_fd *parent_fde;
2555 struct tevent_fd *read_fde;
2556 struct tevent_req *write_req;
2559 static void smbd_echo_writer_done(struct tevent_req *req);
2561 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2565 if (state->write_req != NULL) {
2569 num_pending = talloc_array_length(state->pending);
2570 if (num_pending == 0) {
2574 state->write_req = writev_send(state, state->ev, NULL,
2575 state->parent_pipe, false,
2576 state->pending, num_pending);
2577 if (state->write_req == NULL) {
2578 DEBUG(1, ("writev_send failed\n"));
2582 talloc_steal(state->write_req, state->pending);
2583 state->pending = NULL;
2585 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2589 static void smbd_echo_writer_done(struct tevent_req *req)
2591 struct smbd_echo_state *state = tevent_req_callback_data(
2592 req, struct smbd_echo_state);
2596 written = writev_recv(req, &err);
2598 state->write_req = NULL;
2599 if (written == -1) {
2600 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2603 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2604 smbd_echo_activate_writer(state);
2607 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2610 struct smb_request req;
2611 uint16_t num_replies;
2616 if (inbuf_len < smb_size) {
2617 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2620 if (!valid_smb_header(inbuf)) {
2621 DEBUG(10, ("Got invalid SMB header\n"));
2625 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2631 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2632 smb_messages[req.cmd].name
2633 ? smb_messages[req.cmd].name : "unknown"));
2635 if (req.cmd != SMBecho) {
2642 num_replies = SVAL(req.vwv+0, 0);
2643 if (num_replies != 1) {
2644 /* Not a Windows "Hey, you're still there?" request */
2648 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2650 DEBUG(10, ("create_outbuf failed\n"));
2653 req.outbuf = (uint8_t *)outbuf;
2655 SSVAL(req.outbuf, smb_vwv0, num_replies);
2657 if (req.buflen > 0) {
2658 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2661 out_len = smb_len(req.outbuf) + 4;
2663 ok = srv_send_smb(req.sconn,
2667 TALLOC_FREE(outbuf);
2675 static void smbd_echo_exit(struct tevent_context *ev,
2676 struct tevent_fd *fde, uint16_t flags,
2679 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2683 static void smbd_echo_reader(struct tevent_context *ev,
2684 struct tevent_fd *fde, uint16_t flags,
2687 struct smbd_echo_state *state = talloc_get_type_abort(
2688 private_data, struct smbd_echo_state);
2689 struct smbd_server_connection *sconn = state->sconn;
2690 size_t unread, num_pending;
2694 uint32_t seqnum = 0;
2697 bool encrypted = false;
2701 ok = smbd_lock_socket_internal(sconn);
2703 DEBUG(0, ("%s: failed to lock socket\n",
2708 if (!fd_is_readable(sconn->sock)) {
2709 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2710 (int)sys_getpid()));
2711 ok = smbd_unlock_socket_internal(sconn);
2713 DEBUG(1, ("%s: failed to unlock socket in\n",
2720 num_pending = talloc_array_length(state->pending);
2721 tmp = talloc_realloc(state, state->pending, struct iovec,
2724 DEBUG(1, ("talloc_realloc failed\n"));
2727 state->pending = tmp;
2729 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2731 status = receive_smb_talloc(state->pending, sconn->sock,
2732 (char **)(void *)&state->pending[num_pending].iov_base,
2738 false /* trusted_channel*/);
2739 if (!NT_STATUS_IS_OK(status)) {
2740 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2741 (int)sys_getpid(), nt_errstr(status)));
2744 state->pending[num_pending].iov_len = iov_len;
2746 ok = smbd_unlock_socket_internal(sconn);
2748 DEBUG(1, ("%s: failed to unlock socket in\n",
2754 * place the seqnum in the packet so that the main process can reply
2757 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2758 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2760 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2761 state->pending[num_pending].iov_len,
2764 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2765 /* no check, shrinking by some bytes does not fail */
2766 state->pending = talloc_realloc(state, state->pending,
2770 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2771 smbd_echo_activate_writer(state);
2775 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2778 struct smbd_echo_state *state;
2780 state = talloc_zero(sconn, struct smbd_echo_state);
2781 if (state == NULL) {
2782 DEBUG(1, ("talloc failed\n"));
2785 state->sconn = sconn;
2786 state->parent_pipe = parent_pipe;
2787 state->ev = s3_tevent_context_init(state);
2788 if (state->ev == NULL) {
2789 DEBUG(1, ("tevent_context_init failed\n"));
2793 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2794 TEVENT_FD_READ, smbd_echo_exit,
2796 if (state->parent_fde == NULL) {
2797 DEBUG(1, ("tevent_add_fd failed\n"));
2801 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2802 TEVENT_FD_READ, smbd_echo_reader,
2804 if (state->read_fde == NULL) {
2805 DEBUG(1, ("tevent_add_fd failed\n"));
2811 if (tevent_loop_once(state->ev) == -1) {
2812 DEBUG(1, ("tevent_loop_once failed: %s\n",
2821 * Handle SMBecho requests in a forked child process
2823 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2825 int listener_pipe[2];
2829 res = pipe(listener_pipe);
2831 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2834 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2835 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2836 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2844 close(listener_pipe[0]);
2846 status = reinit_after_fork(sconn->msg_ctx,
2847 smbd_event_context(),
2848 procid_self(), false);
2849 if (!NT_STATUS_IS_OK(status)) {
2850 DEBUG(1, ("reinit_after_fork failed: %s\n",
2851 nt_errstr(status)));
2854 smbd_echo_loop(sconn, listener_pipe[1]);
2857 close(listener_pipe[1]);
2858 listener_pipe[1] = -1;
2859 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2861 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2864 * Without smb signing this is the same as the normal smbd
2865 * listener. This needs to change once signing comes in.
2867 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2869 sconn->smb1.echo_handler.trusted_fd,
2871 smbd_server_echo_handler,
2873 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2874 DEBUG(1, ("event_add_fd failed\n"));
2881 if (listener_pipe[0] != -1) {
2882 close(listener_pipe[0]);
2884 if (listener_pipe[1] != -1) {
2885 close(listener_pipe[1]);
2887 sconn->smb1.echo_handler.trusted_fd = -1;
2888 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2889 close(sconn->smb1.echo_handler.socket_lock_fd);
2891 sconn->smb1.echo_handler.trusted_fd = -1;
2892 sconn->smb1.echo_handler.socket_lock_fd = -1;
2898 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2899 struct sockaddr_storage *srv,
2900 struct sockaddr_storage *clnt)
2902 struct ctdbd_connection *cconn;
2903 char tmp_addr[INET6_ADDRSTRLEN];
2906 cconn = messaging_ctdbd_connection();
2907 if (cconn == NULL) {
2908 return NT_STATUS_NO_MEMORY;
2911 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2912 addr = talloc_strdup(cconn, tmp_addr);
2914 return NT_STATUS_NO_MEMORY;
2916 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2921 /****************************************************************************
2922 Process commands from the client
2923 ****************************************************************************/
2925 void smbd_process(struct smbd_server_connection *sconn)
2927 TALLOC_CTX *frame = talloc_stackframe();
2928 struct sockaddr_storage ss;
2929 struct sockaddr *sa = NULL;
2930 socklen_t sa_socklen;
2931 struct tsocket_address *local_address = NULL;
2932 struct tsocket_address *remote_address = NULL;
2933 const char *remaddr = NULL;
2936 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2937 lp_security() != SEC_SHARE &&
2938 !lp_async_smb_echo_handler()) {
2940 * We're not making the desion here,
2941 * we're just allowing the client
2942 * to decide between SMB1 and SMB2
2943 * with the first negprot
2946 sconn->using_smb2 = true;
2949 /* Ensure child is set to blocking mode */
2950 set_blocking(sconn->sock,True);
2952 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2953 set_socket_options(sconn->sock, lp_socket_options());
2955 sa = (struct sockaddr *)(void *)&ss;
2956 sa_socklen = sizeof(ss);
2957 ret = getpeername(sconn->sock, sa, &sa_socklen);
2959 int level = (errno == ENOTCONN)?2:0;
2960 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2961 exit_server_cleanly("getpeername() failed.\n");
2963 ret = tsocket_address_bsd_from_sockaddr(sconn,
2967 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2968 __location__, strerror(errno)));
2969 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2972 sa = (struct sockaddr *)(void *)&ss;
2973 sa_socklen = sizeof(ss);
2974 ret = getsockname(sconn->sock, sa, &sa_socklen);
2976 int level = (errno == ENOTCONN)?2:0;
2977 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2978 exit_server_cleanly("getsockname() failed.\n");
2980 ret = tsocket_address_bsd_from_sockaddr(sconn,
2984 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2985 __location__, strerror(errno)));
2986 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2989 sconn->local_address = local_address;
2990 sconn->remote_address = remote_address;
2992 if (tsocket_address_is_inet(remote_address, "ip")) {
2993 remaddr = tsocket_address_inet_addr_string(
2994 sconn->remote_address,
2996 if (remaddr == NULL) {
3000 remaddr = "0.0.0.0";
3003 /* this is needed so that we get decent entries
3004 in smbstatus for port 445 connects */
3005 set_remote_machine_name(remaddr, false);
3006 reload_services(sconn->msg_ctx, sconn->sock, true);
3009 * Before the first packet, check the global hosts allow/ hosts deny
3010 * parameters before doing any parsing of packets passed to us by the
3011 * client. This prevents attacks on our parsing code from hosts not in
3012 * the hosts allow list.
3015 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3016 sconn->client_id.name,
3017 sconn->client_id.addr)) {
3019 * send a negative session response "not listening on calling
3022 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3023 DEBUG( 1, ("Connection denied from %s to %s\n",
3024 tsocket_address_string(remote_address, talloc_tos()),
3025 tsocket_address_string(local_address, talloc_tos())));
3026 (void)srv_send_smb(sconn,(char *)buf, false,
3028 exit_server_cleanly("connection denied");
3031 DEBUG(10, ("Connection allowed from %s to %s\n",
3032 tsocket_address_string(remote_address, talloc_tos()),
3033 tsocket_address_string(local_address, talloc_tos())));
3037 smb_perfcount_init();
3039 if (!init_account_policy()) {
3040 exit_server("Could not open account policy tdb.\n");
3043 if (*lp_rootdir()) {
3044 if (chroot(lp_rootdir()) != 0) {
3045 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3046 exit_server("Failed to chroot()");
3048 if (chdir("/") == -1) {
3049 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3050 exit_server("Failed to chroot()");
3052 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3055 if (!srv_init_signing(sconn)) {
3056 exit_server("Failed to init smb_signing");
3059 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3060 exit_server("Failed to fork echo handler");
3064 if (!init_oplocks(sconn->msg_ctx))
3065 exit_server("Failed to init oplocks");
3067 /* register our message handlers */
3068 messaging_register(sconn->msg_ctx, NULL,
3069 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3070 messaging_register(sconn->msg_ctx, sconn,
3071 MSG_SMB_RELEASE_IP, msg_release_ip);
3072 messaging_register(sconn->msg_ctx, NULL,
3073 MSG_SMB_CLOSE_FILE, msg_close_file);
3076 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3077 * MSGs to all child processes
3079 messaging_deregister(sconn->msg_ctx,
3081 messaging_register(sconn->msg_ctx, NULL,
3082 MSG_DEBUG, debug_message);
3084 if ((lp_keepalive() != 0)
3085 && !(event_add_idle(smbd_event_context(), NULL,
3086 timeval_set(lp_keepalive(), 0),
3087 "keepalive", keepalive_fn,
3089 DEBUG(0, ("Could not add keepalive event\n"));
3093 if (!(event_add_idle(smbd_event_context(), NULL,
3094 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3095 "deadtime", deadtime_fn, sconn))) {
3096 DEBUG(0, ("Could not add deadtime event\n"));
3100 if (!(event_add_idle(smbd_event_context(), NULL,
3101 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3102 "housekeeping", housekeeping_fn, sconn))) {
3103 DEBUG(0, ("Could not add housekeeping event\n"));
3107 #ifdef CLUSTER_SUPPORT
3109 if (lp_clustering()) {
3111 * We need to tell ctdb about our client's TCP
3112 * connection, so that for failover ctdbd can send
3113 * tickle acks, triggering a reconnection by the
3117 struct sockaddr_storage srv, clnt;
3119 if (client_get_tcp_info(&srv, &clnt) == 0) {
3121 status = smbd_register_ips(sconn, &srv, &clnt);
3122 if (!NT_STATUS_IS_OK(status)) {
3123 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3124 nt_errstr(status)));
3128 DEBUG(0,("Unable to get tcp info for "
3129 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3136 sconn->nbt.got_session = false;
3138 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3140 sconn->smb1.sessions.done_sesssetup = false;
3141 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3142 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3143 /* users from session setup */
3144 sconn->smb1.sessions.session_userlist = NULL;
3145 /* workgroup from session setup. */
3146 sconn->smb1.sessions.session_workgroup = NULL;
3147 /* this holds info on user ids that are already validated for this VC */
3148 sconn->smb1.sessions.validated_users = NULL;
3149 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3150 sconn->smb1.sessions.num_validated_vuids = 0;
3153 if (!init_dptrs(sconn)) {
3154 exit_server("init_dptrs() failed");
3157 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3161 smbd_server_connection_handler,
3163 if (!sconn->smb1.fde) {
3164 exit_server("failed to create smbd_server_connection fde");
3172 frame = talloc_stackframe_pool(8192);
3176 status = smbd_server_connection_loop_once(sconn);
3177 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3178 !NT_STATUS_IS_OK(status)) {
3179 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3180 " exiting\n", nt_errstr(status)));
3187 exit_server_cleanly(NULL);
3190 bool req_is_in_chain(struct smb_request *req)
3192 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3194 * We're right now handling a subsequent request, so we must
3200 if (!is_andx_req(req->cmd)) {
3206 * Okay, an illegal request, but definitely not chained :-)
3211 return (CVAL(req->vwv+0, 0) != 0xFF);