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, int fd,
416 char **buffer, unsigned int timeout,
417 size_t *p_unread, bool *p_encrypted,
420 bool trusted_channel)
425 *p_encrypted = false;
427 status = receive_smb_raw_talloc(mem_ctx, smbd_server_conn, buffer,
428 timeout, p_unread, &len);
429 if (!NT_STATUS_IS_OK(status)) {
430 char addr[INET6_ADDRSTRLEN];
431 DEBUG(1, ("read_smb_length_return_keepalive failed for "
432 "client %s read error = %s.\n",
433 get_peer_addr(fd, addr, sizeof(addr)),
438 if (is_encrypted_packet((uint8_t *)*buffer)) {
439 status = srv_decrypt_buffer(*buffer);
440 if (!NT_STATUS_IS_OK(status)) {
441 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
442 "incoming packet! Error %s\n",
443 nt_errstr(status) ));
449 /* Check the incoming SMB signature. */
450 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
451 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
452 "incoming packet!\n"));
453 return NT_STATUS_INVALID_NETWORK_RESPONSE;
461 * Initialize a struct smb_request from an inbuf
464 static bool init_smb_request(struct smb_request *req,
465 struct smbd_server_connection *sconn,
467 size_t unread_bytes, bool encrypted,
470 size_t req_size = smb_len(inbuf) + 4;
471 /* Ensure we have at least smb_size bytes. */
472 if (req_size < smb_size) {
473 DEBUG(0,("init_smb_request: invalid request size %u\n",
474 (unsigned int)req_size ));
477 req->cmd = CVAL(inbuf, smb_com);
478 req->flags2 = SVAL(inbuf, smb_flg2);
479 req->smbpid = SVAL(inbuf, smb_pid);
480 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
481 req->seqnum = seqnum;
482 req->vuid = SVAL(inbuf, smb_uid);
483 req->tid = SVAL(inbuf, smb_tid);
484 req->wct = CVAL(inbuf, smb_wct);
485 req->vwv = (uint16_t *)(inbuf+smb_vwv);
486 req->buflen = smb_buflen(inbuf);
487 req->buf = (const uint8_t *)smb_buf(inbuf);
488 req->unread_bytes = unread_bytes;
489 req->encrypted = encrypted;
491 req->conn = conn_find(sconn,req->tid);
492 req->chain_fsp = NULL;
493 req->chain_outbuf = NULL;
496 smb_init_perfcount_data(&req->pcd);
498 /* Ensure we have at least wct words and 2 bytes of bcc. */
499 if (smb_size + req->wct*2 > req_size) {
500 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
501 (unsigned int)req->wct,
502 (unsigned int)req_size));
505 /* Ensure bcc is correct. */
506 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
507 DEBUG(0,("init_smb_request: invalid bcc number %u "
508 "(wct = %u, size %u)\n",
509 (unsigned int)req->buflen,
510 (unsigned int)req->wct,
511 (unsigned int)req_size));
519 static void process_smb(struct smbd_server_connection *conn,
520 uint8_t *inbuf, size_t nread, size_t unread_bytes,
521 uint32_t seqnum, bool encrypted,
522 struct smb_perfcount_data *deferred_pcd);
524 static void smbd_deferred_open_timer(struct event_context *ev,
525 struct timed_event *te,
526 struct timeval _tval,
529 struct pending_message_list *msg = talloc_get_type(private_data,
530 struct pending_message_list);
531 TALLOC_CTX *mem_ctx = talloc_tos();
532 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
535 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
538 exit_server("smbd_deferred_open_timer: talloc failed\n");
542 /* We leave this message on the queue so the open code can
543 know this is a retry. */
544 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
545 (unsigned long long)mid ));
547 /* Mark the message as processed so this is not
548 * re-processed in error. */
549 msg->processed = true;
551 process_smb(smbd_server_conn, inbuf,
553 msg->seqnum, msg->encrypted, &msg->pcd);
555 /* If it's still there and was processed, remove it. */
556 msg = get_deferred_open_message_smb(mid);
557 if (msg && msg->processed) {
558 remove_deferred_open_message_smb(mid);
562 /****************************************************************************
563 Function to push a message onto the tail of a linked list of smb messages ready
565 ****************************************************************************/
567 static bool push_queued_message(struct smb_request *req,
568 struct timeval request_time,
569 struct timeval end_time,
570 char *private_data, size_t private_len)
572 int msg_len = smb_len(req->inbuf) + 4;
573 struct pending_message_list *msg;
575 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
578 DEBUG(0,("push_message: malloc fail (1)\n"));
582 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
583 if(msg->buf.data == NULL) {
584 DEBUG(0,("push_message: malloc fail (2)\n"));
589 msg->request_time = request_time;
590 msg->seqnum = req->seqnum;
591 msg->encrypted = req->encrypted;
592 msg->processed = false;
593 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
596 msg->private_data = data_blob_talloc(msg, private_data,
598 if (msg->private_data.data == NULL) {
599 DEBUG(0,("push_message: malloc fail (3)\n"));
605 msg->te = event_add_timed(smbd_event_context(),
608 smbd_deferred_open_timer,
611 DEBUG(0,("push_message: event_add_timed failed\n"));
616 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
618 DEBUG(10,("push_message: pushed message length %u on "
619 "deferred_open_queue\n", (unsigned int)msg_len));
624 /****************************************************************************
625 Function to delete a sharing violation open message by mid.
626 ****************************************************************************/
628 void remove_deferred_open_message_smb(uint64_t mid)
630 struct pending_message_list *pml;
632 if (smbd_server_conn->using_smb2) {
633 remove_deferred_open_message_smb2(smbd_server_conn, mid);
637 for (pml = deferred_open_queue; pml; pml = pml->next) {
638 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
639 DEBUG(10,("remove_deferred_open_message_smb: "
640 "deleting mid %llu len %u\n",
641 (unsigned long long)mid,
642 (unsigned int)pml->buf.length ));
643 DLIST_REMOVE(deferred_open_queue, pml);
650 /****************************************************************************
651 Move a sharing violation open retry message to the front of the list and
652 schedule it for immediate processing.
653 ****************************************************************************/
655 void schedule_deferred_open_message_smb(uint64_t mid)
657 struct pending_message_list *pml;
660 if (smbd_server_conn->using_smb2) {
661 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
665 for (pml = deferred_open_queue; pml; pml = pml->next) {
666 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
668 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
671 (unsigned long long)msg_mid ));
673 if (mid == msg_mid) {
674 struct timed_event *te;
676 if (pml->processed) {
677 /* A processed message should not be
679 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
680 "message mid %llu was already processed\n",
681 (unsigned long long)msg_mid ));
685 DEBUG(10,("schedule_deferred_open_message_smb: "
686 "scheduling mid %llu\n",
687 (unsigned long long)mid ));
689 te = event_add_timed(smbd_event_context(),
692 smbd_deferred_open_timer,
695 DEBUG(10,("schedule_deferred_open_message_smb: "
696 "event_add_timed() failed, "
697 "skipping mid %llu\n",
698 (unsigned long long)msg_mid ));
701 TALLOC_FREE(pml->te);
703 DLIST_PROMOTE(deferred_open_queue, pml);
708 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
709 "find message mid %llu\n",
710 (unsigned long long)mid ));
713 /****************************************************************************
714 Return true if this mid is on the deferred queue and was not yet processed.
715 ****************************************************************************/
717 bool open_was_deferred(uint64_t mid)
719 struct pending_message_list *pml;
721 if (smbd_server_conn->using_smb2) {
722 return open_was_deferred_smb2(smbd_server_conn, mid);
725 for (pml = deferred_open_queue; pml; pml = pml->next) {
726 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
733 /****************************************************************************
734 Return the message queued by this mid.
735 ****************************************************************************/
737 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
739 struct pending_message_list *pml;
741 for (pml = deferred_open_queue; pml; pml = pml->next) {
742 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
749 /****************************************************************************
750 Get the state data queued by this mid.
751 ****************************************************************************/
753 bool get_deferred_open_message_state(struct smb_request *smbreq,
754 struct timeval *p_request_time,
757 struct pending_message_list *pml;
759 if (smbd_server_conn->using_smb2) {
760 return get_deferred_open_message_state_smb2(smbreq->smb2req,
765 pml = get_deferred_open_message_smb(smbreq->mid);
769 if (p_request_time) {
770 *p_request_time = pml->request_time;
773 *pp_state = (void *)pml->private_data.data;
778 /****************************************************************************
779 Function to push a deferred open smb message onto a linked list of local smb
780 messages ready for processing.
781 ****************************************************************************/
783 bool push_deferred_open_message_smb(struct smb_request *req,
784 struct timeval request_time,
785 struct timeval timeout,
787 char *private_data, size_t priv_len)
789 struct timeval end_time;
792 return push_deferred_open_message_smb2(req->smb2req,
800 if (req->unread_bytes) {
801 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
802 "unread_bytes = %u\n",
803 (unsigned int)req->unread_bytes ));
804 smb_panic("push_deferred_open_message_smb: "
805 "logic error unread_bytes != 0" );
808 end_time = timeval_sum(&request_time, &timeout);
810 DEBUG(10,("push_deferred_open_message_smb: pushing message "
811 "len %u mid %llu timeout time [%u.%06u]\n",
812 (unsigned int) smb_len(req->inbuf)+4,
813 (unsigned long long)req->mid,
814 (unsigned int)end_time.tv_sec,
815 (unsigned int)end_time.tv_usec));
817 return push_queued_message(req, request_time, end_time,
818 private_data, priv_len);
822 struct timed_event *te;
823 struct timeval interval;
825 bool (*handler)(const struct timeval *now, void *private_data);
829 static void smbd_idle_event_handler(struct event_context *ctx,
830 struct timed_event *te,
834 struct idle_event *event =
835 talloc_get_type_abort(private_data, struct idle_event);
837 TALLOC_FREE(event->te);
839 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
840 event->name, event->te));
842 if (!event->handler(&now, event->private_data)) {
843 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
844 event->name, event->te));
845 /* Don't repeat, delete ourselves */
850 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
851 event->name, event->te));
853 event->te = event_add_timed(ctx, event,
854 timeval_sum(&now, &event->interval),
855 smbd_idle_event_handler, event);
857 /* We can't do much but fail here. */
858 SMB_ASSERT(event->te != NULL);
861 struct idle_event *event_add_idle(struct event_context *event_ctx,
863 struct timeval interval,
865 bool (*handler)(const struct timeval *now,
869 struct idle_event *result;
870 struct timeval now = timeval_current();
872 result = TALLOC_P(mem_ctx, struct idle_event);
873 if (result == NULL) {
874 DEBUG(0, ("talloc failed\n"));
878 result->interval = interval;
879 result->handler = handler;
880 result->private_data = private_data;
882 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
883 DEBUG(0, ("talloc failed\n"));
888 result->te = event_add_timed(event_ctx, result,
889 timeval_sum(&now, &interval),
890 smbd_idle_event_handler, result);
891 if (result->te == NULL) {
892 DEBUG(0, ("event_add_timed failed\n"));
897 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
901 static void smbd_sig_term_handler(struct tevent_context *ev,
902 struct tevent_signal *se,
908 exit_server_cleanly("termination signal");
911 void smbd_setup_sig_term_handler(void)
913 struct tevent_signal *se;
915 se = tevent_add_signal(smbd_event_context(),
916 smbd_event_context(),
918 smbd_sig_term_handler,
921 exit_server("failed to setup SIGTERM handler");
925 static void smbd_sig_hup_handler(struct tevent_context *ev,
926 struct tevent_signal *se,
932 struct messaging_context *msg_ctx = talloc_get_type_abort(
933 private_data, struct messaging_context);
934 change_to_root_user();
935 DEBUG(1,("Reloading services after SIGHUP\n"));
936 reload_services(msg_ctx, smbd_server_conn->sock, False);
939 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
940 struct messaging_context *msg_ctx)
942 struct tevent_signal *se;
944 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
947 exit_server("failed to setup SIGHUP handler");
951 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
958 to.tv_sec = SMBD_SELECT_TIMEOUT;
962 * Setup the select fd sets.
969 * Are there any timed events waiting ? If so, ensure we don't
970 * select for longer than it would take to wait for them.
977 event_add_to_select_args(smbd_event_context(), &now,
978 &r_fds, &w_fds, &to, &maxfd);
981 /* Process a signal and timed events now... */
982 if (run_events(smbd_event_context(), &selrtn, NULL, NULL)) {
983 return NT_STATUS_RETRY;
988 START_PROFILE(smbd_idle);
990 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
993 END_PROFILE(smbd_idle);
1000 return NT_STATUS_RETRY;
1002 /* Maybe the socket is dead? */
1003 return map_nt_error_from_unix(errno);
1006 /* Process events until all available fds have been handled.
1007 * This allows for fair round-robin handling of all available fds
1008 * on each select() wakeup, while still maintaining responsiveness
1009 * by re-checking for signal and timed events between the handling
1010 * of each ready fd. */
1012 run_events(smbd_event_context(), &selrtn, &r_fds, &w_fds);
1013 } while (selrtn > 0);
1015 /* Processed all fds or timed out */
1017 return NT_STATUS_RETRY;
1020 /* should not be reached */
1021 return NT_STATUS_INTERNAL_ERROR;
1025 * Only allow 5 outstanding trans requests. We're allocating memory, so
1029 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1032 for (; list != NULL; list = list->next) {
1034 if (list->mid == mid) {
1035 return NT_STATUS_INVALID_PARAMETER;
1041 return NT_STATUS_INSUFFICIENT_RESOURCES;
1044 return NT_STATUS_OK;
1048 These flags determine some of the permissions required to do an operation
1050 Note that I don't set NEED_WRITE on some write operations because they
1051 are used by some brain-dead clients when printing, and I don't want to
1052 force write permissions on print services.
1054 #define AS_USER (1<<0)
1055 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1056 #define TIME_INIT (1<<2)
1057 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1058 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1059 #define DO_CHDIR (1<<6)
1062 define a list of possible SMB messages and their corresponding
1063 functions. Any message that has a NULL function is unimplemented -
1064 please feel free to contribute implementations!
1066 static const struct smb_message_struct {
1068 void (*fn)(struct smb_request *req);
1070 } smb_messages[256] = {
1072 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1073 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1074 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1075 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1076 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1077 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1078 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1079 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1080 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1081 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1082 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1083 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1084 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1085 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1086 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1087 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1088 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1089 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1090 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1091 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1092 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1093 /* 0x15 */ { NULL, NULL, 0 },
1094 /* 0x16 */ { NULL, NULL, 0 },
1095 /* 0x17 */ { NULL, NULL, 0 },
1096 /* 0x18 */ { NULL, NULL, 0 },
1097 /* 0x19 */ { NULL, NULL, 0 },
1098 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1099 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1100 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1101 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1102 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1103 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1104 /* 0x20 */ { "SMBwritec", NULL,0},
1105 /* 0x21 */ { NULL, NULL, 0 },
1106 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1107 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1108 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1109 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1110 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1111 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1112 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1113 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1114 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1115 /* 0x2b */ { "SMBecho",reply_echo,0},
1116 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1117 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1118 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1119 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1120 /* 0x30 */ { NULL, NULL, 0 },
1121 /* 0x31 */ { NULL, NULL, 0 },
1122 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1123 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1124 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1125 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1126 /* 0x36 */ { NULL, NULL, 0 },
1127 /* 0x37 */ { NULL, NULL, 0 },
1128 /* 0x38 */ { NULL, NULL, 0 },
1129 /* 0x39 */ { NULL, NULL, 0 },
1130 /* 0x3a */ { NULL, NULL, 0 },
1131 /* 0x3b */ { NULL, NULL, 0 },
1132 /* 0x3c */ { NULL, NULL, 0 },
1133 /* 0x3d */ { NULL, NULL, 0 },
1134 /* 0x3e */ { NULL, NULL, 0 },
1135 /* 0x3f */ { NULL, NULL, 0 },
1136 /* 0x40 */ { NULL, NULL, 0 },
1137 /* 0x41 */ { NULL, NULL, 0 },
1138 /* 0x42 */ { NULL, NULL, 0 },
1139 /* 0x43 */ { NULL, NULL, 0 },
1140 /* 0x44 */ { NULL, NULL, 0 },
1141 /* 0x45 */ { NULL, NULL, 0 },
1142 /* 0x46 */ { NULL, NULL, 0 },
1143 /* 0x47 */ { NULL, NULL, 0 },
1144 /* 0x48 */ { NULL, NULL, 0 },
1145 /* 0x49 */ { NULL, NULL, 0 },
1146 /* 0x4a */ { NULL, NULL, 0 },
1147 /* 0x4b */ { NULL, NULL, 0 },
1148 /* 0x4c */ { NULL, NULL, 0 },
1149 /* 0x4d */ { NULL, NULL, 0 },
1150 /* 0x4e */ { NULL, NULL, 0 },
1151 /* 0x4f */ { NULL, NULL, 0 },
1152 /* 0x50 */ { NULL, NULL, 0 },
1153 /* 0x51 */ { NULL, NULL, 0 },
1154 /* 0x52 */ { NULL, NULL, 0 },
1155 /* 0x53 */ { NULL, NULL, 0 },
1156 /* 0x54 */ { NULL, NULL, 0 },
1157 /* 0x55 */ { NULL, NULL, 0 },
1158 /* 0x56 */ { NULL, NULL, 0 },
1159 /* 0x57 */ { NULL, NULL, 0 },
1160 /* 0x58 */ { NULL, NULL, 0 },
1161 /* 0x59 */ { NULL, NULL, 0 },
1162 /* 0x5a */ { NULL, NULL, 0 },
1163 /* 0x5b */ { NULL, NULL, 0 },
1164 /* 0x5c */ { NULL, NULL, 0 },
1165 /* 0x5d */ { NULL, NULL, 0 },
1166 /* 0x5e */ { NULL, NULL, 0 },
1167 /* 0x5f */ { NULL, NULL, 0 },
1168 /* 0x60 */ { NULL, NULL, 0 },
1169 /* 0x61 */ { NULL, NULL, 0 },
1170 /* 0x62 */ { NULL, NULL, 0 },
1171 /* 0x63 */ { NULL, NULL, 0 },
1172 /* 0x64 */ { NULL, NULL, 0 },
1173 /* 0x65 */ { NULL, NULL, 0 },
1174 /* 0x66 */ { NULL, NULL, 0 },
1175 /* 0x67 */ { NULL, NULL, 0 },
1176 /* 0x68 */ { NULL, NULL, 0 },
1177 /* 0x69 */ { NULL, NULL, 0 },
1178 /* 0x6a */ { NULL, NULL, 0 },
1179 /* 0x6b */ { NULL, NULL, 0 },
1180 /* 0x6c */ { NULL, NULL, 0 },
1181 /* 0x6d */ { NULL, NULL, 0 },
1182 /* 0x6e */ { NULL, NULL, 0 },
1183 /* 0x6f */ { NULL, NULL, 0 },
1184 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1185 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1186 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1187 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1188 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1189 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1190 /* 0x76 */ { NULL, NULL, 0 },
1191 /* 0x77 */ { NULL, NULL, 0 },
1192 /* 0x78 */ { NULL, NULL, 0 },
1193 /* 0x79 */ { NULL, NULL, 0 },
1194 /* 0x7a */ { NULL, NULL, 0 },
1195 /* 0x7b */ { NULL, NULL, 0 },
1196 /* 0x7c */ { NULL, NULL, 0 },
1197 /* 0x7d */ { NULL, NULL, 0 },
1198 /* 0x7e */ { NULL, NULL, 0 },
1199 /* 0x7f */ { NULL, NULL, 0 },
1200 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1201 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1202 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1203 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1204 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1205 /* 0x85 */ { NULL, NULL, 0 },
1206 /* 0x86 */ { NULL, NULL, 0 },
1207 /* 0x87 */ { NULL, NULL, 0 },
1208 /* 0x88 */ { NULL, NULL, 0 },
1209 /* 0x89 */ { NULL, NULL, 0 },
1210 /* 0x8a */ { NULL, NULL, 0 },
1211 /* 0x8b */ { NULL, NULL, 0 },
1212 /* 0x8c */ { NULL, NULL, 0 },
1213 /* 0x8d */ { NULL, NULL, 0 },
1214 /* 0x8e */ { NULL, NULL, 0 },
1215 /* 0x8f */ { NULL, NULL, 0 },
1216 /* 0x90 */ { NULL, NULL, 0 },
1217 /* 0x91 */ { NULL, NULL, 0 },
1218 /* 0x92 */ { NULL, NULL, 0 },
1219 /* 0x93 */ { NULL, NULL, 0 },
1220 /* 0x94 */ { NULL, NULL, 0 },
1221 /* 0x95 */ { NULL, NULL, 0 },
1222 /* 0x96 */ { NULL, NULL, 0 },
1223 /* 0x97 */ { NULL, NULL, 0 },
1224 /* 0x98 */ { NULL, NULL, 0 },
1225 /* 0x99 */ { NULL, NULL, 0 },
1226 /* 0x9a */ { NULL, NULL, 0 },
1227 /* 0x9b */ { NULL, NULL, 0 },
1228 /* 0x9c */ { NULL, NULL, 0 },
1229 /* 0x9d */ { NULL, NULL, 0 },
1230 /* 0x9e */ { NULL, NULL, 0 },
1231 /* 0x9f */ { NULL, NULL, 0 },
1232 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1233 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1234 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1235 /* 0xa3 */ { NULL, NULL, 0 },
1236 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1237 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1238 /* 0xa6 */ { NULL, NULL, 0 },
1239 /* 0xa7 */ { NULL, NULL, 0 },
1240 /* 0xa8 */ { NULL, NULL, 0 },
1241 /* 0xa9 */ { NULL, NULL, 0 },
1242 /* 0xaa */ { NULL, NULL, 0 },
1243 /* 0xab */ { NULL, NULL, 0 },
1244 /* 0xac */ { NULL, NULL, 0 },
1245 /* 0xad */ { NULL, NULL, 0 },
1246 /* 0xae */ { NULL, NULL, 0 },
1247 /* 0xaf */ { NULL, NULL, 0 },
1248 /* 0xb0 */ { NULL, NULL, 0 },
1249 /* 0xb1 */ { NULL, NULL, 0 },
1250 /* 0xb2 */ { NULL, NULL, 0 },
1251 /* 0xb3 */ { NULL, NULL, 0 },
1252 /* 0xb4 */ { NULL, NULL, 0 },
1253 /* 0xb5 */ { NULL, NULL, 0 },
1254 /* 0xb6 */ { NULL, NULL, 0 },
1255 /* 0xb7 */ { NULL, NULL, 0 },
1256 /* 0xb8 */ { NULL, NULL, 0 },
1257 /* 0xb9 */ { NULL, NULL, 0 },
1258 /* 0xba */ { NULL, NULL, 0 },
1259 /* 0xbb */ { NULL, NULL, 0 },
1260 /* 0xbc */ { NULL, NULL, 0 },
1261 /* 0xbd */ { NULL, NULL, 0 },
1262 /* 0xbe */ { NULL, NULL, 0 },
1263 /* 0xbf */ { NULL, NULL, 0 },
1264 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1265 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1266 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1267 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1268 /* 0xc4 */ { NULL, NULL, 0 },
1269 /* 0xc5 */ { NULL, NULL, 0 },
1270 /* 0xc6 */ { NULL, NULL, 0 },
1271 /* 0xc7 */ { NULL, NULL, 0 },
1272 /* 0xc8 */ { NULL, NULL, 0 },
1273 /* 0xc9 */ { NULL, NULL, 0 },
1274 /* 0xca */ { NULL, NULL, 0 },
1275 /* 0xcb */ { NULL, NULL, 0 },
1276 /* 0xcc */ { NULL, NULL, 0 },
1277 /* 0xcd */ { NULL, NULL, 0 },
1278 /* 0xce */ { NULL, NULL, 0 },
1279 /* 0xcf */ { NULL, NULL, 0 },
1280 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1281 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1282 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1283 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1284 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1285 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1286 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1287 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1288 /* 0xd8 */ { NULL, NULL, 0 },
1289 /* 0xd9 */ { NULL, NULL, 0 },
1290 /* 0xda */ { NULL, NULL, 0 },
1291 /* 0xdb */ { NULL, NULL, 0 },
1292 /* 0xdc */ { NULL, NULL, 0 },
1293 /* 0xdd */ { NULL, NULL, 0 },
1294 /* 0xde */ { NULL, NULL, 0 },
1295 /* 0xdf */ { NULL, NULL, 0 },
1296 /* 0xe0 */ { NULL, NULL, 0 },
1297 /* 0xe1 */ { NULL, NULL, 0 },
1298 /* 0xe2 */ { NULL, NULL, 0 },
1299 /* 0xe3 */ { NULL, NULL, 0 },
1300 /* 0xe4 */ { NULL, NULL, 0 },
1301 /* 0xe5 */ { NULL, NULL, 0 },
1302 /* 0xe6 */ { NULL, NULL, 0 },
1303 /* 0xe7 */ { NULL, NULL, 0 },
1304 /* 0xe8 */ { NULL, NULL, 0 },
1305 /* 0xe9 */ { NULL, NULL, 0 },
1306 /* 0xea */ { NULL, NULL, 0 },
1307 /* 0xeb */ { NULL, NULL, 0 },
1308 /* 0xec */ { NULL, NULL, 0 },
1309 /* 0xed */ { NULL, NULL, 0 },
1310 /* 0xee */ { NULL, NULL, 0 },
1311 /* 0xef */ { NULL, NULL, 0 },
1312 /* 0xf0 */ { NULL, NULL, 0 },
1313 /* 0xf1 */ { NULL, NULL, 0 },
1314 /* 0xf2 */ { NULL, NULL, 0 },
1315 /* 0xf3 */ { NULL, NULL, 0 },
1316 /* 0xf4 */ { NULL, NULL, 0 },
1317 /* 0xf5 */ { NULL, NULL, 0 },
1318 /* 0xf6 */ { NULL, NULL, 0 },
1319 /* 0xf7 */ { NULL, NULL, 0 },
1320 /* 0xf8 */ { NULL, NULL, 0 },
1321 /* 0xf9 */ { NULL, NULL, 0 },
1322 /* 0xfa */ { NULL, NULL, 0 },
1323 /* 0xfb */ { NULL, NULL, 0 },
1324 /* 0xfc */ { NULL, NULL, 0 },
1325 /* 0xfd */ { NULL, NULL, 0 },
1326 /* 0xfe */ { NULL, NULL, 0 },
1327 /* 0xff */ { NULL, NULL, 0 }
1331 /*******************************************************************
1332 allocate and initialize a reply packet
1333 ********************************************************************/
1335 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1336 const char *inbuf, char **outbuf, uint8_t num_words,
1340 * Protect against integer wrap
1342 if ((num_bytes > 0xffffff)
1343 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1345 if (asprintf(&msg, "num_bytes too large: %u",
1346 (unsigned)num_bytes) == -1) {
1347 msg = CONST_DISCARD(char *, "num_bytes too large");
1352 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1353 smb_size + num_words*2 + num_bytes);
1354 if (*outbuf == NULL) {
1358 construct_reply_common(req, inbuf, *outbuf);
1359 srv_set_message(*outbuf, num_words, num_bytes, false);
1361 * Zero out the word area, the caller has to take care of the bcc area
1364 if (num_words != 0) {
1365 memset(*outbuf + smb_vwv0, 0, num_words*2);
1371 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1374 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1376 smb_panic("could not allocate output buffer\n");
1378 req->outbuf = (uint8_t *)outbuf;
1382 /*******************************************************************
1383 Dump a packet to a file.
1384 ********************************************************************/
1386 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1390 if (DEBUGLEVEL < 50) {
1394 if (len < 4) len = smb_len(data)+4;
1395 for (i=1;i<100;i++) {
1396 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1397 type ? "req" : "resp") == -1) {
1400 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1401 if (fd != -1 || errno != EEXIST) break;
1404 ssize_t ret = write(fd, data, len);
1406 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1408 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1413 /****************************************************************************
1414 Prepare everything for calling the actual request function, and potentially
1415 call the request function via the "new" interface.
1417 Return False if the "legacy" function needs to be called, everything is
1420 Return True if we're done.
1422 I know this API sucks, but it is the one with the least code change I could
1424 ****************************************************************************/
1426 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1430 connection_struct *conn = NULL;
1431 struct smbd_server_connection *sconn = req->sconn;
1435 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1436 * so subtract 4 from it. */
1437 if (!valid_smb_header(req->inbuf)
1438 || (size < (smb_size - 4))) {
1439 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1440 smb_len(req->inbuf)));
1441 exit_server_cleanly("Non-SMB packet");
1444 if (smb_messages[type].fn == NULL) {
1445 DEBUG(0,("Unknown message type %d!\n",type));
1446 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1447 reply_unknown_new(req, type);
1451 flags = smb_messages[type].flags;
1453 /* In share mode security we must ignore the vuid. */
1454 session_tag = (lp_security() == SEC_SHARE)
1455 ? UID_FIELD_INVALID : req->vuid;
1458 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1459 (int)sys_getpid(), (unsigned long)conn));
1461 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1463 /* Ensure this value is replaced in the incoming packet. */
1464 SSVAL(req->inbuf,smb_uid,session_tag);
1467 * Ensure the correct username is in current_user_info. This is a
1468 * really ugly bugfix for problems with multiple session_setup_and_X's
1469 * being done and allowing %U and %G substitutions to work correctly.
1470 * There is a reason this code is done here, don't move it unless you
1471 * know what you're doing... :-).
1475 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1476 user_struct *vuser = NULL;
1478 sconn->smb1.sessions.last_session_tag = session_tag;
1479 if(session_tag != UID_FIELD_INVALID) {
1480 vuser = get_valid_user_struct(sconn, session_tag);
1482 set_current_user_info(
1483 vuser->server_info->sanitized_username,
1484 vuser->server_info->unix_name,
1485 vuser->server_info->info3->base.domain.string);
1490 /* Does this call need to be run as the connected user? */
1491 if (flags & AS_USER) {
1493 /* Does this call need a valid tree connection? */
1496 * Amazingly, the error code depends on the command
1499 if (type == SMBntcreateX) {
1500 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1502 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1507 if (!change_to_user(conn,session_tag)) {
1508 DEBUG(0, ("Error: Could not change to user. Removing "
1509 "deferred open, mid=%llu.\n",
1510 (unsigned long long)req->mid));
1511 reply_force_doserror(req, ERRSRV, ERRbaduid);
1515 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1517 /* Does it need write permission? */
1518 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1519 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1523 /* IPC services are limited */
1524 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1525 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1529 /* This call needs to be run as root */
1530 change_to_root_user();
1533 /* load service specific parameters */
1535 if (req->encrypted) {
1536 conn->encrypted_tid = true;
1537 /* encrypted required from now on. */
1538 conn->encrypt_level = Required;
1539 } else if (ENCRYPTION_REQUIRED(conn)) {
1540 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1541 exit_server_cleanly("encryption required "
1547 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1548 (flags & (AS_USER|DO_CHDIR)
1550 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1553 conn->num_smb_operations++;
1556 /* does this protocol need to be run as guest? */
1557 if ((flags & AS_GUEST)
1558 && (!change_to_guest() ||
1559 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1560 sconn->client_id.name,
1561 sconn->client_id.addr))) {
1562 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1566 smb_messages[type].fn(req);
1570 /****************************************************************************
1571 Construct a reply to the incoming packet.
1572 ****************************************************************************/
1574 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1575 uint32_t seqnum, bool encrypted,
1576 struct smb_perfcount_data *deferred_pcd)
1578 connection_struct *conn;
1579 struct smb_request *req;
1581 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1582 smb_panic("could not allocate smb_request");
1585 if (!init_smb_request(req, smbd_server_conn, (uint8 *)inbuf,
1586 unread_bytes, encrypted, seqnum)) {
1587 exit_server_cleanly("Invalid SMB request");
1590 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1592 /* we popped this message off the queue - keep original perf data */
1594 req->pcd = *deferred_pcd;
1596 SMB_PERFCOUNT_START(&req->pcd);
1597 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1598 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1601 conn = switch_message(req->cmd, req, size);
1603 if (req->unread_bytes) {
1604 /* writeX failed. drain socket. */
1605 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1606 req->unread_bytes) {
1607 smb_panic("failed to drain pending bytes");
1609 req->unread_bytes = 0;
1617 if (req->outbuf == NULL) {
1621 if (CVAL(req->outbuf,0) == 0) {
1622 show_msg((char *)req->outbuf);
1625 if (!srv_send_smb(req->sconn,
1626 (char *)req->outbuf,
1627 true, req->seqnum+1,
1628 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1630 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1638 /****************************************************************************
1639 Process an smb from the client
1640 ****************************************************************************/
1641 static void process_smb(struct smbd_server_connection *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((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1683 sconn->smb1.num_requests++;
1685 /* The timeout_processing function isn't run nearly
1686 often enough to implement 'max log size' without
1687 overrunning the size of the file by many megabytes.
1688 This is especially true if we are running at debug
1689 level 10. Checking every 50 SMBs is a nice
1690 tradeoff of performance vs log file size overrun. */
1692 if ((sconn->smb1.num_requests % 50) == 0 &&
1693 need_to_check_log_size()) {
1694 change_to_root_user();
1699 /****************************************************************************
1700 Return a string containing the function name of a SMB command.
1701 ****************************************************************************/
1703 const char *smb_fn_name(int type)
1705 const char *unknown_name = "SMBunknown";
1707 if (smb_messages[type].name == NULL)
1708 return(unknown_name);
1710 return(smb_messages[type].name);
1713 /****************************************************************************
1714 Helper functions for contruct_reply.
1715 ****************************************************************************/
1717 void add_to_common_flags2(uint32 v)
1722 void remove_from_common_flags2(uint32 v)
1724 common_flags2 &= ~v;
1727 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1730 srv_set_message(outbuf,0,0,false);
1732 SCVAL(outbuf, smb_com, req->cmd);
1733 SIVAL(outbuf,smb_rcls,0);
1734 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1735 SSVAL(outbuf,smb_flg2,
1736 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1738 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1740 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1741 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1742 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1743 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1746 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1748 construct_reply_common(req, (char *)req->inbuf, outbuf);
1752 * How many bytes have we already accumulated up to the current wct field
1756 size_t req_wct_ofs(struct smb_request *req)
1760 if (req->chain_outbuf == NULL) {
1763 buf_size = talloc_get_size(req->chain_outbuf);
1764 if ((buf_size % 4) != 0) {
1765 buf_size += (4 - (buf_size % 4));
1767 return buf_size - 4;
1771 * Hack around reply_nterror & friends not being aware of chained requests,
1772 * generating illegal (i.e. wct==0) chain replies.
1775 static void fixup_chain_error_packet(struct smb_request *req)
1777 uint8_t *outbuf = req->outbuf;
1779 reply_outbuf(req, 2, 0);
1780 memcpy(req->outbuf, outbuf, smb_wct);
1781 TALLOC_FREE(outbuf);
1782 SCVAL(req->outbuf, smb_vwv0, 0xff);
1786 * @brief Find the smb_cmd offset of the last command pushed
1787 * @param[in] buf The buffer we're building up
1788 * @retval Where can we put our next andx cmd?
1790 * While chaining requests, the "next" request we're looking at needs to put
1791 * its SMB_Command before the data the previous request already built up added
1792 * to the chain. Find the offset to the place where we have to put our cmd.
1795 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1800 cmd = CVAL(buf, smb_com);
1802 SMB_ASSERT(is_andx_req(cmd));
1806 while (CVAL(buf, ofs) != 0xff) {
1808 if (!is_andx_req(CVAL(buf, ofs))) {
1813 * ofs is from start of smb header, so add the 4 length
1814 * bytes. The next cmd is right after the wct field.
1816 ofs = SVAL(buf, ofs+2) + 4 + 1;
1818 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1826 * @brief Do the smb chaining at a buffer level
1827 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1828 * @param[in] smb_command The command that we want to issue
1829 * @param[in] wct How many words?
1830 * @param[in] vwv The words, already in network order
1831 * @param[in] bytes_alignment How shall we align "bytes"?
1832 * @param[in] num_bytes How many bytes?
1833 * @param[in] bytes The data the request ships
1835 * smb_splice_chain() adds the vwv and bytes to the request already present in
1839 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1840 uint8_t wct, const uint16_t *vwv,
1841 size_t bytes_alignment,
1842 uint32_t num_bytes, const uint8_t *bytes)
1845 size_t old_size, new_size;
1847 size_t chain_padding = 0;
1848 size_t bytes_padding = 0;
1851 old_size = talloc_get_size(*poutbuf);
1854 * old_size == smb_wct means we're pushing the first request in for
1858 first_request = (old_size == smb_wct);
1860 if (!first_request && ((old_size % 4) != 0)) {
1862 * Align the wct field of subsequent requests to a 4-byte
1865 chain_padding = 4 - (old_size % 4);
1869 * After the old request comes the new wct field (1 byte), the vwv's
1870 * and the num_bytes field. After at we might need to align the bytes
1871 * given to us to "bytes_alignment", increasing the num_bytes value.
1874 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1876 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1877 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1880 new_size += bytes_padding + num_bytes;
1882 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1883 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1884 (unsigned)new_size));
1888 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1889 if (outbuf == NULL) {
1890 DEBUG(0, ("talloc failed\n"));
1895 if (first_request) {
1896 SCVAL(outbuf, smb_com, smb_command);
1898 size_t andx_cmd_ofs;
1900 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1901 DEBUG(1, ("invalid command chain\n"));
1902 *poutbuf = TALLOC_REALLOC_ARRAY(
1903 NULL, *poutbuf, uint8_t, old_size);
1907 if (chain_padding != 0) {
1908 memset(outbuf + old_size, 0, chain_padding);
1909 old_size += chain_padding;
1912 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1913 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1919 * Push the chained request:
1924 SCVAL(outbuf, ofs, wct);
1931 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1932 ofs += sizeof(uint16_t) * wct;
1938 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1939 ofs += sizeof(uint16_t);
1945 if (bytes_padding != 0) {
1946 memset(outbuf + ofs, 0, bytes_padding);
1947 ofs += bytes_padding;
1954 memcpy(outbuf + ofs, bytes, num_bytes);
1959 /****************************************************************************
1960 Construct a chained reply and add it to the already made reply
1961 ****************************************************************************/
1963 void chain_reply(struct smb_request *req)
1965 size_t smblen = smb_len(req->inbuf);
1966 size_t already_used, length_needed;
1968 uint32_t chain_offset; /* uint32_t to avoid overflow */
1975 if (IVAL(req->outbuf, smb_rcls) != 0) {
1976 fixup_chain_error_packet(req);
1980 * Any of the AndX requests and replies have at least a wct of
1981 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1982 * beginning of the SMB header to the next wct field.
1984 * None of the AndX requests put anything valuable in vwv[0] and [1],
1985 * so we can overwrite it here to form the chain.
1988 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1989 if (req->chain_outbuf == NULL) {
1990 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1991 req, req->outbuf, uint8_t,
1992 smb_len(req->outbuf) + 4);
1993 if (req->chain_outbuf == NULL) {
1994 smb_panic("talloc failed");
2002 * Here we assume that this is the end of the chain. For that we need
2003 * to set "next command" to 0xff and the offset to 0. If we later find
2004 * more commands in the chain, this will be overwritten again.
2007 SCVAL(req->outbuf, smb_vwv0, 0xff);
2008 SCVAL(req->outbuf, smb_vwv0+1, 0);
2009 SSVAL(req->outbuf, smb_vwv1, 0);
2011 if (req->chain_outbuf == NULL) {
2013 * In req->chain_outbuf we collect all the replies. Start the
2014 * chain by copying in the first reply.
2016 * We do the realloc because later on we depend on
2017 * talloc_get_size to determine the length of
2018 * chain_outbuf. The reply_xxx routines might have
2019 * over-allocated (reply_pipe_read_and_X used to be such an
2022 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2023 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2024 if (req->chain_outbuf == NULL) {
2025 smb_panic("talloc failed");
2030 * Update smb headers where subsequent chained commands
2031 * may have updated them.
2033 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2034 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2036 if (!smb_splice_chain(&req->chain_outbuf,
2037 CVAL(req->outbuf, smb_com),
2038 CVAL(req->outbuf, smb_wct),
2039 (uint16_t *)(req->outbuf + smb_vwv),
2040 0, smb_buflen(req->outbuf),
2041 (uint8_t *)smb_buf(req->outbuf))) {
2044 TALLOC_FREE(req->outbuf);
2048 * We use the old request's vwv field to grab the next chained command
2049 * and offset into the chained fields.
2052 chain_cmd = CVAL(req->vwv+0, 0);
2053 chain_offset = SVAL(req->vwv+1, 0);
2055 if (chain_cmd == 0xff) {
2057 * End of chain, no more requests from the client. So ship the
2060 smb_setlen((char *)(req->chain_outbuf),
2061 talloc_get_size(req->chain_outbuf) - 4);
2063 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2064 true, req->seqnum+1,
2065 IS_CONN_ENCRYPTED(req->conn)
2068 exit_server_cleanly("chain_reply: srv_send_smb "
2071 TALLOC_FREE(req->chain_outbuf);
2076 /* add a new perfcounter for this element of chain */
2077 SMB_PERFCOUNT_ADD(&req->pcd);
2078 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2079 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2082 * Check if the client tries to fool us. The request so far uses the
2083 * space to the end of the byte buffer in the request just
2084 * processed. The chain_offset can't point into that area. If that was
2085 * the case, we could end up with an endless processing of the chain,
2086 * we would always handle the same request.
2089 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2090 if (chain_offset < already_used) {
2095 * Next check: Make sure the chain offset does not point beyond the
2096 * overall smb request length.
2099 length_needed = chain_offset+1; /* wct */
2100 if (length_needed > smblen) {
2105 * Now comes the pointer magic. Goal here is to set up req->vwv and
2106 * req->buf correctly again to be able to call the subsequent
2107 * switch_message(). The chain offset (the former vwv[1]) points at
2108 * the new wct field.
2111 wct = CVAL(smb_base(req->inbuf), chain_offset);
2114 * Next consistency check: Make the new vwv array fits in the overall
2118 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2119 if (length_needed > smblen) {
2122 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2125 * Now grab the new byte buffer....
2128 buflen = SVAL(vwv+wct, 0);
2131 * .. and check that it fits.
2134 length_needed += buflen;
2135 if (length_needed > smblen) {
2138 buf = (uint8_t *)(vwv+wct+1);
2140 req->cmd = chain_cmd;
2143 req->buflen = buflen;
2146 switch_message(chain_cmd, req, smblen);
2148 if (req->outbuf == NULL) {
2150 * This happens if the chained command has suspended itself or
2151 * if it has called srv_send_smb() itself.
2157 * We end up here if the chained command was not itself chained or
2158 * suspended, but for example a close() command. We now need to splice
2159 * the chained commands' outbuf into the already built up chain_outbuf
2160 * and ship the result.
2166 * We end up here if there's any error in the chain syntax. Report a
2167 * DOS error, just like Windows does.
2169 reply_force_doserror(req, ERRSRV, ERRerror);
2170 fixup_chain_error_packet(req);
2174 * This scary statement intends to set the
2175 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2176 * to the value req->outbuf carries
2178 SSVAL(req->chain_outbuf, smb_flg2,
2179 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2180 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2183 * Transfer the error codes from the subrequest to the main one
2185 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2186 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2188 if (!smb_splice_chain(&req->chain_outbuf,
2189 CVAL(req->outbuf, smb_com),
2190 CVAL(req->outbuf, smb_wct),
2191 (uint16_t *)(req->outbuf + smb_vwv),
2192 0, smb_buflen(req->outbuf),
2193 (uint8_t *)smb_buf(req->outbuf))) {
2194 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2196 TALLOC_FREE(req->outbuf);
2198 smb_setlen((char *)(req->chain_outbuf),
2199 talloc_get_size(req->chain_outbuf) - 4);
2201 show_msg((char *)(req->chain_outbuf));
2203 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2204 true, req->seqnum+1,
2205 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2207 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2209 TALLOC_FREE(req->chain_outbuf);
2213 /****************************************************************************
2214 Check if services need reloading.
2215 ****************************************************************************/
2217 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2219 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2221 if(last_smb_conf_reload_time == 0) {
2222 last_smb_conf_reload_time = t;
2223 /* Our printing subsystem might not be ready at smbd start up.
2224 Then no printer is available till the first printers check
2225 is performed. A lower initial interval circumvents this. */
2226 if ( printcap_cache_time > 60 )
2227 last_printer_reload_time = t - printcap_cache_time + 60;
2229 last_printer_reload_time = t;
2232 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2233 /* randomize over 60 second the printcap reload to avoid all
2234 * process hitting cupsd at the same time */
2235 int time_range = 60;
2237 last_printer_reload_time += random() % time_range;
2241 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2242 reload_services(sconn->msg_ctx, sconn->sock, True);
2243 last_smb_conf_reload_time = t;
2246 /* 'printcap cache time = 0' disable the feature */
2248 if ( printcap_cache_time != 0 )
2250 /* see if it's time to reload or if the clock has been set back */
2252 if ( (t >= last_printer_reload_time+printcap_cache_time)
2253 || (t-last_printer_reload_time < 0) )
2255 DEBUG( 3,( "Printcap cache time expired.\n"));
2256 reload_printers(sconn->msg_ctx);
2257 last_printer_reload_time = t;
2262 static bool fd_is_readable(int fd)
2265 struct timeval timeout = {0, };
2271 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2275 return FD_ISSET(fd, &fds);
2278 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2280 /* TODO: make write nonblocking */
2283 static void smbd_server_connection_read_handler(
2284 struct smbd_server_connection *conn, int fd)
2286 uint8_t *inbuf = NULL;
2287 size_t inbuf_len = 0;
2288 size_t unread_bytes = 0;
2289 bool encrypted = false;
2290 TALLOC_CTX *mem_ctx = talloc_tos();
2294 bool from_client = (conn->sock == fd);
2297 smbd_lock_socket(conn);
2299 if (!fd_is_readable(fd)) {
2300 DEBUG(10,("the echo listener was faster\n"));
2301 smbd_unlock_socket(conn);
2305 /* TODO: make this completely nonblocking */
2306 status = receive_smb_talloc(mem_ctx, fd,
2307 (char **)(void *)&inbuf,
2311 &inbuf_len, &seqnum,
2312 false /* trusted channel */);
2313 smbd_unlock_socket(conn);
2315 /* TODO: make this completely nonblocking */
2316 status = receive_smb_talloc(mem_ctx, fd,
2317 (char **)(void *)&inbuf,
2321 &inbuf_len, &seqnum,
2322 true /* trusted channel */);
2325 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2328 if (NT_STATUS_IS_ERR(status)) {
2329 exit_server_cleanly("failed to receive smb request");
2331 if (!NT_STATUS_IS_OK(status)) {
2336 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2337 seqnum, encrypted, NULL);
2340 static void smbd_server_connection_handler(struct event_context *ev,
2341 struct fd_event *fde,
2345 struct smbd_server_connection *conn = talloc_get_type(private_data,
2346 struct smbd_server_connection);
2348 if (flags & EVENT_FD_WRITE) {
2349 smbd_server_connection_write_handler(conn);
2352 if (flags & EVENT_FD_READ) {
2353 smbd_server_connection_read_handler(conn, conn->sock);
2358 static void smbd_server_echo_handler(struct event_context *ev,
2359 struct fd_event *fde,
2363 struct smbd_server_connection *conn = talloc_get_type(private_data,
2364 struct smbd_server_connection);
2366 if (flags & EVENT_FD_WRITE) {
2367 smbd_server_connection_write_handler(conn);
2370 if (flags & EVENT_FD_READ) {
2371 smbd_server_connection_read_handler(
2372 conn, conn->smb1.echo_handler.trusted_fd);
2377 /****************************************************************************
2378 received when we should release a specific IP
2379 ****************************************************************************/
2380 static void release_ip(const char *ip, void *priv)
2382 const char *addr = (const char *)priv;
2383 const char *p = addr;
2385 if (strncmp("::ffff:", addr, 7) == 0) {
2389 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2390 /* we can't afford to do a clean exit - that involves
2391 database writes, which would potentially mean we
2392 are still running after the failover has finished -
2393 we have to get rid of this process ID straight
2395 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2397 /* note we must exit with non-zero status so the unclean handler gets
2398 called in the parent, so that the brl database is tickled */
2403 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2404 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2406 struct smbd_server_connection *sconn = talloc_get_type_abort(
2407 private_data, struct smbd_server_connection);
2409 release_ip((char *)data->data, sconn->client_id.addr);
2412 #ifdef CLUSTER_SUPPORT
2413 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2414 struct sockaddr_storage *client)
2417 length = sizeof(*server);
2418 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2421 length = sizeof(*client);
2422 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2430 * Send keepalive packets to our client
2432 static bool keepalive_fn(const struct timeval *now, void *private_data)
2434 struct smbd_server_connection *sconn = smbd_server_conn;
2437 if (sconn->using_smb2) {
2438 /* Don't do keepalives on an SMB2 connection. */
2442 smbd_lock_socket(smbd_server_conn);
2443 ret = send_keepalive(sconn->sock);
2444 smbd_unlock_socket(smbd_server_conn);
2447 char addr[INET6_ADDRSTRLEN];
2449 * Try and give an error message saying what
2452 DEBUG(0, ("send_keepalive failed for client %s. "
2453 "Error %s - exiting\n",
2454 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2462 * Do the recurring check if we're idle
2464 static bool deadtime_fn(const struct timeval *now, void *private_data)
2466 struct smbd_server_connection *sconn =
2467 (struct smbd_server_connection *)private_data;
2469 if (sconn->using_smb2) {
2470 /* TODO: implement real idle check */
2471 if (sconn->smb2.sessions.list) {
2474 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2475 messaging_send(sconn->msg_ctx,
2476 messaging_server_id(sconn->msg_ctx),
2477 MSG_SHUTDOWN, &data_blob_null);
2481 if ((conn_num_open(sconn) == 0)
2482 || (conn_idle_all(sconn, now->tv_sec))) {
2483 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2484 messaging_send(sconn->msg_ctx,
2485 messaging_server_id(sconn->msg_ctx),
2486 MSG_SHUTDOWN, &data_blob_null);
2494 * Do the recurring log file and smb.conf reload checks.
2497 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2499 struct smbd_server_connection *sconn = talloc_get_type_abort(
2500 private_data, struct smbd_server_connection);
2501 change_to_root_user();
2503 /* update printer queue caches if necessary */
2504 update_monitored_printq_cache(sconn->msg_ctx);
2506 /* check if we need to reload services */
2507 check_reload(sconn, time(NULL));
2509 /* Change machine password if neccessary. */
2510 attempt_machine_password_change();
2513 * Force a log file check.
2515 force_check_log_size();
2520 static int create_unlink_tmp(const char *dir)
2525 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2526 if (fname == NULL) {
2530 fd = mkstemp(fname);
2535 if (unlink(fname) == -1) {
2536 int sys_errno = errno;
2546 struct smbd_echo_state {
2547 struct tevent_context *ev;
2548 struct iovec *pending;
2549 struct smbd_server_connection *sconn;
2552 struct tevent_fd *parent_fde;
2554 struct tevent_fd *read_fde;
2555 struct tevent_req *write_req;
2558 static void smbd_echo_writer_done(struct tevent_req *req);
2560 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2564 if (state->write_req != NULL) {
2568 num_pending = talloc_array_length(state->pending);
2569 if (num_pending == 0) {
2573 state->write_req = writev_send(state, state->ev, NULL,
2574 state->parent_pipe, false,
2575 state->pending, num_pending);
2576 if (state->write_req == NULL) {
2577 DEBUG(1, ("writev_send failed\n"));
2581 talloc_steal(state->write_req, state->pending);
2582 state->pending = NULL;
2584 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2588 static void smbd_echo_writer_done(struct tevent_req *req)
2590 struct smbd_echo_state *state = tevent_req_callback_data(
2591 req, struct smbd_echo_state);
2595 written = writev_recv(req, &err);
2597 state->write_req = NULL;
2598 if (written == -1) {
2599 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2602 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2603 smbd_echo_activate_writer(state);
2606 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2609 struct smb_request req;
2610 uint16_t num_replies;
2615 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2616 DEBUG(10, ("Got netbios keepalive\n"));
2623 if (inbuf_len < smb_size) {
2624 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2627 if (!valid_smb_header(inbuf)) {
2628 DEBUG(10, ("Got invalid SMB header\n"));
2632 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2638 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2639 smb_messages[req.cmd].name
2640 ? smb_messages[req.cmd].name : "unknown"));
2642 if (req.cmd != SMBecho) {
2649 num_replies = SVAL(req.vwv+0, 0);
2650 if (num_replies != 1) {
2651 /* Not a Windows "Hey, you're still there?" request */
2655 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2657 DEBUG(10, ("create_outbuf failed\n"));
2660 req.outbuf = (uint8_t *)outbuf;
2662 SSVAL(req.outbuf, smb_vwv0, num_replies);
2664 if (req.buflen > 0) {
2665 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2668 out_len = smb_len(req.outbuf) + 4;
2670 ok = srv_send_smb(req.sconn,
2674 TALLOC_FREE(outbuf);
2682 static void smbd_echo_exit(struct tevent_context *ev,
2683 struct tevent_fd *fde, uint16_t flags,
2686 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2690 static void smbd_echo_reader(struct tevent_context *ev,
2691 struct tevent_fd *fde, uint16_t flags,
2694 struct smbd_echo_state *state = talloc_get_type_abort(
2695 private_data, struct smbd_echo_state);
2696 struct smbd_server_connection *sconn = state->sconn;
2697 size_t unread, num_pending;
2701 uint32_t seqnum = 0;
2704 bool encrypted = false;
2708 ok = smbd_lock_socket_internal(sconn);
2710 DEBUG(0, ("%s: failed to lock socket\n",
2715 if (!fd_is_readable(sconn->sock)) {
2716 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2717 (int)sys_getpid()));
2718 ok = smbd_unlock_socket_internal(sconn);
2720 DEBUG(1, ("%s: failed to unlock socket in\n",
2727 num_pending = talloc_array_length(state->pending);
2728 tmp = talloc_realloc(state, state->pending, struct iovec,
2731 DEBUG(1, ("talloc_realloc failed\n"));
2734 state->pending = tmp;
2736 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2738 status = receive_smb_talloc(state->pending, sconn->sock,
2739 (char **)(void *)&state->pending[num_pending].iov_base,
2745 false /* trusted_channel*/);
2746 if (!NT_STATUS_IS_OK(status)) {
2747 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2748 (int)sys_getpid(), nt_errstr(status)));
2751 state->pending[num_pending].iov_len = iov_len;
2753 ok = smbd_unlock_socket_internal(sconn);
2755 DEBUG(1, ("%s: failed to unlock socket in\n",
2760 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2761 state->pending[num_pending].iov_len,
2764 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2765 /* no check, shrinking by some bytes does not fail */
2766 state->pending = talloc_realloc(state, state->pending,
2772 if (state->pending[num_pending].iov_len >= smb_size) {
2774 * place the seqnum in the packet so that the main process
2775 * can reply with signing
2777 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2778 smb_ss_field, seqnum);
2779 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2780 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2783 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2784 smbd_echo_activate_writer(state);
2787 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2790 struct smbd_echo_state *state;
2792 state = talloc_zero(sconn, struct smbd_echo_state);
2793 if (state == NULL) {
2794 DEBUG(1, ("talloc failed\n"));
2797 state->sconn = sconn;
2798 state->parent_pipe = parent_pipe;
2799 state->ev = s3_tevent_context_init(state);
2800 if (state->ev == NULL) {
2801 DEBUG(1, ("tevent_context_init failed\n"));
2805 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2806 TEVENT_FD_READ, smbd_echo_exit,
2808 if (state->parent_fde == NULL) {
2809 DEBUG(1, ("tevent_add_fd failed\n"));
2813 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2814 TEVENT_FD_READ, smbd_echo_reader,
2816 if (state->read_fde == NULL) {
2817 DEBUG(1, ("tevent_add_fd failed\n"));
2823 if (tevent_loop_once(state->ev) == -1) {
2824 DEBUG(1, ("tevent_loop_once failed: %s\n",
2833 * Handle SMBecho requests in a forked child process
2835 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2837 int listener_pipe[2];
2841 res = pipe(listener_pipe);
2843 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2846 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2847 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2848 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2856 close(listener_pipe[0]);
2857 set_blocking(listener_pipe[1], false);
2859 status = reinit_after_fork(sconn->msg_ctx,
2860 smbd_event_context(),
2861 procid_self(), false);
2862 if (!NT_STATUS_IS_OK(status)) {
2863 DEBUG(1, ("reinit_after_fork failed: %s\n",
2864 nt_errstr(status)));
2867 smbd_echo_loop(sconn, listener_pipe[1]);
2870 close(listener_pipe[1]);
2871 listener_pipe[1] = -1;
2872 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2874 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2877 * Without smb signing this is the same as the normal smbd
2878 * listener. This needs to change once signing comes in.
2880 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2882 sconn->smb1.echo_handler.trusted_fd,
2884 smbd_server_echo_handler,
2886 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2887 DEBUG(1, ("event_add_fd failed\n"));
2894 if (listener_pipe[0] != -1) {
2895 close(listener_pipe[0]);
2897 if (listener_pipe[1] != -1) {
2898 close(listener_pipe[1]);
2900 sconn->smb1.echo_handler.trusted_fd = -1;
2901 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2902 close(sconn->smb1.echo_handler.socket_lock_fd);
2904 sconn->smb1.echo_handler.trusted_fd = -1;
2905 sconn->smb1.echo_handler.socket_lock_fd = -1;
2911 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2912 struct sockaddr_storage *srv,
2913 struct sockaddr_storage *clnt)
2915 struct ctdbd_connection *cconn;
2916 char tmp_addr[INET6_ADDRSTRLEN];
2919 cconn = messaging_ctdbd_connection();
2920 if (cconn == NULL) {
2921 return NT_STATUS_NO_MEMORY;
2924 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2925 addr = talloc_strdup(cconn, tmp_addr);
2927 return NT_STATUS_NO_MEMORY;
2929 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2934 /****************************************************************************
2935 Process commands from the client
2936 ****************************************************************************/
2938 void smbd_process(struct smbd_server_connection *sconn)
2940 TALLOC_CTX *frame = talloc_stackframe();
2941 struct sockaddr_storage ss;
2942 struct sockaddr *sa = NULL;
2943 socklen_t sa_socklen;
2944 struct tsocket_address *local_address = NULL;
2945 struct tsocket_address *remote_address = NULL;
2946 const char *remaddr = NULL;
2949 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2950 lp_security() != SEC_SHARE &&
2951 !lp_async_smb_echo_handler()) {
2953 * We're not making the desion here,
2954 * we're just allowing the client
2955 * to decide between SMB1 and SMB2
2956 * with the first negprot
2959 sconn->using_smb2 = true;
2962 /* Ensure child is set to blocking mode */
2963 set_blocking(sconn->sock,True);
2965 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2966 set_socket_options(sconn->sock, lp_socket_options());
2968 sa = (struct sockaddr *)(void *)&ss;
2969 sa_socklen = sizeof(ss);
2970 ret = getpeername(sconn->sock, sa, &sa_socklen);
2972 int level = (errno == ENOTCONN)?2:0;
2973 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2974 exit_server_cleanly("getpeername() failed.\n");
2976 ret = tsocket_address_bsd_from_sockaddr(sconn,
2980 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2981 __location__, strerror(errno)));
2982 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2985 sa = (struct sockaddr *)(void *)&ss;
2986 sa_socklen = sizeof(ss);
2987 ret = getsockname(sconn->sock, sa, &sa_socklen);
2989 int level = (errno == ENOTCONN)?2:0;
2990 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2991 exit_server_cleanly("getsockname() failed.\n");
2993 ret = tsocket_address_bsd_from_sockaddr(sconn,
2997 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2998 __location__, strerror(errno)));
2999 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3002 sconn->local_address = local_address;
3003 sconn->remote_address = remote_address;
3005 if (tsocket_address_is_inet(remote_address, "ip")) {
3006 remaddr = tsocket_address_inet_addr_string(
3007 sconn->remote_address,
3009 if (remaddr == NULL) {
3013 remaddr = "0.0.0.0";
3016 /* this is needed so that we get decent entries
3017 in smbstatus for port 445 connects */
3018 set_remote_machine_name(remaddr, false);
3019 reload_services(sconn->msg_ctx, sconn->sock, true);
3022 * Before the first packet, check the global hosts allow/ hosts deny
3023 * parameters before doing any parsing of packets passed to us by the
3024 * client. This prevents attacks on our parsing code from hosts not in
3025 * the hosts allow list.
3028 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3029 sconn->client_id.name,
3030 sconn->client_id.addr)) {
3032 * send a negative session response "not listening on calling
3035 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3036 DEBUG( 1, ("Connection denied from %s to %s\n",
3037 tsocket_address_string(remote_address, talloc_tos()),
3038 tsocket_address_string(local_address, talloc_tos())));
3039 (void)srv_send_smb(sconn,(char *)buf, false,
3041 exit_server_cleanly("connection denied");
3044 DEBUG(10, ("Connection allowed from %s to %s\n",
3045 tsocket_address_string(remote_address, talloc_tos()),
3046 tsocket_address_string(local_address, talloc_tos())));
3050 smb_perfcount_init();
3052 if (!init_account_policy()) {
3053 exit_server("Could not open account policy tdb.\n");
3056 if (*lp_rootdir()) {
3057 if (chroot(lp_rootdir()) != 0) {
3058 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3059 exit_server("Failed to chroot()");
3061 if (chdir("/") == -1) {
3062 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3063 exit_server("Failed to chroot()");
3065 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3068 if (!srv_init_signing(sconn)) {
3069 exit_server("Failed to init smb_signing");
3072 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3073 exit_server("Failed to fork echo handler");
3077 if (!init_oplocks(sconn->msg_ctx))
3078 exit_server("Failed to init oplocks");
3080 /* register our message handlers */
3081 messaging_register(sconn->msg_ctx, NULL,
3082 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3083 messaging_register(sconn->msg_ctx, sconn,
3084 MSG_SMB_RELEASE_IP, msg_release_ip);
3085 messaging_register(sconn->msg_ctx, NULL,
3086 MSG_SMB_CLOSE_FILE, msg_close_file);
3089 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3090 * MSGs to all child processes
3092 messaging_deregister(sconn->msg_ctx,
3094 messaging_register(sconn->msg_ctx, NULL,
3095 MSG_DEBUG, debug_message);
3097 if ((lp_keepalive() != 0)
3098 && !(event_add_idle(smbd_event_context(), NULL,
3099 timeval_set(lp_keepalive(), 0),
3100 "keepalive", keepalive_fn,
3102 DEBUG(0, ("Could not add keepalive event\n"));
3106 if (!(event_add_idle(smbd_event_context(), NULL,
3107 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3108 "deadtime", deadtime_fn, sconn))) {
3109 DEBUG(0, ("Could not add deadtime event\n"));
3113 if (!(event_add_idle(smbd_event_context(), NULL,
3114 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3115 "housekeeping", housekeeping_fn, sconn))) {
3116 DEBUG(0, ("Could not add housekeeping event\n"));
3120 #ifdef CLUSTER_SUPPORT
3122 if (lp_clustering()) {
3124 * We need to tell ctdb about our client's TCP
3125 * connection, so that for failover ctdbd can send
3126 * tickle acks, triggering a reconnection by the
3130 struct sockaddr_storage srv, clnt;
3132 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3134 status = smbd_register_ips(sconn, &srv, &clnt);
3135 if (!NT_STATUS_IS_OK(status)) {
3136 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3137 nt_errstr(status)));
3141 DEBUG(0,("Unable to get tcp info for "
3142 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3149 sconn->nbt.got_session = false;
3151 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3153 sconn->smb1.sessions.done_sesssetup = false;
3154 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3155 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3156 /* users from session setup */
3157 sconn->smb1.sessions.session_userlist = NULL;
3158 /* workgroup from session setup. */
3159 sconn->smb1.sessions.session_workgroup = NULL;
3160 /* this holds info on user ids that are already validated for this VC */
3161 sconn->smb1.sessions.validated_users = NULL;
3162 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3163 sconn->smb1.sessions.num_validated_vuids = 0;
3166 if (!init_dptrs(sconn)) {
3167 exit_server("init_dptrs() failed");
3170 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3174 smbd_server_connection_handler,
3176 if (!sconn->smb1.fde) {
3177 exit_server("failed to create smbd_server_connection fde");
3185 frame = talloc_stackframe_pool(8192);
3189 status = smbd_server_connection_loop_once(sconn);
3190 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3191 !NT_STATUS_IS_OK(status)) {
3192 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3193 " exiting\n", nt_errstr(status)));
3200 exit_server_cleanly(NULL);
3203 bool req_is_in_chain(struct smb_request *req)
3205 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3207 * We're right now handling a subsequent request, so we must
3213 if (!is_andx_req(req->cmd)) {
3219 * Okay, an illegal request, but definitely not chained :-)
3224 return (CVAL(req->vwv+0, 0) != 0xFF);