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 "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
40 extern bool global_machine_password_needs_changing;
42 static void construct_reply_common(struct smb_request *req, const char *inbuf,
44 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
46 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
50 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
54 sconn->smb1.echo_handler.ref_count++;
56 if (sconn->smb1.echo_handler.ref_count > 1) {
60 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
64 sconn->smb1.echo_handler.socket_lock_fd,
65 SMB_F_SETLKW, 0, 0, F_WRLCK);
66 } while (!ok && (errno == EINTR));
69 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
73 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
78 void smbd_lock_socket(struct smbd_server_connection *sconn)
80 if (!smbd_lock_socket_internal(sconn)) {
81 exit_server_cleanly("failed to lock socket");
85 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
89 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
93 sconn->smb1.echo_handler.ref_count--;
95 if (sconn->smb1.echo_handler.ref_count > 0) {
101 sconn->smb1.echo_handler.socket_lock_fd,
102 SMB_F_SETLKW, 0, 0, F_UNLCK);
103 } while (!ok && (errno == EINTR));
106 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
110 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
115 void smbd_unlock_socket(struct smbd_server_connection *sconn)
117 if (!smbd_unlock_socket_internal(sconn)) {
118 exit_server_cleanly("failed to unlock socket");
122 /* Accessor function for smb_read_error for smbd functions. */
124 /****************************************************************************
126 ****************************************************************************/
128 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
129 bool do_signing, uint32_t seqnum,
131 struct smb_perfcount_data *pcd)
136 char *buf_out = buffer;
138 smbd_lock_socket(sconn);
141 /* Sign the outgoing packet if required. */
142 srv_calculate_sign_mac(sconn, buf_out, seqnum);
146 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
147 if (!NT_STATUS_IS_OK(status)) {
148 DEBUG(0, ("send_smb: SMB encryption failed "
149 "on outgoing packet! Error %s\n",
150 nt_errstr(status) ));
155 len = smb_len(buf_out) + 4;
157 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
160 char addr[INET6_ADDRSTRLEN];
162 * Try and give an error message saying what
165 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
166 (int)sys_getpid(), (int)len,
167 get_peer_addr(sconn->sock, addr, sizeof(addr)),
168 (int)ret, strerror(errno) ));
170 srv_free_enc_buffer(buf_out);
174 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
175 srv_free_enc_buffer(buf_out);
177 SMB_PERFCOUNT_END(pcd);
179 smbd_unlock_socket(sconn);
183 /*******************************************************************
184 Setup the word count and byte count for a smb message.
185 ********************************************************************/
187 int srv_set_message(char *buf,
192 if (zero && (num_words || num_bytes)) {
193 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
195 SCVAL(buf,smb_wct,num_words);
196 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
197 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
198 return (smb_size + num_words*2 + num_bytes);
201 static bool valid_smb_header(const uint8_t *inbuf)
203 if (is_encrypted_packet(inbuf)) {
207 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
208 * but it just looks weird to call strncmp for this one.
210 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
213 /* Socket functions for smbd packet processing. */
215 static bool valid_packet_size(size_t len)
218 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
219 * of header. Don't print the error if this fits.... JRA.
222 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
223 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
224 (unsigned long)len));
230 static NTSTATUS read_packet_remainder(int fd, char *buffer,
231 unsigned int timeout, ssize_t len)
239 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
240 if (!NT_STATUS_IS_OK(status)) {
241 char addr[INET6_ADDRSTRLEN];
242 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
244 get_peer_addr(fd, addr, sizeof(addr)),
250 /****************************************************************************
251 Attempt a zerocopy writeX read. We know here that len > smb_size-4
252 ****************************************************************************/
255 * Unfortunately, earlier versions of smbclient/libsmbclient
256 * don't send this "standard" writeX header. I've fixed this
257 * for 3.2 but we'll use the old method with earlier versions.
258 * Windows and CIFSFS at least use this standard size. Not
262 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
263 (2*14) + /* word count (including bcc) */ \
266 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
267 const char lenbuf[4],
268 struct smbd_server_connection *sconn,
271 unsigned int timeout,
275 /* Size of a WRITEX call (+4 byte len). */
276 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
277 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
281 memcpy(writeX_header, lenbuf, 4);
283 status = read_fd_with_timeout(
284 sock, writeX_header + 4,
285 STANDARD_WRITE_AND_X_HEADER_SIZE,
286 STANDARD_WRITE_AND_X_HEADER_SIZE,
289 if (!NT_STATUS_IS_OK(status)) {
290 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
292 tsocket_address_string(sconn->remote_address,
299 * Ok - now try and see if this is a possible
303 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
305 * If the data offset is beyond what
306 * we've read, drain the extra bytes.
308 uint16_t doff = SVAL(writeX_header,smb_vwv11);
311 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
312 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
313 if (drain_socket(sock, drain) != drain) {
314 smb_panic("receive_smb_raw_talloc_partial_read:"
315 " failed to drain pending bytes");
318 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
321 /* Spoof down the length and null out the bcc. */
322 set_message_bcc(writeX_header, 0);
323 newlen = smb_len(writeX_header);
325 /* Copy the header we've written. */
327 *buffer = (char *)talloc_memdup(mem_ctx,
329 sizeof(writeX_header));
331 if (*buffer == NULL) {
332 DEBUG(0, ("Could not allocate inbuf of length %d\n",
333 (int)sizeof(writeX_header)));
334 return NT_STATUS_NO_MEMORY;
337 /* Work out the remaining bytes. */
338 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
339 *len_ret = newlen + 4;
343 if (!valid_packet_size(len)) {
344 return NT_STATUS_INVALID_PARAMETER;
348 * Not a valid writeX call. Just do the standard
352 *buffer = talloc_array(mem_ctx, char, len+4);
354 if (*buffer == NULL) {
355 DEBUG(0, ("Could not allocate inbuf of length %d\n",
357 return NT_STATUS_NO_MEMORY;
360 /* Copy in what we already read. */
363 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
364 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
367 status = read_packet_remainder(
369 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
372 if (!NT_STATUS_IS_OK(status)) {
373 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
383 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
384 struct smbd_server_connection *sconn,
386 char **buffer, unsigned int timeout,
387 size_t *p_unread, size_t *plen)
391 int min_recv_size = lp_min_receive_file_size();
396 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
398 if (!NT_STATUS_IS_OK(status)) {
402 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
403 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
404 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
405 !srv_is_signing_active(sconn) &&
406 sconn->smb1.echo_handler.trusted_fde == NULL) {
408 return receive_smb_raw_talloc_partial_read(
409 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
413 if (!valid_packet_size(len)) {
414 return NT_STATUS_INVALID_PARAMETER;
418 * The +4 here can't wrap, we've checked the length above already.
421 *buffer = talloc_array(mem_ctx, char, len+4);
423 if (*buffer == NULL) {
424 DEBUG(0, ("Could not allocate inbuf of length %d\n",
426 return NT_STATUS_NO_MEMORY;
429 memcpy(*buffer, lenbuf, sizeof(lenbuf));
431 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
432 if (!NT_STATUS_IS_OK(status)) {
440 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
441 struct smbd_server_connection *sconn,
443 char **buffer, unsigned int timeout,
444 size_t *p_unread, bool *p_encrypted,
447 bool trusted_channel)
452 *p_encrypted = false;
454 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
456 if (!NT_STATUS_IS_OK(status)) {
457 DEBUG(1, ("read_smb_length_return_keepalive failed for "
458 "client %s read error = %s.\n",
459 tsocket_address_string(sconn->remote_address,
465 if (is_encrypted_packet((uint8_t *)*buffer)) {
466 status = srv_decrypt_buffer(*buffer);
467 if (!NT_STATUS_IS_OK(status)) {
468 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
469 "incoming packet! Error %s\n",
470 nt_errstr(status) ));
476 /* Check the incoming SMB signature. */
477 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
478 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
479 "incoming packet!\n"));
480 return NT_STATUS_INVALID_NETWORK_RESPONSE;
488 * Initialize a struct smb_request from an inbuf
491 static bool init_smb_request(struct smb_request *req,
492 struct smbd_server_connection *sconn,
494 size_t unread_bytes, bool encrypted,
497 size_t req_size = smb_len(inbuf) + 4;
498 /* Ensure we have at least smb_size bytes. */
499 if (req_size < smb_size) {
500 DEBUG(0,("init_smb_request: invalid request size %u\n",
501 (unsigned int)req_size ));
504 req->cmd = CVAL(inbuf, smb_com);
505 req->flags2 = SVAL(inbuf, smb_flg2);
506 req->smbpid = SVAL(inbuf, smb_pid);
507 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
508 req->seqnum = seqnum;
509 req->vuid = SVAL(inbuf, smb_uid);
510 req->tid = SVAL(inbuf, smb_tid);
511 req->wct = CVAL(inbuf, smb_wct);
512 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
513 req->buflen = smb_buflen(inbuf);
514 req->buf = (const uint8_t *)smb_buf_const(inbuf);
515 req->unread_bytes = unread_bytes;
516 req->encrypted = encrypted;
518 req->conn = conn_find(sconn,req->tid);
519 req->chain_fsp = NULL;
520 req->chain_outbuf = NULL;
523 smb_init_perfcount_data(&req->pcd);
525 /* Ensure we have at least wct words and 2 bytes of bcc. */
526 if (smb_size + req->wct*2 > req_size) {
527 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
528 (unsigned int)req->wct,
529 (unsigned int)req_size));
532 /* Ensure bcc is correct. */
533 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
534 DEBUG(0,("init_smb_request: invalid bcc number %u "
535 "(wct = %u, size %u)\n",
536 (unsigned int)req->buflen,
537 (unsigned int)req->wct,
538 (unsigned int)req_size));
546 static void process_smb(struct smbd_server_connection *conn,
547 uint8_t *inbuf, size_t nread, size_t unread_bytes,
548 uint32_t seqnum, bool encrypted,
549 struct smb_perfcount_data *deferred_pcd);
551 static void smbd_deferred_open_timer(struct event_context *ev,
552 struct timed_event *te,
553 struct timeval _tval,
556 struct pending_message_list *msg = talloc_get_type(private_data,
557 struct pending_message_list);
558 TALLOC_CTX *mem_ctx = talloc_tos();
559 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
562 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
565 exit_server("smbd_deferred_open_timer: talloc failed\n");
569 /* We leave this message on the queue so the open code can
570 know this is a retry. */
571 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
572 (unsigned long long)mid ));
574 /* Mark the message as processed so this is not
575 * re-processed in error. */
576 msg->processed = true;
578 process_smb(smbd_server_conn, inbuf,
580 msg->seqnum, msg->encrypted, &msg->pcd);
582 /* If it's still there and was processed, remove it. */
583 msg = get_deferred_open_message_smb(mid);
584 if (msg && msg->processed) {
585 remove_deferred_open_message_smb(smbd_server_conn, mid);
589 /****************************************************************************
590 Function to push a message onto the tail of a linked list of smb messages ready
592 ****************************************************************************/
594 static bool push_queued_message(struct smb_request *req,
595 struct timeval request_time,
596 struct timeval end_time,
597 char *private_data, size_t private_len)
599 int msg_len = smb_len(req->inbuf) + 4;
600 struct pending_message_list *msg;
602 msg = talloc_zero(NULL, struct pending_message_list);
605 DEBUG(0,("push_message: malloc fail (1)\n"));
609 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
610 if(msg->buf.data == NULL) {
611 DEBUG(0,("push_message: malloc fail (2)\n"));
616 msg->request_time = request_time;
617 msg->seqnum = req->seqnum;
618 msg->encrypted = req->encrypted;
619 msg->processed = false;
620 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
623 msg->private_data = data_blob_talloc(msg, private_data,
625 if (msg->private_data.data == NULL) {
626 DEBUG(0,("push_message: malloc fail (3)\n"));
632 msg->te = event_add_timed(server_event_context(),
635 smbd_deferred_open_timer,
638 DEBUG(0,("push_message: event_add_timed failed\n"));
643 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
645 DEBUG(10,("push_message: pushed message length %u on "
646 "deferred_open_queue\n", (unsigned int)msg_len));
651 /****************************************************************************
652 Function to delete a sharing violation open message by mid.
653 ****************************************************************************/
655 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
658 struct pending_message_list *pml;
660 if (sconn->using_smb2) {
661 remove_deferred_open_message_smb2(sconn, mid);
665 for (pml = deferred_open_queue; pml; pml = pml->next) {
666 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
667 DEBUG(10,("remove_deferred_open_message_smb: "
668 "deleting mid %llu len %u\n",
669 (unsigned long long)mid,
670 (unsigned int)pml->buf.length ));
671 DLIST_REMOVE(deferred_open_queue, pml);
678 /****************************************************************************
679 Move a sharing violation open retry message to the front of the list and
680 schedule it for immediate processing.
681 ****************************************************************************/
683 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
686 struct pending_message_list *pml;
689 if (sconn->using_smb2) {
690 schedule_deferred_open_message_smb2(sconn, mid);
694 for (pml = deferred_open_queue; pml; pml = pml->next) {
695 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
697 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
700 (unsigned long long)msg_mid ));
702 if (mid == msg_mid) {
703 struct timed_event *te;
705 if (pml->processed) {
706 /* A processed message should not be
708 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
709 "message mid %llu was already processed\n",
710 (unsigned long long)msg_mid ));
714 DEBUG(10,("schedule_deferred_open_message_smb: "
715 "scheduling mid %llu\n",
716 (unsigned long long)mid ));
718 te = event_add_timed(server_event_context(),
721 smbd_deferred_open_timer,
724 DEBUG(10,("schedule_deferred_open_message_smb: "
725 "event_add_timed() failed, "
726 "skipping mid %llu\n",
727 (unsigned long long)msg_mid ));
730 TALLOC_FREE(pml->te);
732 DLIST_PROMOTE(deferred_open_queue, pml);
737 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
738 "find message mid %llu\n",
739 (unsigned long long)mid ));
742 /****************************************************************************
743 Return true if this mid is on the deferred queue and was not yet processed.
744 ****************************************************************************/
746 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
748 struct pending_message_list *pml;
750 if (sconn->using_smb2) {
751 return open_was_deferred_smb2(sconn, mid);
754 for (pml = deferred_open_queue; pml; pml = pml->next) {
755 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
762 /****************************************************************************
763 Return the message queued by this mid.
764 ****************************************************************************/
766 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
768 struct pending_message_list *pml;
770 for (pml = deferred_open_queue; pml; pml = pml->next) {
771 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
778 /****************************************************************************
779 Get the state data queued by this mid.
780 ****************************************************************************/
782 bool get_deferred_open_message_state(struct smb_request *smbreq,
783 struct timeval *p_request_time,
786 struct pending_message_list *pml;
788 if (smbd_server_conn->using_smb2) {
789 return get_deferred_open_message_state_smb2(smbreq->smb2req,
794 pml = get_deferred_open_message_smb(smbreq->mid);
798 if (p_request_time) {
799 *p_request_time = pml->request_time;
802 *pp_state = (void *)pml->private_data.data;
807 /****************************************************************************
808 Function to push a deferred open smb message onto a linked list of local smb
809 messages ready for processing.
810 ****************************************************************************/
812 bool push_deferred_open_message_smb(struct smb_request *req,
813 struct timeval request_time,
814 struct timeval timeout,
816 char *private_data, size_t priv_len)
818 struct timeval end_time;
821 return push_deferred_open_message_smb2(req->smb2req,
829 if (req->unread_bytes) {
830 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
831 "unread_bytes = %u\n",
832 (unsigned int)req->unread_bytes ));
833 smb_panic("push_deferred_open_message_smb: "
834 "logic error unread_bytes != 0" );
837 end_time = timeval_sum(&request_time, &timeout);
839 DEBUG(10,("push_deferred_open_message_smb: pushing message "
840 "len %u mid %llu timeout time [%u.%06u]\n",
841 (unsigned int) smb_len(req->inbuf)+4,
842 (unsigned long long)req->mid,
843 (unsigned int)end_time.tv_sec,
844 (unsigned int)end_time.tv_usec));
846 return push_queued_message(req, request_time, end_time,
847 private_data, priv_len);
850 static void smbd_sig_term_handler(struct tevent_context *ev,
851 struct tevent_signal *se,
857 exit_server_cleanly("termination signal");
860 void smbd_setup_sig_term_handler(void)
862 struct tevent_signal *se;
864 se = tevent_add_signal(server_event_context(),
865 server_event_context(),
867 smbd_sig_term_handler,
870 exit_server("failed to setup SIGTERM handler");
874 static void smbd_sig_hup_handler(struct tevent_context *ev,
875 struct tevent_signal *se,
881 struct messaging_context *msg_ctx = talloc_get_type_abort(
882 private_data, struct messaging_context);
883 change_to_root_user();
884 DEBUG(1,("Reloading services after SIGHUP\n"));
885 reload_services(msg_ctx, smbd_server_conn->sock, False);
887 printing_subsystem_update(ev, msg_ctx);
891 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
892 struct messaging_context *msg_ctx)
894 struct tevent_signal *se;
896 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
899 exit_server("failed to setup SIGHUP handler");
903 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
910 timeout = SMBD_SELECT_TIMEOUT * 1000;
913 * Are there any timed events waiting ? If so, ensure we don't
914 * select for longer than it would take to wait for them.
917 event_add_to_poll_args(server_event_context(), conn,
918 &conn->pfds, &num_pfds, &timeout);
920 /* Process a signal and timed events now... */
921 if (run_events_poll(server_event_context(), 0, NULL, 0)) {
922 return NT_STATUS_RETRY;
927 START_PROFILE(smbd_idle);
929 ret = sys_poll(conn->pfds, num_pfds, timeout);
932 END_PROFILE(smbd_idle);
937 if (errno == EINTR) {
938 return NT_STATUS_RETRY;
940 return map_nt_error_from_unix(errno);
943 retry = run_events_poll(server_event_context(), ret, conn->pfds,
946 return NT_STATUS_RETRY;
949 /* Did we timeout ? */
951 return NT_STATUS_RETRY;
954 /* should not be reached */
955 return NT_STATUS_INTERNAL_ERROR;
959 * Only allow 5 outstanding trans requests. We're allocating memory, so
963 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
966 for (; list != NULL; list = list->next) {
968 if (list->mid == mid) {
969 return NT_STATUS_INVALID_PARAMETER;
975 return NT_STATUS_INSUFFICIENT_RESOURCES;
982 These flags determine some of the permissions required to do an operation
984 Note that I don't set NEED_WRITE on some write operations because they
985 are used by some brain-dead clients when printing, and I don't want to
986 force write permissions on print services.
988 #define AS_USER (1<<0)
989 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
990 #define TIME_INIT (1<<2)
991 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
992 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
993 #define DO_CHDIR (1<<6)
996 define a list of possible SMB messages and their corresponding
997 functions. Any message that has a NULL function is unimplemented -
998 please feel free to contribute implementations!
1000 static const struct smb_message_struct {
1002 void (*fn)(struct smb_request *req);
1004 } smb_messages[256] = {
1006 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1007 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1008 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1009 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1010 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1011 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1012 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1013 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1014 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1015 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1016 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1017 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1018 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1019 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1020 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1021 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1022 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1023 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1024 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1025 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1026 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1027 /* 0x15 */ { NULL, NULL, 0 },
1028 /* 0x16 */ { NULL, NULL, 0 },
1029 /* 0x17 */ { NULL, NULL, 0 },
1030 /* 0x18 */ { NULL, NULL, 0 },
1031 /* 0x19 */ { NULL, NULL, 0 },
1032 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1033 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1034 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1035 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1036 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1037 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1038 /* 0x20 */ { "SMBwritec", NULL,0},
1039 /* 0x21 */ { NULL, NULL, 0 },
1040 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1041 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1042 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1043 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1044 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1045 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1046 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1047 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1048 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1049 /* 0x2b */ { "SMBecho",reply_echo,0},
1050 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1051 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1052 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1053 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1054 /* 0x30 */ { NULL, NULL, 0 },
1055 /* 0x31 */ { NULL, NULL, 0 },
1056 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1057 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1058 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1059 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1060 /* 0x36 */ { NULL, NULL, 0 },
1061 /* 0x37 */ { NULL, NULL, 0 },
1062 /* 0x38 */ { NULL, NULL, 0 },
1063 /* 0x39 */ { NULL, NULL, 0 },
1064 /* 0x3a */ { NULL, NULL, 0 },
1065 /* 0x3b */ { NULL, NULL, 0 },
1066 /* 0x3c */ { NULL, NULL, 0 },
1067 /* 0x3d */ { NULL, NULL, 0 },
1068 /* 0x3e */ { NULL, NULL, 0 },
1069 /* 0x3f */ { NULL, NULL, 0 },
1070 /* 0x40 */ { NULL, NULL, 0 },
1071 /* 0x41 */ { NULL, NULL, 0 },
1072 /* 0x42 */ { NULL, NULL, 0 },
1073 /* 0x43 */ { NULL, NULL, 0 },
1074 /* 0x44 */ { NULL, NULL, 0 },
1075 /* 0x45 */ { NULL, NULL, 0 },
1076 /* 0x46 */ { NULL, NULL, 0 },
1077 /* 0x47 */ { NULL, NULL, 0 },
1078 /* 0x48 */ { NULL, NULL, 0 },
1079 /* 0x49 */ { NULL, NULL, 0 },
1080 /* 0x4a */ { NULL, NULL, 0 },
1081 /* 0x4b */ { NULL, NULL, 0 },
1082 /* 0x4c */ { NULL, NULL, 0 },
1083 /* 0x4d */ { NULL, NULL, 0 },
1084 /* 0x4e */ { NULL, NULL, 0 },
1085 /* 0x4f */ { NULL, NULL, 0 },
1086 /* 0x50 */ { NULL, NULL, 0 },
1087 /* 0x51 */ { NULL, NULL, 0 },
1088 /* 0x52 */ { NULL, NULL, 0 },
1089 /* 0x53 */ { NULL, NULL, 0 },
1090 /* 0x54 */ { NULL, NULL, 0 },
1091 /* 0x55 */ { NULL, NULL, 0 },
1092 /* 0x56 */ { NULL, NULL, 0 },
1093 /* 0x57 */ { NULL, NULL, 0 },
1094 /* 0x58 */ { NULL, NULL, 0 },
1095 /* 0x59 */ { NULL, NULL, 0 },
1096 /* 0x5a */ { NULL, NULL, 0 },
1097 /* 0x5b */ { NULL, NULL, 0 },
1098 /* 0x5c */ { NULL, NULL, 0 },
1099 /* 0x5d */ { NULL, NULL, 0 },
1100 /* 0x5e */ { NULL, NULL, 0 },
1101 /* 0x5f */ { NULL, NULL, 0 },
1102 /* 0x60 */ { NULL, NULL, 0 },
1103 /* 0x61 */ { NULL, NULL, 0 },
1104 /* 0x62 */ { NULL, NULL, 0 },
1105 /* 0x63 */ { NULL, NULL, 0 },
1106 /* 0x64 */ { NULL, NULL, 0 },
1107 /* 0x65 */ { NULL, NULL, 0 },
1108 /* 0x66 */ { NULL, NULL, 0 },
1109 /* 0x67 */ { NULL, NULL, 0 },
1110 /* 0x68 */ { NULL, NULL, 0 },
1111 /* 0x69 */ { NULL, NULL, 0 },
1112 /* 0x6a */ { NULL, NULL, 0 },
1113 /* 0x6b */ { NULL, NULL, 0 },
1114 /* 0x6c */ { NULL, NULL, 0 },
1115 /* 0x6d */ { NULL, NULL, 0 },
1116 /* 0x6e */ { NULL, NULL, 0 },
1117 /* 0x6f */ { NULL, NULL, 0 },
1118 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1119 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1120 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1121 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1122 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1123 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1124 /* 0x76 */ { NULL, NULL, 0 },
1125 /* 0x77 */ { NULL, NULL, 0 },
1126 /* 0x78 */ { NULL, NULL, 0 },
1127 /* 0x79 */ { NULL, NULL, 0 },
1128 /* 0x7a */ { NULL, NULL, 0 },
1129 /* 0x7b */ { NULL, NULL, 0 },
1130 /* 0x7c */ { NULL, NULL, 0 },
1131 /* 0x7d */ { NULL, NULL, 0 },
1132 /* 0x7e */ { NULL, NULL, 0 },
1133 /* 0x7f */ { NULL, NULL, 0 },
1134 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1135 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1136 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1137 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1138 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1139 /* 0x85 */ { NULL, NULL, 0 },
1140 /* 0x86 */ { NULL, NULL, 0 },
1141 /* 0x87 */ { NULL, NULL, 0 },
1142 /* 0x88 */ { NULL, NULL, 0 },
1143 /* 0x89 */ { NULL, NULL, 0 },
1144 /* 0x8a */ { NULL, NULL, 0 },
1145 /* 0x8b */ { NULL, NULL, 0 },
1146 /* 0x8c */ { NULL, NULL, 0 },
1147 /* 0x8d */ { NULL, NULL, 0 },
1148 /* 0x8e */ { NULL, NULL, 0 },
1149 /* 0x8f */ { NULL, NULL, 0 },
1150 /* 0x90 */ { NULL, NULL, 0 },
1151 /* 0x91 */ { NULL, NULL, 0 },
1152 /* 0x92 */ { NULL, NULL, 0 },
1153 /* 0x93 */ { NULL, NULL, 0 },
1154 /* 0x94 */ { NULL, NULL, 0 },
1155 /* 0x95 */ { NULL, NULL, 0 },
1156 /* 0x96 */ { NULL, NULL, 0 },
1157 /* 0x97 */ { NULL, NULL, 0 },
1158 /* 0x98 */ { NULL, NULL, 0 },
1159 /* 0x99 */ { NULL, NULL, 0 },
1160 /* 0x9a */ { NULL, NULL, 0 },
1161 /* 0x9b */ { NULL, NULL, 0 },
1162 /* 0x9c */ { NULL, NULL, 0 },
1163 /* 0x9d */ { NULL, NULL, 0 },
1164 /* 0x9e */ { NULL, NULL, 0 },
1165 /* 0x9f */ { NULL, NULL, 0 },
1166 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1167 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1168 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1169 /* 0xa3 */ { NULL, NULL, 0 },
1170 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1171 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1172 /* 0xa6 */ { NULL, NULL, 0 },
1173 /* 0xa7 */ { NULL, NULL, 0 },
1174 /* 0xa8 */ { NULL, NULL, 0 },
1175 /* 0xa9 */ { NULL, NULL, 0 },
1176 /* 0xaa */ { NULL, NULL, 0 },
1177 /* 0xab */ { NULL, NULL, 0 },
1178 /* 0xac */ { NULL, NULL, 0 },
1179 /* 0xad */ { NULL, NULL, 0 },
1180 /* 0xae */ { NULL, NULL, 0 },
1181 /* 0xaf */ { NULL, NULL, 0 },
1182 /* 0xb0 */ { NULL, NULL, 0 },
1183 /* 0xb1 */ { NULL, NULL, 0 },
1184 /* 0xb2 */ { NULL, NULL, 0 },
1185 /* 0xb3 */ { NULL, NULL, 0 },
1186 /* 0xb4 */ { NULL, NULL, 0 },
1187 /* 0xb5 */ { NULL, NULL, 0 },
1188 /* 0xb6 */ { NULL, NULL, 0 },
1189 /* 0xb7 */ { NULL, NULL, 0 },
1190 /* 0xb8 */ { NULL, NULL, 0 },
1191 /* 0xb9 */ { NULL, NULL, 0 },
1192 /* 0xba */ { NULL, NULL, 0 },
1193 /* 0xbb */ { NULL, NULL, 0 },
1194 /* 0xbc */ { NULL, NULL, 0 },
1195 /* 0xbd */ { NULL, NULL, 0 },
1196 /* 0xbe */ { NULL, NULL, 0 },
1197 /* 0xbf */ { NULL, NULL, 0 },
1198 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1199 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1200 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1201 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1202 /* 0xc4 */ { NULL, NULL, 0 },
1203 /* 0xc5 */ { NULL, NULL, 0 },
1204 /* 0xc6 */ { NULL, NULL, 0 },
1205 /* 0xc7 */ { NULL, NULL, 0 },
1206 /* 0xc8 */ { NULL, NULL, 0 },
1207 /* 0xc9 */ { NULL, NULL, 0 },
1208 /* 0xca */ { NULL, NULL, 0 },
1209 /* 0xcb */ { NULL, NULL, 0 },
1210 /* 0xcc */ { NULL, NULL, 0 },
1211 /* 0xcd */ { NULL, NULL, 0 },
1212 /* 0xce */ { NULL, NULL, 0 },
1213 /* 0xcf */ { NULL, NULL, 0 },
1214 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1215 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1216 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1217 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1218 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1219 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1220 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1221 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1222 /* 0xd8 */ { NULL, NULL, 0 },
1223 /* 0xd9 */ { NULL, NULL, 0 },
1224 /* 0xda */ { NULL, NULL, 0 },
1225 /* 0xdb */ { NULL, NULL, 0 },
1226 /* 0xdc */ { NULL, NULL, 0 },
1227 /* 0xdd */ { NULL, NULL, 0 },
1228 /* 0xde */ { NULL, NULL, 0 },
1229 /* 0xdf */ { NULL, NULL, 0 },
1230 /* 0xe0 */ { NULL, NULL, 0 },
1231 /* 0xe1 */ { NULL, NULL, 0 },
1232 /* 0xe2 */ { NULL, NULL, 0 },
1233 /* 0xe3 */ { NULL, NULL, 0 },
1234 /* 0xe4 */ { NULL, NULL, 0 },
1235 /* 0xe5 */ { NULL, NULL, 0 },
1236 /* 0xe6 */ { NULL, NULL, 0 },
1237 /* 0xe7 */ { NULL, NULL, 0 },
1238 /* 0xe8 */ { NULL, NULL, 0 },
1239 /* 0xe9 */ { NULL, NULL, 0 },
1240 /* 0xea */ { NULL, NULL, 0 },
1241 /* 0xeb */ { NULL, NULL, 0 },
1242 /* 0xec */ { NULL, NULL, 0 },
1243 /* 0xed */ { NULL, NULL, 0 },
1244 /* 0xee */ { NULL, NULL, 0 },
1245 /* 0xef */ { NULL, NULL, 0 },
1246 /* 0xf0 */ { NULL, NULL, 0 },
1247 /* 0xf1 */ { NULL, NULL, 0 },
1248 /* 0xf2 */ { NULL, NULL, 0 },
1249 /* 0xf3 */ { NULL, NULL, 0 },
1250 /* 0xf4 */ { NULL, NULL, 0 },
1251 /* 0xf5 */ { NULL, NULL, 0 },
1252 /* 0xf6 */ { NULL, NULL, 0 },
1253 /* 0xf7 */ { NULL, NULL, 0 },
1254 /* 0xf8 */ { NULL, NULL, 0 },
1255 /* 0xf9 */ { NULL, NULL, 0 },
1256 /* 0xfa */ { NULL, NULL, 0 },
1257 /* 0xfb */ { NULL, NULL, 0 },
1258 /* 0xfc */ { NULL, NULL, 0 },
1259 /* 0xfd */ { NULL, NULL, 0 },
1260 /* 0xfe */ { NULL, NULL, 0 },
1261 /* 0xff */ { NULL, NULL, 0 }
1265 /*******************************************************************
1266 allocate and initialize a reply packet
1267 ********************************************************************/
1269 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1270 const char *inbuf, char **outbuf, uint8_t num_words,
1274 * Protect against integer wrap
1276 if ((num_bytes > 0xffffff)
1277 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1279 if (asprintf(&msg, "num_bytes too large: %u",
1280 (unsigned)num_bytes) == -1) {
1281 msg = discard_const_p(char, "num_bytes too large");
1286 *outbuf = talloc_array(mem_ctx, char,
1287 smb_size + num_words*2 + num_bytes);
1288 if (*outbuf == NULL) {
1292 construct_reply_common(req, inbuf, *outbuf);
1293 srv_set_message(*outbuf, num_words, num_bytes, false);
1295 * Zero out the word area, the caller has to take care of the bcc area
1298 if (num_words != 0) {
1299 memset(*outbuf + smb_vwv0, 0, num_words*2);
1305 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1308 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1310 smb_panic("could not allocate output buffer\n");
1312 req->outbuf = (uint8_t *)outbuf;
1316 /*******************************************************************
1317 Dump a packet to a file.
1318 ********************************************************************/
1320 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1324 if (DEBUGLEVEL < 50) {
1328 if (len < 4) len = smb_len(data)+4;
1329 for (i=1;i<100;i++) {
1330 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1331 type ? "req" : "resp") == -1) {
1334 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1335 if (fd != -1 || errno != EEXIST) break;
1338 ssize_t ret = write(fd, data, len);
1340 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1342 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1347 /****************************************************************************
1348 Prepare everything for calling the actual request function, and potentially
1349 call the request function via the "new" interface.
1351 Return False if the "legacy" function needs to be called, everything is
1354 Return True if we're done.
1356 I know this API sucks, but it is the one with the least code change I could
1358 ****************************************************************************/
1360 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1364 connection_struct *conn = NULL;
1365 struct smbd_server_connection *sconn = req->sconn;
1370 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1371 * so subtract 4 from it. */
1372 if (!valid_smb_header(req->inbuf)
1373 || (size < (smb_size - 4))) {
1374 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1375 smb_len(req->inbuf)));
1376 exit_server_cleanly("Non-SMB packet");
1379 if (smb_messages[type].fn == NULL) {
1380 DEBUG(0,("Unknown message type %d!\n",type));
1381 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1382 reply_unknown_new(req, type);
1386 flags = smb_messages[type].flags;
1388 /* In share mode security we must ignore the vuid. */
1389 session_tag = (lp_security() == SEC_SHARE)
1390 ? UID_FIELD_INVALID : req->vuid;
1393 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1394 (int)sys_getpid(), (unsigned long)conn));
1396 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1398 /* Ensure this value is replaced in the incoming packet. */
1399 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1402 * Ensure the correct username is in current_user_info. This is a
1403 * really ugly bugfix for problems with multiple session_setup_and_X's
1404 * being done and allowing %U and %G substitutions to work correctly.
1405 * There is a reason this code is done here, don't move it unless you
1406 * know what you're doing... :-).
1410 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1411 user_struct *vuser = NULL;
1413 sconn->smb1.sessions.last_session_tag = session_tag;
1414 if(session_tag != UID_FIELD_INVALID) {
1415 vuser = get_valid_user_struct(sconn, session_tag);
1417 set_current_user_info(
1418 vuser->session_info->unix_info->sanitized_username,
1419 vuser->session_info->unix_info->unix_name,
1420 vuser->session_info->info->domain_name);
1425 /* Does this call need to be run as the connected user? */
1426 if (flags & AS_USER) {
1428 /* Does this call need a valid tree connection? */
1431 * Amazingly, the error code depends on the command
1434 if (type == SMBntcreateX) {
1435 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1437 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1442 if (!change_to_user(conn,session_tag)) {
1443 DEBUG(0, ("Error: Could not change to user. Removing "
1444 "deferred open, mid=%llu.\n",
1445 (unsigned long long)req->mid));
1446 reply_force_doserror(req, ERRSRV, ERRbaduid);
1450 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1452 /* Does it need write permission? */
1453 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1454 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1458 /* IPC services are limited */
1459 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1460 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1464 /* This call needs to be run as root */
1465 change_to_root_user();
1468 /* load service specific parameters */
1470 if (req->encrypted) {
1471 conn->encrypted_tid = true;
1472 /* encrypted required from now on. */
1473 conn->encrypt_level = Required;
1474 } else if (ENCRYPTION_REQUIRED(conn)) {
1475 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1476 exit_server_cleanly("encryption required "
1482 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1483 (flags & (AS_USER|DO_CHDIR)
1485 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1488 conn->num_smb_operations++;
1491 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1493 if (raddr == NULL) {
1494 reply_nterror(req, NT_STATUS_NO_MEMORY);
1498 /* does this protocol need to be run as guest? */
1499 if ((flags & AS_GUEST)
1500 && (!change_to_guest() ||
1501 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1502 sconn->remote_hostname,
1504 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1508 smb_messages[type].fn(req);
1512 /****************************************************************************
1513 Construct a reply to the incoming packet.
1514 ****************************************************************************/
1516 static void construct_reply(struct smbd_server_connection *sconn,
1517 char *inbuf, int size, size_t unread_bytes,
1518 uint32_t seqnum, bool encrypted,
1519 struct smb_perfcount_data *deferred_pcd)
1521 connection_struct *conn;
1522 struct smb_request *req;
1524 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1525 smb_panic("could not allocate smb_request");
1528 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1529 encrypted, seqnum)) {
1530 exit_server_cleanly("Invalid SMB request");
1533 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1535 /* we popped this message off the queue - keep original perf data */
1537 req->pcd = *deferred_pcd;
1539 SMB_PERFCOUNT_START(&req->pcd);
1540 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1541 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1544 conn = switch_message(req->cmd, req, size);
1546 if (req->unread_bytes) {
1547 /* writeX failed. drain socket. */
1548 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1549 req->unread_bytes) {
1550 smb_panic("failed to drain pending bytes");
1552 req->unread_bytes = 0;
1560 if (req->outbuf == NULL) {
1564 if (CVAL(req->outbuf,0) == 0) {
1565 show_msg((char *)req->outbuf);
1568 if (!srv_send_smb(req->sconn,
1569 (char *)req->outbuf,
1570 true, req->seqnum+1,
1571 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1573 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1581 /****************************************************************************
1582 Process an smb from the client
1583 ****************************************************************************/
1584 static void process_smb(struct smbd_server_connection *sconn,
1585 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1586 uint32_t seqnum, bool encrypted,
1587 struct smb_perfcount_data *deferred_pcd)
1589 int msg_type = CVAL(inbuf,0);
1591 DO_PROFILE_INC(smb_count);
1593 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1595 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1596 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1598 if (msg_type != NBSSmessage) {
1600 * NetBIOS session request, keepalive, etc.
1602 reply_special(sconn, (char *)inbuf, nread);
1606 if (sconn->using_smb2) {
1607 /* At this point we're not really using smb2,
1608 * we make the decision here.. */
1609 if (smbd_is_smb2_header(inbuf, nread)) {
1610 smbd_smb2_first_negprot(sconn, inbuf, nread);
1612 } else if (nread >= smb_size && valid_smb_header(inbuf)
1613 && CVAL(inbuf, smb_com) != 0x72) {
1614 /* This is a non-negprot SMB1 packet.
1615 Disable SMB2 from now on. */
1616 sconn->using_smb2 = false;
1620 show_msg((char *)inbuf);
1622 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1623 encrypted, deferred_pcd);
1627 sconn->num_requests++;
1629 /* The timeout_processing function isn't run nearly
1630 often enough to implement 'max log size' without
1631 overrunning the size of the file by many megabytes.
1632 This is especially true if we are running at debug
1633 level 10. Checking every 50 SMBs is a nice
1634 tradeoff of performance vs log file size overrun. */
1636 if ((sconn->num_requests % 50) == 0 &&
1637 need_to_check_log_size()) {
1638 change_to_root_user();
1643 /****************************************************************************
1644 Return a string containing the function name of a SMB command.
1645 ****************************************************************************/
1647 const char *smb_fn_name(int type)
1649 const char *unknown_name = "SMBunknown";
1651 if (smb_messages[type].name == NULL)
1652 return(unknown_name);
1654 return(smb_messages[type].name);
1657 /****************************************************************************
1658 Helper functions for contruct_reply.
1659 ****************************************************************************/
1661 void add_to_common_flags2(uint32 v)
1666 void remove_from_common_flags2(uint32 v)
1668 common_flags2 &= ~v;
1671 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1674 srv_set_message(outbuf,0,0,false);
1676 SCVAL(outbuf, smb_com, req->cmd);
1677 SIVAL(outbuf,smb_rcls,0);
1678 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1679 SSVAL(outbuf,smb_flg2,
1680 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1682 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1684 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1685 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1686 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1687 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1690 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1692 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1696 * How many bytes have we already accumulated up to the current wct field
1700 size_t req_wct_ofs(struct smb_request *req)
1704 if (req->chain_outbuf == NULL) {
1707 buf_size = talloc_get_size(req->chain_outbuf);
1708 if ((buf_size % 4) != 0) {
1709 buf_size += (4 - (buf_size % 4));
1711 return buf_size - 4;
1715 * Hack around reply_nterror & friends not being aware of chained requests,
1716 * generating illegal (i.e. wct==0) chain replies.
1719 static void fixup_chain_error_packet(struct smb_request *req)
1721 uint8_t *outbuf = req->outbuf;
1723 reply_outbuf(req, 2, 0);
1724 memcpy(req->outbuf, outbuf, smb_wct);
1725 TALLOC_FREE(outbuf);
1726 SCVAL(req->outbuf, smb_vwv0, 0xff);
1730 * @brief Find the smb_cmd offset of the last command pushed
1731 * @param[in] buf The buffer we're building up
1732 * @retval Where can we put our next andx cmd?
1734 * While chaining requests, the "next" request we're looking at needs to put
1735 * its SMB_Command before the data the previous request already built up added
1736 * to the chain. Find the offset to the place where we have to put our cmd.
1739 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1744 cmd = CVAL(buf, smb_com);
1746 SMB_ASSERT(is_andx_req(cmd));
1750 while (CVAL(buf, ofs) != 0xff) {
1752 if (!is_andx_req(CVAL(buf, ofs))) {
1757 * ofs is from start of smb header, so add the 4 length
1758 * bytes. The next cmd is right after the wct field.
1760 ofs = SVAL(buf, ofs+2) + 4 + 1;
1762 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1770 * @brief Do the smb chaining at a buffer level
1771 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1772 * @param[in] smb_command The command that we want to issue
1773 * @param[in] wct How many words?
1774 * @param[in] vwv The words, already in network order
1775 * @param[in] bytes_alignment How shall we align "bytes"?
1776 * @param[in] num_bytes How many bytes?
1777 * @param[in] bytes The data the request ships
1779 * smb_splice_chain() adds the vwv and bytes to the request already present in
1783 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1784 uint8_t wct, const uint16_t *vwv,
1785 size_t bytes_alignment,
1786 uint32_t num_bytes, const uint8_t *bytes)
1789 size_t old_size, new_size;
1791 size_t chain_padding = 0;
1792 size_t bytes_padding = 0;
1795 old_size = talloc_get_size(*poutbuf);
1798 * old_size == smb_wct means we're pushing the first request in for
1802 first_request = (old_size == smb_wct);
1804 if (!first_request && ((old_size % 4) != 0)) {
1806 * Align the wct field of subsequent requests to a 4-byte
1809 chain_padding = 4 - (old_size % 4);
1813 * After the old request comes the new wct field (1 byte), the vwv's
1814 * and the num_bytes field. After at we might need to align the bytes
1815 * given to us to "bytes_alignment", increasing the num_bytes value.
1818 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1820 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1821 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1824 new_size += bytes_padding + num_bytes;
1826 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1827 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1828 (unsigned)new_size));
1832 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1833 if (outbuf == NULL) {
1834 DEBUG(0, ("talloc failed\n"));
1839 if (first_request) {
1840 SCVAL(outbuf, smb_com, smb_command);
1842 size_t andx_cmd_ofs;
1844 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1845 DEBUG(1, ("invalid command chain\n"));
1846 *poutbuf = talloc_realloc(
1847 NULL, *poutbuf, uint8_t, old_size);
1851 if (chain_padding != 0) {
1852 memset(outbuf + old_size, 0, chain_padding);
1853 old_size += chain_padding;
1856 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1857 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1863 * Push the chained request:
1868 SCVAL(outbuf, ofs, wct);
1875 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1876 ofs += sizeof(uint16_t) * wct;
1882 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1883 ofs += sizeof(uint16_t);
1889 if (bytes_padding != 0) {
1890 memset(outbuf + ofs, 0, bytes_padding);
1891 ofs += bytes_padding;
1898 memcpy(outbuf + ofs, bytes, num_bytes);
1903 /****************************************************************************
1904 Construct a chained reply and add it to the already made reply
1905 ****************************************************************************/
1907 void chain_reply(struct smb_request *req)
1909 size_t smblen = smb_len(req->inbuf);
1910 size_t already_used, length_needed;
1912 uint32_t chain_offset; /* uint32_t to avoid overflow */
1915 const uint16_t *vwv;
1919 if (IVAL(req->outbuf, smb_rcls) != 0) {
1920 fixup_chain_error_packet(req);
1924 * Any of the AndX requests and replies have at least a wct of
1925 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1926 * beginning of the SMB header to the next wct field.
1928 * None of the AndX requests put anything valuable in vwv[0] and [1],
1929 * so we can overwrite it here to form the chain.
1932 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1933 if (req->chain_outbuf == NULL) {
1934 req->chain_outbuf = talloc_realloc(
1935 req, req->outbuf, uint8_t,
1936 smb_len(req->outbuf) + 4);
1937 if (req->chain_outbuf == NULL) {
1938 smb_panic("talloc failed");
1946 * Here we assume that this is the end of the chain. For that we need
1947 * to set "next command" to 0xff and the offset to 0. If we later find
1948 * more commands in the chain, this will be overwritten again.
1951 SCVAL(req->outbuf, smb_vwv0, 0xff);
1952 SCVAL(req->outbuf, smb_vwv0+1, 0);
1953 SSVAL(req->outbuf, smb_vwv1, 0);
1955 if (req->chain_outbuf == NULL) {
1957 * In req->chain_outbuf we collect all the replies. Start the
1958 * chain by copying in the first reply.
1960 * We do the realloc because later on we depend on
1961 * talloc_get_size to determine the length of
1962 * chain_outbuf. The reply_xxx routines might have
1963 * over-allocated (reply_pipe_read_and_X used to be such an
1966 req->chain_outbuf = talloc_realloc(
1967 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1968 if (req->chain_outbuf == NULL) {
1969 smb_panic("talloc failed");
1974 * Update smb headers where subsequent chained commands
1975 * may have updated them.
1977 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1978 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1980 if (!smb_splice_chain(&req->chain_outbuf,
1981 CVAL(req->outbuf, smb_com),
1982 CVAL(req->outbuf, smb_wct),
1983 (uint16_t *)(req->outbuf + smb_vwv),
1984 0, smb_buflen(req->outbuf),
1985 (uint8_t *)smb_buf(req->outbuf))) {
1988 TALLOC_FREE(req->outbuf);
1992 * We use the old request's vwv field to grab the next chained command
1993 * and offset into the chained fields.
1996 chain_cmd = CVAL(req->vwv+0, 0);
1997 chain_offset = SVAL(req->vwv+1, 0);
1999 if (chain_cmd == 0xff) {
2001 * End of chain, no more requests from the client. So ship the
2004 smb_setlen((char *)(req->chain_outbuf),
2005 talloc_get_size(req->chain_outbuf) - 4);
2007 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2008 true, req->seqnum+1,
2009 IS_CONN_ENCRYPTED(req->conn)
2012 exit_server_cleanly("chain_reply: srv_send_smb "
2015 TALLOC_FREE(req->chain_outbuf);
2020 /* add a new perfcounter for this element of chain */
2021 SMB_PERFCOUNT_ADD(&req->pcd);
2022 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2023 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2026 * Check if the client tries to fool us. The request so far uses the
2027 * space to the end of the byte buffer in the request just
2028 * processed. The chain_offset can't point into that area. If that was
2029 * the case, we could end up with an endless processing of the chain,
2030 * we would always handle the same request.
2033 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2034 if (chain_offset < already_used) {
2039 * Next check: Make sure the chain offset does not point beyond the
2040 * overall smb request length.
2043 length_needed = chain_offset+1; /* wct */
2044 if (length_needed > smblen) {
2049 * Now comes the pointer magic. Goal here is to set up req->vwv and
2050 * req->buf correctly again to be able to call the subsequent
2051 * switch_message(). The chain offset (the former vwv[1]) points at
2052 * the new wct field.
2055 wct = CVAL(smb_base(req->inbuf), chain_offset);
2058 * Next consistency check: Make the new vwv array fits in the overall
2062 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2063 if (length_needed > smblen) {
2066 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2069 * Now grab the new byte buffer....
2072 buflen = SVAL(vwv+wct, 0);
2075 * .. and check that it fits.
2078 length_needed += buflen;
2079 if (length_needed > smblen) {
2082 buf = (const uint8_t *)(vwv+wct+1);
2084 req->cmd = chain_cmd;
2086 req->vwv = discard_const_p(uint16_t, vwv);
2087 req->buflen = buflen;
2090 switch_message(chain_cmd, req, smblen);
2092 if (req->outbuf == NULL) {
2094 * This happens if the chained command has suspended itself or
2095 * if it has called srv_send_smb() itself.
2101 * We end up here if the chained command was not itself chained or
2102 * suspended, but for example a close() command. We now need to splice
2103 * the chained commands' outbuf into the already built up chain_outbuf
2104 * and ship the result.
2110 * We end up here if there's any error in the chain syntax. Report a
2111 * DOS error, just like Windows does.
2113 reply_force_doserror(req, ERRSRV, ERRerror);
2114 fixup_chain_error_packet(req);
2118 * This scary statement intends to set the
2119 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2120 * to the value req->outbuf carries
2122 SSVAL(req->chain_outbuf, smb_flg2,
2123 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2124 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2127 * Transfer the error codes from the subrequest to the main one
2129 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2130 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2132 if (!smb_splice_chain(&req->chain_outbuf,
2133 CVAL(req->outbuf, smb_com),
2134 CVAL(req->outbuf, smb_wct),
2135 (uint16_t *)(req->outbuf + smb_vwv),
2136 0, smb_buflen(req->outbuf),
2137 (uint8_t *)smb_buf(req->outbuf))) {
2138 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2140 TALLOC_FREE(req->outbuf);
2142 smb_setlen((char *)(req->chain_outbuf),
2143 talloc_get_size(req->chain_outbuf) - 4);
2145 show_msg((char *)(req->chain_outbuf));
2147 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2148 true, req->seqnum+1,
2149 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2151 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2153 TALLOC_FREE(req->chain_outbuf);
2157 /****************************************************************************
2158 Check if services need reloading.
2159 ****************************************************************************/
2161 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2164 if (last_smb_conf_reload_time == 0) {
2165 last_smb_conf_reload_time = t;
2168 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2169 reload_services(sconn->msg_ctx, sconn->sock, True);
2170 last_smb_conf_reload_time = t;
2174 static bool fd_is_readable(int fd)
2178 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2180 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2184 static void smbd_server_connection_write_handler(
2185 struct smbd_server_connection *sconn)
2187 /* TODO: make write nonblocking */
2190 static void smbd_server_connection_read_handler(
2191 struct smbd_server_connection *sconn, int fd)
2193 uint8_t *inbuf = NULL;
2194 size_t inbuf_len = 0;
2195 size_t unread_bytes = 0;
2196 bool encrypted = false;
2197 TALLOC_CTX *mem_ctx = talloc_tos();
2201 bool from_client = (sconn->sock == fd);
2204 smbd_lock_socket(sconn);
2206 if (lp_async_smb_echo_handler()) {
2208 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2210 * This is the super-ugly hack to
2211 * prefer the packets forwarded by the
2212 * echo handler over the ones by the
2215 fd = sconn->smb1.echo_handler.trusted_fd;
2216 } else if (!fd_is_readable(fd)) {
2217 DEBUG(10,("the echo listener was faster\n"));
2218 smbd_unlock_socket(sconn);
2223 /* TODO: make this completely nonblocking */
2224 status = receive_smb_talloc(mem_ctx, sconn, fd,
2225 (char **)(void *)&inbuf,
2229 &inbuf_len, &seqnum,
2230 false /* trusted channel */);
2231 smbd_unlock_socket(sconn);
2233 /* TODO: make this completely nonblocking */
2234 status = receive_smb_talloc(mem_ctx, sconn, fd,
2235 (char **)(void *)&inbuf,
2239 &inbuf_len, &seqnum,
2240 true /* trusted channel */);
2243 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2246 if (NT_STATUS_IS_ERR(status)) {
2247 exit_server_cleanly("failed to receive smb request");
2249 if (!NT_STATUS_IS_OK(status)) {
2254 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2255 seqnum, encrypted, NULL);
2258 static void smbd_server_connection_handler(struct event_context *ev,
2259 struct fd_event *fde,
2263 struct smbd_server_connection *conn = talloc_get_type(private_data,
2264 struct smbd_server_connection);
2266 if (flags & EVENT_FD_WRITE) {
2267 smbd_server_connection_write_handler(conn);
2270 if (flags & EVENT_FD_READ) {
2271 smbd_server_connection_read_handler(conn, conn->sock);
2276 static void smbd_server_echo_handler(struct event_context *ev,
2277 struct fd_event *fde,
2281 struct smbd_server_connection *conn = talloc_get_type(private_data,
2282 struct smbd_server_connection);
2284 if (flags & EVENT_FD_WRITE) {
2285 smbd_server_connection_write_handler(conn);
2288 if (flags & EVENT_FD_READ) {
2289 smbd_server_connection_read_handler(
2290 conn, conn->smb1.echo_handler.trusted_fd);
2295 #ifdef CLUSTER_SUPPORT
2296 /****************************************************************************
2297 received when we should release a specific IP
2298 ****************************************************************************/
2299 static void release_ip(const char *ip, void *priv)
2301 const char *addr = (const char *)priv;
2302 const char *p = addr;
2304 if (strncmp("::ffff:", addr, 7) == 0) {
2308 DEBUG(10, ("Got release IP message for %s, "
2309 "our address is %s\n", ip, p));
2311 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2312 /* we can't afford to do a clean exit - that involves
2313 database writes, which would potentially mean we
2314 are still running after the failover has finished -
2315 we have to get rid of this process ID straight
2317 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2319 /* note we must exit with non-zero status so the unclean handler gets
2320 called in the parent, so that the brl database is tickled */
2325 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2326 struct sockaddr_storage *client)
2329 length = sizeof(*server);
2330 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2333 length = sizeof(*client);
2334 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2342 * Send keepalive packets to our client
2344 static bool keepalive_fn(const struct timeval *now, void *private_data)
2346 struct smbd_server_connection *sconn = smbd_server_conn;
2349 if (sconn->using_smb2) {
2350 /* Don't do keepalives on an SMB2 connection. */
2354 smbd_lock_socket(smbd_server_conn);
2355 ret = send_keepalive(sconn->sock);
2356 smbd_unlock_socket(smbd_server_conn);
2359 char addr[INET6_ADDRSTRLEN];
2361 * Try and give an error message saying what
2364 DEBUG(0, ("send_keepalive failed for client %s. "
2365 "Error %s - exiting\n",
2366 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2374 * Do the recurring check if we're idle
2376 static bool deadtime_fn(const struct timeval *now, void *private_data)
2378 struct smbd_server_connection *sconn =
2379 (struct smbd_server_connection *)private_data;
2381 if ((conn_num_open(sconn) == 0)
2382 || (conn_idle_all(sconn, now->tv_sec))) {
2383 DEBUG( 2, ( "Closing idle connection\n" ) );
2384 messaging_send(sconn->msg_ctx,
2385 messaging_server_id(sconn->msg_ctx),
2386 MSG_SHUTDOWN, &data_blob_null);
2394 * Do the recurring log file and smb.conf reload checks.
2397 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2399 struct smbd_server_connection *sconn = talloc_get_type_abort(
2400 private_data, struct smbd_server_connection);
2402 DEBUG(5, ("housekeeping\n"));
2404 change_to_root_user();
2406 /* update printer queue caches if necessary */
2407 update_monitored_printq_cache(sconn->msg_ctx);
2409 /* check if we need to reload services */
2410 check_reload(sconn, time_mono(NULL));
2412 /* Change machine password if neccessary. */
2413 attempt_machine_password_change();
2416 * Force a log file check.
2418 force_check_log_size();
2423 static int create_unlink_tmp(const char *dir)
2428 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2429 if (fname == NULL) {
2433 fd = mkstemp(fname);
2438 if (unlink(fname) == -1) {
2439 int sys_errno = errno;
2450 * Read an smb packet in the echo handler child, giving the parent
2451 * smbd one second to react once the socket becomes readable.
2454 struct smbd_echo_read_state {
2455 struct tevent_context *ev;
2456 struct smbd_server_connection *sconn;
2463 static void smbd_echo_read_readable(struct tevent_req *subreq);
2464 static void smbd_echo_read_waited(struct tevent_req *subreq);
2466 static struct tevent_req *smbd_echo_read_send(
2467 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2468 struct smbd_server_connection *sconn)
2470 struct tevent_req *req, *subreq;
2471 struct smbd_echo_read_state *state;
2473 req = tevent_req_create(mem_ctx, &state,
2474 struct smbd_echo_read_state);
2479 state->sconn = sconn;
2481 subreq = wait_for_read_send(state, ev, sconn->sock);
2482 if (tevent_req_nomem(subreq, req)) {
2483 return tevent_req_post(req, ev);
2485 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2489 static void smbd_echo_read_readable(struct tevent_req *subreq)
2491 struct tevent_req *req = tevent_req_callback_data(
2492 subreq, struct tevent_req);
2493 struct smbd_echo_read_state *state = tevent_req_data(
2494 req, struct smbd_echo_read_state);
2498 ok = wait_for_read_recv(subreq, &err);
2499 TALLOC_FREE(subreq);
2501 tevent_req_nterror(req, map_nt_error_from_unix(err));
2506 * Give the parent smbd one second to step in
2509 subreq = tevent_wakeup_send(
2510 state, state->ev, timeval_current_ofs(1, 0));
2511 if (tevent_req_nomem(subreq, req)) {
2514 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2517 static void smbd_echo_read_waited(struct tevent_req *subreq)
2519 struct tevent_req *req = tevent_req_callback_data(
2520 subreq, struct tevent_req);
2521 struct smbd_echo_read_state *state = tevent_req_data(
2522 req, struct smbd_echo_read_state);
2523 struct smbd_server_connection *sconn = state->sconn;
2529 ok = tevent_wakeup_recv(subreq);
2530 TALLOC_FREE(subreq);
2532 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2536 ok = smbd_lock_socket_internal(sconn);
2538 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2539 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2543 if (!fd_is_readable(sconn->sock)) {
2544 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2545 (int)sys_getpid()));
2547 ok = smbd_unlock_socket_internal(sconn);
2549 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2550 DEBUG(1, ("%s: failed to unlock socket\n",
2555 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2556 if (tevent_req_nomem(subreq, req)) {
2559 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2563 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2569 false /* trusted_channel*/);
2571 if (tevent_req_nterror(req, status)) {
2572 tevent_req_nterror(req, status);
2573 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2574 (int)sys_getpid(), nt_errstr(status)));
2578 ok = smbd_unlock_socket_internal(sconn);
2580 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2581 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2584 tevent_req_done(req);
2587 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2588 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2590 struct smbd_echo_read_state *state = tevent_req_data(
2591 req, struct smbd_echo_read_state);
2594 if (tevent_req_is_nterror(req, &status)) {
2597 *pbuf = talloc_move(mem_ctx, &state->buf);
2598 *pbuflen = state->buflen;
2599 *pseqnum = state->seqnum;
2600 return NT_STATUS_OK;
2603 struct smbd_echo_state {
2604 struct tevent_context *ev;
2605 struct iovec *pending;
2606 struct smbd_server_connection *sconn;
2609 struct tevent_fd *parent_fde;
2611 struct tevent_req *write_req;
2614 static void smbd_echo_writer_done(struct tevent_req *req);
2616 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2620 if (state->write_req != NULL) {
2624 num_pending = talloc_array_length(state->pending);
2625 if (num_pending == 0) {
2629 state->write_req = writev_send(state, state->ev, NULL,
2630 state->parent_pipe, false,
2631 state->pending, num_pending);
2632 if (state->write_req == NULL) {
2633 DEBUG(1, ("writev_send failed\n"));
2637 talloc_steal(state->write_req, state->pending);
2638 state->pending = NULL;
2640 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2644 static void smbd_echo_writer_done(struct tevent_req *req)
2646 struct smbd_echo_state *state = tevent_req_callback_data(
2647 req, struct smbd_echo_state);
2651 written = writev_recv(req, &err);
2653 state->write_req = NULL;
2654 if (written == -1) {
2655 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2658 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2659 smbd_echo_activate_writer(state);
2662 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2665 struct smb_request req;
2666 uint16_t num_replies;
2671 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2672 DEBUG(10, ("Got netbios keepalive\n"));
2679 if (inbuf_len < smb_size) {
2680 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2683 if (!valid_smb_header(inbuf)) {
2684 DEBUG(10, ("Got invalid SMB header\n"));
2688 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2694 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2695 smb_messages[req.cmd].name
2696 ? smb_messages[req.cmd].name : "unknown"));
2698 if (req.cmd != SMBecho) {
2705 num_replies = SVAL(req.vwv+0, 0);
2706 if (num_replies != 1) {
2707 /* Not a Windows "Hey, you're still there?" request */
2711 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2713 DEBUG(10, ("create_outbuf failed\n"));
2716 req.outbuf = (uint8_t *)outbuf;
2718 SSVAL(req.outbuf, smb_vwv0, num_replies);
2720 if (req.buflen > 0) {
2721 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2724 out_len = smb_len(req.outbuf) + 4;
2726 ok = srv_send_smb(req.sconn,
2730 TALLOC_FREE(outbuf);
2738 static void smbd_echo_exit(struct tevent_context *ev,
2739 struct tevent_fd *fde, uint16_t flags,
2742 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2746 static void smbd_echo_got_packet(struct tevent_req *req);
2748 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2751 struct smbd_echo_state *state;
2752 struct tevent_req *read_req;
2754 state = talloc_zero(sconn, struct smbd_echo_state);
2755 if (state == NULL) {
2756 DEBUG(1, ("talloc failed\n"));
2759 state->sconn = sconn;
2760 state->parent_pipe = parent_pipe;
2761 state->ev = s3_tevent_context_init(state);
2762 if (state->ev == NULL) {
2763 DEBUG(1, ("tevent_context_init failed\n"));
2767 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2768 TEVENT_FD_READ, smbd_echo_exit,
2770 if (state->parent_fde == NULL) {
2771 DEBUG(1, ("tevent_add_fd failed\n"));
2776 read_req = smbd_echo_read_send(state, state->ev, sconn);
2777 if (read_req == NULL) {
2778 DEBUG(1, ("smbd_echo_read_send failed\n"));
2782 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2785 if (tevent_loop_once(state->ev) == -1) {
2786 DEBUG(1, ("tevent_loop_once failed: %s\n",
2794 static void smbd_echo_got_packet(struct tevent_req *req)
2796 struct smbd_echo_state *state = tevent_req_callback_data(
2797 req, struct smbd_echo_state);
2801 uint32_t seqnum = 0;
2804 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2806 if (!NT_STATUS_IS_OK(status)) {
2807 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2808 nt_errstr(status)));
2812 reply = smbd_echo_reply((uint8_t *)buf, buflen, seqnum);
2818 num_pending = talloc_array_length(state->pending);
2819 tmp = talloc_realloc(state, state->pending, struct iovec,
2822 DEBUG(1, ("talloc_realloc failed\n"));
2825 state->pending = tmp;
2827 if (buflen >= smb_size) {
2829 * place the seqnum in the packet so that the main process
2830 * can reply with signing
2832 SIVAL(buf, smb_ss_field, seqnum);
2833 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2836 iov = &state->pending[num_pending];
2837 iov->iov_base = buf;
2838 iov->iov_len = buflen;
2840 DEBUG(10,("echo_handler[%d]: forward to main\n",
2841 (int)sys_getpid()));
2842 smbd_echo_activate_writer(state);
2845 req = smbd_echo_read_send(state, state->ev, state->sconn);
2847 DEBUG(1, ("smbd_echo_read_send failed\n"));
2850 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2855 * Handle SMBecho requests in a forked child process
2857 bool fork_echo_handler(struct smbd_server_connection *sconn)
2859 int listener_pipe[2];
2863 res = pipe(listener_pipe);
2865 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2868 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2869 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2870 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2878 close(listener_pipe[0]);
2879 set_blocking(listener_pipe[1], false);
2881 status = reinit_after_fork(sconn->msg_ctx,
2882 server_event_context(),
2883 procid_self(), false);
2884 if (!NT_STATUS_IS_OK(status)) {
2885 DEBUG(1, ("reinit_after_fork failed: %s\n",
2886 nt_errstr(status)));
2889 smbd_echo_loop(sconn, listener_pipe[1]);
2892 close(listener_pipe[1]);
2893 listener_pipe[1] = -1;
2894 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2896 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2899 * Without smb signing this is the same as the normal smbd
2900 * listener. This needs to change once signing comes in.
2902 sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
2904 sconn->smb1.echo_handler.trusted_fd,
2906 smbd_server_echo_handler,
2908 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2909 DEBUG(1, ("event_add_fd failed\n"));
2916 if (listener_pipe[0] != -1) {
2917 close(listener_pipe[0]);
2919 if (listener_pipe[1] != -1) {
2920 close(listener_pipe[1]);
2922 sconn->smb1.echo_handler.trusted_fd = -1;
2923 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2924 close(sconn->smb1.echo_handler.socket_lock_fd);
2926 sconn->smb1.echo_handler.trusted_fd = -1;
2927 sconn->smb1.echo_handler.socket_lock_fd = -1;
2933 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2934 struct sockaddr_storage *srv,
2935 struct sockaddr_storage *clnt)
2937 struct ctdbd_connection *cconn;
2938 char tmp_addr[INET6_ADDRSTRLEN];
2941 cconn = messaging_ctdbd_connection();
2942 if (cconn == NULL) {
2943 return NT_STATUS_NO_MEMORY;
2946 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2947 addr = talloc_strdup(cconn, tmp_addr);
2949 return NT_STATUS_NO_MEMORY;
2951 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2956 /****************************************************************************
2957 Process commands from the client
2958 ****************************************************************************/
2960 void smbd_process(struct smbd_server_connection *sconn)
2962 TALLOC_CTX *frame = talloc_stackframe();
2963 struct sockaddr_storage ss;
2964 struct sockaddr *sa = NULL;
2965 socklen_t sa_socklen;
2966 struct tsocket_address *local_address = NULL;
2967 struct tsocket_address *remote_address = NULL;
2968 const char *remaddr = NULL;
2972 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
2974 * We're not making the decision here,
2975 * we're just allowing the client
2976 * to decide between SMB1 and SMB2
2977 * with the first negprot
2980 sconn->using_smb2 = true;
2983 /* Ensure child is set to blocking mode */
2984 set_blocking(sconn->sock,True);
2986 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2987 set_socket_options(sconn->sock, lp_socket_options());
2989 sa = (struct sockaddr *)(void *)&ss;
2990 sa_socklen = sizeof(ss);
2991 ret = getpeername(sconn->sock, sa, &sa_socklen);
2993 int level = (errno == ENOTCONN)?2:0;
2994 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2995 exit_server_cleanly("getpeername() failed.\n");
2997 ret = tsocket_address_bsd_from_sockaddr(sconn,
3001 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3002 __location__, strerror(errno)));
3003 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3006 sa = (struct sockaddr *)(void *)&ss;
3007 sa_socklen = sizeof(ss);
3008 ret = getsockname(sconn->sock, sa, &sa_socklen);
3010 int level = (errno == ENOTCONN)?2:0;
3011 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3012 exit_server_cleanly("getsockname() failed.\n");
3014 ret = tsocket_address_bsd_from_sockaddr(sconn,
3018 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3019 __location__, strerror(errno)));
3020 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3023 sconn->local_address = local_address;
3024 sconn->remote_address = remote_address;
3026 if (tsocket_address_is_inet(remote_address, "ip")) {
3027 remaddr = tsocket_address_inet_addr_string(
3028 sconn->remote_address,
3030 if (remaddr == NULL) {
3031 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3032 __location__, strerror(errno)));
3033 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3036 remaddr = "0.0.0.0";
3039 /* this is needed so that we get decent entries
3040 in smbstatus for port 445 connects */
3041 set_remote_machine_name(remaddr, false);
3042 reload_services(sconn->msg_ctx, sconn->sock, true);
3045 * Before the first packet, check the global hosts allow/ hosts deny
3046 * parameters before doing any parsing of packets passed to us by the
3047 * client. This prevents attacks on our parsing code from hosts not in
3048 * the hosts allow list.
3051 ret = get_remote_hostname(remote_address,
3055 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3056 __location__, strerror(errno)));
3057 exit_server_cleanly("get_remote_hostname failed.\n");
3059 if (strequal(rhost, "UNKNOWN")) {
3060 rhost = talloc_strdup(talloc_tos(), remaddr);
3062 sconn->remote_hostname = talloc_move(sconn, &rhost);
3064 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3065 sconn->remote_hostname,
3068 * send a negative session response "not listening on calling
3071 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3072 DEBUG( 1, ("Connection denied from %s to %s\n",
3073 tsocket_address_string(remote_address, talloc_tos()),
3074 tsocket_address_string(local_address, talloc_tos())));
3075 (void)srv_send_smb(sconn,(char *)buf, false,
3077 exit_server_cleanly("connection denied");
3080 DEBUG(10, ("Connection allowed from %s to %s\n",
3081 tsocket_address_string(remote_address, talloc_tos()),
3082 tsocket_address_string(local_address, talloc_tos())));
3086 smb_perfcount_init();
3088 if (!init_account_policy()) {
3089 exit_server("Could not open account policy tdb.\n");
3092 if (*lp_rootdir()) {
3093 if (chroot(lp_rootdir()) != 0) {
3094 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3095 exit_server("Failed to chroot()");
3097 if (chdir("/") == -1) {
3098 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3099 exit_server("Failed to chroot()");
3101 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3104 if (!srv_init_signing(sconn)) {
3105 exit_server("Failed to init smb_signing");
3109 if (!init_oplocks(sconn->msg_ctx))
3110 exit_server("Failed to init oplocks");
3112 /* register our message handlers */
3113 messaging_register(sconn->msg_ctx, NULL,
3114 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3115 messaging_register(sconn->msg_ctx, NULL,
3116 MSG_SMB_CLOSE_FILE, msg_close_file);
3119 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3120 * MSGs to all child processes
3122 messaging_deregister(sconn->msg_ctx,
3124 messaging_register(sconn->msg_ctx, NULL,
3125 MSG_DEBUG, debug_message);
3127 if ((lp_keepalive() != 0)
3128 && !(event_add_idle(server_event_context(), NULL,
3129 timeval_set(lp_keepalive(), 0),
3130 "keepalive", keepalive_fn,
3132 DEBUG(0, ("Could not add keepalive event\n"));
3136 if (!(event_add_idle(server_event_context(), NULL,
3137 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3138 "deadtime", deadtime_fn, sconn))) {
3139 DEBUG(0, ("Could not add deadtime event\n"));
3143 if (!(event_add_idle(server_event_context(), NULL,
3144 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3145 "housekeeping", housekeeping_fn, sconn))) {
3146 DEBUG(0, ("Could not add housekeeping event\n"));
3150 #ifdef CLUSTER_SUPPORT
3152 if (lp_clustering()) {
3154 * We need to tell ctdb about our client's TCP
3155 * connection, so that for failover ctdbd can send
3156 * tickle acks, triggering a reconnection by the
3160 struct sockaddr_storage srv, clnt;
3162 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3164 status = smbd_register_ips(sconn, &srv, &clnt);
3165 if (!NT_STATUS_IS_OK(status)) {
3166 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3167 nt_errstr(status)));
3171 DEBUG(0,("Unable to get tcp info for "
3172 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3179 sconn->nbt.got_session = false;
3181 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3183 sconn->smb1.sessions.done_sesssetup = false;
3184 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3185 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3186 /* users from session setup */
3187 sconn->smb1.sessions.session_userlist = NULL;
3188 /* workgroup from session setup. */
3189 sconn->smb1.sessions.session_workgroup = NULL;
3190 /* this holds info on user ids that are already validated for this VC */
3191 sconn->smb1.sessions.validated_users = NULL;
3192 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3193 sconn->smb1.sessions.num_validated_vuids = 0;
3196 if (!init_dptrs(sconn)) {
3197 exit_server("init_dptrs() failed");
3200 sconn->smb1.fde = event_add_fd(server_event_context(),
3204 smbd_server_connection_handler,
3206 if (!sconn->smb1.fde) {
3207 exit_server("failed to create smbd_server_connection fde");
3215 frame = talloc_stackframe_pool(8192);
3219 status = smbd_server_connection_loop_once(sconn);
3220 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3221 !NT_STATUS_IS_OK(status)) {
3222 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3223 " exiting\n", nt_errstr(status)));
3230 exit_server_cleanly(NULL);
3233 bool req_is_in_chain(struct smb_request *req)
3235 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3237 * We're right now handling a subsequent request, so we must
3243 if (!is_andx_req(req->cmd)) {
3249 * Okay, an illegal request, but definitely not chained :-)
3254 return (CVAL(req->vwv+0, 0) != 0xFF);