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"
27 #include "../lib/util/select.h"
29 extern bool global_machine_password_needs_changing;
31 static void construct_reply_common(struct smb_request *req, const char *inbuf,
33 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
35 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
39 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
43 sconn->smb1.echo_handler.ref_count++;
45 if (sconn->smb1.echo_handler.ref_count > 1) {
49 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
53 sconn->smb1.echo_handler.socket_lock_fd,
54 SMB_F_SETLKW, 0, 0, F_WRLCK);
55 } while (!ok && (errno == EINTR));
58 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
62 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
67 void smbd_lock_socket(struct smbd_server_connection *sconn)
69 if (!smbd_lock_socket_internal(sconn)) {
70 exit_server_cleanly("failed to lock socket");
74 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
78 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
82 sconn->smb1.echo_handler.ref_count--;
84 if (sconn->smb1.echo_handler.ref_count > 0) {
90 sconn->smb1.echo_handler.socket_lock_fd,
91 SMB_F_SETLKW, 0, 0, F_UNLCK);
92 } while (!ok && (errno == EINTR));
95 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
99 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
104 void smbd_unlock_socket(struct smbd_server_connection *sconn)
106 if (!smbd_unlock_socket_internal(sconn)) {
107 exit_server_cleanly("failed to unlock socket");
111 /* Accessor function for smb_read_error for smbd functions. */
113 /****************************************************************************
115 ****************************************************************************/
117 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
118 bool do_signing, uint32_t seqnum,
120 struct smb_perfcount_data *pcd)
125 char *buf_out = buffer;
127 smbd_lock_socket(sconn);
130 /* Sign the outgoing packet if required. */
131 srv_calculate_sign_mac(sconn, buf_out, seqnum);
135 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
136 if (!NT_STATUS_IS_OK(status)) {
137 DEBUG(0, ("send_smb: SMB encryption failed "
138 "on outgoing packet! Error %s\n",
139 nt_errstr(status) ));
144 len = smb_len(buf_out) + 4;
146 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
149 char addr[INET6_ADDRSTRLEN];
151 * Try and give an error message saying what
154 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
155 (int)sys_getpid(), (int)len,
156 get_peer_addr(sconn->sock, addr, sizeof(addr)),
157 (int)ret, strerror(errno) ));
159 srv_free_enc_buffer(buf_out);
163 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
164 srv_free_enc_buffer(buf_out);
166 SMB_PERFCOUNT_END(pcd);
168 smbd_unlock_socket(sconn);
172 /*******************************************************************
173 Setup the word count and byte count for a smb message.
174 ********************************************************************/
176 int srv_set_message(char *buf,
181 if (zero && (num_words || num_bytes)) {
182 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
184 SCVAL(buf,smb_wct,num_words);
185 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
186 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
187 return (smb_size + num_words*2 + num_bytes);
190 static bool valid_smb_header(const uint8_t *inbuf)
192 if (is_encrypted_packet(inbuf)) {
196 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
197 * but it just looks weird to call strncmp for this one.
199 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
202 /* Socket functions for smbd packet processing. */
204 static bool valid_packet_size(size_t len)
207 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
208 * of header. Don't print the error if this fits.... JRA.
211 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
212 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
213 (unsigned long)len));
219 static NTSTATUS read_packet_remainder(int fd, char *buffer,
220 unsigned int timeout, ssize_t len)
228 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
229 if (!NT_STATUS_IS_OK(status)) {
230 char addr[INET6_ADDRSTRLEN];
231 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
233 get_peer_addr(fd, addr, sizeof(addr)),
239 /****************************************************************************
240 Attempt a zerocopy writeX read. We know here that len > smb_size-4
241 ****************************************************************************/
244 * Unfortunately, earlier versions of smbclient/libsmbclient
245 * don't send this "standard" writeX header. I've fixed this
246 * for 3.2 but we'll use the old method with earlier versions.
247 * Windows and CIFSFS at least use this standard size. Not
251 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
252 (2*14) + /* word count (including bcc) */ \
255 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
256 const char lenbuf[4],
257 struct smbd_server_connection *sconn,
259 unsigned int timeout,
263 /* Size of a WRITEX call (+4 byte len). */
264 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
265 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
269 memcpy(writeX_header, lenbuf, 4);
271 status = read_fd_with_timeout(
272 sconn->sock, writeX_header + 4,
273 STANDARD_WRITE_AND_X_HEADER_SIZE,
274 STANDARD_WRITE_AND_X_HEADER_SIZE,
277 if (!NT_STATUS_IS_OK(status)) {
278 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
279 "error = %s.\n", sconn->client_id.addr,
285 * Ok - now try and see if this is a possible
289 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
291 * If the data offset is beyond what
292 * we've read, drain the extra bytes.
294 uint16_t doff = SVAL(writeX_header,smb_vwv11);
297 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
298 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
299 if (drain_socket(sconn->sock, drain) != drain) {
300 smb_panic("receive_smb_raw_talloc_partial_read:"
301 " failed to drain pending bytes");
304 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
307 /* Spoof down the length and null out the bcc. */
308 set_message_bcc(writeX_header, 0);
309 newlen = smb_len(writeX_header);
311 /* Copy the header we've written. */
313 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
315 sizeof(writeX_header));
317 if (*buffer == NULL) {
318 DEBUG(0, ("Could not allocate inbuf of length %d\n",
319 (int)sizeof(writeX_header)));
320 return NT_STATUS_NO_MEMORY;
323 /* Work out the remaining bytes. */
324 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
325 *len_ret = newlen + 4;
329 if (!valid_packet_size(len)) {
330 return NT_STATUS_INVALID_PARAMETER;
334 * Not a valid writeX call. Just do the standard
338 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
340 if (*buffer == NULL) {
341 DEBUG(0, ("Could not allocate inbuf of length %d\n",
343 return NT_STATUS_NO_MEMORY;
346 /* Copy in what we already read. */
349 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
350 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
353 status = read_packet_remainder(
355 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
358 if (!NT_STATUS_IS_OK(status)) {
359 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
369 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
370 struct smbd_server_connection *sconn,
371 char **buffer, unsigned int timeout,
372 size_t *p_unread, size_t *plen)
376 int min_recv_size = lp_min_receive_file_size();
381 status = read_smb_length_return_keepalive(sconn->sock, lenbuf, timeout,
383 if (!NT_STATUS_IS_OK(status)) {
387 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
388 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
389 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
390 !srv_is_signing_active(sconn) &&
391 sconn->smb1.echo_handler.trusted_fde == NULL) {
393 return receive_smb_raw_talloc_partial_read(
394 mem_ctx, lenbuf, sconn, buffer, timeout,
398 if (!valid_packet_size(len)) {
399 return NT_STATUS_INVALID_PARAMETER;
403 * The +4 here can't wrap, we've checked the length above already.
406 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
408 if (*buffer == NULL) {
409 DEBUG(0, ("Could not allocate inbuf of length %d\n",
411 return NT_STATUS_NO_MEMORY;
414 memcpy(*buffer, lenbuf, sizeof(lenbuf));
416 status = read_packet_remainder(sconn->sock, (*buffer)+4, timeout, len);
417 if (!NT_STATUS_IS_OK(status)) {
425 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
426 struct smbd_server_connection *sconn,
427 char **buffer, unsigned int timeout,
428 size_t *p_unread, bool *p_encrypted,
431 bool trusted_channel)
436 *p_encrypted = false;
438 status = receive_smb_raw_talloc(mem_ctx, sconn, buffer, timeout,
440 if (!NT_STATUS_IS_OK(status)) {
441 DEBUG(1, ("read_smb_length_return_keepalive failed for "
442 "client %s read error = %s.\n",
443 sconn->client_id.addr, nt_errstr(status)));
447 if (is_encrypted_packet((uint8_t *)*buffer)) {
448 status = srv_decrypt_buffer(*buffer);
449 if (!NT_STATUS_IS_OK(status)) {
450 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
451 "incoming packet! Error %s\n",
452 nt_errstr(status) ));
458 /* Check the incoming SMB signature. */
459 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
460 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
461 "incoming packet!\n"));
462 return NT_STATUS_INVALID_NETWORK_RESPONSE;
470 * Initialize a struct smb_request from an inbuf
473 static bool init_smb_request(struct smb_request *req,
474 struct smbd_server_connection *sconn,
476 size_t unread_bytes, bool encrypted,
479 size_t req_size = smb_len(inbuf) + 4;
480 /* Ensure we have at least smb_size bytes. */
481 if (req_size < smb_size) {
482 DEBUG(0,("init_smb_request: invalid request size %u\n",
483 (unsigned int)req_size ));
486 req->cmd = CVAL(inbuf, smb_com);
487 req->flags2 = SVAL(inbuf, smb_flg2);
488 req->smbpid = SVAL(inbuf, smb_pid);
489 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
490 req->seqnum = seqnum;
491 req->vuid = SVAL(inbuf, smb_uid);
492 req->tid = SVAL(inbuf, smb_tid);
493 req->wct = CVAL(inbuf, smb_wct);
494 req->vwv = (uint16_t *)(inbuf+smb_vwv);
495 req->buflen = smb_buflen(inbuf);
496 req->buf = (const uint8_t *)smb_buf(inbuf);
497 req->unread_bytes = unread_bytes;
498 req->encrypted = encrypted;
500 req->conn = conn_find(sconn,req->tid);
501 req->chain_fsp = NULL;
502 req->chain_outbuf = NULL;
505 smb_init_perfcount_data(&req->pcd);
507 /* Ensure we have at least wct words and 2 bytes of bcc. */
508 if (smb_size + req->wct*2 > req_size) {
509 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
510 (unsigned int)req->wct,
511 (unsigned int)req_size));
514 /* Ensure bcc is correct. */
515 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
516 DEBUG(0,("init_smb_request: invalid bcc number %u "
517 "(wct = %u, size %u)\n",
518 (unsigned int)req->buflen,
519 (unsigned int)req->wct,
520 (unsigned int)req_size));
528 static void process_smb(struct smbd_server_connection *conn,
529 uint8_t *inbuf, size_t nread, size_t unread_bytes,
530 uint32_t seqnum, bool encrypted,
531 struct smb_perfcount_data *deferred_pcd);
533 static void smbd_deferred_open_timer(struct event_context *ev,
534 struct timed_event *te,
535 struct timeval _tval,
538 struct pending_message_list *msg = talloc_get_type(private_data,
539 struct pending_message_list);
540 TALLOC_CTX *mem_ctx = talloc_tos();
541 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
544 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
547 exit_server("smbd_deferred_open_timer: talloc failed\n");
551 /* We leave this message on the queue so the open code can
552 know this is a retry. */
553 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
554 (unsigned long long)mid ));
556 /* Mark the message as processed so this is not
557 * re-processed in error. */
558 msg->processed = true;
560 process_smb(smbd_server_conn, inbuf,
562 msg->seqnum, msg->encrypted, &msg->pcd);
564 /* If it's still there and was processed, remove it. */
565 msg = get_deferred_open_message_smb(mid);
566 if (msg && msg->processed) {
567 remove_deferred_open_message_smb(mid);
571 /****************************************************************************
572 Function to push a message onto the tail of a linked list of smb messages ready
574 ****************************************************************************/
576 static bool push_queued_message(struct smb_request *req,
577 struct timeval request_time,
578 struct timeval end_time,
579 char *private_data, size_t private_len)
581 int msg_len = smb_len(req->inbuf) + 4;
582 struct pending_message_list *msg;
584 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
587 DEBUG(0,("push_message: malloc fail (1)\n"));
591 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
592 if(msg->buf.data == NULL) {
593 DEBUG(0,("push_message: malloc fail (2)\n"));
598 msg->request_time = request_time;
599 msg->seqnum = req->seqnum;
600 msg->encrypted = req->encrypted;
601 msg->processed = false;
602 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
605 msg->private_data = data_blob_talloc(msg, private_data,
607 if (msg->private_data.data == NULL) {
608 DEBUG(0,("push_message: malloc fail (3)\n"));
614 msg->te = event_add_timed(smbd_event_context(),
617 smbd_deferred_open_timer,
620 DEBUG(0,("push_message: event_add_timed failed\n"));
625 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
627 DEBUG(10,("push_message: pushed message length %u on "
628 "deferred_open_queue\n", (unsigned int)msg_len));
633 /****************************************************************************
634 Function to delete a sharing violation open message by mid.
635 ****************************************************************************/
637 void remove_deferred_open_message_smb(uint64_t mid)
639 struct pending_message_list *pml;
641 if (smbd_server_conn->using_smb2) {
642 remove_deferred_open_message_smb2(smbd_server_conn, mid);
646 for (pml = deferred_open_queue; pml; pml = pml->next) {
647 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
648 DEBUG(10,("remove_deferred_open_message_smb: "
649 "deleting mid %llu len %u\n",
650 (unsigned long long)mid,
651 (unsigned int)pml->buf.length ));
652 DLIST_REMOVE(deferred_open_queue, pml);
659 /****************************************************************************
660 Move a sharing violation open retry message to the front of the list and
661 schedule it for immediate processing.
662 ****************************************************************************/
664 void schedule_deferred_open_message_smb(uint64_t mid)
666 struct pending_message_list *pml;
669 if (smbd_server_conn->using_smb2) {
670 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
674 for (pml = deferred_open_queue; pml; pml = pml->next) {
675 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
677 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
680 (unsigned long long)msg_mid ));
682 if (mid == msg_mid) {
683 struct timed_event *te;
685 if (pml->processed) {
686 /* A processed message should not be
688 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
689 "message mid %llu was already processed\n",
690 (unsigned long long)msg_mid ));
694 DEBUG(10,("schedule_deferred_open_message_smb: "
695 "scheduling mid %llu\n",
696 (unsigned long long)mid ));
698 te = event_add_timed(smbd_event_context(),
701 smbd_deferred_open_timer,
704 DEBUG(10,("schedule_deferred_open_message_smb: "
705 "event_add_timed() failed, "
706 "skipping mid %llu\n",
707 (unsigned long long)msg_mid ));
710 TALLOC_FREE(pml->te);
712 DLIST_PROMOTE(deferred_open_queue, pml);
717 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
718 "find message mid %llu\n",
719 (unsigned long long)mid ));
722 /****************************************************************************
723 Return true if this mid is on the deferred queue and was not yet processed.
724 ****************************************************************************/
726 bool open_was_deferred(uint64_t mid)
728 struct pending_message_list *pml;
730 if (smbd_server_conn->using_smb2) {
731 return open_was_deferred_smb2(smbd_server_conn, mid);
734 for (pml = deferred_open_queue; pml; pml = pml->next) {
735 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
742 /****************************************************************************
743 Return the message queued by this mid.
744 ****************************************************************************/
746 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
748 struct pending_message_list *pml;
750 for (pml = deferred_open_queue; pml; pml = pml->next) {
751 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
758 /****************************************************************************
759 Get the state data queued by this mid.
760 ****************************************************************************/
762 bool get_deferred_open_message_state(struct smb_request *smbreq,
763 struct timeval *p_request_time,
766 struct pending_message_list *pml;
768 if (smbd_server_conn->using_smb2) {
769 return get_deferred_open_message_state_smb2(smbreq->smb2req,
774 pml = get_deferred_open_message_smb(smbreq->mid);
778 if (p_request_time) {
779 *p_request_time = pml->request_time;
782 *pp_state = (void *)pml->private_data.data;
787 /****************************************************************************
788 Function to push a deferred open smb message onto a linked list of local smb
789 messages ready for processing.
790 ****************************************************************************/
792 bool push_deferred_open_message_smb(struct smb_request *req,
793 struct timeval request_time,
794 struct timeval timeout,
796 char *private_data, size_t priv_len)
798 struct timeval end_time;
801 return push_deferred_open_message_smb2(req->smb2req,
809 if (req->unread_bytes) {
810 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
811 "unread_bytes = %u\n",
812 (unsigned int)req->unread_bytes ));
813 smb_panic("push_deferred_open_message_smb: "
814 "logic error unread_bytes != 0" );
817 end_time = timeval_sum(&request_time, &timeout);
819 DEBUG(10,("push_deferred_open_message_smb: pushing message "
820 "len %u mid %llu timeout time [%u.%06u]\n",
821 (unsigned int) smb_len(req->inbuf)+4,
822 (unsigned long long)req->mid,
823 (unsigned int)end_time.tv_sec,
824 (unsigned int)end_time.tv_usec));
826 return push_queued_message(req, request_time, end_time,
827 private_data, priv_len);
831 struct timed_event *te;
832 struct timeval interval;
834 bool (*handler)(const struct timeval *now, void *private_data);
838 static void smbd_idle_event_handler(struct event_context *ctx,
839 struct timed_event *te,
843 struct idle_event *event =
844 talloc_get_type_abort(private_data, struct idle_event);
846 TALLOC_FREE(event->te);
848 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
849 event->name, event->te));
851 if (!event->handler(&now, event->private_data)) {
852 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
853 event->name, event->te));
854 /* Don't repeat, delete ourselves */
859 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
860 event->name, event->te));
862 event->te = event_add_timed(ctx, event,
863 timeval_sum(&now, &event->interval),
864 smbd_idle_event_handler, event);
866 /* We can't do much but fail here. */
867 SMB_ASSERT(event->te != NULL);
870 struct idle_event *event_add_idle(struct event_context *event_ctx,
872 struct timeval interval,
874 bool (*handler)(const struct timeval *now,
878 struct idle_event *result;
879 struct timeval now = timeval_current();
881 result = TALLOC_P(mem_ctx, struct idle_event);
882 if (result == NULL) {
883 DEBUG(0, ("talloc failed\n"));
887 result->interval = interval;
888 result->handler = handler;
889 result->private_data = private_data;
891 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
892 DEBUG(0, ("talloc failed\n"));
897 result->te = event_add_timed(event_ctx, result,
898 timeval_sum(&now, &interval),
899 smbd_idle_event_handler, result);
900 if (result->te == NULL) {
901 DEBUG(0, ("event_add_timed failed\n"));
906 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
910 static void smbd_sig_term_handler(struct tevent_context *ev,
911 struct tevent_signal *se,
917 exit_server_cleanly("termination signal");
920 void smbd_setup_sig_term_handler(void)
922 struct tevent_signal *se;
924 se = tevent_add_signal(smbd_event_context(),
925 smbd_event_context(),
927 smbd_sig_term_handler,
930 exit_server("failed to setup SIGTERM handler");
934 static void smbd_sig_hup_handler(struct tevent_context *ev,
935 struct tevent_signal *se,
941 struct messaging_context *msg_ctx = talloc_get_type_abort(
942 private_data, struct messaging_context);
943 change_to_root_user();
944 DEBUG(1,("Reloading services after SIGHUP\n"));
945 reload_services(msg_ctx, smbd_server_conn->sock, False);
948 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
949 struct messaging_context *msg_ctx)
951 struct tevent_signal *se;
953 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
956 exit_server("failed to setup SIGHUP handler");
960 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
967 to.tv_sec = SMBD_SELECT_TIMEOUT;
971 * Setup the select fd sets.
978 * Are there any timed events waiting ? If so, ensure we don't
979 * select for longer than it would take to wait for them.
986 event_add_to_select_args(smbd_event_context(), &now,
987 &r_fds, &w_fds, &to, &maxfd);
990 /* Process a signal and timed events now... */
991 if (run_events(smbd_event_context(), &selrtn, NULL, NULL)) {
992 return NT_STATUS_RETRY;
997 START_PROFILE(smbd_idle);
999 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
1002 END_PROFILE(smbd_idle);
1006 /* Check if error */
1009 return NT_STATUS_RETRY;
1011 /* Maybe the socket is dead? */
1012 return map_nt_error_from_unix(errno);
1015 /* Process events until all available fds have been handled.
1016 * This allows for fair round-robin handling of all available fds
1017 * on each select() wakeup, while still maintaining responsiveness
1018 * by re-checking for signal and timed events between the handling
1019 * of each ready fd. */
1021 run_events(smbd_event_context(), &selrtn, &r_fds, &w_fds);
1022 } while (selrtn > 0);
1024 /* Processed all fds or timed out */
1026 return NT_STATUS_RETRY;
1029 /* should not be reached */
1030 return NT_STATUS_INTERNAL_ERROR;
1034 * Only allow 5 outstanding trans requests. We're allocating memory, so
1038 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1041 for (; list != NULL; list = list->next) {
1043 if (list->mid == mid) {
1044 return NT_STATUS_INVALID_PARAMETER;
1050 return NT_STATUS_INSUFFICIENT_RESOURCES;
1053 return NT_STATUS_OK;
1057 These flags determine some of the permissions required to do an operation
1059 Note that I don't set NEED_WRITE on some write operations because they
1060 are used by some brain-dead clients when printing, and I don't want to
1061 force write permissions on print services.
1063 #define AS_USER (1<<0)
1064 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1065 #define TIME_INIT (1<<2)
1066 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1067 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1068 #define DO_CHDIR (1<<6)
1071 define a list of possible SMB messages and their corresponding
1072 functions. Any message that has a NULL function is unimplemented -
1073 please feel free to contribute implementations!
1075 static const struct smb_message_struct {
1077 void (*fn)(struct smb_request *req);
1079 } smb_messages[256] = {
1081 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1082 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1083 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1084 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1085 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1086 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1087 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1088 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1089 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1090 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1091 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1092 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1093 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1094 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1095 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1096 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1097 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1098 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1099 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1100 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1101 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1102 /* 0x15 */ { NULL, NULL, 0 },
1103 /* 0x16 */ { NULL, NULL, 0 },
1104 /* 0x17 */ { NULL, NULL, 0 },
1105 /* 0x18 */ { NULL, NULL, 0 },
1106 /* 0x19 */ { NULL, NULL, 0 },
1107 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1108 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1109 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1110 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1111 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1112 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1113 /* 0x20 */ { "SMBwritec", NULL,0},
1114 /* 0x21 */ { NULL, NULL, 0 },
1115 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1116 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1117 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1118 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1119 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1120 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1121 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1122 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1123 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1124 /* 0x2b */ { "SMBecho",reply_echo,0},
1125 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1126 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1127 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1128 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1129 /* 0x30 */ { NULL, NULL, 0 },
1130 /* 0x31 */ { NULL, NULL, 0 },
1131 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1132 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1133 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1134 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1135 /* 0x36 */ { NULL, NULL, 0 },
1136 /* 0x37 */ { NULL, NULL, 0 },
1137 /* 0x38 */ { NULL, NULL, 0 },
1138 /* 0x39 */ { NULL, NULL, 0 },
1139 /* 0x3a */ { NULL, NULL, 0 },
1140 /* 0x3b */ { NULL, NULL, 0 },
1141 /* 0x3c */ { NULL, NULL, 0 },
1142 /* 0x3d */ { NULL, NULL, 0 },
1143 /* 0x3e */ { NULL, NULL, 0 },
1144 /* 0x3f */ { NULL, NULL, 0 },
1145 /* 0x40 */ { NULL, NULL, 0 },
1146 /* 0x41 */ { NULL, NULL, 0 },
1147 /* 0x42 */ { NULL, NULL, 0 },
1148 /* 0x43 */ { NULL, NULL, 0 },
1149 /* 0x44 */ { NULL, NULL, 0 },
1150 /* 0x45 */ { NULL, NULL, 0 },
1151 /* 0x46 */ { NULL, NULL, 0 },
1152 /* 0x47 */ { NULL, NULL, 0 },
1153 /* 0x48 */ { NULL, NULL, 0 },
1154 /* 0x49 */ { NULL, NULL, 0 },
1155 /* 0x4a */ { NULL, NULL, 0 },
1156 /* 0x4b */ { NULL, NULL, 0 },
1157 /* 0x4c */ { NULL, NULL, 0 },
1158 /* 0x4d */ { NULL, NULL, 0 },
1159 /* 0x4e */ { NULL, NULL, 0 },
1160 /* 0x4f */ { NULL, NULL, 0 },
1161 /* 0x50 */ { NULL, NULL, 0 },
1162 /* 0x51 */ { NULL, NULL, 0 },
1163 /* 0x52 */ { NULL, NULL, 0 },
1164 /* 0x53 */ { NULL, NULL, 0 },
1165 /* 0x54 */ { NULL, NULL, 0 },
1166 /* 0x55 */ { NULL, NULL, 0 },
1167 /* 0x56 */ { NULL, NULL, 0 },
1168 /* 0x57 */ { NULL, NULL, 0 },
1169 /* 0x58 */ { NULL, NULL, 0 },
1170 /* 0x59 */ { NULL, NULL, 0 },
1171 /* 0x5a */ { NULL, NULL, 0 },
1172 /* 0x5b */ { NULL, NULL, 0 },
1173 /* 0x5c */ { NULL, NULL, 0 },
1174 /* 0x5d */ { NULL, NULL, 0 },
1175 /* 0x5e */ { NULL, NULL, 0 },
1176 /* 0x5f */ { NULL, NULL, 0 },
1177 /* 0x60 */ { NULL, NULL, 0 },
1178 /* 0x61 */ { NULL, NULL, 0 },
1179 /* 0x62 */ { NULL, NULL, 0 },
1180 /* 0x63 */ { NULL, NULL, 0 },
1181 /* 0x64 */ { NULL, NULL, 0 },
1182 /* 0x65 */ { NULL, NULL, 0 },
1183 /* 0x66 */ { NULL, NULL, 0 },
1184 /* 0x67 */ { NULL, NULL, 0 },
1185 /* 0x68 */ { NULL, NULL, 0 },
1186 /* 0x69 */ { NULL, NULL, 0 },
1187 /* 0x6a */ { NULL, NULL, 0 },
1188 /* 0x6b */ { NULL, NULL, 0 },
1189 /* 0x6c */ { NULL, NULL, 0 },
1190 /* 0x6d */ { NULL, NULL, 0 },
1191 /* 0x6e */ { NULL, NULL, 0 },
1192 /* 0x6f */ { NULL, NULL, 0 },
1193 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1194 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1195 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1196 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1197 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1198 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1199 /* 0x76 */ { NULL, NULL, 0 },
1200 /* 0x77 */ { NULL, NULL, 0 },
1201 /* 0x78 */ { NULL, NULL, 0 },
1202 /* 0x79 */ { NULL, NULL, 0 },
1203 /* 0x7a */ { NULL, NULL, 0 },
1204 /* 0x7b */ { NULL, NULL, 0 },
1205 /* 0x7c */ { NULL, NULL, 0 },
1206 /* 0x7d */ { NULL, NULL, 0 },
1207 /* 0x7e */ { NULL, NULL, 0 },
1208 /* 0x7f */ { NULL, NULL, 0 },
1209 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1210 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1211 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1212 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1213 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1214 /* 0x85 */ { NULL, NULL, 0 },
1215 /* 0x86 */ { NULL, NULL, 0 },
1216 /* 0x87 */ { NULL, NULL, 0 },
1217 /* 0x88 */ { NULL, NULL, 0 },
1218 /* 0x89 */ { NULL, NULL, 0 },
1219 /* 0x8a */ { NULL, NULL, 0 },
1220 /* 0x8b */ { NULL, NULL, 0 },
1221 /* 0x8c */ { NULL, NULL, 0 },
1222 /* 0x8d */ { NULL, NULL, 0 },
1223 /* 0x8e */ { NULL, NULL, 0 },
1224 /* 0x8f */ { NULL, NULL, 0 },
1225 /* 0x90 */ { NULL, NULL, 0 },
1226 /* 0x91 */ { NULL, NULL, 0 },
1227 /* 0x92 */ { NULL, NULL, 0 },
1228 /* 0x93 */ { NULL, NULL, 0 },
1229 /* 0x94 */ { NULL, NULL, 0 },
1230 /* 0x95 */ { NULL, NULL, 0 },
1231 /* 0x96 */ { NULL, NULL, 0 },
1232 /* 0x97 */ { NULL, NULL, 0 },
1233 /* 0x98 */ { NULL, NULL, 0 },
1234 /* 0x99 */ { NULL, NULL, 0 },
1235 /* 0x9a */ { NULL, NULL, 0 },
1236 /* 0x9b */ { NULL, NULL, 0 },
1237 /* 0x9c */ { NULL, NULL, 0 },
1238 /* 0x9d */ { NULL, NULL, 0 },
1239 /* 0x9e */ { NULL, NULL, 0 },
1240 /* 0x9f */ { NULL, NULL, 0 },
1241 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1242 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1243 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1244 /* 0xa3 */ { NULL, NULL, 0 },
1245 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1246 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1247 /* 0xa6 */ { NULL, NULL, 0 },
1248 /* 0xa7 */ { NULL, NULL, 0 },
1249 /* 0xa8 */ { NULL, NULL, 0 },
1250 /* 0xa9 */ { NULL, NULL, 0 },
1251 /* 0xaa */ { NULL, NULL, 0 },
1252 /* 0xab */ { NULL, NULL, 0 },
1253 /* 0xac */ { NULL, NULL, 0 },
1254 /* 0xad */ { NULL, NULL, 0 },
1255 /* 0xae */ { NULL, NULL, 0 },
1256 /* 0xaf */ { NULL, NULL, 0 },
1257 /* 0xb0 */ { NULL, NULL, 0 },
1258 /* 0xb1 */ { NULL, NULL, 0 },
1259 /* 0xb2 */ { NULL, NULL, 0 },
1260 /* 0xb3 */ { NULL, NULL, 0 },
1261 /* 0xb4 */ { NULL, NULL, 0 },
1262 /* 0xb5 */ { NULL, NULL, 0 },
1263 /* 0xb6 */ { NULL, NULL, 0 },
1264 /* 0xb7 */ { NULL, NULL, 0 },
1265 /* 0xb8 */ { NULL, NULL, 0 },
1266 /* 0xb9 */ { NULL, NULL, 0 },
1267 /* 0xba */ { NULL, NULL, 0 },
1268 /* 0xbb */ { NULL, NULL, 0 },
1269 /* 0xbc */ { NULL, NULL, 0 },
1270 /* 0xbd */ { NULL, NULL, 0 },
1271 /* 0xbe */ { NULL, NULL, 0 },
1272 /* 0xbf */ { NULL, NULL, 0 },
1273 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1274 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1275 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1276 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1277 /* 0xc4 */ { NULL, NULL, 0 },
1278 /* 0xc5 */ { NULL, NULL, 0 },
1279 /* 0xc6 */ { NULL, NULL, 0 },
1280 /* 0xc7 */ { NULL, NULL, 0 },
1281 /* 0xc8 */ { NULL, NULL, 0 },
1282 /* 0xc9 */ { NULL, NULL, 0 },
1283 /* 0xca */ { NULL, NULL, 0 },
1284 /* 0xcb */ { NULL, NULL, 0 },
1285 /* 0xcc */ { NULL, NULL, 0 },
1286 /* 0xcd */ { NULL, NULL, 0 },
1287 /* 0xce */ { NULL, NULL, 0 },
1288 /* 0xcf */ { NULL, NULL, 0 },
1289 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1290 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1291 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1292 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1293 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1294 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1295 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1296 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1297 /* 0xd8 */ { NULL, NULL, 0 },
1298 /* 0xd9 */ { NULL, NULL, 0 },
1299 /* 0xda */ { NULL, NULL, 0 },
1300 /* 0xdb */ { NULL, NULL, 0 },
1301 /* 0xdc */ { NULL, NULL, 0 },
1302 /* 0xdd */ { NULL, NULL, 0 },
1303 /* 0xde */ { NULL, NULL, 0 },
1304 /* 0xdf */ { NULL, NULL, 0 },
1305 /* 0xe0 */ { NULL, NULL, 0 },
1306 /* 0xe1 */ { NULL, NULL, 0 },
1307 /* 0xe2 */ { NULL, NULL, 0 },
1308 /* 0xe3 */ { NULL, NULL, 0 },
1309 /* 0xe4 */ { NULL, NULL, 0 },
1310 /* 0xe5 */ { NULL, NULL, 0 },
1311 /* 0xe6 */ { NULL, NULL, 0 },
1312 /* 0xe7 */ { NULL, NULL, 0 },
1313 /* 0xe8 */ { NULL, NULL, 0 },
1314 /* 0xe9 */ { NULL, NULL, 0 },
1315 /* 0xea */ { NULL, NULL, 0 },
1316 /* 0xeb */ { NULL, NULL, 0 },
1317 /* 0xec */ { NULL, NULL, 0 },
1318 /* 0xed */ { NULL, NULL, 0 },
1319 /* 0xee */ { NULL, NULL, 0 },
1320 /* 0xef */ { NULL, NULL, 0 },
1321 /* 0xf0 */ { NULL, NULL, 0 },
1322 /* 0xf1 */ { NULL, NULL, 0 },
1323 /* 0xf2 */ { NULL, NULL, 0 },
1324 /* 0xf3 */ { NULL, NULL, 0 },
1325 /* 0xf4 */ { NULL, NULL, 0 },
1326 /* 0xf5 */ { NULL, NULL, 0 },
1327 /* 0xf6 */ { NULL, NULL, 0 },
1328 /* 0xf7 */ { NULL, NULL, 0 },
1329 /* 0xf8 */ { NULL, NULL, 0 },
1330 /* 0xf9 */ { NULL, NULL, 0 },
1331 /* 0xfa */ { NULL, NULL, 0 },
1332 /* 0xfb */ { NULL, NULL, 0 },
1333 /* 0xfc */ { NULL, NULL, 0 },
1334 /* 0xfd */ { NULL, NULL, 0 },
1335 /* 0xfe */ { NULL, NULL, 0 },
1336 /* 0xff */ { NULL, NULL, 0 }
1340 /*******************************************************************
1341 allocate and initialize a reply packet
1342 ********************************************************************/
1344 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1345 const char *inbuf, char **outbuf, uint8_t num_words,
1349 * Protect against integer wrap
1351 if ((num_bytes > 0xffffff)
1352 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1354 if (asprintf(&msg, "num_bytes too large: %u",
1355 (unsigned)num_bytes) == -1) {
1356 msg = CONST_DISCARD(char *, "num_bytes too large");
1361 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1362 smb_size + num_words*2 + num_bytes);
1363 if (*outbuf == NULL) {
1367 construct_reply_common(req, inbuf, *outbuf);
1368 srv_set_message(*outbuf, num_words, num_bytes, false);
1370 * Zero out the word area, the caller has to take care of the bcc area
1373 if (num_words != 0) {
1374 memset(*outbuf + smb_vwv0, 0, num_words*2);
1380 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1383 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1385 smb_panic("could not allocate output buffer\n");
1387 req->outbuf = (uint8_t *)outbuf;
1391 /*******************************************************************
1392 Dump a packet to a file.
1393 ********************************************************************/
1395 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1399 if (DEBUGLEVEL < 50) {
1403 if (len < 4) len = smb_len(data)+4;
1404 for (i=1;i<100;i++) {
1405 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1406 type ? "req" : "resp") == -1) {
1409 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1410 if (fd != -1 || errno != EEXIST) break;
1413 ssize_t ret = write(fd, data, len);
1415 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1417 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1422 /****************************************************************************
1423 Prepare everything for calling the actual request function, and potentially
1424 call the request function via the "new" interface.
1426 Return False if the "legacy" function needs to be called, everything is
1429 Return True if we're done.
1431 I know this API sucks, but it is the one with the least code change I could
1433 ****************************************************************************/
1435 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1439 connection_struct *conn = NULL;
1440 struct smbd_server_connection *sconn = req->sconn;
1444 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1445 * so subtract 4 from it. */
1446 if (!valid_smb_header(req->inbuf)
1447 || (size < (smb_size - 4))) {
1448 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1449 smb_len(req->inbuf)));
1450 exit_server_cleanly("Non-SMB packet");
1453 if (smb_messages[type].fn == NULL) {
1454 DEBUG(0,("Unknown message type %d!\n",type));
1455 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1456 reply_unknown_new(req, type);
1460 flags = smb_messages[type].flags;
1462 /* In share mode security we must ignore the vuid. */
1463 session_tag = (lp_security() == SEC_SHARE)
1464 ? UID_FIELD_INVALID : req->vuid;
1467 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1468 (int)sys_getpid(), (unsigned long)conn));
1470 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1472 /* Ensure this value is replaced in the incoming packet. */
1473 SSVAL(req->inbuf,smb_uid,session_tag);
1476 * Ensure the correct username is in current_user_info. This is a
1477 * really ugly bugfix for problems with multiple session_setup_and_X's
1478 * being done and allowing %U and %G substitutions to work correctly.
1479 * There is a reason this code is done here, don't move it unless you
1480 * know what you're doing... :-).
1484 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1485 user_struct *vuser = NULL;
1487 sconn->smb1.sessions.last_session_tag = session_tag;
1488 if(session_tag != UID_FIELD_INVALID) {
1489 vuser = get_valid_user_struct(sconn, session_tag);
1491 set_current_user_info(
1492 vuser->server_info->sanitized_username,
1493 vuser->server_info->unix_name,
1494 vuser->server_info->info3->base.domain.string);
1499 /* Does this call need to be run as the connected user? */
1500 if (flags & AS_USER) {
1502 /* Does this call need a valid tree connection? */
1505 * Amazingly, the error code depends on the command
1508 if (type == SMBntcreateX) {
1509 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1511 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1516 if (!change_to_user(conn,session_tag)) {
1517 DEBUG(0, ("Error: Could not change to user. Removing "
1518 "deferred open, mid=%llu.\n",
1519 (unsigned long long)req->mid));
1520 reply_force_doserror(req, ERRSRV, ERRbaduid);
1524 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1526 /* Does it need write permission? */
1527 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1528 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1532 /* IPC services are limited */
1533 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1534 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1538 /* This call needs to be run as root */
1539 change_to_root_user();
1542 /* load service specific parameters */
1544 if (req->encrypted) {
1545 conn->encrypted_tid = true;
1546 /* encrypted required from now on. */
1547 conn->encrypt_level = Required;
1548 } else if (ENCRYPTION_REQUIRED(conn)) {
1549 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1550 exit_server_cleanly("encryption required "
1556 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1557 (flags & (AS_USER|DO_CHDIR)
1559 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1562 conn->num_smb_operations++;
1565 /* does this protocol need to be run as guest? */
1566 if ((flags & AS_GUEST)
1567 && (!change_to_guest() ||
1568 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1569 sconn->client_id.name,
1570 sconn->client_id.addr))) {
1571 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1575 smb_messages[type].fn(req);
1579 /****************************************************************************
1580 Construct a reply to the incoming packet.
1581 ****************************************************************************/
1583 static void construct_reply(struct smbd_server_connection *sconn,
1584 char *inbuf, int size, size_t unread_bytes,
1585 uint32_t seqnum, bool encrypted,
1586 struct smb_perfcount_data *deferred_pcd)
1588 connection_struct *conn;
1589 struct smb_request *req;
1591 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1592 smb_panic("could not allocate smb_request");
1595 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1596 encrypted, seqnum)) {
1597 exit_server_cleanly("Invalid SMB request");
1600 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1602 /* we popped this message off the queue - keep original perf data */
1604 req->pcd = *deferred_pcd;
1606 SMB_PERFCOUNT_START(&req->pcd);
1607 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1608 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1611 conn = switch_message(req->cmd, req, size);
1613 if (req->unread_bytes) {
1614 /* writeX failed. drain socket. */
1615 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1616 req->unread_bytes) {
1617 smb_panic("failed to drain pending bytes");
1619 req->unread_bytes = 0;
1627 if (req->outbuf == NULL) {
1631 if (CVAL(req->outbuf,0) == 0) {
1632 show_msg((char *)req->outbuf);
1635 if (!srv_send_smb(req->sconn,
1636 (char *)req->outbuf,
1637 true, req->seqnum+1,
1638 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1640 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1648 /****************************************************************************
1649 Process an smb from the client
1650 ****************************************************************************/
1651 static void process_smb(struct smbd_server_connection *sconn,
1652 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1653 uint32_t seqnum, bool encrypted,
1654 struct smb_perfcount_data *deferred_pcd)
1656 int msg_type = CVAL(inbuf,0);
1658 DO_PROFILE_INC(smb_count);
1660 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1662 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1663 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1665 if (msg_type != 0) {
1667 * NetBIOS session request, keepalive, etc.
1669 reply_special(sconn, (char *)inbuf, nread);
1673 if (sconn->using_smb2) {
1674 /* At this point we're not really using smb2,
1675 * we make the decision here.. */
1676 if (smbd_is_smb2_header(inbuf, nread)) {
1677 smbd_smb2_first_negprot(sconn, inbuf, nread);
1679 } else if (nread >= smb_size && valid_smb_header(inbuf)
1680 && CVAL(inbuf, smb_com) != 0x72) {
1681 /* This is a non-negprot SMB1 packet.
1682 Disable SMB2 from now on. */
1683 sconn->using_smb2 = false;
1687 show_msg((char *)inbuf);
1689 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1690 encrypted, deferred_pcd);
1694 sconn->smb1.num_requests++;
1696 /* The timeout_processing function isn't run nearly
1697 often enough to implement 'max log size' without
1698 overrunning the size of the file by many megabytes.
1699 This is especially true if we are running at debug
1700 level 10. Checking every 50 SMBs is a nice
1701 tradeoff of performance vs log file size overrun. */
1703 if ((sconn->smb1.num_requests % 50) == 0 &&
1704 need_to_check_log_size()) {
1705 change_to_root_user();
1710 /****************************************************************************
1711 Return a string containing the function name of a SMB command.
1712 ****************************************************************************/
1714 const char *smb_fn_name(int type)
1716 const char *unknown_name = "SMBunknown";
1718 if (smb_messages[type].name == NULL)
1719 return(unknown_name);
1721 return(smb_messages[type].name);
1724 /****************************************************************************
1725 Helper functions for contruct_reply.
1726 ****************************************************************************/
1728 void add_to_common_flags2(uint32 v)
1733 void remove_from_common_flags2(uint32 v)
1735 common_flags2 &= ~v;
1738 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1741 srv_set_message(outbuf,0,0,false);
1743 SCVAL(outbuf, smb_com, req->cmd);
1744 SIVAL(outbuf,smb_rcls,0);
1745 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1746 SSVAL(outbuf,smb_flg2,
1747 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1749 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1751 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1752 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1753 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1754 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1757 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1759 construct_reply_common(req, (char *)req->inbuf, outbuf);
1763 * How many bytes have we already accumulated up to the current wct field
1767 size_t req_wct_ofs(struct smb_request *req)
1771 if (req->chain_outbuf == NULL) {
1774 buf_size = talloc_get_size(req->chain_outbuf);
1775 if ((buf_size % 4) != 0) {
1776 buf_size += (4 - (buf_size % 4));
1778 return buf_size - 4;
1782 * Hack around reply_nterror & friends not being aware of chained requests,
1783 * generating illegal (i.e. wct==0) chain replies.
1786 static void fixup_chain_error_packet(struct smb_request *req)
1788 uint8_t *outbuf = req->outbuf;
1790 reply_outbuf(req, 2, 0);
1791 memcpy(req->outbuf, outbuf, smb_wct);
1792 TALLOC_FREE(outbuf);
1793 SCVAL(req->outbuf, smb_vwv0, 0xff);
1797 * @brief Find the smb_cmd offset of the last command pushed
1798 * @param[in] buf The buffer we're building up
1799 * @retval Where can we put our next andx cmd?
1801 * While chaining requests, the "next" request we're looking at needs to put
1802 * its SMB_Command before the data the previous request already built up added
1803 * to the chain. Find the offset to the place where we have to put our cmd.
1806 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1811 cmd = CVAL(buf, smb_com);
1813 SMB_ASSERT(is_andx_req(cmd));
1817 while (CVAL(buf, ofs) != 0xff) {
1819 if (!is_andx_req(CVAL(buf, ofs))) {
1824 * ofs is from start of smb header, so add the 4 length
1825 * bytes. The next cmd is right after the wct field.
1827 ofs = SVAL(buf, ofs+2) + 4 + 1;
1829 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1837 * @brief Do the smb chaining at a buffer level
1838 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1839 * @param[in] smb_command The command that we want to issue
1840 * @param[in] wct How many words?
1841 * @param[in] vwv The words, already in network order
1842 * @param[in] bytes_alignment How shall we align "bytes"?
1843 * @param[in] num_bytes How many bytes?
1844 * @param[in] bytes The data the request ships
1846 * smb_splice_chain() adds the vwv and bytes to the request already present in
1850 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1851 uint8_t wct, const uint16_t *vwv,
1852 size_t bytes_alignment,
1853 uint32_t num_bytes, const uint8_t *bytes)
1856 size_t old_size, new_size;
1858 size_t chain_padding = 0;
1859 size_t bytes_padding = 0;
1862 old_size = talloc_get_size(*poutbuf);
1865 * old_size == smb_wct means we're pushing the first request in for
1869 first_request = (old_size == smb_wct);
1871 if (!first_request && ((old_size % 4) != 0)) {
1873 * Align the wct field of subsequent requests to a 4-byte
1876 chain_padding = 4 - (old_size % 4);
1880 * After the old request comes the new wct field (1 byte), the vwv's
1881 * and the num_bytes field. After at we might need to align the bytes
1882 * given to us to "bytes_alignment", increasing the num_bytes value.
1885 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1887 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1888 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1891 new_size += bytes_padding + num_bytes;
1893 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1894 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1895 (unsigned)new_size));
1899 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1900 if (outbuf == NULL) {
1901 DEBUG(0, ("talloc failed\n"));
1906 if (first_request) {
1907 SCVAL(outbuf, smb_com, smb_command);
1909 size_t andx_cmd_ofs;
1911 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1912 DEBUG(1, ("invalid command chain\n"));
1913 *poutbuf = TALLOC_REALLOC_ARRAY(
1914 NULL, *poutbuf, uint8_t, old_size);
1918 if (chain_padding != 0) {
1919 memset(outbuf + old_size, 0, chain_padding);
1920 old_size += chain_padding;
1923 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1924 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1930 * Push the chained request:
1935 SCVAL(outbuf, ofs, wct);
1942 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1943 ofs += sizeof(uint16_t) * wct;
1949 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1950 ofs += sizeof(uint16_t);
1956 if (bytes_padding != 0) {
1957 memset(outbuf + ofs, 0, bytes_padding);
1958 ofs += bytes_padding;
1965 memcpy(outbuf + ofs, bytes, num_bytes);
1970 /****************************************************************************
1971 Construct a chained reply and add it to the already made reply
1972 ****************************************************************************/
1974 void chain_reply(struct smb_request *req)
1976 size_t smblen = smb_len(req->inbuf);
1977 size_t already_used, length_needed;
1979 uint32_t chain_offset; /* uint32_t to avoid overflow */
1986 if (IVAL(req->outbuf, smb_rcls) != 0) {
1987 fixup_chain_error_packet(req);
1991 * Any of the AndX requests and replies have at least a wct of
1992 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1993 * beginning of the SMB header to the next wct field.
1995 * None of the AndX requests put anything valuable in vwv[0] and [1],
1996 * so we can overwrite it here to form the chain.
1999 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
2000 if (req->chain_outbuf == NULL) {
2001 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2002 req, req->outbuf, uint8_t,
2003 smb_len(req->outbuf) + 4);
2004 if (req->chain_outbuf == NULL) {
2005 smb_panic("talloc failed");
2013 * Here we assume that this is the end of the chain. For that we need
2014 * to set "next command" to 0xff and the offset to 0. If we later find
2015 * more commands in the chain, this will be overwritten again.
2018 SCVAL(req->outbuf, smb_vwv0, 0xff);
2019 SCVAL(req->outbuf, smb_vwv0+1, 0);
2020 SSVAL(req->outbuf, smb_vwv1, 0);
2022 if (req->chain_outbuf == NULL) {
2024 * In req->chain_outbuf we collect all the replies. Start the
2025 * chain by copying in the first reply.
2027 * We do the realloc because later on we depend on
2028 * talloc_get_size to determine the length of
2029 * chain_outbuf. The reply_xxx routines might have
2030 * over-allocated (reply_pipe_read_and_X used to be such an
2033 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2034 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2035 if (req->chain_outbuf == NULL) {
2036 smb_panic("talloc failed");
2041 * Update smb headers where subsequent chained commands
2042 * may have updated them.
2044 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2045 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2047 if (!smb_splice_chain(&req->chain_outbuf,
2048 CVAL(req->outbuf, smb_com),
2049 CVAL(req->outbuf, smb_wct),
2050 (uint16_t *)(req->outbuf + smb_vwv),
2051 0, smb_buflen(req->outbuf),
2052 (uint8_t *)smb_buf(req->outbuf))) {
2055 TALLOC_FREE(req->outbuf);
2059 * We use the old request's vwv field to grab the next chained command
2060 * and offset into the chained fields.
2063 chain_cmd = CVAL(req->vwv+0, 0);
2064 chain_offset = SVAL(req->vwv+1, 0);
2066 if (chain_cmd == 0xff) {
2068 * End of chain, no more requests from the client. So ship the
2071 smb_setlen((char *)(req->chain_outbuf),
2072 talloc_get_size(req->chain_outbuf) - 4);
2074 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2075 true, req->seqnum+1,
2076 IS_CONN_ENCRYPTED(req->conn)
2079 exit_server_cleanly("chain_reply: srv_send_smb "
2082 TALLOC_FREE(req->chain_outbuf);
2087 /* add a new perfcounter for this element of chain */
2088 SMB_PERFCOUNT_ADD(&req->pcd);
2089 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2090 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2093 * Check if the client tries to fool us. The request so far uses the
2094 * space to the end of the byte buffer in the request just
2095 * processed. The chain_offset can't point into that area. If that was
2096 * the case, we could end up with an endless processing of the chain,
2097 * we would always handle the same request.
2100 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2101 if (chain_offset < already_used) {
2106 * Next check: Make sure the chain offset does not point beyond the
2107 * overall smb request length.
2110 length_needed = chain_offset+1; /* wct */
2111 if (length_needed > smblen) {
2116 * Now comes the pointer magic. Goal here is to set up req->vwv and
2117 * req->buf correctly again to be able to call the subsequent
2118 * switch_message(). The chain offset (the former vwv[1]) points at
2119 * the new wct field.
2122 wct = CVAL(smb_base(req->inbuf), chain_offset);
2125 * Next consistency check: Make the new vwv array fits in the overall
2129 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2130 if (length_needed > smblen) {
2133 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2136 * Now grab the new byte buffer....
2139 buflen = SVAL(vwv+wct, 0);
2142 * .. and check that it fits.
2145 length_needed += buflen;
2146 if (length_needed > smblen) {
2149 buf = (uint8_t *)(vwv+wct+1);
2151 req->cmd = chain_cmd;
2154 req->buflen = buflen;
2157 switch_message(chain_cmd, req, smblen);
2159 if (req->outbuf == NULL) {
2161 * This happens if the chained command has suspended itself or
2162 * if it has called srv_send_smb() itself.
2168 * We end up here if the chained command was not itself chained or
2169 * suspended, but for example a close() command. We now need to splice
2170 * the chained commands' outbuf into the already built up chain_outbuf
2171 * and ship the result.
2177 * We end up here if there's any error in the chain syntax. Report a
2178 * DOS error, just like Windows does.
2180 reply_force_doserror(req, ERRSRV, ERRerror);
2181 fixup_chain_error_packet(req);
2185 * This scary statement intends to set the
2186 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2187 * to the value req->outbuf carries
2189 SSVAL(req->chain_outbuf, smb_flg2,
2190 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2191 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2194 * Transfer the error codes from the subrequest to the main one
2196 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2197 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2199 if (!smb_splice_chain(&req->chain_outbuf,
2200 CVAL(req->outbuf, smb_com),
2201 CVAL(req->outbuf, smb_wct),
2202 (uint16_t *)(req->outbuf + smb_vwv),
2203 0, smb_buflen(req->outbuf),
2204 (uint8_t *)smb_buf(req->outbuf))) {
2205 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2207 TALLOC_FREE(req->outbuf);
2209 smb_setlen((char *)(req->chain_outbuf),
2210 talloc_get_size(req->chain_outbuf) - 4);
2212 show_msg((char *)(req->chain_outbuf));
2214 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2215 true, req->seqnum+1,
2216 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2218 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2220 TALLOC_FREE(req->chain_outbuf);
2224 /****************************************************************************
2225 Check if services need reloading.
2226 ****************************************************************************/
2228 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2230 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2232 if(last_smb_conf_reload_time == 0) {
2233 last_smb_conf_reload_time = t;
2234 /* Our printing subsystem might not be ready at smbd start up.
2235 Then no printer is available till the first printers check
2236 is performed. A lower initial interval circumvents this. */
2237 if ( printcap_cache_time > 60 )
2238 last_printer_reload_time = t - printcap_cache_time + 60;
2240 last_printer_reload_time = t;
2243 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2244 /* randomize over 60 second the printcap reload to avoid all
2245 * process hitting cupsd at the same time */
2246 int time_range = 60;
2248 last_printer_reload_time += random() % time_range;
2252 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2253 reload_services(sconn->msg_ctx, sconn->sock, True);
2254 last_smb_conf_reload_time = t;
2257 /* 'printcap cache time = 0' disable the feature */
2259 if ( printcap_cache_time != 0 )
2261 /* see if it's time to reload or if the clock has been set back */
2263 if ( (t >= last_printer_reload_time+printcap_cache_time)
2264 || (t-last_printer_reload_time < 0) )
2266 DEBUG( 3,( "Printcap cache time expired.\n"));
2267 reload_printers(sconn->msg_ctx);
2268 last_printer_reload_time = t;
2273 static bool fd_is_readable(int fd)
2276 struct timeval timeout = {0, };
2282 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2286 return FD_ISSET(fd, &fds);
2289 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2291 /* TODO: make write nonblocking */
2294 static void smbd_server_connection_read_handler(
2295 struct smbd_server_connection *conn, int fd)
2297 uint8_t *inbuf = NULL;
2298 size_t inbuf_len = 0;
2299 size_t unread_bytes = 0;
2300 bool encrypted = false;
2301 TALLOC_CTX *mem_ctx = talloc_tos();
2305 bool from_client = (conn->sock == fd);
2308 smbd_lock_socket(conn);
2310 if (!fd_is_readable(fd)) {
2311 DEBUG(10,("the echo listener was faster\n"));
2312 smbd_unlock_socket(conn);
2316 /* TODO: make this completely nonblocking */
2317 status = receive_smb_talloc(mem_ctx, conn,
2318 (char **)(void *)&inbuf,
2322 &inbuf_len, &seqnum,
2323 false /* trusted channel */);
2324 smbd_unlock_socket(conn);
2326 /* TODO: make this completely nonblocking */
2327 status = receive_smb_talloc(mem_ctx, conn,
2328 (char **)(void *)&inbuf,
2332 &inbuf_len, &seqnum,
2333 true /* trusted channel */);
2336 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2339 if (NT_STATUS_IS_ERR(status)) {
2340 exit_server_cleanly("failed to receive smb request");
2342 if (!NT_STATUS_IS_OK(status)) {
2347 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2348 seqnum, encrypted, NULL);
2351 static void smbd_server_connection_handler(struct event_context *ev,
2352 struct fd_event *fde,
2356 struct smbd_server_connection *conn = talloc_get_type(private_data,
2357 struct smbd_server_connection);
2359 if (flags & EVENT_FD_WRITE) {
2360 smbd_server_connection_write_handler(conn);
2363 if (flags & EVENT_FD_READ) {
2364 smbd_server_connection_read_handler(conn, conn->sock);
2369 static void smbd_server_echo_handler(struct event_context *ev,
2370 struct fd_event *fde,
2374 struct smbd_server_connection *conn = talloc_get_type(private_data,
2375 struct smbd_server_connection);
2377 if (flags & EVENT_FD_WRITE) {
2378 smbd_server_connection_write_handler(conn);
2381 if (flags & EVENT_FD_READ) {
2382 smbd_server_connection_read_handler(
2383 conn, conn->smb1.echo_handler.trusted_fd);
2388 /****************************************************************************
2389 received when we should release a specific IP
2390 ****************************************************************************/
2391 static void release_ip(const char *ip, void *priv)
2393 const char *addr = (const char *)priv;
2394 const char *p = addr;
2396 if (strncmp("::ffff:", addr, 7) == 0) {
2400 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2401 /* we can't afford to do a clean exit - that involves
2402 database writes, which would potentially mean we
2403 are still running after the failover has finished -
2404 we have to get rid of this process ID straight
2406 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2408 /* note we must exit with non-zero status so the unclean handler gets
2409 called in the parent, so that the brl database is tickled */
2414 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2415 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2417 struct smbd_server_connection *sconn = talloc_get_type_abort(
2418 private_data, struct smbd_server_connection);
2420 release_ip((char *)data->data, sconn->client_id.addr);
2423 #ifdef CLUSTER_SUPPORT
2424 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2425 struct sockaddr_storage *client)
2428 length = sizeof(*server);
2429 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2432 length = sizeof(*client);
2433 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2441 * Send keepalive packets to our client
2443 static bool keepalive_fn(const struct timeval *now, void *private_data)
2445 struct smbd_server_connection *sconn = smbd_server_conn;
2448 if (sconn->using_smb2) {
2449 /* Don't do keepalives on an SMB2 connection. */
2453 smbd_lock_socket(smbd_server_conn);
2454 ret = send_keepalive(sconn->sock);
2455 smbd_unlock_socket(smbd_server_conn);
2458 char addr[INET6_ADDRSTRLEN];
2460 * Try and give an error message saying what
2463 DEBUG(0, ("send_keepalive failed for client %s. "
2464 "Error %s - exiting\n",
2465 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2473 * Do the recurring check if we're idle
2475 static bool deadtime_fn(const struct timeval *now, void *private_data)
2477 struct smbd_server_connection *sconn =
2478 (struct smbd_server_connection *)private_data;
2480 if ((conn_num_open(sconn) == 0)
2481 || (conn_idle_all(sconn, now->tv_sec))) {
2482 DEBUG( 2, ( "Closing idle connection\n" ) );
2483 messaging_send(sconn->msg_ctx,
2484 messaging_server_id(sconn->msg_ctx),
2485 MSG_SHUTDOWN, &data_blob_null);
2493 * Do the recurring log file and smb.conf reload checks.
2496 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2498 struct smbd_server_connection *sconn = talloc_get_type_abort(
2499 private_data, struct smbd_server_connection);
2500 change_to_root_user();
2502 /* update printer queue caches if necessary */
2503 update_monitored_printq_cache(sconn->msg_ctx);
2505 /* check if we need to reload services */
2506 check_reload(sconn, time(NULL));
2508 /* Change machine password if neccessary. */
2509 attempt_machine_password_change();
2512 * Force a log file check.
2514 force_check_log_size();
2519 static int create_unlink_tmp(const char *dir)
2524 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2525 if (fname == NULL) {
2529 fd = mkstemp(fname);
2534 if (unlink(fname) == -1) {
2535 int sys_errno = errno;
2545 struct smbd_echo_state {
2546 struct tevent_context *ev;
2547 struct iovec *pending;
2548 struct smbd_server_connection *sconn;
2551 struct tevent_fd *parent_fde;
2553 struct tevent_fd *read_fde;
2554 struct tevent_req *write_req;
2557 static void smbd_echo_writer_done(struct tevent_req *req);
2559 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2563 if (state->write_req != NULL) {
2567 num_pending = talloc_array_length(state->pending);
2568 if (num_pending == 0) {
2572 state->write_req = writev_send(state, state->ev, NULL,
2573 state->parent_pipe, false,
2574 state->pending, num_pending);
2575 if (state->write_req == NULL) {
2576 DEBUG(1, ("writev_send failed\n"));
2580 talloc_steal(state->write_req, state->pending);
2581 state->pending = NULL;
2583 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2587 static void smbd_echo_writer_done(struct tevent_req *req)
2589 struct smbd_echo_state *state = tevent_req_callback_data(
2590 req, struct smbd_echo_state);
2594 written = writev_recv(req, &err);
2596 state->write_req = NULL;
2597 if (written == -1) {
2598 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2601 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2602 smbd_echo_activate_writer(state);
2605 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2608 struct smb_request req;
2609 uint16_t num_replies;
2614 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2615 DEBUG(10, ("Got netbios keepalive\n"));
2622 if (inbuf_len < smb_size) {
2623 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2626 if (!valid_smb_header(inbuf)) {
2627 DEBUG(10, ("Got invalid SMB header\n"));
2631 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2637 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2638 smb_messages[req.cmd].name
2639 ? smb_messages[req.cmd].name : "unknown"));
2641 if (req.cmd != SMBecho) {
2648 num_replies = SVAL(req.vwv+0, 0);
2649 if (num_replies != 1) {
2650 /* Not a Windows "Hey, you're still there?" request */
2654 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2656 DEBUG(10, ("create_outbuf failed\n"));
2659 req.outbuf = (uint8_t *)outbuf;
2661 SSVAL(req.outbuf, smb_vwv0, num_replies);
2663 if (req.buflen > 0) {
2664 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2667 out_len = smb_len(req.outbuf) + 4;
2669 ok = srv_send_smb(req.sconn,
2673 TALLOC_FREE(outbuf);
2681 static void smbd_echo_exit(struct tevent_context *ev,
2682 struct tevent_fd *fde, uint16_t flags,
2685 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2689 static void smbd_echo_reader(struct tevent_context *ev,
2690 struct tevent_fd *fde, uint16_t flags,
2693 struct smbd_echo_state *state = talloc_get_type_abort(
2694 private_data, struct smbd_echo_state);
2695 struct smbd_server_connection *sconn = state->sconn;
2696 size_t unread, num_pending;
2700 uint32_t seqnum = 0;
2703 bool encrypted = false;
2707 ok = smbd_lock_socket_internal(sconn);
2709 DEBUG(0, ("%s: failed to lock socket\n",
2714 if (!fd_is_readable(sconn->sock)) {
2715 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2716 (int)sys_getpid()));
2717 ok = smbd_unlock_socket_internal(sconn);
2719 DEBUG(1, ("%s: failed to unlock socket in\n",
2726 num_pending = talloc_array_length(state->pending);
2727 tmp = talloc_realloc(state, state->pending, struct iovec,
2730 DEBUG(1, ("talloc_realloc failed\n"));
2733 state->pending = tmp;
2735 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2737 status = receive_smb_talloc(state->pending, sconn,
2738 (char **)(void *)&state->pending[num_pending].iov_base,
2744 false /* trusted_channel*/);
2745 if (!NT_STATUS_IS_OK(status)) {
2746 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2747 (int)sys_getpid(), nt_errstr(status)));
2750 state->pending[num_pending].iov_len = iov_len;
2752 ok = smbd_unlock_socket_internal(sconn);
2754 DEBUG(1, ("%s: failed to unlock socket in\n",
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,
2771 if (state->pending[num_pending].iov_len >= smb_size) {
2773 * place the seqnum in the packet so that the main process
2774 * can reply with signing
2776 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2777 smb_ss_field, seqnum);
2778 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2779 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2782 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2783 smbd_echo_activate_writer(state);
2786 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2789 struct smbd_echo_state *state;
2791 state = talloc_zero(sconn, struct smbd_echo_state);
2792 if (state == NULL) {
2793 DEBUG(1, ("talloc failed\n"));
2796 state->sconn = sconn;
2797 state->parent_pipe = parent_pipe;
2798 state->ev = s3_tevent_context_init(state);
2799 if (state->ev == NULL) {
2800 DEBUG(1, ("tevent_context_init failed\n"));
2804 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2805 TEVENT_FD_READ, smbd_echo_exit,
2807 if (state->parent_fde == NULL) {
2808 DEBUG(1, ("tevent_add_fd failed\n"));
2812 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2813 TEVENT_FD_READ, smbd_echo_reader,
2815 if (state->read_fde == NULL) {
2816 DEBUG(1, ("tevent_add_fd failed\n"));
2822 if (tevent_loop_once(state->ev) == -1) {
2823 DEBUG(1, ("tevent_loop_once failed: %s\n",
2832 * Handle SMBecho requests in a forked child process
2834 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2836 int listener_pipe[2];
2840 res = pipe(listener_pipe);
2842 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2845 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2846 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2847 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2855 close(listener_pipe[0]);
2856 set_blocking(listener_pipe[1], false);
2858 status = reinit_after_fork(sconn->msg_ctx,
2859 smbd_event_context(),
2860 procid_self(), false);
2861 if (!NT_STATUS_IS_OK(status)) {
2862 DEBUG(1, ("reinit_after_fork failed: %s\n",
2863 nt_errstr(status)));
2866 smbd_echo_loop(sconn, listener_pipe[1]);
2869 close(listener_pipe[1]);
2870 listener_pipe[1] = -1;
2871 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2873 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2876 * Without smb signing this is the same as the normal smbd
2877 * listener. This needs to change once signing comes in.
2879 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2881 sconn->smb1.echo_handler.trusted_fd,
2883 smbd_server_echo_handler,
2885 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2886 DEBUG(1, ("event_add_fd failed\n"));
2893 if (listener_pipe[0] != -1) {
2894 close(listener_pipe[0]);
2896 if (listener_pipe[1] != -1) {
2897 close(listener_pipe[1]);
2899 sconn->smb1.echo_handler.trusted_fd = -1;
2900 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2901 close(sconn->smb1.echo_handler.socket_lock_fd);
2903 sconn->smb1.echo_handler.trusted_fd = -1;
2904 sconn->smb1.echo_handler.socket_lock_fd = -1;
2910 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2911 struct sockaddr_storage *srv,
2912 struct sockaddr_storage *clnt)
2914 struct ctdbd_connection *cconn;
2915 char tmp_addr[INET6_ADDRSTRLEN];
2918 cconn = messaging_ctdbd_connection();
2919 if (cconn == NULL) {
2920 return NT_STATUS_NO_MEMORY;
2923 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2924 addr = talloc_strdup(cconn, tmp_addr);
2926 return NT_STATUS_NO_MEMORY;
2928 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2933 /****************************************************************************
2934 Process commands from the client
2935 ****************************************************************************/
2937 void smbd_process(struct smbd_server_connection *sconn)
2939 TALLOC_CTX *frame = talloc_stackframe();
2940 struct sockaddr_storage ss;
2941 struct sockaddr *sa = NULL;
2942 socklen_t sa_socklen;
2943 struct tsocket_address *local_address = NULL;
2944 struct tsocket_address *remote_address = NULL;
2945 const char *remaddr = NULL;
2948 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2949 lp_security() != SEC_SHARE &&
2950 !lp_async_smb_echo_handler()) {
2952 * We're not making the desion here,
2953 * we're just allowing the client
2954 * to decide between SMB1 and SMB2
2955 * with the first negprot
2958 sconn->using_smb2 = true;
2961 /* Ensure child is set to blocking mode */
2962 set_blocking(sconn->sock,True);
2964 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2965 set_socket_options(sconn->sock, lp_socket_options());
2967 sa = (struct sockaddr *)(void *)&ss;
2968 sa_socklen = sizeof(ss);
2969 ret = getpeername(sconn->sock, sa, &sa_socklen);
2971 int level = (errno == ENOTCONN)?2:0;
2972 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2973 exit_server_cleanly("getpeername() failed.\n");
2975 ret = tsocket_address_bsd_from_sockaddr(sconn,
2979 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2980 __location__, strerror(errno)));
2981 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2984 sa = (struct sockaddr *)(void *)&ss;
2985 sa_socklen = sizeof(ss);
2986 ret = getsockname(sconn->sock, sa, &sa_socklen);
2988 int level = (errno == ENOTCONN)?2:0;
2989 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2990 exit_server_cleanly("getsockname() failed.\n");
2992 ret = tsocket_address_bsd_from_sockaddr(sconn,
2996 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2997 __location__, strerror(errno)));
2998 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3001 sconn->local_address = local_address;
3002 sconn->remote_address = remote_address;
3004 if (tsocket_address_is_inet(remote_address, "ip")) {
3005 remaddr = tsocket_address_inet_addr_string(
3006 sconn->remote_address,
3008 if (remaddr == NULL) {
3012 remaddr = "0.0.0.0";
3015 /* this is needed so that we get decent entries
3016 in smbstatus for port 445 connects */
3017 set_remote_machine_name(remaddr, false);
3018 reload_services(sconn->msg_ctx, sconn->sock, true);
3021 * Before the first packet, check the global hosts allow/ hosts deny
3022 * parameters before doing any parsing of packets passed to us by the
3023 * client. This prevents attacks on our parsing code from hosts not in
3024 * the hosts allow list.
3027 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3028 sconn->client_id.name,
3029 sconn->client_id.addr)) {
3031 * send a negative session response "not listening on calling
3034 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3035 DEBUG( 1, ("Connection denied from %s to %s\n",
3036 tsocket_address_string(remote_address, talloc_tos()),
3037 tsocket_address_string(local_address, talloc_tos())));
3038 (void)srv_send_smb(sconn,(char *)buf, false,
3040 exit_server_cleanly("connection denied");
3043 DEBUG(10, ("Connection allowed from %s to %s\n",
3044 tsocket_address_string(remote_address, talloc_tos()),
3045 tsocket_address_string(local_address, talloc_tos())));
3049 smb_perfcount_init();
3051 if (!init_account_policy()) {
3052 exit_server("Could not open account policy tdb.\n");
3055 if (*lp_rootdir()) {
3056 if (chroot(lp_rootdir()) != 0) {
3057 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3058 exit_server("Failed to chroot()");
3060 if (chdir("/") == -1) {
3061 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3062 exit_server("Failed to chroot()");
3064 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3067 if (!srv_init_signing(sconn)) {
3068 exit_server("Failed to init smb_signing");
3071 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3072 exit_server("Failed to fork echo handler");
3076 if (!init_oplocks(sconn->msg_ctx))
3077 exit_server("Failed to init oplocks");
3079 /* register our message handlers */
3080 messaging_register(sconn->msg_ctx, NULL,
3081 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3082 messaging_register(sconn->msg_ctx, sconn,
3083 MSG_SMB_RELEASE_IP, msg_release_ip);
3084 messaging_register(sconn->msg_ctx, NULL,
3085 MSG_SMB_CLOSE_FILE, msg_close_file);
3088 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3089 * MSGs to all child processes
3091 messaging_deregister(sconn->msg_ctx,
3093 messaging_register(sconn->msg_ctx, NULL,
3094 MSG_DEBUG, debug_message);
3096 if ((lp_keepalive() != 0)
3097 && !(event_add_idle(smbd_event_context(), NULL,
3098 timeval_set(lp_keepalive(), 0),
3099 "keepalive", keepalive_fn,
3101 DEBUG(0, ("Could not add keepalive event\n"));
3105 if (!(event_add_idle(smbd_event_context(), NULL,
3106 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3107 "deadtime", deadtime_fn, sconn))) {
3108 DEBUG(0, ("Could not add deadtime event\n"));
3112 if (!(event_add_idle(smbd_event_context(), NULL,
3113 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3114 "housekeeping", housekeeping_fn, sconn))) {
3115 DEBUG(0, ("Could not add housekeeping event\n"));
3119 #ifdef CLUSTER_SUPPORT
3121 if (lp_clustering()) {
3123 * We need to tell ctdb about our client's TCP
3124 * connection, so that for failover ctdbd can send
3125 * tickle acks, triggering a reconnection by the
3129 struct sockaddr_storage srv, clnt;
3131 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3133 status = smbd_register_ips(sconn, &srv, &clnt);
3134 if (!NT_STATUS_IS_OK(status)) {
3135 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3136 nt_errstr(status)));
3140 DEBUG(0,("Unable to get tcp info for "
3141 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3148 sconn->nbt.got_session = false;
3150 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3152 sconn->smb1.sessions.done_sesssetup = false;
3153 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3154 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3155 /* users from session setup */
3156 sconn->smb1.sessions.session_userlist = NULL;
3157 /* workgroup from session setup. */
3158 sconn->smb1.sessions.session_workgroup = NULL;
3159 /* this holds info on user ids that are already validated for this VC */
3160 sconn->smb1.sessions.validated_users = NULL;
3161 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3162 sconn->smb1.sessions.num_validated_vuids = 0;
3165 if (!init_dptrs(sconn)) {
3166 exit_server("init_dptrs() failed");
3169 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3173 smbd_server_connection_handler,
3175 if (!sconn->smb1.fde) {
3176 exit_server("failed to create smbd_server_connection fde");
3184 frame = talloc_stackframe_pool(8192);
3188 status = smbd_server_connection_loop_once(sconn);
3189 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3190 !NT_STATUS_IS_OK(status)) {
3191 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3192 " exiting\n", nt_errstr(status)));
3199 exit_server_cleanly(NULL);
3202 bool req_is_in_chain(struct smb_request *req)
3204 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3206 * We're right now handling a subsequent request, so we must
3212 if (!is_andx_req(req->cmd)) {
3218 * Okay, an illegal request, but definitely not chained :-)
3223 return (CVAL(req->vwv+0, 0) != 0xFF);