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"
27 extern bool global_machine_password_needs_changing;
29 static void construct_reply_common(struct smb_request *req, const char *inbuf,
31 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
33 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
37 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
41 sconn->smb1.echo_handler.ref_count++;
43 if (sconn->smb1.echo_handler.ref_count > 1) {
47 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
49 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
50 SMB_F_SETLKW, 0, 0, F_WRLCK);
55 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
60 void smbd_lock_socket(struct smbd_server_connection *sconn)
62 if (!smbd_lock_socket_internal(sconn)) {
63 exit_server_cleanly("failed to lock socket");
67 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
71 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
75 sconn->smb1.echo_handler.ref_count--;
77 if (sconn->smb1.echo_handler.ref_count > 0) {
81 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
82 SMB_F_SETLKW, 0, 0, F_UNLCK);
87 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
92 void smbd_unlock_socket(struct smbd_server_connection *sconn)
94 if (!smbd_unlock_socket_internal(sconn)) {
95 exit_server_cleanly("failed to unlock socket");
99 /* Accessor function for smb_read_error for smbd functions. */
101 /****************************************************************************
103 ****************************************************************************/
105 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
106 bool do_signing, uint32_t seqnum,
108 struct smb_perfcount_data *pcd)
113 char *buf_out = buffer;
115 smbd_lock_socket(sconn);
118 /* Sign the outgoing packet if required. */
119 srv_calculate_sign_mac(sconn, buf_out, seqnum);
123 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
124 if (!NT_STATUS_IS_OK(status)) {
125 DEBUG(0, ("send_smb: SMB encryption failed "
126 "on outgoing packet! Error %s\n",
127 nt_errstr(status) ));
132 len = smb_len(buf_out) + 4;
134 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
137 char addr[INET6_ADDRSTRLEN];
139 * Try and give an error message saying what
142 DEBUG(0,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
143 (int)sys_getpid(), (int)len,
144 get_peer_addr(sconn->sock, addr, sizeof(addr)),
145 (int)ret, strerror(errno) ));
147 srv_free_enc_buffer(buf_out);
151 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
152 srv_free_enc_buffer(buf_out);
154 SMB_PERFCOUNT_END(pcd);
156 smbd_unlock_socket(sconn);
160 /*******************************************************************
161 Setup the word count and byte count for a smb message.
162 ********************************************************************/
164 int srv_set_message(char *buf,
169 if (zero && (num_words || num_bytes)) {
170 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
172 SCVAL(buf,smb_wct,num_words);
173 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
174 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
175 return (smb_size + num_words*2 + num_bytes);
178 static bool valid_smb_header(const uint8_t *inbuf)
180 if (is_encrypted_packet(inbuf)) {
184 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
185 * but it just looks weird to call strncmp for this one.
187 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
190 /* Socket functions for smbd packet processing. */
192 static bool valid_packet_size(size_t len)
195 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
196 * of header. Don't print the error if this fits.... JRA.
199 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
200 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
201 (unsigned long)len));
207 static NTSTATUS read_packet_remainder(int fd, char *buffer,
208 unsigned int timeout, ssize_t len)
216 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
217 if (!NT_STATUS_IS_OK(status)) {
218 char addr[INET6_ADDRSTRLEN];
219 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
221 get_peer_addr(fd, addr, sizeof(addr)),
227 /****************************************************************************
228 Attempt a zerocopy writeX read. We know here that len > smb_size-4
229 ****************************************************************************/
232 * Unfortunately, earlier versions of smbclient/libsmbclient
233 * don't send this "standard" writeX header. I've fixed this
234 * for 3.2 but we'll use the old method with earlier versions.
235 * Windows and CIFSFS at least use this standard size. Not
239 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
240 (2*14) + /* word count (including bcc) */ \
243 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
244 const char lenbuf[4],
245 int fd, char **buffer,
246 unsigned int timeout,
250 /* Size of a WRITEX call (+4 byte len). */
251 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
252 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
256 memcpy(writeX_header, lenbuf, 4);
258 status = read_fd_with_timeout(
259 fd, writeX_header + 4,
260 STANDARD_WRITE_AND_X_HEADER_SIZE,
261 STANDARD_WRITE_AND_X_HEADER_SIZE,
264 if (!NT_STATUS_IS_OK(status)) {
265 char addr[INET6_ADDRSTRLEN];
266 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
268 get_peer_addr(fd, addr, sizeof(addr)),
274 * Ok - now try and see if this is a possible
278 if (is_valid_writeX_buffer(smbd_server_conn,
279 (uint8_t *)writeX_header)) {
281 * If the data offset is beyond what
282 * we've read, drain the extra bytes.
284 uint16_t doff = SVAL(writeX_header,smb_vwv11);
287 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
288 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
289 if (drain_socket(fd, drain) != drain) {
290 smb_panic("receive_smb_raw_talloc_partial_read:"
291 " failed to drain pending bytes");
294 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
297 /* Spoof down the length and null out the bcc. */
298 set_message_bcc(writeX_header, 0);
299 newlen = smb_len(writeX_header);
301 /* Copy the header we've written. */
303 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
305 sizeof(writeX_header));
307 if (*buffer == NULL) {
308 DEBUG(0, ("Could not allocate inbuf of length %d\n",
309 (int)sizeof(writeX_header)));
310 return NT_STATUS_NO_MEMORY;
313 /* Work out the remaining bytes. */
314 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
315 *len_ret = newlen + 4;
319 if (!valid_packet_size(len)) {
320 return NT_STATUS_INVALID_PARAMETER;
324 * Not a valid writeX call. Just do the standard
328 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
330 if (*buffer == NULL) {
331 DEBUG(0, ("Could not allocate inbuf of length %d\n",
333 return NT_STATUS_NO_MEMORY;
336 /* Copy in what we already read. */
339 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
340 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
343 status = read_packet_remainder(
344 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
347 if (!NT_STATUS_IS_OK(status)) {
348 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
358 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
359 char **buffer, unsigned int timeout,
360 size_t *p_unread, size_t *plen)
364 int min_recv_size = lp_min_receive_file_size();
369 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
370 if (!NT_STATUS_IS_OK(status)) {
374 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
375 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
376 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
377 !srv_is_signing_active(smbd_server_conn) &&
378 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
380 return receive_smb_raw_talloc_partial_read(
381 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
384 if (!valid_packet_size(len)) {
385 return NT_STATUS_INVALID_PARAMETER;
389 * The +4 here can't wrap, we've checked the length above already.
392 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
394 if (*buffer == NULL) {
395 DEBUG(0, ("Could not allocate inbuf of length %d\n",
397 return NT_STATUS_NO_MEMORY;
400 memcpy(*buffer, lenbuf, sizeof(lenbuf));
402 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
403 if (!NT_STATUS_IS_OK(status)) {
411 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
412 char **buffer, unsigned int timeout,
413 size_t *p_unread, bool *p_encrypted,
416 bool trusted_channel)
421 *p_encrypted = false;
423 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
425 if (!NT_STATUS_IS_OK(status)) {
426 char addr[INET6_ADDRSTRLEN];
427 DEBUG(0, ("read_smb_length_return_keepalive failed for "
428 "client %s read error = %s.\n",
429 get_peer_addr(fd, addr, sizeof(addr)),
434 if (is_encrypted_packet((uint8_t *)*buffer)) {
435 status = srv_decrypt_buffer(*buffer);
436 if (!NT_STATUS_IS_OK(status)) {
437 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
438 "incoming packet! Error %s\n",
439 nt_errstr(status) ));
445 /* Check the incoming SMB signature. */
446 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
447 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
448 "incoming packet!\n"));
449 return NT_STATUS_INVALID_NETWORK_RESPONSE;
457 * Initialize a struct smb_request from an inbuf
460 static bool init_smb_request(struct smb_request *req,
461 struct smbd_server_connection *sconn,
463 size_t unread_bytes, bool encrypted,
466 size_t req_size = smb_len(inbuf) + 4;
467 /* Ensure we have at least smb_size bytes. */
468 if (req_size < smb_size) {
469 DEBUG(0,("init_smb_request: invalid request size %u\n",
470 (unsigned int)req_size ));
473 req->cmd = CVAL(inbuf, smb_com);
474 req->flags2 = SVAL(inbuf, smb_flg2);
475 req->smbpid = SVAL(inbuf, smb_pid);
476 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
477 req->seqnum = seqnum;
478 req->vuid = SVAL(inbuf, smb_uid);
479 req->tid = SVAL(inbuf, smb_tid);
480 req->wct = CVAL(inbuf, smb_wct);
481 req->vwv = (uint16_t *)(inbuf+smb_vwv);
482 req->buflen = smb_buflen(inbuf);
483 req->buf = (const uint8_t *)smb_buf(inbuf);
484 req->unread_bytes = unread_bytes;
485 req->encrypted = encrypted;
487 req->conn = conn_find(sconn,req->tid);
488 req->chain_fsp = NULL;
489 req->chain_outbuf = NULL;
492 smb_init_perfcount_data(&req->pcd);
494 /* Ensure we have at least wct words and 2 bytes of bcc. */
495 if (smb_size + req->wct*2 > req_size) {
496 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
497 (unsigned int)req->wct,
498 (unsigned int)req_size));
501 /* Ensure bcc is correct. */
502 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
503 DEBUG(0,("init_smb_request: invalid bcc number %u "
504 "(wct = %u, size %u)\n",
505 (unsigned int)req->buflen,
506 (unsigned int)req->wct,
507 (unsigned int)req_size));
515 static void process_smb(struct smbd_server_connection *conn,
516 uint8_t *inbuf, size_t nread, size_t unread_bytes,
517 uint32_t seqnum, bool encrypted,
518 struct smb_perfcount_data *deferred_pcd);
520 static void smbd_deferred_open_timer(struct event_context *ev,
521 struct timed_event *te,
522 struct timeval _tval,
525 struct pending_message_list *msg = talloc_get_type(private_data,
526 struct pending_message_list);
527 TALLOC_CTX *mem_ctx = talloc_tos();
528 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
531 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
534 exit_server("smbd_deferred_open_timer: talloc failed\n");
538 /* We leave this message on the queue so the open code can
539 know this is a retry. */
540 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
541 (unsigned long long)mid ));
543 /* Mark the message as processed so this is not
544 * re-processed in error. */
545 msg->processed = true;
547 process_smb(smbd_server_conn, inbuf,
549 msg->seqnum, msg->encrypted, &msg->pcd);
551 /* If it's still there and was processed, remove it. */
552 msg = get_deferred_open_message_smb(mid);
553 if (msg && msg->processed) {
554 remove_deferred_open_message_smb(mid);
558 /****************************************************************************
559 Function to push a message onto the tail of a linked list of smb messages ready
561 ****************************************************************************/
563 static bool push_queued_message(struct smb_request *req,
564 struct timeval request_time,
565 struct timeval end_time,
566 char *private_data, size_t private_len)
568 int msg_len = smb_len(req->inbuf) + 4;
569 struct pending_message_list *msg;
571 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
574 DEBUG(0,("push_message: malloc fail (1)\n"));
578 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
579 if(msg->buf.data == NULL) {
580 DEBUG(0,("push_message: malloc fail (2)\n"));
585 msg->request_time = request_time;
586 msg->seqnum = req->seqnum;
587 msg->encrypted = req->encrypted;
588 msg->processed = false;
589 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
592 msg->private_data = data_blob_talloc(msg, private_data,
594 if (msg->private_data.data == NULL) {
595 DEBUG(0,("push_message: malloc fail (3)\n"));
601 msg->te = event_add_timed(smbd_event_context(),
604 smbd_deferred_open_timer,
607 DEBUG(0,("push_message: event_add_timed failed\n"));
612 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
614 DEBUG(10,("push_message: pushed message length %u on "
615 "deferred_open_queue\n", (unsigned int)msg_len));
620 /****************************************************************************
621 Function to delete a sharing violation open message by mid.
622 ****************************************************************************/
624 void remove_deferred_open_message_smb(uint64_t mid)
626 struct pending_message_list *pml;
628 if (smbd_server_conn->using_smb2) {
629 remove_deferred_open_message_smb2(smbd_server_conn, mid);
633 for (pml = deferred_open_queue; pml; pml = pml->next) {
634 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
635 DEBUG(10,("remove_deferred_open_message_smb: "
636 "deleting mid %llu len %u\n",
637 (unsigned long long)mid,
638 (unsigned int)pml->buf.length ));
639 DLIST_REMOVE(deferred_open_queue, pml);
646 /****************************************************************************
647 Move a sharing violation open retry message to the front of the list and
648 schedule it for immediate processing.
649 ****************************************************************************/
651 void schedule_deferred_open_message_smb(uint64_t mid)
653 struct pending_message_list *pml;
656 if (smbd_server_conn->using_smb2) {
657 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
661 for (pml = deferred_open_queue; pml; pml = pml->next) {
662 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
664 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
667 (unsigned long long)msg_mid ));
669 if (mid == msg_mid) {
670 struct timed_event *te;
672 if (pml->processed) {
673 /* A processed message should not be
675 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
676 "message mid %llu was already processed\n",
677 (unsigned long long)msg_mid ));
681 DEBUG(10,("schedule_deferred_open_message_smb: "
682 "scheduling mid %llu\n",
683 (unsigned long long)mid ));
685 te = event_add_timed(smbd_event_context(),
688 smbd_deferred_open_timer,
691 DEBUG(10,("schedule_deferred_open_message_smb: "
692 "event_add_timed() failed, "
693 "skipping mid %llu\n",
694 (unsigned long long)msg_mid ));
697 TALLOC_FREE(pml->te);
699 DLIST_PROMOTE(deferred_open_queue, pml);
704 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
705 "find message mid %llu\n",
706 (unsigned long long)mid ));
709 /****************************************************************************
710 Return true if this mid is on the deferred queue and was not yet processed.
711 ****************************************************************************/
713 bool open_was_deferred(uint64_t mid)
715 struct pending_message_list *pml;
717 if (smbd_server_conn->using_smb2) {
718 return open_was_deferred_smb2(smbd_server_conn, mid);
721 for (pml = deferred_open_queue; pml; pml = pml->next) {
722 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
729 /****************************************************************************
730 Return the message queued by this mid.
731 ****************************************************************************/
733 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
735 struct pending_message_list *pml;
737 for (pml = deferred_open_queue; pml; pml = pml->next) {
738 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
745 /****************************************************************************
746 Get the state data queued by this mid.
747 ****************************************************************************/
749 bool get_deferred_open_message_state(struct smb_request *smbreq,
750 struct timeval *p_request_time,
753 struct pending_message_list *pml;
755 if (smbd_server_conn->using_smb2) {
756 return get_deferred_open_message_state_smb2(smbreq->smb2req,
761 pml = get_deferred_open_message_smb(smbreq->mid);
765 if (p_request_time) {
766 *p_request_time = pml->request_time;
769 *pp_state = (void *)pml->private_data.data;
774 /****************************************************************************
775 Function to push a deferred open smb message onto a linked list of local smb
776 messages ready for processing.
777 ****************************************************************************/
779 bool push_deferred_open_message_smb(struct smb_request *req,
780 struct timeval request_time,
781 struct timeval timeout,
783 char *private_data, size_t priv_len)
785 struct timeval end_time;
788 return push_deferred_open_message_smb2(req->smb2req,
796 if (req->unread_bytes) {
797 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
798 "unread_bytes = %u\n",
799 (unsigned int)req->unread_bytes ));
800 smb_panic("push_deferred_open_message_smb: "
801 "logic error unread_bytes != 0" );
804 end_time = timeval_sum(&request_time, &timeout);
806 DEBUG(10,("push_deferred_open_message_smb: pushing message "
807 "len %u mid %llu timeout time [%u.%06u]\n",
808 (unsigned int) smb_len(req->inbuf)+4,
809 (unsigned long long)req->mid,
810 (unsigned int)end_time.tv_sec,
811 (unsigned int)end_time.tv_usec));
813 return push_queued_message(req, request_time, end_time,
814 private_data, priv_len);
818 struct timed_event *te;
819 struct timeval interval;
821 bool (*handler)(const struct timeval *now, void *private_data);
825 static void smbd_idle_event_handler(struct event_context *ctx,
826 struct timed_event *te,
830 struct idle_event *event =
831 talloc_get_type_abort(private_data, struct idle_event);
833 TALLOC_FREE(event->te);
835 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
836 event->name, event->te));
838 if (!event->handler(&now, event->private_data)) {
839 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
840 event->name, event->te));
841 /* Don't repeat, delete ourselves */
846 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
847 event->name, event->te));
849 event->te = event_add_timed(ctx, event,
850 timeval_sum(&now, &event->interval),
851 smbd_idle_event_handler, event);
853 /* We can't do much but fail here. */
854 SMB_ASSERT(event->te != NULL);
857 struct idle_event *event_add_idle(struct event_context *event_ctx,
859 struct timeval interval,
861 bool (*handler)(const struct timeval *now,
865 struct idle_event *result;
866 struct timeval now = timeval_current();
868 result = TALLOC_P(mem_ctx, struct idle_event);
869 if (result == NULL) {
870 DEBUG(0, ("talloc failed\n"));
874 result->interval = interval;
875 result->handler = handler;
876 result->private_data = private_data;
878 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
879 DEBUG(0, ("talloc failed\n"));
884 result->te = event_add_timed(event_ctx, result,
885 timeval_sum(&now, &interval),
886 smbd_idle_event_handler, result);
887 if (result->te == NULL) {
888 DEBUG(0, ("event_add_timed failed\n"));
893 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
897 static void smbd_sig_term_handler(struct tevent_context *ev,
898 struct tevent_signal *se,
904 exit_server_cleanly("termination signal");
907 void smbd_setup_sig_term_handler(void)
909 struct tevent_signal *se;
911 se = tevent_add_signal(smbd_event_context(),
912 smbd_event_context(),
914 smbd_sig_term_handler,
917 exit_server("failed to setup SIGTERM handler");
921 static void smbd_sig_hup_handler(struct tevent_context *ev,
922 struct tevent_signal *se,
928 struct messaging_context *msg_ctx = talloc_get_type_abort(
929 private_data, struct messaging_context);
930 change_to_root_user();
931 DEBUG(1,("Reloading services after SIGHUP\n"));
932 reload_services(msg_ctx, smbd_server_conn->sock, False);
935 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
936 struct messaging_context *msg_ctx)
938 struct tevent_signal *se;
940 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
943 exit_server("failed to setup SIGHUP handler");
947 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
954 to.tv_sec = SMBD_SELECT_TIMEOUT;
958 * Setup the select fd sets.
965 * Are there any timed events waiting ? If so, ensure we don't
966 * select for longer than it would take to wait for them.
973 event_add_to_select_args(smbd_event_context(), &now,
974 &r_fds, &w_fds, &to, &maxfd);
977 /* Process a signal and timed events now... */
978 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
979 return NT_STATUS_RETRY;
984 START_PROFILE(smbd_idle);
986 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
989 END_PROFILE(smbd_idle);
993 if ((conn->smb1.echo_handler.trusted_fd != -1)
994 && FD_ISSET(conn->sock, &r_fds)
995 && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
997 * Prefer to read pending requests from the echo handler. To
998 * quote Jeremy (da70f8ab1): This is a hack of monstrous
1001 FD_CLR(conn->sock, &r_fds);
1004 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
1005 return NT_STATUS_RETRY;
1008 /* Check if error */
1010 /* something is wrong. Maybe the socket is dead? */
1011 return map_nt_error_from_unix(errno);
1014 /* Did we timeout ? */
1016 return NT_STATUS_RETRY;
1019 /* should not be reached */
1020 return NT_STATUS_INTERNAL_ERROR;
1024 * Only allow 5 outstanding trans requests. We're allocating memory, so
1028 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1031 for (; list != NULL; list = list->next) {
1033 if (list->mid == mid) {
1034 return NT_STATUS_INVALID_PARAMETER;
1040 return NT_STATUS_INSUFFICIENT_RESOURCES;
1043 return NT_STATUS_OK;
1047 These flags determine some of the permissions required to do an operation
1049 Note that I don't set NEED_WRITE on some write operations because they
1050 are used by some brain-dead clients when printing, and I don't want to
1051 force write permissions on print services.
1053 #define AS_USER (1<<0)
1054 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1055 #define TIME_INIT (1<<2)
1056 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1057 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1058 #define DO_CHDIR (1<<6)
1061 define a list of possible SMB messages and their corresponding
1062 functions. Any message that has a NULL function is unimplemented -
1063 please feel free to contribute implementations!
1065 static const struct smb_message_struct {
1067 void (*fn)(struct smb_request *req);
1069 } smb_messages[256] = {
1071 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1072 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1073 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1074 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1075 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1076 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1077 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1078 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1079 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1080 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1081 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1082 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1083 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1084 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1085 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1086 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1087 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1088 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1089 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1090 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1091 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1092 /* 0x15 */ { NULL, NULL, 0 },
1093 /* 0x16 */ { NULL, NULL, 0 },
1094 /* 0x17 */ { NULL, NULL, 0 },
1095 /* 0x18 */ { NULL, NULL, 0 },
1096 /* 0x19 */ { NULL, NULL, 0 },
1097 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1098 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1099 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1100 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1101 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1102 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1103 /* 0x20 */ { "SMBwritec", NULL,0},
1104 /* 0x21 */ { NULL, NULL, 0 },
1105 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1106 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1107 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1108 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1109 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1110 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1111 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1112 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1113 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1114 /* 0x2b */ { "SMBecho",reply_echo,0},
1115 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1116 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1117 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1118 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1119 /* 0x30 */ { NULL, NULL, 0 },
1120 /* 0x31 */ { NULL, NULL, 0 },
1121 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1122 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1123 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1124 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1125 /* 0x36 */ { NULL, NULL, 0 },
1126 /* 0x37 */ { NULL, NULL, 0 },
1127 /* 0x38 */ { NULL, NULL, 0 },
1128 /* 0x39 */ { NULL, NULL, 0 },
1129 /* 0x3a */ { NULL, NULL, 0 },
1130 /* 0x3b */ { NULL, NULL, 0 },
1131 /* 0x3c */ { NULL, NULL, 0 },
1132 /* 0x3d */ { NULL, NULL, 0 },
1133 /* 0x3e */ { NULL, NULL, 0 },
1134 /* 0x3f */ { NULL, NULL, 0 },
1135 /* 0x40 */ { NULL, NULL, 0 },
1136 /* 0x41 */ { NULL, NULL, 0 },
1137 /* 0x42 */ { NULL, NULL, 0 },
1138 /* 0x43 */ { NULL, NULL, 0 },
1139 /* 0x44 */ { NULL, NULL, 0 },
1140 /* 0x45 */ { NULL, NULL, 0 },
1141 /* 0x46 */ { NULL, NULL, 0 },
1142 /* 0x47 */ { NULL, NULL, 0 },
1143 /* 0x48 */ { NULL, NULL, 0 },
1144 /* 0x49 */ { NULL, NULL, 0 },
1145 /* 0x4a */ { NULL, NULL, 0 },
1146 /* 0x4b */ { NULL, NULL, 0 },
1147 /* 0x4c */ { NULL, NULL, 0 },
1148 /* 0x4d */ { NULL, NULL, 0 },
1149 /* 0x4e */ { NULL, NULL, 0 },
1150 /* 0x4f */ { NULL, NULL, 0 },
1151 /* 0x50 */ { NULL, NULL, 0 },
1152 /* 0x51 */ { NULL, NULL, 0 },
1153 /* 0x52 */ { NULL, NULL, 0 },
1154 /* 0x53 */ { NULL, NULL, 0 },
1155 /* 0x54 */ { NULL, NULL, 0 },
1156 /* 0x55 */ { NULL, NULL, 0 },
1157 /* 0x56 */ { NULL, NULL, 0 },
1158 /* 0x57 */ { NULL, NULL, 0 },
1159 /* 0x58 */ { NULL, NULL, 0 },
1160 /* 0x59 */ { NULL, NULL, 0 },
1161 /* 0x5a */ { NULL, NULL, 0 },
1162 /* 0x5b */ { NULL, NULL, 0 },
1163 /* 0x5c */ { NULL, NULL, 0 },
1164 /* 0x5d */ { NULL, NULL, 0 },
1165 /* 0x5e */ { NULL, NULL, 0 },
1166 /* 0x5f */ { NULL, NULL, 0 },
1167 /* 0x60 */ { NULL, NULL, 0 },
1168 /* 0x61 */ { NULL, NULL, 0 },
1169 /* 0x62 */ { NULL, NULL, 0 },
1170 /* 0x63 */ { NULL, NULL, 0 },
1171 /* 0x64 */ { NULL, NULL, 0 },
1172 /* 0x65 */ { NULL, NULL, 0 },
1173 /* 0x66 */ { NULL, NULL, 0 },
1174 /* 0x67 */ { NULL, NULL, 0 },
1175 /* 0x68 */ { NULL, NULL, 0 },
1176 /* 0x69 */ { NULL, NULL, 0 },
1177 /* 0x6a */ { NULL, NULL, 0 },
1178 /* 0x6b */ { NULL, NULL, 0 },
1179 /* 0x6c */ { NULL, NULL, 0 },
1180 /* 0x6d */ { NULL, NULL, 0 },
1181 /* 0x6e */ { NULL, NULL, 0 },
1182 /* 0x6f */ { NULL, NULL, 0 },
1183 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1184 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1185 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1186 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1187 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1188 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1189 /* 0x76 */ { NULL, NULL, 0 },
1190 /* 0x77 */ { NULL, NULL, 0 },
1191 /* 0x78 */ { NULL, NULL, 0 },
1192 /* 0x79 */ { NULL, NULL, 0 },
1193 /* 0x7a */ { NULL, NULL, 0 },
1194 /* 0x7b */ { NULL, NULL, 0 },
1195 /* 0x7c */ { NULL, NULL, 0 },
1196 /* 0x7d */ { NULL, NULL, 0 },
1197 /* 0x7e */ { NULL, NULL, 0 },
1198 /* 0x7f */ { NULL, NULL, 0 },
1199 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1200 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1201 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1202 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1203 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1204 /* 0x85 */ { NULL, NULL, 0 },
1205 /* 0x86 */ { NULL, NULL, 0 },
1206 /* 0x87 */ { NULL, NULL, 0 },
1207 /* 0x88 */ { NULL, NULL, 0 },
1208 /* 0x89 */ { NULL, NULL, 0 },
1209 /* 0x8a */ { NULL, NULL, 0 },
1210 /* 0x8b */ { NULL, NULL, 0 },
1211 /* 0x8c */ { NULL, NULL, 0 },
1212 /* 0x8d */ { NULL, NULL, 0 },
1213 /* 0x8e */ { NULL, NULL, 0 },
1214 /* 0x8f */ { NULL, NULL, 0 },
1215 /* 0x90 */ { NULL, NULL, 0 },
1216 /* 0x91 */ { NULL, NULL, 0 },
1217 /* 0x92 */ { NULL, NULL, 0 },
1218 /* 0x93 */ { NULL, NULL, 0 },
1219 /* 0x94 */ { NULL, NULL, 0 },
1220 /* 0x95 */ { NULL, NULL, 0 },
1221 /* 0x96 */ { NULL, NULL, 0 },
1222 /* 0x97 */ { NULL, NULL, 0 },
1223 /* 0x98 */ { NULL, NULL, 0 },
1224 /* 0x99 */ { NULL, NULL, 0 },
1225 /* 0x9a */ { NULL, NULL, 0 },
1226 /* 0x9b */ { NULL, NULL, 0 },
1227 /* 0x9c */ { NULL, NULL, 0 },
1228 /* 0x9d */ { NULL, NULL, 0 },
1229 /* 0x9e */ { NULL, NULL, 0 },
1230 /* 0x9f */ { NULL, NULL, 0 },
1231 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1232 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1233 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1234 /* 0xa3 */ { NULL, NULL, 0 },
1235 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1236 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1237 /* 0xa6 */ { NULL, NULL, 0 },
1238 /* 0xa7 */ { NULL, NULL, 0 },
1239 /* 0xa8 */ { NULL, NULL, 0 },
1240 /* 0xa9 */ { NULL, NULL, 0 },
1241 /* 0xaa */ { NULL, NULL, 0 },
1242 /* 0xab */ { NULL, NULL, 0 },
1243 /* 0xac */ { NULL, NULL, 0 },
1244 /* 0xad */ { NULL, NULL, 0 },
1245 /* 0xae */ { NULL, NULL, 0 },
1246 /* 0xaf */ { NULL, NULL, 0 },
1247 /* 0xb0 */ { NULL, NULL, 0 },
1248 /* 0xb1 */ { NULL, NULL, 0 },
1249 /* 0xb2 */ { NULL, NULL, 0 },
1250 /* 0xb3 */ { NULL, NULL, 0 },
1251 /* 0xb4 */ { NULL, NULL, 0 },
1252 /* 0xb5 */ { NULL, NULL, 0 },
1253 /* 0xb6 */ { NULL, NULL, 0 },
1254 /* 0xb7 */ { NULL, NULL, 0 },
1255 /* 0xb8 */ { NULL, NULL, 0 },
1256 /* 0xb9 */ { NULL, NULL, 0 },
1257 /* 0xba */ { NULL, NULL, 0 },
1258 /* 0xbb */ { NULL, NULL, 0 },
1259 /* 0xbc */ { NULL, NULL, 0 },
1260 /* 0xbd */ { NULL, NULL, 0 },
1261 /* 0xbe */ { NULL, NULL, 0 },
1262 /* 0xbf */ { NULL, NULL, 0 },
1263 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1264 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1265 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1266 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1267 /* 0xc4 */ { NULL, NULL, 0 },
1268 /* 0xc5 */ { NULL, NULL, 0 },
1269 /* 0xc6 */ { NULL, NULL, 0 },
1270 /* 0xc7 */ { NULL, NULL, 0 },
1271 /* 0xc8 */ { NULL, NULL, 0 },
1272 /* 0xc9 */ { NULL, NULL, 0 },
1273 /* 0xca */ { NULL, NULL, 0 },
1274 /* 0xcb */ { NULL, NULL, 0 },
1275 /* 0xcc */ { NULL, NULL, 0 },
1276 /* 0xcd */ { NULL, NULL, 0 },
1277 /* 0xce */ { NULL, NULL, 0 },
1278 /* 0xcf */ { NULL, NULL, 0 },
1279 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1280 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1281 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1282 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1283 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1284 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1285 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1286 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1287 /* 0xd8 */ { NULL, NULL, 0 },
1288 /* 0xd9 */ { NULL, NULL, 0 },
1289 /* 0xda */ { NULL, NULL, 0 },
1290 /* 0xdb */ { NULL, NULL, 0 },
1291 /* 0xdc */ { NULL, NULL, 0 },
1292 /* 0xdd */ { NULL, NULL, 0 },
1293 /* 0xde */ { NULL, NULL, 0 },
1294 /* 0xdf */ { NULL, NULL, 0 },
1295 /* 0xe0 */ { NULL, NULL, 0 },
1296 /* 0xe1 */ { NULL, NULL, 0 },
1297 /* 0xe2 */ { NULL, NULL, 0 },
1298 /* 0xe3 */ { NULL, NULL, 0 },
1299 /* 0xe4 */ { NULL, NULL, 0 },
1300 /* 0xe5 */ { NULL, NULL, 0 },
1301 /* 0xe6 */ { NULL, NULL, 0 },
1302 /* 0xe7 */ { NULL, NULL, 0 },
1303 /* 0xe8 */ { NULL, NULL, 0 },
1304 /* 0xe9 */ { NULL, NULL, 0 },
1305 /* 0xea */ { NULL, NULL, 0 },
1306 /* 0xeb */ { NULL, NULL, 0 },
1307 /* 0xec */ { NULL, NULL, 0 },
1308 /* 0xed */ { NULL, NULL, 0 },
1309 /* 0xee */ { NULL, NULL, 0 },
1310 /* 0xef */ { NULL, NULL, 0 },
1311 /* 0xf0 */ { NULL, NULL, 0 },
1312 /* 0xf1 */ { NULL, NULL, 0 },
1313 /* 0xf2 */ { NULL, NULL, 0 },
1314 /* 0xf3 */ { NULL, NULL, 0 },
1315 /* 0xf4 */ { NULL, NULL, 0 },
1316 /* 0xf5 */ { NULL, NULL, 0 },
1317 /* 0xf6 */ { NULL, NULL, 0 },
1318 /* 0xf7 */ { NULL, NULL, 0 },
1319 /* 0xf8 */ { NULL, NULL, 0 },
1320 /* 0xf9 */ { NULL, NULL, 0 },
1321 /* 0xfa */ { NULL, NULL, 0 },
1322 /* 0xfb */ { NULL, NULL, 0 },
1323 /* 0xfc */ { NULL, NULL, 0 },
1324 /* 0xfd */ { NULL, NULL, 0 },
1325 /* 0xfe */ { NULL, NULL, 0 },
1326 /* 0xff */ { NULL, NULL, 0 }
1330 /*******************************************************************
1331 allocate and initialize a reply packet
1332 ********************************************************************/
1334 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1335 const char *inbuf, char **outbuf, uint8_t num_words,
1339 * Protect against integer wrap
1341 if ((num_bytes > 0xffffff)
1342 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1344 if (asprintf(&msg, "num_bytes too large: %u",
1345 (unsigned)num_bytes) == -1) {
1346 msg = CONST_DISCARD(char *, "num_bytes too large");
1351 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1352 smb_size + num_words*2 + num_bytes);
1353 if (*outbuf == NULL) {
1357 construct_reply_common(req, inbuf, *outbuf);
1358 srv_set_message(*outbuf, num_words, num_bytes, false);
1360 * Zero out the word area, the caller has to take care of the bcc area
1363 if (num_words != 0) {
1364 memset(*outbuf + smb_vwv0, 0, num_words*2);
1370 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1373 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1375 smb_panic("could not allocate output buffer\n");
1377 req->outbuf = (uint8_t *)outbuf;
1381 /*******************************************************************
1382 Dump a packet to a file.
1383 ********************************************************************/
1385 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1389 if (DEBUGLEVEL < 50) {
1393 if (len < 4) len = smb_len(data)+4;
1394 for (i=1;i<100;i++) {
1395 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1396 type ? "req" : "resp") == -1) {
1399 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1400 if (fd != -1 || errno != EEXIST) break;
1403 ssize_t ret = write(fd, data, len);
1405 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1407 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1412 /****************************************************************************
1413 Prepare everything for calling the actual request function, and potentially
1414 call the request function via the "new" interface.
1416 Return False if the "legacy" function needs to be called, everything is
1419 Return True if we're done.
1421 I know this API sucks, but it is the one with the least code change I could
1423 ****************************************************************************/
1425 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1429 connection_struct *conn = NULL;
1430 struct smbd_server_connection *sconn = req->sconn;
1434 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1435 * so subtract 4 from it. */
1436 if (!valid_smb_header(req->inbuf)
1437 || (size < (smb_size - 4))) {
1438 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1439 smb_len(req->inbuf)));
1440 exit_server_cleanly("Non-SMB packet");
1443 if (smb_messages[type].fn == NULL) {
1444 DEBUG(0,("Unknown message type %d!\n",type));
1445 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1446 reply_unknown_new(req, type);
1450 flags = smb_messages[type].flags;
1452 /* In share mode security we must ignore the vuid. */
1453 session_tag = (lp_security() == SEC_SHARE)
1454 ? UID_FIELD_INVALID : req->vuid;
1457 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1458 (int)sys_getpid(), (unsigned long)conn));
1460 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1462 /* Ensure this value is replaced in the incoming packet. */
1463 SSVAL(req->inbuf,smb_uid,session_tag);
1466 * Ensure the correct username is in current_user_info. This is a
1467 * really ugly bugfix for problems with multiple session_setup_and_X's
1468 * being done and allowing %U and %G substitutions to work correctly.
1469 * There is a reason this code is done here, don't move it unless you
1470 * know what you're doing... :-).
1474 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1475 user_struct *vuser = NULL;
1477 sconn->smb1.sessions.last_session_tag = session_tag;
1478 if(session_tag != UID_FIELD_INVALID) {
1479 vuser = get_valid_user_struct(sconn, session_tag);
1481 set_current_user_info(
1482 vuser->server_info->sanitized_username,
1483 vuser->server_info->unix_name,
1484 vuser->server_info->info3->base.domain.string);
1489 /* Does this call need to be run as the connected user? */
1490 if (flags & AS_USER) {
1492 /* Does this call need a valid tree connection? */
1495 * Amazingly, the error code depends on the command
1498 if (type == SMBntcreateX) {
1499 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1501 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1506 if (!change_to_user(conn,session_tag)) {
1507 DEBUG(0, ("Error: Could not change to user. Removing "
1508 "deferred open, mid=%llu.\n",
1509 (unsigned long long)req->mid));
1510 reply_force_doserror(req, ERRSRV, ERRbaduid);
1514 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1516 /* Does it need write permission? */
1517 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1518 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1522 /* IPC services are limited */
1523 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1524 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1528 /* This call needs to be run as root */
1529 change_to_root_user();
1532 /* load service specific parameters */
1534 if (req->encrypted) {
1535 conn->encrypted_tid = true;
1536 /* encrypted required from now on. */
1537 conn->encrypt_level = Required;
1538 } else if (ENCRYPTION_REQUIRED(conn)) {
1539 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1540 exit_server_cleanly("encryption required "
1546 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1547 (flags & (AS_USER|DO_CHDIR)
1549 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1552 conn->num_smb_operations++;
1555 /* does this protocol need to be run as guest? */
1556 if ((flags & AS_GUEST)
1557 && (!change_to_guest() ||
1558 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1559 sconn->client_id.name,
1560 sconn->client_id.addr))) {
1561 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1565 smb_messages[type].fn(req);
1569 /****************************************************************************
1570 Construct a reply to the incoming packet.
1571 ****************************************************************************/
1573 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1574 uint32_t seqnum, bool encrypted,
1575 struct smb_perfcount_data *deferred_pcd)
1577 connection_struct *conn;
1578 struct smb_request *req;
1580 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1581 smb_panic("could not allocate smb_request");
1584 if (!init_smb_request(req, smbd_server_conn, (uint8 *)inbuf,
1585 unread_bytes, encrypted, seqnum)) {
1586 exit_server_cleanly("Invalid SMB request");
1589 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1591 /* we popped this message off the queue - keep original perf data */
1593 req->pcd = *deferred_pcd;
1595 SMB_PERFCOUNT_START(&req->pcd);
1596 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1597 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1600 conn = switch_message(req->cmd, req, size);
1602 if (req->unread_bytes) {
1603 /* writeX failed. drain socket. */
1604 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1605 req->unread_bytes) {
1606 smb_panic("failed to drain pending bytes");
1608 req->unread_bytes = 0;
1616 if (req->outbuf == NULL) {
1620 if (CVAL(req->outbuf,0) == 0) {
1621 show_msg((char *)req->outbuf);
1624 if (!srv_send_smb(req->sconn,
1625 (char *)req->outbuf,
1626 true, req->seqnum+1,
1627 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1629 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1637 /****************************************************************************
1638 Process an smb from the client
1639 ****************************************************************************/
1640 static void process_smb(struct smbd_server_connection *conn,
1641 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1642 uint32_t seqnum, bool encrypted,
1643 struct smb_perfcount_data *deferred_pcd)
1645 int msg_type = CVAL(inbuf,0);
1647 DO_PROFILE_INC(smb_count);
1649 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1651 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1652 conn->trans_num, (int)nread, (unsigned int)unread_bytes));
1654 if (msg_type != 0) {
1656 * NetBIOS session request, keepalive, etc.
1658 reply_special(conn, (char *)inbuf);
1662 if (smbd_server_conn->using_smb2) {
1663 /* At this point we're not really using smb2,
1664 * we make the decision here.. */
1665 if (smbd_is_smb2_header(inbuf, nread)) {
1666 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1668 } else if (nread >= smb_size && valid_smb_header(inbuf)
1669 && CVAL(inbuf, smb_com) != 0x72) {
1670 /* This is a non-negprot SMB1 packet.
1671 Disable SMB2 from now on. */
1672 smbd_server_conn->using_smb2 = false;
1676 show_msg((char *)inbuf);
1678 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1682 conn->smb1.num_requests++;
1684 /* The timeout_processing function isn't run nearly
1685 often enough to implement 'max log size' without
1686 overrunning the size of the file by many megabytes.
1687 This is especially true if we are running at debug
1688 level 10. Checking every 50 SMBs is a nice
1689 tradeoff of performance vs log file size overrun. */
1691 if ((conn->smb1.num_requests % 50) == 0 &&
1692 need_to_check_log_size()) {
1693 change_to_root_user();
1698 /****************************************************************************
1699 Return a string containing the function name of a SMB command.
1700 ****************************************************************************/
1702 const char *smb_fn_name(int type)
1704 const char *unknown_name = "SMBunknown";
1706 if (smb_messages[type].name == NULL)
1707 return(unknown_name);
1709 return(smb_messages[type].name);
1712 /****************************************************************************
1713 Helper functions for contruct_reply.
1714 ****************************************************************************/
1716 void add_to_common_flags2(uint32 v)
1721 void remove_from_common_flags2(uint32 v)
1723 common_flags2 &= ~v;
1726 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1729 srv_set_message(outbuf,0,0,false);
1731 SCVAL(outbuf, smb_com, req->cmd);
1732 SIVAL(outbuf,smb_rcls,0);
1733 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1734 SSVAL(outbuf,smb_flg2,
1735 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1737 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1739 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1740 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1741 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1742 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1745 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1747 construct_reply_common(req, (char *)req->inbuf, outbuf);
1751 * How many bytes have we already accumulated up to the current wct field
1755 size_t req_wct_ofs(struct smb_request *req)
1759 if (req->chain_outbuf == NULL) {
1762 buf_size = talloc_get_size(req->chain_outbuf);
1763 if ((buf_size % 4) != 0) {
1764 buf_size += (4 - (buf_size % 4));
1766 return buf_size - 4;
1770 * Hack around reply_nterror & friends not being aware of chained requests,
1771 * generating illegal (i.e. wct==0) chain replies.
1774 static void fixup_chain_error_packet(struct smb_request *req)
1776 uint8_t *outbuf = req->outbuf;
1778 reply_outbuf(req, 2, 0);
1779 memcpy(req->outbuf, outbuf, smb_wct);
1780 TALLOC_FREE(outbuf);
1781 SCVAL(req->outbuf, smb_vwv0, 0xff);
1785 * @brief Find the smb_cmd offset of the last command pushed
1786 * @param[in] buf The buffer we're building up
1787 * @retval Where can we put our next andx cmd?
1789 * While chaining requests, the "next" request we're looking at needs to put
1790 * its SMB_Command before the data the previous request already built up added
1791 * to the chain. Find the offset to the place where we have to put our cmd.
1794 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1799 cmd = CVAL(buf, smb_com);
1801 SMB_ASSERT(is_andx_req(cmd));
1805 while (CVAL(buf, ofs) != 0xff) {
1807 if (!is_andx_req(CVAL(buf, ofs))) {
1812 * ofs is from start of smb header, so add the 4 length
1813 * bytes. The next cmd is right after the wct field.
1815 ofs = SVAL(buf, ofs+2) + 4 + 1;
1817 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1825 * @brief Do the smb chaining at a buffer level
1826 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1827 * @param[in] smb_command The command that we want to issue
1828 * @param[in] wct How many words?
1829 * @param[in] vwv The words, already in network order
1830 * @param[in] bytes_alignment How shall we align "bytes"?
1831 * @param[in] num_bytes How many bytes?
1832 * @param[in] bytes The data the request ships
1834 * smb_splice_chain() adds the vwv and bytes to the request already present in
1838 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1839 uint8_t wct, const uint16_t *vwv,
1840 size_t bytes_alignment,
1841 uint32_t num_bytes, const uint8_t *bytes)
1844 size_t old_size, new_size;
1846 size_t chain_padding = 0;
1847 size_t bytes_padding = 0;
1850 old_size = talloc_get_size(*poutbuf);
1853 * old_size == smb_wct means we're pushing the first request in for
1857 first_request = (old_size == smb_wct);
1859 if (!first_request && ((old_size % 4) != 0)) {
1861 * Align the wct field of subsequent requests to a 4-byte
1864 chain_padding = 4 - (old_size % 4);
1868 * After the old request comes the new wct field (1 byte), the vwv's
1869 * and the num_bytes field. After at we might need to align the bytes
1870 * given to us to "bytes_alignment", increasing the num_bytes value.
1873 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1875 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1876 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1879 new_size += bytes_padding + num_bytes;
1881 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1882 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1883 (unsigned)new_size));
1887 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1888 if (outbuf == NULL) {
1889 DEBUG(0, ("talloc failed\n"));
1894 if (first_request) {
1895 SCVAL(outbuf, smb_com, smb_command);
1897 size_t andx_cmd_ofs;
1899 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1900 DEBUG(1, ("invalid command chain\n"));
1901 *poutbuf = TALLOC_REALLOC_ARRAY(
1902 NULL, *poutbuf, uint8_t, old_size);
1906 if (chain_padding != 0) {
1907 memset(outbuf + old_size, 0, chain_padding);
1908 old_size += chain_padding;
1911 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1912 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1918 * Push the chained request:
1923 SCVAL(outbuf, ofs, wct);
1930 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1931 ofs += sizeof(uint16_t) * wct;
1937 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1938 ofs += sizeof(uint16_t);
1944 if (bytes_padding != 0) {
1945 memset(outbuf + ofs, 0, bytes_padding);
1946 ofs += bytes_padding;
1953 memcpy(outbuf + ofs, bytes, num_bytes);
1958 /****************************************************************************
1959 Construct a chained reply and add it to the already made reply
1960 ****************************************************************************/
1962 void chain_reply(struct smb_request *req)
1964 size_t smblen = smb_len(req->inbuf);
1965 size_t already_used, length_needed;
1967 uint32_t chain_offset; /* uint32_t to avoid overflow */
1974 if (IVAL(req->outbuf, smb_rcls) != 0) {
1975 fixup_chain_error_packet(req);
1979 * Any of the AndX requests and replies have at least a wct of
1980 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1981 * beginning of the SMB header to the next wct field.
1983 * None of the AndX requests put anything valuable in vwv[0] and [1],
1984 * so we can overwrite it here to form the chain.
1987 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1988 if (req->chain_outbuf == NULL) {
1989 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1990 req, req->outbuf, uint8_t,
1991 smb_len(req->outbuf) + 4);
1992 if (req->chain_outbuf == NULL) {
1993 smb_panic("talloc failed");
2001 * Here we assume that this is the end of the chain. For that we need
2002 * to set "next command" to 0xff and the offset to 0. If we later find
2003 * more commands in the chain, this will be overwritten again.
2006 SCVAL(req->outbuf, smb_vwv0, 0xff);
2007 SCVAL(req->outbuf, smb_vwv0+1, 0);
2008 SSVAL(req->outbuf, smb_vwv1, 0);
2010 if (req->chain_outbuf == NULL) {
2012 * In req->chain_outbuf we collect all the replies. Start the
2013 * chain by copying in the first reply.
2015 * We do the realloc because later on we depend on
2016 * talloc_get_size to determine the length of
2017 * chain_outbuf. The reply_xxx routines might have
2018 * over-allocated (reply_pipe_read_and_X used to be such an
2021 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2022 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2023 if (req->chain_outbuf == NULL) {
2024 smb_panic("talloc failed");
2029 * Update smb headers where subsequent chained commands
2030 * may have updated them.
2032 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2033 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2035 if (!smb_splice_chain(&req->chain_outbuf,
2036 CVAL(req->outbuf, smb_com),
2037 CVAL(req->outbuf, smb_wct),
2038 (uint16_t *)(req->outbuf + smb_vwv),
2039 0, smb_buflen(req->outbuf),
2040 (uint8_t *)smb_buf(req->outbuf))) {
2043 TALLOC_FREE(req->outbuf);
2047 * We use the old request's vwv field to grab the next chained command
2048 * and offset into the chained fields.
2051 chain_cmd = CVAL(req->vwv+0, 0);
2052 chain_offset = SVAL(req->vwv+1, 0);
2054 if (chain_cmd == 0xff) {
2056 * End of chain, no more requests from the client. So ship the
2059 smb_setlen((char *)(req->chain_outbuf),
2060 talloc_get_size(req->chain_outbuf) - 4);
2062 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2063 true, req->seqnum+1,
2064 IS_CONN_ENCRYPTED(req->conn)
2067 exit_server_cleanly("chain_reply: srv_send_smb "
2070 TALLOC_FREE(req->chain_outbuf);
2075 /* add a new perfcounter for this element of chain */
2076 SMB_PERFCOUNT_ADD(&req->pcd);
2077 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2078 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2081 * Check if the client tries to fool us. The request so far uses the
2082 * space to the end of the byte buffer in the request just
2083 * processed. The chain_offset can't point into that area. If that was
2084 * the case, we could end up with an endless processing of the chain,
2085 * we would always handle the same request.
2088 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2089 if (chain_offset < already_used) {
2094 * Next check: Make sure the chain offset does not point beyond the
2095 * overall smb request length.
2098 length_needed = chain_offset+1; /* wct */
2099 if (length_needed > smblen) {
2104 * Now comes the pointer magic. Goal here is to set up req->vwv and
2105 * req->buf correctly again to be able to call the subsequent
2106 * switch_message(). The chain offset (the former vwv[1]) points at
2107 * the new wct field.
2110 wct = CVAL(smb_base(req->inbuf), chain_offset);
2113 * Next consistency check: Make the new vwv array fits in the overall
2117 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2118 if (length_needed > smblen) {
2121 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2124 * Now grab the new byte buffer....
2127 buflen = SVAL(vwv+wct, 0);
2130 * .. and check that it fits.
2133 length_needed += buflen;
2134 if (length_needed > smblen) {
2137 buf = (uint8_t *)(vwv+wct+1);
2139 req->cmd = chain_cmd;
2142 req->buflen = buflen;
2145 switch_message(chain_cmd, req, smblen);
2147 if (req->outbuf == NULL) {
2149 * This happens if the chained command has suspended itself or
2150 * if it has called srv_send_smb() itself.
2156 * We end up here if the chained command was not itself chained or
2157 * suspended, but for example a close() command. We now need to splice
2158 * the chained commands' outbuf into the already built up chain_outbuf
2159 * and ship the result.
2165 * We end up here if there's any error in the chain syntax. Report a
2166 * DOS error, just like Windows does.
2168 reply_force_doserror(req, ERRSRV, ERRerror);
2169 fixup_chain_error_packet(req);
2173 * This scary statement intends to set the
2174 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2175 * to the value req->outbuf carries
2177 SSVAL(req->chain_outbuf, smb_flg2,
2178 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2179 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2182 * Transfer the error codes from the subrequest to the main one
2184 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2185 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2187 if (!smb_splice_chain(&req->chain_outbuf,
2188 CVAL(req->outbuf, smb_com),
2189 CVAL(req->outbuf, smb_wct),
2190 (uint16_t *)(req->outbuf + smb_vwv),
2191 0, smb_buflen(req->outbuf),
2192 (uint8_t *)smb_buf(req->outbuf))) {
2193 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2195 TALLOC_FREE(req->outbuf);
2197 smb_setlen((char *)(req->chain_outbuf),
2198 talloc_get_size(req->chain_outbuf) - 4);
2200 show_msg((char *)(req->chain_outbuf));
2202 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2203 true, req->seqnum+1,
2204 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2206 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2208 TALLOC_FREE(req->chain_outbuf);
2212 /****************************************************************************
2213 Check if services need reloading.
2214 ****************************************************************************/
2216 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2218 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2220 if(last_smb_conf_reload_time == 0) {
2221 last_smb_conf_reload_time = t;
2222 /* Our printing subsystem might not be ready at smbd start up.
2223 Then no printer is available till the first printers check
2224 is performed. A lower initial interval circumvents this. */
2225 if ( printcap_cache_time > 60 )
2226 last_printer_reload_time = t - printcap_cache_time + 60;
2228 last_printer_reload_time = t;
2231 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2232 /* randomize over 60 second the printcap reload to avoid all
2233 * process hitting cupsd at the same time */
2234 int time_range = 60;
2236 last_printer_reload_time += random() % time_range;
2240 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2241 reload_services(sconn->msg_ctx, sconn->sock, True);
2242 last_smb_conf_reload_time = t;
2245 /* 'printcap cache time = 0' disable the feature */
2247 if ( printcap_cache_time != 0 )
2249 /* see if it's time to reload or if the clock has been set back */
2251 if ( (t >= last_printer_reload_time+printcap_cache_time)
2252 || (t-last_printer_reload_time < 0) )
2254 DEBUG( 3,( "Printcap cache time expired.\n"));
2255 reload_printers(sconn->msg_ctx);
2256 last_printer_reload_time = t;
2261 static bool fd_is_readable(int fd)
2264 struct timeval timeout = {0, };
2270 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2274 return FD_ISSET(fd, &fds);
2277 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2279 /* TODO: make write nonblocking */
2282 static void smbd_server_connection_read_handler(
2283 struct smbd_server_connection *conn, int fd)
2285 uint8_t *inbuf = NULL;
2286 size_t inbuf_len = 0;
2287 size_t unread_bytes = 0;
2288 bool encrypted = false;
2289 TALLOC_CTX *mem_ctx = talloc_tos();
2293 bool from_client = (conn->sock == fd);
2296 smbd_lock_socket(conn);
2298 if (!fd_is_readable(fd)) {
2299 DEBUG(10,("the echo listener was faster\n"));
2300 smbd_unlock_socket(conn);
2304 /* TODO: make this completely nonblocking */
2305 status = receive_smb_talloc(mem_ctx, fd,
2306 (char **)(void *)&inbuf,
2310 &inbuf_len, &seqnum,
2311 false /* trusted channel */);
2312 smbd_unlock_socket(conn);
2314 /* TODO: make this completely nonblocking */
2315 status = receive_smb_talloc(mem_ctx, fd,
2316 (char **)(void *)&inbuf,
2320 &inbuf_len, &seqnum,
2321 true /* trusted channel */);
2324 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2327 if (NT_STATUS_IS_ERR(status)) {
2328 exit_server_cleanly("failed to receive smb request");
2330 if (!NT_STATUS_IS_OK(status)) {
2335 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2336 seqnum, encrypted, NULL);
2339 static void smbd_server_connection_handler(struct event_context *ev,
2340 struct fd_event *fde,
2344 struct smbd_server_connection *conn = talloc_get_type(private_data,
2345 struct smbd_server_connection);
2347 if (flags & EVENT_FD_WRITE) {
2348 smbd_server_connection_write_handler(conn);
2351 if (flags & EVENT_FD_READ) {
2352 smbd_server_connection_read_handler(conn, conn->sock);
2357 static void smbd_server_echo_handler(struct event_context *ev,
2358 struct fd_event *fde,
2362 struct smbd_server_connection *conn = talloc_get_type(private_data,
2363 struct smbd_server_connection);
2365 if (flags & EVENT_FD_WRITE) {
2366 smbd_server_connection_write_handler(conn);
2369 if (flags & EVENT_FD_READ) {
2370 smbd_server_connection_read_handler(
2371 conn, conn->smb1.echo_handler.trusted_fd);
2376 /****************************************************************************
2377 received when we should release a specific IP
2378 ****************************************************************************/
2379 static void release_ip(const char *ip, void *priv)
2381 const char *addr = (const char *)priv;
2382 const char *p = addr;
2384 if (strncmp("::ffff:", addr, 7) == 0) {
2388 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2389 /* we can't afford to do a clean exit - that involves
2390 database writes, which would potentially mean we
2391 are still running after the failover has finished -
2392 we have to get rid of this process ID straight
2394 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2396 /* note we must exit with non-zero status so the unclean handler gets
2397 called in the parent, so that the brl database is tickled */
2402 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2403 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2405 struct smbd_server_connection *sconn = talloc_get_type_abort(
2406 private_data, struct smbd_server_connection);
2408 release_ip((char *)data->data, sconn->client_id.addr);
2411 #ifdef CLUSTER_SUPPORT
2412 static int client_get_tcp_info(struct sockaddr_storage *server,
2413 struct sockaddr_storage *client)
2416 if (server_fd == -1) {
2419 length = sizeof(*server);
2420 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2423 length = sizeof(*client);
2424 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2432 * Send keepalive packets to our client
2434 static bool keepalive_fn(const struct timeval *now, void *private_data)
2436 struct smbd_server_connection *sconn = smbd_server_conn;
2439 if (sconn->using_smb2) {
2440 /* Don't do keepalives on an SMB2 connection. */
2444 smbd_lock_socket(smbd_server_conn);
2445 ret = send_keepalive(sconn->sock);
2446 smbd_unlock_socket(smbd_server_conn);
2449 char addr[INET6_ADDRSTRLEN];
2451 * Try and give an error message saying what
2454 DEBUG(0, ("send_keepalive failed for client %s. "
2455 "Error %s - exiting\n",
2456 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2464 * Do the recurring check if we're idle
2466 static bool deadtime_fn(const struct timeval *now, void *private_data)
2468 struct smbd_server_connection *sconn =
2469 (struct smbd_server_connection *)private_data;
2471 if (sconn->using_smb2) {
2472 /* TODO: implement real idle check */
2473 if (sconn->smb2.sessions.list) {
2476 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2477 messaging_send(sconn->msg_ctx, procid_self(),
2478 MSG_SHUTDOWN, &data_blob_null);
2482 if ((conn_num_open(sconn) == 0)
2483 || (conn_idle_all(sconn, now->tv_sec))) {
2484 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2485 messaging_send(sconn->msg_ctx, procid_self(),
2486 MSG_SHUTDOWN, &data_blob_null);
2494 * Do the recurring log file and smb.conf reload checks.
2497 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2499 struct smbd_server_connection *sconn = talloc_get_type_abort(
2500 private_data, struct smbd_server_connection);
2501 change_to_root_user();
2503 /* update printer queue caches if necessary */
2504 update_monitored_printq_cache(sconn->msg_ctx);
2506 /* check if we need to reload services */
2507 check_reload(sconn, time(NULL));
2509 /* Change machine password if neccessary. */
2510 attempt_machine_password_change();
2513 * Force a log file check.
2515 force_check_log_size();
2520 static int create_unlink_tmp(const char *dir)
2525 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2526 if (fname == NULL) {
2530 fd = mkstemp(fname);
2535 if (unlink(fname) == -1) {
2536 int sys_errno = errno;
2546 struct smbd_echo_state {
2547 struct tevent_context *ev;
2548 struct iovec *pending;
2549 struct smbd_server_connection *sconn;
2552 struct tevent_fd *parent_fde;
2554 struct tevent_fd *read_fde;
2555 struct tevent_req *write_req;
2558 static void smbd_echo_writer_done(struct tevent_req *req);
2560 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2564 if (state->write_req != NULL) {
2568 num_pending = talloc_array_length(state->pending);
2569 if (num_pending == 0) {
2573 state->write_req = writev_send(state, state->ev, NULL,
2574 state->parent_pipe, false,
2575 state->pending, num_pending);
2576 if (state->write_req == NULL) {
2577 DEBUG(1, ("writev_send failed\n"));
2581 talloc_steal(state->write_req, state->pending);
2582 state->pending = NULL;
2584 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2588 static void smbd_echo_writer_done(struct tevent_req *req)
2590 struct smbd_echo_state *state = tevent_req_callback_data(
2591 req, struct smbd_echo_state);
2595 written = writev_recv(req, &err);
2597 state->write_req = NULL;
2598 if (written == -1) {
2599 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2602 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2603 smbd_echo_activate_writer(state);
2606 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2609 struct smb_request req;
2610 uint16_t num_replies;
2615 if (inbuf_len < smb_size) {
2616 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2619 if (!valid_smb_header(inbuf)) {
2620 DEBUG(10, ("Got invalid SMB header\n"));
2624 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2630 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2631 smb_messages[req.cmd].name
2632 ? smb_messages[req.cmd].name : "unknown"));
2634 if (req.cmd != SMBecho) {
2641 num_replies = SVAL(req.vwv+0, 0);
2642 if (num_replies != 1) {
2643 /* Not a Windows "Hey, you're still there?" request */
2647 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2649 DEBUG(10, ("create_outbuf failed\n"));
2652 req.outbuf = (uint8_t *)outbuf;
2654 SSVAL(req.outbuf, smb_vwv0, num_replies);
2656 if (req.buflen > 0) {
2657 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2660 out_len = smb_len(req.outbuf) + 4;
2662 ok = srv_send_smb(req.sconn,
2666 TALLOC_FREE(outbuf);
2674 static void smbd_echo_exit(struct tevent_context *ev,
2675 struct tevent_fd *fde, uint16_t flags,
2678 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2682 static void smbd_echo_reader(struct tevent_context *ev,
2683 struct tevent_fd *fde, uint16_t flags,
2686 struct smbd_echo_state *state = talloc_get_type_abort(
2687 private_data, struct smbd_echo_state);
2688 struct smbd_server_connection *sconn = state->sconn;
2689 size_t unread, num_pending;
2693 uint32_t seqnum = 0;
2696 bool encrypted = false;
2700 ok = smbd_lock_socket_internal(sconn);
2702 DEBUG(0, ("%s: failed to lock socket\n",
2707 if (!fd_is_readable(sconn->sock)) {
2708 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2709 (int)sys_getpid()));
2710 ok = smbd_unlock_socket_internal(sconn);
2712 DEBUG(1, ("%s: failed to unlock socket in\n",
2719 num_pending = talloc_array_length(state->pending);
2720 tmp = talloc_realloc(state, state->pending, struct iovec,
2723 DEBUG(1, ("talloc_realloc failed\n"));
2726 state->pending = tmp;
2728 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2730 status = receive_smb_talloc(state->pending, sconn->sock,
2731 (char **)(void *)&state->pending[num_pending].iov_base,
2737 false /* trusted_channel*/);
2738 if (!NT_STATUS_IS_OK(status)) {
2739 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2740 (int)sys_getpid(), nt_errstr(status)));
2743 state->pending[num_pending].iov_len = iov_len;
2745 ok = smbd_unlock_socket_internal(sconn);
2747 DEBUG(1, ("%s: failed to unlock socket in\n",
2753 * place the seqnum in the packet so that the main process can reply
2756 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2757 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2759 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2760 state->pending[num_pending].iov_len,
2763 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2764 /* no check, shrinking by some bytes does not fail */
2765 state->pending = talloc_realloc(state, state->pending,
2769 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2770 smbd_echo_activate_writer(state);
2774 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2777 struct smbd_echo_state *state;
2779 state = talloc_zero(sconn, struct smbd_echo_state);
2780 if (state == NULL) {
2781 DEBUG(1, ("talloc failed\n"));
2784 state->sconn = sconn;
2785 state->parent_pipe = parent_pipe;
2786 state->ev = s3_tevent_context_init(state);
2787 if (state->ev == NULL) {
2788 DEBUG(1, ("tevent_context_init failed\n"));
2792 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2793 TEVENT_FD_READ, smbd_echo_exit,
2795 if (state->parent_fde == NULL) {
2796 DEBUG(1, ("tevent_add_fd failed\n"));
2800 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2801 TEVENT_FD_READ, smbd_echo_reader,
2803 if (state->read_fde == NULL) {
2804 DEBUG(1, ("tevent_add_fd failed\n"));
2810 if (tevent_loop_once(state->ev) == -1) {
2811 DEBUG(1, ("tevent_loop_once failed: %s\n",
2820 * Handle SMBecho requests in a forked child process
2822 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2824 int listener_pipe[2];
2828 res = pipe(listener_pipe);
2830 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2833 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2834 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2835 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2843 close(listener_pipe[0]);
2845 status = reinit_after_fork(sconn->msg_ctx,
2846 smbd_event_context(),
2847 procid_self(), false);
2848 if (!NT_STATUS_IS_OK(status)) {
2849 DEBUG(1, ("reinit_after_fork failed: %s\n",
2850 nt_errstr(status)));
2853 smbd_echo_loop(sconn, listener_pipe[1]);
2856 close(listener_pipe[1]);
2857 listener_pipe[1] = -1;
2858 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2860 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2863 * Without smb signing this is the same as the normal smbd
2864 * listener. This needs to change once signing comes in.
2866 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2868 sconn->smb1.echo_handler.trusted_fd,
2870 smbd_server_echo_handler,
2872 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2873 DEBUG(1, ("event_add_fd failed\n"));
2880 if (listener_pipe[0] != -1) {
2881 close(listener_pipe[0]);
2883 if (listener_pipe[1] != -1) {
2884 close(listener_pipe[1]);
2886 sconn->smb1.echo_handler.trusted_fd = -1;
2887 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2888 close(sconn->smb1.echo_handler.socket_lock_fd);
2890 sconn->smb1.echo_handler.trusted_fd = -1;
2891 sconn->smb1.echo_handler.socket_lock_fd = -1;
2897 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2898 struct sockaddr_storage *srv,
2899 struct sockaddr_storage *clnt)
2901 struct ctdbd_connection *cconn;
2902 char tmp_addr[INET6_ADDRSTRLEN];
2905 cconn = messaging_ctdbd_connection();
2906 if (cconn == NULL) {
2907 return NT_STATUS_NO_MEMORY;
2910 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2911 addr = talloc_strdup(cconn, tmp_addr);
2913 return NT_STATUS_NO_MEMORY;
2915 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2920 /****************************************************************************
2921 Process commands from the client
2922 ****************************************************************************/
2924 void smbd_process(struct smbd_server_connection *sconn)
2926 TALLOC_CTX *frame = talloc_stackframe();
2927 struct sockaddr_storage ss;
2928 struct sockaddr *sa = NULL;
2929 socklen_t sa_socklen;
2930 struct tsocket_address *local_address = NULL;
2931 struct tsocket_address *remote_address = NULL;
2932 const char *remaddr = NULL;
2935 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2936 lp_security() != SEC_SHARE &&
2937 !lp_async_smb_echo_handler()) {
2939 * We're not making the desion here,
2940 * we're just allowing the client
2941 * to decide between SMB1 and SMB2
2942 * with the first negprot
2945 sconn->using_smb2 = true;
2948 /* Ensure child is set to blocking mode */
2949 set_blocking(sconn->sock,True);
2951 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2952 set_socket_options(sconn->sock, lp_socket_options());
2954 sa = (struct sockaddr *)(void *)&ss;
2955 sa_socklen = sizeof(ss);
2956 ret = getpeername(sconn->sock, sa, &sa_socklen);
2958 int level = (errno == ENOTCONN)?2:0;
2959 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2960 exit_server_cleanly("getpeername() failed.\n");
2962 ret = tsocket_address_bsd_from_sockaddr(sconn,
2966 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2967 __location__, strerror(errno)));
2968 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2971 sa = (struct sockaddr *)(void *)&ss;
2972 sa_socklen = sizeof(ss);
2973 ret = getsockname(sconn->sock, sa, &sa_socklen);
2975 int level = (errno == ENOTCONN)?2:0;
2976 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2977 exit_server_cleanly("getsockname() failed.\n");
2979 ret = tsocket_address_bsd_from_sockaddr(sconn,
2983 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2984 __location__, strerror(errno)));
2985 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2988 sconn->local_address = local_address;
2989 sconn->remote_address = remote_address;
2991 if (tsocket_address_is_inet(remote_address, "ip")) {
2992 remaddr = tsocket_address_inet_addr_string(
2993 sconn->remote_address,
2995 if (remaddr == NULL) {
2999 remaddr = "0.0.0.0";
3002 /* this is needed so that we get decent entries
3003 in smbstatus for port 445 connects */
3004 set_remote_machine_name(remaddr, false);
3005 reload_services(sconn->msg_ctx, sconn->sock, true);
3008 * Before the first packet, check the global hosts allow/ hosts deny
3009 * parameters before doing any parsing of packets passed to us by the
3010 * client. This prevents attacks on our parsing code from hosts not in
3011 * the hosts allow list.
3014 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3015 sconn->client_id.name,
3016 sconn->client_id.addr)) {
3018 * send a negative session response "not listening on calling
3021 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3022 DEBUG( 1, ("Connection denied from %s to %s\n",
3023 tsocket_address_string(remote_address, talloc_tos()),
3024 tsocket_address_string(local_address, talloc_tos())));
3025 (void)srv_send_smb(sconn,(char *)buf, false,
3027 exit_server_cleanly("connection denied");
3030 DEBUG(10, ("Connection allowed from %s to %s\n",
3031 tsocket_address_string(remote_address, talloc_tos()),
3032 tsocket_address_string(local_address, talloc_tos())));
3036 smb_perfcount_init();
3038 if (!init_account_policy()) {
3039 exit_server("Could not open account policy tdb.\n");
3042 if (*lp_rootdir()) {
3043 if (chroot(lp_rootdir()) != 0) {
3044 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3045 exit_server("Failed to chroot()");
3047 if (chdir("/") == -1) {
3048 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3049 exit_server("Failed to chroot()");
3051 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3054 if (!srv_init_signing(sconn)) {
3055 exit_server("Failed to init smb_signing");
3058 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3059 exit_server("Failed to fork echo handler");
3063 if (!init_oplocks(sconn->msg_ctx))
3064 exit_server("Failed to init oplocks");
3066 /* register our message handlers */
3067 messaging_register(sconn->msg_ctx, NULL,
3068 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3069 messaging_register(sconn->msg_ctx, sconn,
3070 MSG_SMB_RELEASE_IP, msg_release_ip);
3071 messaging_register(sconn->msg_ctx, NULL,
3072 MSG_SMB_CLOSE_FILE, msg_close_file);
3075 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3076 * MSGs to all child processes
3078 messaging_deregister(sconn->msg_ctx,
3080 messaging_register(sconn->msg_ctx, NULL,
3081 MSG_DEBUG, debug_message);
3083 if ((lp_keepalive() != 0)
3084 && !(event_add_idle(smbd_event_context(), NULL,
3085 timeval_set(lp_keepalive(), 0),
3086 "keepalive", keepalive_fn,
3088 DEBUG(0, ("Could not add keepalive event\n"));
3092 if (!(event_add_idle(smbd_event_context(), NULL,
3093 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3094 "deadtime", deadtime_fn, sconn))) {
3095 DEBUG(0, ("Could not add deadtime event\n"));
3099 if (!(event_add_idle(smbd_event_context(), NULL,
3100 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3101 "housekeeping", housekeeping_fn, sconn))) {
3102 DEBUG(0, ("Could not add housekeeping event\n"));
3106 #ifdef CLUSTER_SUPPORT
3108 if (lp_clustering()) {
3110 * We need to tell ctdb about our client's TCP
3111 * connection, so that for failover ctdbd can send
3112 * tickle acks, triggering a reconnection by the
3116 struct sockaddr_storage srv, clnt;
3118 if (client_get_tcp_info(&srv, &clnt) == 0) {
3120 status = smbd_register_ips(sconn, &srv, &clnt);
3121 if (!NT_STATUS_IS_OK(status)) {
3122 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3123 nt_errstr(status)));
3127 DEBUG(0,("Unable to get tcp info for "
3128 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3135 sconn->nbt.got_session = false;
3137 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3139 sconn->smb1.sessions.done_sesssetup = false;
3140 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3141 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3142 /* users from session setup */
3143 sconn->smb1.sessions.session_userlist = NULL;
3144 /* workgroup from session setup. */
3145 sconn->smb1.sessions.session_workgroup = NULL;
3146 /* this holds info on user ids that are already validated for this VC */
3147 sconn->smb1.sessions.validated_users = NULL;
3148 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3149 sconn->smb1.sessions.num_validated_vuids = 0;
3152 if (!init_dptrs(sconn)) {
3153 exit_server("init_dptrs() failed");
3156 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3160 smbd_server_connection_handler,
3162 if (!sconn->smb1.fde) {
3163 exit_server("failed to create smbd_server_connection fde");
3171 frame = talloc_stackframe_pool(8192);
3175 status = smbd_server_connection_loop_once(sconn);
3176 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3177 !NT_STATUS_IS_OK(status)) {
3178 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3179 " exiting\n", nt_errstr(status)));
3186 exit_server_cleanly(NULL);
3189 bool req_is_in_chain(struct smb_request *req)
3191 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3193 * We're right now handling a subsequent request, so we must
3199 if (!is_andx_req(req->cmd)) {
3205 * Okay, an illegal request, but definitely not chained :-)
3210 return (CVAL(req->vwv+0, 0) != 0xFF);