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()));
51 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
52 SMB_F_SETLKW, 0, 0, F_WRLCK);
57 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
62 void smbd_lock_socket(struct smbd_server_connection *sconn)
64 if (!smbd_lock_socket_internal(sconn)) {
65 exit_server_cleanly("failed to lock socket");
69 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
73 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
77 sconn->smb1.echo_handler.ref_count--;
79 if (sconn->smb1.echo_handler.ref_count > 0) {
83 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
84 SMB_F_SETLKW, 0, 0, F_UNLCK);
89 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
94 void smbd_unlock_socket(struct smbd_server_connection *sconn)
96 if (!smbd_unlock_socket_internal(sconn)) {
97 exit_server_cleanly("failed to unlock socket");
101 /* Accessor function for smb_read_error for smbd functions. */
103 /****************************************************************************
105 ****************************************************************************/
107 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
108 bool do_signing, uint32_t seqnum,
110 struct smb_perfcount_data *pcd)
115 char *buf_out = buffer;
117 smbd_lock_socket(sconn);
120 /* Sign the outgoing packet if required. */
121 srv_calculate_sign_mac(sconn, buf_out, seqnum);
125 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
126 if (!NT_STATUS_IS_OK(status)) {
127 DEBUG(0, ("send_smb: SMB encryption failed "
128 "on outgoing packet! Error %s\n",
129 nt_errstr(status) ));
134 len = smb_len(buf_out) + 4;
136 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
139 char addr[INET6_ADDRSTRLEN];
141 * Try and give an error message saying what
144 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
145 (int)sys_getpid(), (int)len,
146 get_peer_addr(sconn->sock, addr, sizeof(addr)),
147 (int)ret, strerror(errno) ));
149 srv_free_enc_buffer(buf_out);
153 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
154 srv_free_enc_buffer(buf_out);
156 SMB_PERFCOUNT_END(pcd);
158 smbd_unlock_socket(sconn);
162 /*******************************************************************
163 Setup the word count and byte count for a smb message.
164 ********************************************************************/
166 int srv_set_message(char *buf,
171 if (zero && (num_words || num_bytes)) {
172 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
174 SCVAL(buf,smb_wct,num_words);
175 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
176 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
177 return (smb_size + num_words*2 + num_bytes);
180 static bool valid_smb_header(const uint8_t *inbuf)
182 if (is_encrypted_packet(inbuf)) {
186 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
187 * but it just looks weird to call strncmp for this one.
189 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
192 /* Socket functions for smbd packet processing. */
194 static bool valid_packet_size(size_t len)
197 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
198 * of header. Don't print the error if this fits.... JRA.
201 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
202 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
203 (unsigned long)len));
209 static NTSTATUS read_packet_remainder(int fd, char *buffer,
210 unsigned int timeout, ssize_t len)
218 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
219 if (!NT_STATUS_IS_OK(status)) {
220 char addr[INET6_ADDRSTRLEN];
221 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
223 get_peer_addr(fd, addr, sizeof(addr)),
229 /****************************************************************************
230 Attempt a zerocopy writeX read. We know here that len > smb_size-4
231 ****************************************************************************/
234 * Unfortunately, earlier versions of smbclient/libsmbclient
235 * don't send this "standard" writeX header. I've fixed this
236 * for 3.2 but we'll use the old method with earlier versions.
237 * Windows and CIFSFS at least use this standard size. Not
241 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
242 (2*14) + /* word count (including bcc) */ \
245 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
246 const char lenbuf[4],
247 struct smbd_server_connection *sconn,
249 unsigned int timeout,
253 /* Size of a WRITEX call (+4 byte len). */
254 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
255 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
259 memcpy(writeX_header, lenbuf, 4);
261 status = read_fd_with_timeout(
262 sconn->sock, writeX_header + 4,
263 STANDARD_WRITE_AND_X_HEADER_SIZE,
264 STANDARD_WRITE_AND_X_HEADER_SIZE,
267 if (!NT_STATUS_IS_OK(status)) {
268 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
269 "error = %s.\n", sconn->client_id.addr,
275 * Ok - now try and see if this is a possible
279 if (is_valid_writeX_buffer(sconn, (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(sconn->sock, 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(
345 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
348 if (!NT_STATUS_IS_OK(status)) {
349 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
359 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
360 struct smbd_server_connection *sconn,
361 char **buffer, unsigned int timeout,
362 size_t *p_unread, size_t *plen)
366 int min_recv_size = lp_min_receive_file_size();
371 status = read_smb_length_return_keepalive(sconn->sock, lenbuf, timeout,
373 if (!NT_STATUS_IS_OK(status)) {
377 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
378 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
379 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
380 !srv_is_signing_active(sconn) &&
381 sconn->smb1.echo_handler.trusted_fde == NULL) {
383 return receive_smb_raw_talloc_partial_read(
384 mem_ctx, lenbuf, sconn, buffer, timeout,
388 if (!valid_packet_size(len)) {
389 return NT_STATUS_INVALID_PARAMETER;
393 * The +4 here can't wrap, we've checked the length above already.
396 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
398 if (*buffer == NULL) {
399 DEBUG(0, ("Could not allocate inbuf of length %d\n",
401 return NT_STATUS_NO_MEMORY;
404 memcpy(*buffer, lenbuf, sizeof(lenbuf));
406 status = read_packet_remainder(sconn->sock, (*buffer)+4, timeout, len);
407 if (!NT_STATUS_IS_OK(status)) {
415 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
416 struct smbd_server_connection *sconn,
417 char **buffer, unsigned int timeout,
418 size_t *p_unread, bool *p_encrypted,
421 bool trusted_channel)
426 *p_encrypted = false;
428 status = receive_smb_raw_talloc(mem_ctx, sconn, buffer, timeout,
430 if (!NT_STATUS_IS_OK(status)) {
431 DEBUG(1, ("read_smb_length_return_keepalive failed for "
432 "client %s read error = %s.\n",
433 sconn->client_id.addr, nt_errstr(status)));
437 if (is_encrypted_packet((uint8_t *)*buffer)) {
438 status = srv_decrypt_buffer(*buffer);
439 if (!NT_STATUS_IS_OK(status)) {
440 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
441 "incoming packet! Error %s\n",
442 nt_errstr(status) ));
448 /* Check the incoming SMB signature. */
449 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
450 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
451 "incoming packet!\n"));
452 return NT_STATUS_INVALID_NETWORK_RESPONSE;
460 * Initialize a struct smb_request from an inbuf
463 static bool init_smb_request(struct smb_request *req,
464 struct smbd_server_connection *sconn,
466 size_t unread_bytes, bool encrypted,
469 size_t req_size = smb_len(inbuf) + 4;
470 /* Ensure we have at least smb_size bytes. */
471 if (req_size < smb_size) {
472 DEBUG(0,("init_smb_request: invalid request size %u\n",
473 (unsigned int)req_size ));
476 req->cmd = CVAL(inbuf, smb_com);
477 req->flags2 = SVAL(inbuf, smb_flg2);
478 req->smbpid = SVAL(inbuf, smb_pid);
479 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
480 req->seqnum = seqnum;
481 req->vuid = SVAL(inbuf, smb_uid);
482 req->tid = SVAL(inbuf, smb_tid);
483 req->wct = CVAL(inbuf, smb_wct);
484 req->vwv = (uint16_t *)(inbuf+smb_vwv);
485 req->buflen = smb_buflen(inbuf);
486 req->buf = (const uint8_t *)smb_buf(inbuf);
487 req->unread_bytes = unread_bytes;
488 req->encrypted = encrypted;
490 req->conn = conn_find(sconn,req->tid);
491 req->chain_fsp = NULL;
492 req->chain_outbuf = NULL;
495 smb_init_perfcount_data(&req->pcd);
497 /* Ensure we have at least wct words and 2 bytes of bcc. */
498 if (smb_size + req->wct*2 > req_size) {
499 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
500 (unsigned int)req->wct,
501 (unsigned int)req_size));
504 /* Ensure bcc is correct. */
505 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
506 DEBUG(0,("init_smb_request: invalid bcc number %u "
507 "(wct = %u, size %u)\n",
508 (unsigned int)req->buflen,
509 (unsigned int)req->wct,
510 (unsigned int)req_size));
518 static void process_smb(struct smbd_server_connection *conn,
519 uint8_t *inbuf, size_t nread, size_t unread_bytes,
520 uint32_t seqnum, bool encrypted,
521 struct smb_perfcount_data *deferred_pcd);
523 static void smbd_deferred_open_timer(struct event_context *ev,
524 struct timed_event *te,
525 struct timeval _tval,
528 struct pending_message_list *msg = talloc_get_type(private_data,
529 struct pending_message_list);
530 TALLOC_CTX *mem_ctx = talloc_tos();
531 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
534 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
537 exit_server("smbd_deferred_open_timer: talloc failed\n");
541 /* We leave this message on the queue so the open code can
542 know this is a retry. */
543 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
544 (unsigned long long)mid ));
546 /* Mark the message as processed so this is not
547 * re-processed in error. */
548 msg->processed = true;
550 process_smb(smbd_server_conn, inbuf,
552 msg->seqnum, msg->encrypted, &msg->pcd);
554 /* If it's still there and was processed, remove it. */
555 msg = get_deferred_open_message_smb(mid);
556 if (msg && msg->processed) {
557 remove_deferred_open_message_smb(mid);
561 /****************************************************************************
562 Function to push a message onto the tail of a linked list of smb messages ready
564 ****************************************************************************/
566 static bool push_queued_message(struct smb_request *req,
567 struct timeval request_time,
568 struct timeval end_time,
569 char *private_data, size_t private_len)
571 int msg_len = smb_len(req->inbuf) + 4;
572 struct pending_message_list *msg;
574 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
577 DEBUG(0,("push_message: malloc fail (1)\n"));
581 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
582 if(msg->buf.data == NULL) {
583 DEBUG(0,("push_message: malloc fail (2)\n"));
588 msg->request_time = request_time;
589 msg->seqnum = req->seqnum;
590 msg->encrypted = req->encrypted;
591 msg->processed = false;
592 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
595 msg->private_data = data_blob_talloc(msg, private_data,
597 if (msg->private_data.data == NULL) {
598 DEBUG(0,("push_message: malloc fail (3)\n"));
604 msg->te = event_add_timed(smbd_event_context(),
607 smbd_deferred_open_timer,
610 DEBUG(0,("push_message: event_add_timed failed\n"));
615 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
617 DEBUG(10,("push_message: pushed message length %u on "
618 "deferred_open_queue\n", (unsigned int)msg_len));
623 /****************************************************************************
624 Function to delete a sharing violation open message by mid.
625 ****************************************************************************/
627 void remove_deferred_open_message_smb(uint64_t mid)
629 struct pending_message_list *pml;
631 if (smbd_server_conn->using_smb2) {
632 remove_deferred_open_message_smb2(smbd_server_conn, mid);
636 for (pml = deferred_open_queue; pml; pml = pml->next) {
637 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
638 DEBUG(10,("remove_deferred_open_message_smb: "
639 "deleting mid %llu len %u\n",
640 (unsigned long long)mid,
641 (unsigned int)pml->buf.length ));
642 DLIST_REMOVE(deferred_open_queue, pml);
649 /****************************************************************************
650 Move a sharing violation open retry message to the front of the list and
651 schedule it for immediate processing.
652 ****************************************************************************/
654 void schedule_deferred_open_message_smb(uint64_t mid)
656 struct pending_message_list *pml;
659 if (smbd_server_conn->using_smb2) {
660 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
664 for (pml = deferred_open_queue; pml; pml = pml->next) {
665 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
667 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
670 (unsigned long long)msg_mid ));
672 if (mid == msg_mid) {
673 struct timed_event *te;
675 if (pml->processed) {
676 /* A processed message should not be
678 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
679 "message mid %llu was already processed\n",
680 (unsigned long long)msg_mid ));
684 DEBUG(10,("schedule_deferred_open_message_smb: "
685 "scheduling mid %llu\n",
686 (unsigned long long)mid ));
688 te = event_add_timed(smbd_event_context(),
691 smbd_deferred_open_timer,
694 DEBUG(10,("schedule_deferred_open_message_smb: "
695 "event_add_timed() failed, "
696 "skipping mid %llu\n",
697 (unsigned long long)msg_mid ));
700 TALLOC_FREE(pml->te);
702 DLIST_PROMOTE(deferred_open_queue, pml);
707 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
708 "find message mid %llu\n",
709 (unsigned long long)mid ));
712 /****************************************************************************
713 Return true if this mid is on the deferred queue and was not yet processed.
714 ****************************************************************************/
716 bool open_was_deferred(uint64_t mid)
718 struct pending_message_list *pml;
720 if (smbd_server_conn->using_smb2) {
721 return open_was_deferred_smb2(smbd_server_conn, mid);
724 for (pml = deferred_open_queue; pml; pml = pml->next) {
725 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
732 /****************************************************************************
733 Return the message queued by this mid.
734 ****************************************************************************/
736 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
738 struct pending_message_list *pml;
740 for (pml = deferred_open_queue; pml; pml = pml->next) {
741 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
748 /****************************************************************************
749 Get the state data queued by this mid.
750 ****************************************************************************/
752 bool get_deferred_open_message_state(struct smb_request *smbreq,
753 struct timeval *p_request_time,
756 struct pending_message_list *pml;
758 if (smbd_server_conn->using_smb2) {
759 return get_deferred_open_message_state_smb2(smbreq->smb2req,
764 pml = get_deferred_open_message_smb(smbreq->mid);
768 if (p_request_time) {
769 *p_request_time = pml->request_time;
772 *pp_state = (void *)pml->private_data.data;
777 /****************************************************************************
778 Function to push a deferred open smb message onto a linked list of local smb
779 messages ready for processing.
780 ****************************************************************************/
782 bool push_deferred_open_message_smb(struct smb_request *req,
783 struct timeval request_time,
784 struct timeval timeout,
786 char *private_data, size_t priv_len)
788 struct timeval end_time;
791 return push_deferred_open_message_smb2(req->smb2req,
799 if (req->unread_bytes) {
800 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
801 "unread_bytes = %u\n",
802 (unsigned int)req->unread_bytes ));
803 smb_panic("push_deferred_open_message_smb: "
804 "logic error unread_bytes != 0" );
807 end_time = timeval_sum(&request_time, &timeout);
809 DEBUG(10,("push_deferred_open_message_smb: pushing message "
810 "len %u mid %llu timeout time [%u.%06u]\n",
811 (unsigned int) smb_len(req->inbuf)+4,
812 (unsigned long long)req->mid,
813 (unsigned int)end_time.tv_sec,
814 (unsigned int)end_time.tv_usec));
816 return push_queued_message(req, request_time, end_time,
817 private_data, priv_len);
821 struct timed_event *te;
822 struct timeval interval;
824 bool (*handler)(const struct timeval *now, void *private_data);
828 static void smbd_idle_event_handler(struct event_context *ctx,
829 struct timed_event *te,
833 struct idle_event *event =
834 talloc_get_type_abort(private_data, struct idle_event);
836 TALLOC_FREE(event->te);
838 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
839 event->name, event->te));
841 if (!event->handler(&now, event->private_data)) {
842 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
843 event->name, event->te));
844 /* Don't repeat, delete ourselves */
849 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
850 event->name, event->te));
852 event->te = event_add_timed(ctx, event,
853 timeval_sum(&now, &event->interval),
854 smbd_idle_event_handler, event);
856 /* We can't do much but fail here. */
857 SMB_ASSERT(event->te != NULL);
860 struct idle_event *event_add_idle(struct event_context *event_ctx,
862 struct timeval interval,
864 bool (*handler)(const struct timeval *now,
868 struct idle_event *result;
869 struct timeval now = timeval_current();
871 result = TALLOC_P(mem_ctx, struct idle_event);
872 if (result == NULL) {
873 DEBUG(0, ("talloc failed\n"));
877 result->interval = interval;
878 result->handler = handler;
879 result->private_data = private_data;
881 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
882 DEBUG(0, ("talloc failed\n"));
887 result->te = event_add_timed(event_ctx, result,
888 timeval_sum(&now, &interval),
889 smbd_idle_event_handler, result);
890 if (result->te == NULL) {
891 DEBUG(0, ("event_add_timed failed\n"));
896 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
900 static void smbd_sig_term_handler(struct tevent_context *ev,
901 struct tevent_signal *se,
907 exit_server_cleanly("termination signal");
910 void smbd_setup_sig_term_handler(void)
912 struct tevent_signal *se;
914 se = tevent_add_signal(smbd_event_context(),
915 smbd_event_context(),
917 smbd_sig_term_handler,
920 exit_server("failed to setup SIGTERM handler");
924 static void smbd_sig_hup_handler(struct tevent_context *ev,
925 struct tevent_signal *se,
931 struct messaging_context *msg_ctx = talloc_get_type_abort(
932 private_data, struct messaging_context);
933 change_to_root_user();
934 DEBUG(1,("Reloading services after SIGHUP\n"));
935 reload_services(msg_ctx, smbd_server_conn->sock, False);
938 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
939 struct messaging_context *msg_ctx)
941 struct tevent_signal *se;
943 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
946 exit_server("failed to setup SIGHUP handler");
950 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
957 to.tv_sec = SMBD_SELECT_TIMEOUT;
961 * Setup the select fd sets.
968 * Are there any timed events waiting ? If so, ensure we don't
969 * select for longer than it would take to wait for them.
976 event_add_to_select_args(smbd_event_context(), &now,
977 &r_fds, &w_fds, &to, &maxfd);
980 /* Process a signal and timed events now... */
981 if (run_events(smbd_event_context(), &selrtn, NULL, NULL)) {
982 return NT_STATUS_RETRY;
987 START_PROFILE(smbd_idle);
989 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
992 END_PROFILE(smbd_idle);
999 return NT_STATUS_RETRY;
1001 /* Maybe the socket is dead? */
1002 return map_nt_error_from_unix(errno);
1005 /* Process events until all available fds have been handled.
1006 * This allows for fair round-robin handling of all available fds
1007 * on each select() wakeup, while still maintaining responsiveness
1008 * by re-checking for signal and timed events between the handling
1009 * of each ready fd. */
1011 run_events(smbd_event_context(), &selrtn, &r_fds, &w_fds);
1012 } while (selrtn > 0);
1014 /* Processed all fds or timed out */
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(struct smbd_server_connection *sconn,
1574 char *inbuf, int size, size_t unread_bytes,
1575 uint32_t seqnum, bool encrypted,
1576 struct smb_perfcount_data *deferred_pcd)
1578 connection_struct *conn;
1579 struct smb_request *req;
1581 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1582 smb_panic("could not allocate smb_request");
1585 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1586 encrypted, seqnum)) {
1587 exit_server_cleanly("Invalid SMB request");
1590 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1592 /* we popped this message off the queue - keep original perf data */
1594 req->pcd = *deferred_pcd;
1596 SMB_PERFCOUNT_START(&req->pcd);
1597 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1598 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1601 conn = switch_message(req->cmd, req, size);
1603 if (req->unread_bytes) {
1604 /* writeX failed. drain socket. */
1605 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1606 req->unread_bytes) {
1607 smb_panic("failed to drain pending bytes");
1609 req->unread_bytes = 0;
1617 if (req->outbuf == NULL) {
1621 if (CVAL(req->outbuf,0) == 0) {
1622 show_msg((char *)req->outbuf);
1625 if (!srv_send_smb(req->sconn,
1626 (char *)req->outbuf,
1627 true, req->seqnum+1,
1628 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1630 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1638 /****************************************************************************
1639 Process an smb from the client
1640 ****************************************************************************/
1641 static void process_smb(struct smbd_server_connection *sconn,
1642 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1643 uint32_t seqnum, bool encrypted,
1644 struct smb_perfcount_data *deferred_pcd)
1646 int msg_type = CVAL(inbuf,0);
1648 DO_PROFILE_INC(smb_count);
1650 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1652 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1653 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1655 if (msg_type != 0) {
1657 * NetBIOS session request, keepalive, etc.
1659 reply_special(sconn, (char *)inbuf, nread);
1663 if (sconn->using_smb2) {
1664 /* At this point we're not really using smb2,
1665 * we make the decision here.. */
1666 if (smbd_is_smb2_header(inbuf, nread)) {
1667 smbd_smb2_first_negprot(sconn, inbuf, nread);
1669 } else if (nread >= smb_size && valid_smb_header(inbuf)
1670 && CVAL(inbuf, smb_com) != 0x72) {
1671 /* This is a non-negprot SMB1 packet.
1672 Disable SMB2 from now on. */
1673 sconn->using_smb2 = false;
1677 show_msg((char *)inbuf);
1679 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1680 encrypted, deferred_pcd);
1684 sconn->smb1.num_requests++;
1686 /* The timeout_processing function isn't run nearly
1687 often enough to implement 'max log size' without
1688 overrunning the size of the file by many megabytes.
1689 This is especially true if we are running at debug
1690 level 10. Checking every 50 SMBs is a nice
1691 tradeoff of performance vs log file size overrun. */
1693 if ((sconn->smb1.num_requests % 50) == 0 &&
1694 need_to_check_log_size()) {
1695 change_to_root_user();
1700 /****************************************************************************
1701 Return a string containing the function name of a SMB command.
1702 ****************************************************************************/
1704 const char *smb_fn_name(int type)
1706 const char *unknown_name = "SMBunknown";
1708 if (smb_messages[type].name == NULL)
1709 return(unknown_name);
1711 return(smb_messages[type].name);
1714 /****************************************************************************
1715 Helper functions for contruct_reply.
1716 ****************************************************************************/
1718 void add_to_common_flags2(uint32 v)
1723 void remove_from_common_flags2(uint32 v)
1725 common_flags2 &= ~v;
1728 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1731 srv_set_message(outbuf,0,0,false);
1733 SCVAL(outbuf, smb_com, req->cmd);
1734 SIVAL(outbuf,smb_rcls,0);
1735 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1736 SSVAL(outbuf,smb_flg2,
1737 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1739 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1741 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1742 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1743 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1744 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1747 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1749 construct_reply_common(req, (char *)req->inbuf, outbuf);
1753 * How many bytes have we already accumulated up to the current wct field
1757 size_t req_wct_ofs(struct smb_request *req)
1761 if (req->chain_outbuf == NULL) {
1764 buf_size = talloc_get_size(req->chain_outbuf);
1765 if ((buf_size % 4) != 0) {
1766 buf_size += (4 - (buf_size % 4));
1768 return buf_size - 4;
1772 * Hack around reply_nterror & friends not being aware of chained requests,
1773 * generating illegal (i.e. wct==0) chain replies.
1776 static void fixup_chain_error_packet(struct smb_request *req)
1778 uint8_t *outbuf = req->outbuf;
1780 reply_outbuf(req, 2, 0);
1781 memcpy(req->outbuf, outbuf, smb_wct);
1782 TALLOC_FREE(outbuf);
1783 SCVAL(req->outbuf, smb_vwv0, 0xff);
1787 * @brief Find the smb_cmd offset of the last command pushed
1788 * @param[in] buf The buffer we're building up
1789 * @retval Where can we put our next andx cmd?
1791 * While chaining requests, the "next" request we're looking at needs to put
1792 * its SMB_Command before the data the previous request already built up added
1793 * to the chain. Find the offset to the place where we have to put our cmd.
1796 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1801 cmd = CVAL(buf, smb_com);
1803 SMB_ASSERT(is_andx_req(cmd));
1807 while (CVAL(buf, ofs) != 0xff) {
1809 if (!is_andx_req(CVAL(buf, ofs))) {
1814 * ofs is from start of smb header, so add the 4 length
1815 * bytes. The next cmd is right after the wct field.
1817 ofs = SVAL(buf, ofs+2) + 4 + 1;
1819 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1827 * @brief Do the smb chaining at a buffer level
1828 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1829 * @param[in] smb_command The command that we want to issue
1830 * @param[in] wct How many words?
1831 * @param[in] vwv The words, already in network order
1832 * @param[in] bytes_alignment How shall we align "bytes"?
1833 * @param[in] num_bytes How many bytes?
1834 * @param[in] bytes The data the request ships
1836 * smb_splice_chain() adds the vwv and bytes to the request already present in
1840 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1841 uint8_t wct, const uint16_t *vwv,
1842 size_t bytes_alignment,
1843 uint32_t num_bytes, const uint8_t *bytes)
1846 size_t old_size, new_size;
1848 size_t chain_padding = 0;
1849 size_t bytes_padding = 0;
1852 old_size = talloc_get_size(*poutbuf);
1855 * old_size == smb_wct means we're pushing the first request in for
1859 first_request = (old_size == smb_wct);
1861 if (!first_request && ((old_size % 4) != 0)) {
1863 * Align the wct field of subsequent requests to a 4-byte
1866 chain_padding = 4 - (old_size % 4);
1870 * After the old request comes the new wct field (1 byte), the vwv's
1871 * and the num_bytes field. After at we might need to align the bytes
1872 * given to us to "bytes_alignment", increasing the num_bytes value.
1875 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1877 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1878 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1881 new_size += bytes_padding + num_bytes;
1883 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1884 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1885 (unsigned)new_size));
1889 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1890 if (outbuf == NULL) {
1891 DEBUG(0, ("talloc failed\n"));
1896 if (first_request) {
1897 SCVAL(outbuf, smb_com, smb_command);
1899 size_t andx_cmd_ofs;
1901 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1902 DEBUG(1, ("invalid command chain\n"));
1903 *poutbuf = TALLOC_REALLOC_ARRAY(
1904 NULL, *poutbuf, uint8_t, old_size);
1908 if (chain_padding != 0) {
1909 memset(outbuf + old_size, 0, chain_padding);
1910 old_size += chain_padding;
1913 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1914 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1920 * Push the chained request:
1925 SCVAL(outbuf, ofs, wct);
1932 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1933 ofs += sizeof(uint16_t) * wct;
1939 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1940 ofs += sizeof(uint16_t);
1946 if (bytes_padding != 0) {
1947 memset(outbuf + ofs, 0, bytes_padding);
1948 ofs += bytes_padding;
1955 memcpy(outbuf + ofs, bytes, num_bytes);
1960 /****************************************************************************
1961 Construct a chained reply and add it to the already made reply
1962 ****************************************************************************/
1964 void chain_reply(struct smb_request *req)
1966 size_t smblen = smb_len(req->inbuf);
1967 size_t already_used, length_needed;
1969 uint32_t chain_offset; /* uint32_t to avoid overflow */
1976 if (IVAL(req->outbuf, smb_rcls) != 0) {
1977 fixup_chain_error_packet(req);
1981 * Any of the AndX requests and replies have at least a wct of
1982 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1983 * beginning of the SMB header to the next wct field.
1985 * None of the AndX requests put anything valuable in vwv[0] and [1],
1986 * so we can overwrite it here to form the chain.
1989 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1990 if (req->chain_outbuf == NULL) {
1991 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1992 req, req->outbuf, uint8_t,
1993 smb_len(req->outbuf) + 4);
1994 if (req->chain_outbuf == NULL) {
1995 smb_panic("talloc failed");
2003 * Here we assume that this is the end of the chain. For that we need
2004 * to set "next command" to 0xff and the offset to 0. If we later find
2005 * more commands in the chain, this will be overwritten again.
2008 SCVAL(req->outbuf, smb_vwv0, 0xff);
2009 SCVAL(req->outbuf, smb_vwv0+1, 0);
2010 SSVAL(req->outbuf, smb_vwv1, 0);
2012 if (req->chain_outbuf == NULL) {
2014 * In req->chain_outbuf we collect all the replies. Start the
2015 * chain by copying in the first reply.
2017 * We do the realloc because later on we depend on
2018 * talloc_get_size to determine the length of
2019 * chain_outbuf. The reply_xxx routines might have
2020 * over-allocated (reply_pipe_read_and_X used to be such an
2023 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2024 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2025 if (req->chain_outbuf == NULL) {
2026 smb_panic("talloc failed");
2031 * Update smb headers where subsequent chained commands
2032 * may have updated them.
2034 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2035 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2037 if (!smb_splice_chain(&req->chain_outbuf,
2038 CVAL(req->outbuf, smb_com),
2039 CVAL(req->outbuf, smb_wct),
2040 (uint16_t *)(req->outbuf + smb_vwv),
2041 0, smb_buflen(req->outbuf),
2042 (uint8_t *)smb_buf(req->outbuf))) {
2045 TALLOC_FREE(req->outbuf);
2049 * We use the old request's vwv field to grab the next chained command
2050 * and offset into the chained fields.
2053 chain_cmd = CVAL(req->vwv+0, 0);
2054 chain_offset = SVAL(req->vwv+1, 0);
2056 if (chain_cmd == 0xff) {
2058 * End of chain, no more requests from the client. So ship the
2061 smb_setlen((char *)(req->chain_outbuf),
2062 talloc_get_size(req->chain_outbuf) - 4);
2064 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2065 true, req->seqnum+1,
2066 IS_CONN_ENCRYPTED(req->conn)
2069 exit_server_cleanly("chain_reply: srv_send_smb "
2072 TALLOC_FREE(req->chain_outbuf);
2077 /* add a new perfcounter for this element of chain */
2078 SMB_PERFCOUNT_ADD(&req->pcd);
2079 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2080 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2083 * Check if the client tries to fool us. The request so far uses the
2084 * space to the end of the byte buffer in the request just
2085 * processed. The chain_offset can't point into that area. If that was
2086 * the case, we could end up with an endless processing of the chain,
2087 * we would always handle the same request.
2090 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2091 if (chain_offset < already_used) {
2096 * Next check: Make sure the chain offset does not point beyond the
2097 * overall smb request length.
2100 length_needed = chain_offset+1; /* wct */
2101 if (length_needed > smblen) {
2106 * Now comes the pointer magic. Goal here is to set up req->vwv and
2107 * req->buf correctly again to be able to call the subsequent
2108 * switch_message(). The chain offset (the former vwv[1]) points at
2109 * the new wct field.
2112 wct = CVAL(smb_base(req->inbuf), chain_offset);
2115 * Next consistency check: Make the new vwv array fits in the overall
2119 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2120 if (length_needed > smblen) {
2123 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2126 * Now grab the new byte buffer....
2129 buflen = SVAL(vwv+wct, 0);
2132 * .. and check that it fits.
2135 length_needed += buflen;
2136 if (length_needed > smblen) {
2139 buf = (uint8_t *)(vwv+wct+1);
2141 req->cmd = chain_cmd;
2144 req->buflen = buflen;
2147 switch_message(chain_cmd, req, smblen);
2149 if (req->outbuf == NULL) {
2151 * This happens if the chained command has suspended itself or
2152 * if it has called srv_send_smb() itself.
2158 * We end up here if the chained command was not itself chained or
2159 * suspended, but for example a close() command. We now need to splice
2160 * the chained commands' outbuf into the already built up chain_outbuf
2161 * and ship the result.
2167 * We end up here if there's any error in the chain syntax. Report a
2168 * DOS error, just like Windows does.
2170 reply_force_doserror(req, ERRSRV, ERRerror);
2171 fixup_chain_error_packet(req);
2175 * This scary statement intends to set the
2176 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2177 * to the value req->outbuf carries
2179 SSVAL(req->chain_outbuf, smb_flg2,
2180 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2181 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2184 * Transfer the error codes from the subrequest to the main one
2186 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2187 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2189 if (!smb_splice_chain(&req->chain_outbuf,
2190 CVAL(req->outbuf, smb_com),
2191 CVAL(req->outbuf, smb_wct),
2192 (uint16_t *)(req->outbuf + smb_vwv),
2193 0, smb_buflen(req->outbuf),
2194 (uint8_t *)smb_buf(req->outbuf))) {
2195 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2197 TALLOC_FREE(req->outbuf);
2199 smb_setlen((char *)(req->chain_outbuf),
2200 talloc_get_size(req->chain_outbuf) - 4);
2202 show_msg((char *)(req->chain_outbuf));
2204 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2205 true, req->seqnum+1,
2206 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2208 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2210 TALLOC_FREE(req->chain_outbuf);
2214 /****************************************************************************
2215 Check if services need reloading.
2216 ****************************************************************************/
2218 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2220 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2222 if(last_smb_conf_reload_time == 0) {
2223 last_smb_conf_reload_time = t;
2224 /* Our printing subsystem might not be ready at smbd start up.
2225 Then no printer is available till the first printers check
2226 is performed. A lower initial interval circumvents this. */
2227 if ( printcap_cache_time > 60 )
2228 last_printer_reload_time = t - printcap_cache_time + 60;
2230 last_printer_reload_time = t;
2233 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2234 /* randomize over 60 second the printcap reload to avoid all
2235 * process hitting cupsd at the same time */
2236 int time_range = 60;
2238 last_printer_reload_time += random() % time_range;
2242 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2243 reload_services(sconn->msg_ctx, sconn->sock, True);
2244 last_smb_conf_reload_time = t;
2247 /* 'printcap cache time = 0' disable the feature */
2249 if ( printcap_cache_time != 0 )
2251 /* see if it's time to reload or if the clock has been set back */
2253 if ( (t >= last_printer_reload_time+printcap_cache_time)
2254 || (t-last_printer_reload_time < 0) )
2256 DEBUG( 3,( "Printcap cache time expired.\n"));
2257 reload_printers(sconn->msg_ctx);
2258 last_printer_reload_time = t;
2263 static bool fd_is_readable(int fd)
2266 struct timeval timeout = {0, };
2272 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2276 return FD_ISSET(fd, &fds);
2279 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2281 /* TODO: make write nonblocking */
2284 static void smbd_server_connection_read_handler(
2285 struct smbd_server_connection *conn, int fd)
2287 uint8_t *inbuf = NULL;
2288 size_t inbuf_len = 0;
2289 size_t unread_bytes = 0;
2290 bool encrypted = false;
2291 TALLOC_CTX *mem_ctx = talloc_tos();
2295 bool from_client = (conn->sock == fd);
2298 smbd_lock_socket(conn);
2300 if (!fd_is_readable(fd)) {
2301 DEBUG(10,("the echo listener was faster\n"));
2302 smbd_unlock_socket(conn);
2306 /* TODO: make this completely nonblocking */
2307 status = receive_smb_talloc(mem_ctx, conn,
2308 (char **)(void *)&inbuf,
2312 &inbuf_len, &seqnum,
2313 false /* trusted channel */);
2314 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 true /* trusted channel */);
2326 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2329 if (NT_STATUS_IS_ERR(status)) {
2330 exit_server_cleanly("failed to receive smb request");
2332 if (!NT_STATUS_IS_OK(status)) {
2337 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2338 seqnum, encrypted, NULL);
2341 static void smbd_server_connection_handler(struct event_context *ev,
2342 struct fd_event *fde,
2346 struct smbd_server_connection *conn = talloc_get_type(private_data,
2347 struct smbd_server_connection);
2349 if (flags & EVENT_FD_WRITE) {
2350 smbd_server_connection_write_handler(conn);
2353 if (flags & EVENT_FD_READ) {
2354 smbd_server_connection_read_handler(conn, conn->sock);
2359 static void smbd_server_echo_handler(struct event_context *ev,
2360 struct fd_event *fde,
2364 struct smbd_server_connection *conn = talloc_get_type(private_data,
2365 struct smbd_server_connection);
2367 if (flags & EVENT_FD_WRITE) {
2368 smbd_server_connection_write_handler(conn);
2371 if (flags & EVENT_FD_READ) {
2372 smbd_server_connection_read_handler(
2373 conn, conn->smb1.echo_handler.trusted_fd);
2378 /****************************************************************************
2379 received when we should release a specific IP
2380 ****************************************************************************/
2381 static void release_ip(const char *ip, void *priv)
2383 const char *addr = (const char *)priv;
2384 const char *p = addr;
2386 if (strncmp("::ffff:", addr, 7) == 0) {
2390 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2391 /* we can't afford to do a clean exit - that involves
2392 database writes, which would potentially mean we
2393 are still running after the failover has finished -
2394 we have to get rid of this process ID straight
2396 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2398 /* note we must exit with non-zero status so the unclean handler gets
2399 called in the parent, so that the brl database is tickled */
2404 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2405 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2407 struct smbd_server_connection *sconn = talloc_get_type_abort(
2408 private_data, struct smbd_server_connection);
2410 release_ip((char *)data->data, sconn->client_id.addr);
2413 #ifdef CLUSTER_SUPPORT
2414 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2415 struct sockaddr_storage *client)
2418 length = sizeof(*server);
2419 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2422 length = sizeof(*client);
2423 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2431 * Send keepalive packets to our client
2433 static bool keepalive_fn(const struct timeval *now, void *private_data)
2435 struct smbd_server_connection *sconn = smbd_server_conn;
2438 if (sconn->using_smb2) {
2439 /* Don't do keepalives on an SMB2 connection. */
2443 smbd_lock_socket(smbd_server_conn);
2444 ret = send_keepalive(sconn->sock);
2445 smbd_unlock_socket(smbd_server_conn);
2448 char addr[INET6_ADDRSTRLEN];
2450 * Try and give an error message saying what
2453 DEBUG(0, ("send_keepalive failed for client %s. "
2454 "Error %s - exiting\n",
2455 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2463 * Do the recurring check if we're idle
2465 static bool deadtime_fn(const struct timeval *now, void *private_data)
2467 struct smbd_server_connection *sconn =
2468 (struct smbd_server_connection *)private_data;
2470 if ((conn_num_open(sconn) == 0)
2471 || (conn_idle_all(sconn, now->tv_sec))) {
2472 DEBUG( 2, ( "Closing idle connection\n" ) );
2473 messaging_send(sconn->msg_ctx,
2474 messaging_server_id(sconn->msg_ctx),
2475 MSG_SHUTDOWN, &data_blob_null);
2483 * Do the recurring log file and smb.conf reload checks.
2486 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2488 struct smbd_server_connection *sconn = talloc_get_type_abort(
2489 private_data, struct smbd_server_connection);
2490 change_to_root_user();
2492 /* update printer queue caches if necessary */
2493 update_monitored_printq_cache(sconn->msg_ctx);
2495 /* check if we need to reload services */
2496 check_reload(sconn, time(NULL));
2498 /* Change machine password if neccessary. */
2499 attempt_machine_password_change();
2502 * Force a log file check.
2504 force_check_log_size();
2509 static int create_unlink_tmp(const char *dir)
2514 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2515 if (fname == NULL) {
2519 fd = mkstemp(fname);
2524 if (unlink(fname) == -1) {
2525 int sys_errno = errno;
2535 struct smbd_echo_state {
2536 struct tevent_context *ev;
2537 struct iovec *pending;
2538 struct smbd_server_connection *sconn;
2541 struct tevent_fd *parent_fde;
2543 struct tevent_fd *read_fde;
2544 struct tevent_req *write_req;
2547 static void smbd_echo_writer_done(struct tevent_req *req);
2549 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2553 if (state->write_req != NULL) {
2557 num_pending = talloc_array_length(state->pending);
2558 if (num_pending == 0) {
2562 state->write_req = writev_send(state, state->ev, NULL,
2563 state->parent_pipe, false,
2564 state->pending, num_pending);
2565 if (state->write_req == NULL) {
2566 DEBUG(1, ("writev_send failed\n"));
2570 talloc_steal(state->write_req, state->pending);
2571 state->pending = NULL;
2573 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2577 static void smbd_echo_writer_done(struct tevent_req *req)
2579 struct smbd_echo_state *state = tevent_req_callback_data(
2580 req, struct smbd_echo_state);
2584 written = writev_recv(req, &err);
2586 state->write_req = NULL;
2587 if (written == -1) {
2588 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2591 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2592 smbd_echo_activate_writer(state);
2595 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2598 struct smb_request req;
2599 uint16_t num_replies;
2604 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2605 DEBUG(10, ("Got netbios keepalive\n"));
2612 if (inbuf_len < smb_size) {
2613 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2616 if (!valid_smb_header(inbuf)) {
2617 DEBUG(10, ("Got invalid SMB header\n"));
2621 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2627 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2628 smb_messages[req.cmd].name
2629 ? smb_messages[req.cmd].name : "unknown"));
2631 if (req.cmd != SMBecho) {
2638 num_replies = SVAL(req.vwv+0, 0);
2639 if (num_replies != 1) {
2640 /* Not a Windows "Hey, you're still there?" request */
2644 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2646 DEBUG(10, ("create_outbuf failed\n"));
2649 req.outbuf = (uint8_t *)outbuf;
2651 SSVAL(req.outbuf, smb_vwv0, num_replies);
2653 if (req.buflen > 0) {
2654 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2657 out_len = smb_len(req.outbuf) + 4;
2659 ok = srv_send_smb(req.sconn,
2663 TALLOC_FREE(outbuf);
2671 static void smbd_echo_exit(struct tevent_context *ev,
2672 struct tevent_fd *fde, uint16_t flags,
2675 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2679 static void smbd_echo_reader(struct tevent_context *ev,
2680 struct tevent_fd *fde, uint16_t flags,
2683 struct smbd_echo_state *state = talloc_get_type_abort(
2684 private_data, struct smbd_echo_state);
2685 struct smbd_server_connection *sconn = state->sconn;
2686 size_t unread, num_pending;
2690 uint32_t seqnum = 0;
2693 bool encrypted = false;
2697 ok = smbd_lock_socket_internal(sconn);
2699 DEBUG(0, ("%s: failed to lock socket\n",
2704 if (!fd_is_readable(sconn->sock)) {
2705 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2706 (int)sys_getpid()));
2707 ok = smbd_unlock_socket_internal(sconn);
2709 DEBUG(1, ("%s: failed to unlock socket in\n",
2716 num_pending = talloc_array_length(state->pending);
2717 tmp = talloc_realloc(state, state->pending, struct iovec,
2720 DEBUG(1, ("talloc_realloc failed\n"));
2723 state->pending = tmp;
2725 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2727 status = receive_smb_talloc(state->pending, sconn,
2728 (char **)(void *)&state->pending[num_pending].iov_base,
2734 false /* trusted_channel*/);
2735 if (!NT_STATUS_IS_OK(status)) {
2736 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2737 (int)sys_getpid(), nt_errstr(status)));
2740 state->pending[num_pending].iov_len = iov_len;
2742 ok = smbd_unlock_socket_internal(sconn);
2744 DEBUG(1, ("%s: failed to unlock socket in\n",
2749 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2750 state->pending[num_pending].iov_len,
2753 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2754 /* no check, shrinking by some bytes does not fail */
2755 state->pending = talloc_realloc(state, state->pending,
2761 if (state->pending[num_pending].iov_len >= smb_size) {
2763 * place the seqnum in the packet so that the main process
2764 * can reply with signing
2766 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2767 smb_ss_field, seqnum);
2768 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2769 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2772 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2773 smbd_echo_activate_writer(state);
2776 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2779 struct smbd_echo_state *state;
2781 state = talloc_zero(sconn, struct smbd_echo_state);
2782 if (state == NULL) {
2783 DEBUG(1, ("talloc failed\n"));
2786 state->sconn = sconn;
2787 state->parent_pipe = parent_pipe;
2788 state->ev = s3_tevent_context_init(state);
2789 if (state->ev == NULL) {
2790 DEBUG(1, ("tevent_context_init failed\n"));
2794 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2795 TEVENT_FD_READ, smbd_echo_exit,
2797 if (state->parent_fde == NULL) {
2798 DEBUG(1, ("tevent_add_fd failed\n"));
2802 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2803 TEVENT_FD_READ, smbd_echo_reader,
2805 if (state->read_fde == NULL) {
2806 DEBUG(1, ("tevent_add_fd failed\n"));
2812 if (tevent_loop_once(state->ev) == -1) {
2813 DEBUG(1, ("tevent_loop_once failed: %s\n",
2822 * Handle SMBecho requests in a forked child process
2824 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2826 int listener_pipe[2];
2830 res = pipe(listener_pipe);
2832 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2835 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2836 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2837 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2845 close(listener_pipe[0]);
2846 set_blocking(listener_pipe[1], false);
2848 status = reinit_after_fork(sconn->msg_ctx,
2849 smbd_event_context(),
2850 procid_self(), false);
2851 if (!NT_STATUS_IS_OK(status)) {
2852 DEBUG(1, ("reinit_after_fork failed: %s\n",
2853 nt_errstr(status)));
2856 smbd_echo_loop(sconn, listener_pipe[1]);
2859 close(listener_pipe[1]);
2860 listener_pipe[1] = -1;
2861 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2863 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2866 * Without smb signing this is the same as the normal smbd
2867 * listener. This needs to change once signing comes in.
2869 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2871 sconn->smb1.echo_handler.trusted_fd,
2873 smbd_server_echo_handler,
2875 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2876 DEBUG(1, ("event_add_fd failed\n"));
2883 if (listener_pipe[0] != -1) {
2884 close(listener_pipe[0]);
2886 if (listener_pipe[1] != -1) {
2887 close(listener_pipe[1]);
2889 sconn->smb1.echo_handler.trusted_fd = -1;
2890 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2891 close(sconn->smb1.echo_handler.socket_lock_fd);
2893 sconn->smb1.echo_handler.trusted_fd = -1;
2894 sconn->smb1.echo_handler.socket_lock_fd = -1;
2900 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2901 struct sockaddr_storage *srv,
2902 struct sockaddr_storage *clnt)
2904 struct ctdbd_connection *cconn;
2905 char tmp_addr[INET6_ADDRSTRLEN];
2908 cconn = messaging_ctdbd_connection();
2909 if (cconn == NULL) {
2910 return NT_STATUS_NO_MEMORY;
2913 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2914 addr = talloc_strdup(cconn, tmp_addr);
2916 return NT_STATUS_NO_MEMORY;
2918 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2923 /****************************************************************************
2924 Process commands from the client
2925 ****************************************************************************/
2927 void smbd_process(struct smbd_server_connection *sconn)
2929 TALLOC_CTX *frame = talloc_stackframe();
2930 struct sockaddr_storage ss;
2931 struct sockaddr *sa = NULL;
2932 socklen_t sa_socklen;
2933 struct tsocket_address *local_address = NULL;
2934 struct tsocket_address *remote_address = NULL;
2935 const char *remaddr = NULL;
2938 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2939 lp_security() != SEC_SHARE &&
2940 !lp_async_smb_echo_handler()) {
2942 * We're not making the desion here,
2943 * we're just allowing the client
2944 * to decide between SMB1 and SMB2
2945 * with the first negprot
2948 sconn->using_smb2 = true;
2951 /* Ensure child is set to blocking mode */
2952 set_blocking(sconn->sock,True);
2954 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2955 set_socket_options(sconn->sock, lp_socket_options());
2957 sa = (struct sockaddr *)(void *)&ss;
2958 sa_socklen = sizeof(ss);
2959 ret = getpeername(sconn->sock, sa, &sa_socklen);
2961 int level = (errno == ENOTCONN)?2:0;
2962 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2963 exit_server_cleanly("getpeername() failed.\n");
2965 ret = tsocket_address_bsd_from_sockaddr(sconn,
2969 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2970 __location__, strerror(errno)));
2971 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2974 sa = (struct sockaddr *)(void *)&ss;
2975 sa_socklen = sizeof(ss);
2976 ret = getsockname(sconn->sock, sa, &sa_socklen);
2978 int level = (errno == ENOTCONN)?2:0;
2979 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2980 exit_server_cleanly("getsockname() failed.\n");
2982 ret = tsocket_address_bsd_from_sockaddr(sconn,
2986 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2987 __location__, strerror(errno)));
2988 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2991 sconn->local_address = local_address;
2992 sconn->remote_address = remote_address;
2994 if (tsocket_address_is_inet(remote_address, "ip")) {
2995 remaddr = tsocket_address_inet_addr_string(
2996 sconn->remote_address,
2998 if (remaddr == NULL) {
3002 remaddr = "0.0.0.0";
3005 /* this is needed so that we get decent entries
3006 in smbstatus for port 445 connects */
3007 set_remote_machine_name(remaddr, false);
3008 reload_services(sconn->msg_ctx, sconn->sock, true);
3011 * Before the first packet, check the global hosts allow/ hosts deny
3012 * parameters before doing any parsing of packets passed to us by the
3013 * client. This prevents attacks on our parsing code from hosts not in
3014 * the hosts allow list.
3017 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3018 sconn->client_id.name,
3019 sconn->client_id.addr)) {
3021 * send a negative session response "not listening on calling
3024 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3025 DEBUG( 1, ("Connection denied from %s to %s\n",
3026 tsocket_address_string(remote_address, talloc_tos()),
3027 tsocket_address_string(local_address, talloc_tos())));
3028 (void)srv_send_smb(sconn,(char *)buf, false,
3030 exit_server_cleanly("connection denied");
3033 DEBUG(10, ("Connection allowed from %s to %s\n",
3034 tsocket_address_string(remote_address, talloc_tos()),
3035 tsocket_address_string(local_address, talloc_tos())));
3039 smb_perfcount_init();
3041 if (!init_account_policy()) {
3042 exit_server("Could not open account policy tdb.\n");
3045 if (*lp_rootdir()) {
3046 if (chroot(lp_rootdir()) != 0) {
3047 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3048 exit_server("Failed to chroot()");
3050 if (chdir("/") == -1) {
3051 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3052 exit_server("Failed to chroot()");
3054 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3057 if (!srv_init_signing(sconn)) {
3058 exit_server("Failed to init smb_signing");
3061 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3062 exit_server("Failed to fork echo handler");
3066 if (!init_oplocks(sconn->msg_ctx))
3067 exit_server("Failed to init oplocks");
3069 /* register our message handlers */
3070 messaging_register(sconn->msg_ctx, NULL,
3071 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3072 messaging_register(sconn->msg_ctx, sconn,
3073 MSG_SMB_RELEASE_IP, msg_release_ip);
3074 messaging_register(sconn->msg_ctx, NULL,
3075 MSG_SMB_CLOSE_FILE, msg_close_file);
3078 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3079 * MSGs to all child processes
3081 messaging_deregister(sconn->msg_ctx,
3083 messaging_register(sconn->msg_ctx, NULL,
3084 MSG_DEBUG, debug_message);
3086 if ((lp_keepalive() != 0)
3087 && !(event_add_idle(smbd_event_context(), NULL,
3088 timeval_set(lp_keepalive(), 0),
3089 "keepalive", keepalive_fn,
3091 DEBUG(0, ("Could not add keepalive event\n"));
3095 if (!(event_add_idle(smbd_event_context(), NULL,
3096 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3097 "deadtime", deadtime_fn, sconn))) {
3098 DEBUG(0, ("Could not add deadtime event\n"));
3102 if (!(event_add_idle(smbd_event_context(), NULL,
3103 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3104 "housekeeping", housekeeping_fn, sconn))) {
3105 DEBUG(0, ("Could not add housekeeping event\n"));
3109 #ifdef CLUSTER_SUPPORT
3111 if (lp_clustering()) {
3113 * We need to tell ctdb about our client's TCP
3114 * connection, so that for failover ctdbd can send
3115 * tickle acks, triggering a reconnection by the
3119 struct sockaddr_storage srv, clnt;
3121 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3123 status = smbd_register_ips(sconn, &srv, &clnt);
3124 if (!NT_STATUS_IS_OK(status)) {
3125 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3126 nt_errstr(status)));
3130 DEBUG(0,("Unable to get tcp info for "
3131 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3138 sconn->nbt.got_session = false;
3140 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3142 sconn->smb1.sessions.done_sesssetup = false;
3143 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3144 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3145 /* users from session setup */
3146 sconn->smb1.sessions.session_userlist = NULL;
3147 /* workgroup from session setup. */
3148 sconn->smb1.sessions.session_workgroup = NULL;
3149 /* this holds info on user ids that are already validated for this VC */
3150 sconn->smb1.sessions.validated_users = NULL;
3151 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3152 sconn->smb1.sessions.num_validated_vuids = 0;
3155 if (!init_dptrs(sconn)) {
3156 exit_server("init_dptrs() failed");
3159 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3163 smbd_server_connection_handler,
3165 if (!sconn->smb1.fde) {
3166 exit_server("failed to create smbd_server_connection fde");
3174 frame = talloc_stackframe_pool(8192);
3178 status = smbd_server_connection_loop_once(sconn);
3179 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3180 !NT_STATUS_IS_OK(status)) {
3181 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3182 " exiting\n", nt_errstr(status)));
3189 exit_server_cleanly(NULL);
3192 bool req_is_in_chain(struct smb_request *req)
3194 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3196 * We're right now handling a subsequent request, so we must
3202 if (!is_andx_req(req->cmd)) {
3208 * Okay, an illegal request, but definitely not chained :-)
3213 return (CVAL(req->vwv+0, 0) != 0xFF);