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(uint64_t mid)
685 struct pending_message_list *pml;
688 if (smbd_server_conn->using_smb2) {
689 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
693 for (pml = deferred_open_queue; pml; pml = pml->next) {
694 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
696 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
699 (unsigned long long)msg_mid ));
701 if (mid == msg_mid) {
702 struct timed_event *te;
704 if (pml->processed) {
705 /* A processed message should not be
707 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
708 "message mid %llu was already processed\n",
709 (unsigned long long)msg_mid ));
713 DEBUG(10,("schedule_deferred_open_message_smb: "
714 "scheduling mid %llu\n",
715 (unsigned long long)mid ));
717 te = event_add_timed(server_event_context(),
720 smbd_deferred_open_timer,
723 DEBUG(10,("schedule_deferred_open_message_smb: "
724 "event_add_timed() failed, "
725 "skipping mid %llu\n",
726 (unsigned long long)msg_mid ));
729 TALLOC_FREE(pml->te);
731 DLIST_PROMOTE(deferred_open_queue, pml);
736 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
737 "find message mid %llu\n",
738 (unsigned long long)mid ));
741 /****************************************************************************
742 Return true if this mid is on the deferred queue and was not yet processed.
743 ****************************************************************************/
745 bool open_was_deferred(uint64_t mid)
747 struct pending_message_list *pml;
749 if (smbd_server_conn->using_smb2) {
750 return open_was_deferred_smb2(smbd_server_conn, mid);
753 for (pml = deferred_open_queue; pml; pml = pml->next) {
754 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
761 /****************************************************************************
762 Return the message queued by this mid.
763 ****************************************************************************/
765 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
767 struct pending_message_list *pml;
769 for (pml = deferred_open_queue; pml; pml = pml->next) {
770 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
777 /****************************************************************************
778 Get the state data queued by this mid.
779 ****************************************************************************/
781 bool get_deferred_open_message_state(struct smb_request *smbreq,
782 struct timeval *p_request_time,
785 struct pending_message_list *pml;
787 if (smbd_server_conn->using_smb2) {
788 return get_deferred_open_message_state_smb2(smbreq->smb2req,
793 pml = get_deferred_open_message_smb(smbreq->mid);
797 if (p_request_time) {
798 *p_request_time = pml->request_time;
801 *pp_state = (void *)pml->private_data.data;
806 /****************************************************************************
807 Function to push a deferred open smb message onto a linked list of local smb
808 messages ready for processing.
809 ****************************************************************************/
811 bool push_deferred_open_message_smb(struct smb_request *req,
812 struct timeval request_time,
813 struct timeval timeout,
815 char *private_data, size_t priv_len)
817 struct timeval end_time;
820 return push_deferred_open_message_smb2(req->smb2req,
828 if (req->unread_bytes) {
829 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
830 "unread_bytes = %u\n",
831 (unsigned int)req->unread_bytes ));
832 smb_panic("push_deferred_open_message_smb: "
833 "logic error unread_bytes != 0" );
836 end_time = timeval_sum(&request_time, &timeout);
838 DEBUG(10,("push_deferred_open_message_smb: pushing message "
839 "len %u mid %llu timeout time [%u.%06u]\n",
840 (unsigned int) smb_len(req->inbuf)+4,
841 (unsigned long long)req->mid,
842 (unsigned int)end_time.tv_sec,
843 (unsigned int)end_time.tv_usec));
845 return push_queued_message(req, request_time, end_time,
846 private_data, priv_len);
849 static void smbd_sig_term_handler(struct tevent_context *ev,
850 struct tevent_signal *se,
856 exit_server_cleanly("termination signal");
859 void smbd_setup_sig_term_handler(void)
861 struct tevent_signal *se;
863 se = tevent_add_signal(server_event_context(),
864 server_event_context(),
866 smbd_sig_term_handler,
869 exit_server("failed to setup SIGTERM handler");
873 static void smbd_sig_hup_handler(struct tevent_context *ev,
874 struct tevent_signal *se,
880 struct messaging_context *msg_ctx = talloc_get_type_abort(
881 private_data, struct messaging_context);
882 change_to_root_user();
883 DEBUG(1,("Reloading services after SIGHUP\n"));
884 reload_services(msg_ctx, smbd_server_conn->sock, False);
886 printing_subsystem_update(ev, msg_ctx);
890 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
891 struct messaging_context *msg_ctx)
893 struct tevent_signal *se;
895 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
898 exit_server("failed to setup SIGHUP handler");
902 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
909 timeout = SMBD_SELECT_TIMEOUT * 1000;
912 * Are there any timed events waiting ? If so, ensure we don't
913 * select for longer than it would take to wait for them.
916 event_add_to_poll_args(server_event_context(), conn,
917 &conn->pfds, &num_pfds, &timeout);
919 /* Process a signal and timed events now... */
920 if (run_events_poll(server_event_context(), 0, NULL, 0)) {
921 return NT_STATUS_RETRY;
926 START_PROFILE(smbd_idle);
928 ret = sys_poll(conn->pfds, num_pfds, timeout);
931 END_PROFILE(smbd_idle);
936 if (errno == EINTR) {
937 return NT_STATUS_RETRY;
939 return map_nt_error_from_unix(errno);
942 retry = run_events_poll(server_event_context(), ret, conn->pfds,
945 return NT_STATUS_RETRY;
948 /* Did we timeout ? */
950 return NT_STATUS_RETRY;
953 /* should not be reached */
954 return NT_STATUS_INTERNAL_ERROR;
958 * Only allow 5 outstanding trans requests. We're allocating memory, so
962 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
965 for (; list != NULL; list = list->next) {
967 if (list->mid == mid) {
968 return NT_STATUS_INVALID_PARAMETER;
974 return NT_STATUS_INSUFFICIENT_RESOURCES;
981 These flags determine some of the permissions required to do an operation
983 Note that I don't set NEED_WRITE on some write operations because they
984 are used by some brain-dead clients when printing, and I don't want to
985 force write permissions on print services.
987 #define AS_USER (1<<0)
988 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
989 #define TIME_INIT (1<<2)
990 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
991 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
992 #define DO_CHDIR (1<<6)
995 define a list of possible SMB messages and their corresponding
996 functions. Any message that has a NULL function is unimplemented -
997 please feel free to contribute implementations!
999 static const struct smb_message_struct {
1001 void (*fn)(struct smb_request *req);
1003 } smb_messages[256] = {
1005 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1006 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1007 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1008 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1009 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1010 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1011 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1012 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1013 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1014 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1015 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1016 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1017 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1018 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1019 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1020 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1021 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1022 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1023 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1024 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1025 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1026 /* 0x15 */ { NULL, NULL, 0 },
1027 /* 0x16 */ { NULL, NULL, 0 },
1028 /* 0x17 */ { NULL, NULL, 0 },
1029 /* 0x18 */ { NULL, NULL, 0 },
1030 /* 0x19 */ { NULL, NULL, 0 },
1031 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1032 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1033 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1034 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1035 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1036 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1037 /* 0x20 */ { "SMBwritec", NULL,0},
1038 /* 0x21 */ { NULL, NULL, 0 },
1039 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1040 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1041 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1042 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1043 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1044 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1045 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1046 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1047 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1048 /* 0x2b */ { "SMBecho",reply_echo,0},
1049 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1050 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1051 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1052 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1053 /* 0x30 */ { NULL, NULL, 0 },
1054 /* 0x31 */ { NULL, NULL, 0 },
1055 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1056 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1057 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1058 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1059 /* 0x36 */ { NULL, NULL, 0 },
1060 /* 0x37 */ { NULL, NULL, 0 },
1061 /* 0x38 */ { NULL, NULL, 0 },
1062 /* 0x39 */ { NULL, NULL, 0 },
1063 /* 0x3a */ { NULL, NULL, 0 },
1064 /* 0x3b */ { NULL, NULL, 0 },
1065 /* 0x3c */ { NULL, NULL, 0 },
1066 /* 0x3d */ { NULL, NULL, 0 },
1067 /* 0x3e */ { NULL, NULL, 0 },
1068 /* 0x3f */ { NULL, NULL, 0 },
1069 /* 0x40 */ { NULL, NULL, 0 },
1070 /* 0x41 */ { NULL, NULL, 0 },
1071 /* 0x42 */ { NULL, NULL, 0 },
1072 /* 0x43 */ { NULL, NULL, 0 },
1073 /* 0x44 */ { NULL, NULL, 0 },
1074 /* 0x45 */ { NULL, NULL, 0 },
1075 /* 0x46 */ { NULL, NULL, 0 },
1076 /* 0x47 */ { NULL, NULL, 0 },
1077 /* 0x48 */ { NULL, NULL, 0 },
1078 /* 0x49 */ { NULL, NULL, 0 },
1079 /* 0x4a */ { NULL, NULL, 0 },
1080 /* 0x4b */ { NULL, NULL, 0 },
1081 /* 0x4c */ { NULL, NULL, 0 },
1082 /* 0x4d */ { NULL, NULL, 0 },
1083 /* 0x4e */ { NULL, NULL, 0 },
1084 /* 0x4f */ { NULL, NULL, 0 },
1085 /* 0x50 */ { NULL, NULL, 0 },
1086 /* 0x51 */ { NULL, NULL, 0 },
1087 /* 0x52 */ { NULL, NULL, 0 },
1088 /* 0x53 */ { NULL, NULL, 0 },
1089 /* 0x54 */ { NULL, NULL, 0 },
1090 /* 0x55 */ { NULL, NULL, 0 },
1091 /* 0x56 */ { NULL, NULL, 0 },
1092 /* 0x57 */ { NULL, NULL, 0 },
1093 /* 0x58 */ { NULL, NULL, 0 },
1094 /* 0x59 */ { NULL, NULL, 0 },
1095 /* 0x5a */ { NULL, NULL, 0 },
1096 /* 0x5b */ { NULL, NULL, 0 },
1097 /* 0x5c */ { NULL, NULL, 0 },
1098 /* 0x5d */ { NULL, NULL, 0 },
1099 /* 0x5e */ { NULL, NULL, 0 },
1100 /* 0x5f */ { NULL, NULL, 0 },
1101 /* 0x60 */ { NULL, NULL, 0 },
1102 /* 0x61 */ { NULL, NULL, 0 },
1103 /* 0x62 */ { NULL, NULL, 0 },
1104 /* 0x63 */ { NULL, NULL, 0 },
1105 /* 0x64 */ { NULL, NULL, 0 },
1106 /* 0x65 */ { NULL, NULL, 0 },
1107 /* 0x66 */ { NULL, NULL, 0 },
1108 /* 0x67 */ { NULL, NULL, 0 },
1109 /* 0x68 */ { NULL, NULL, 0 },
1110 /* 0x69 */ { NULL, NULL, 0 },
1111 /* 0x6a */ { NULL, NULL, 0 },
1112 /* 0x6b */ { NULL, NULL, 0 },
1113 /* 0x6c */ { NULL, NULL, 0 },
1114 /* 0x6d */ { NULL, NULL, 0 },
1115 /* 0x6e */ { NULL, NULL, 0 },
1116 /* 0x6f */ { NULL, NULL, 0 },
1117 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1118 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1119 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1120 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1121 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1122 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1123 /* 0x76 */ { NULL, NULL, 0 },
1124 /* 0x77 */ { NULL, NULL, 0 },
1125 /* 0x78 */ { NULL, NULL, 0 },
1126 /* 0x79 */ { NULL, NULL, 0 },
1127 /* 0x7a */ { NULL, NULL, 0 },
1128 /* 0x7b */ { NULL, NULL, 0 },
1129 /* 0x7c */ { NULL, NULL, 0 },
1130 /* 0x7d */ { NULL, NULL, 0 },
1131 /* 0x7e */ { NULL, NULL, 0 },
1132 /* 0x7f */ { NULL, NULL, 0 },
1133 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1134 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1135 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1136 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1137 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1138 /* 0x85 */ { NULL, NULL, 0 },
1139 /* 0x86 */ { NULL, NULL, 0 },
1140 /* 0x87 */ { NULL, NULL, 0 },
1141 /* 0x88 */ { NULL, NULL, 0 },
1142 /* 0x89 */ { NULL, NULL, 0 },
1143 /* 0x8a */ { NULL, NULL, 0 },
1144 /* 0x8b */ { NULL, NULL, 0 },
1145 /* 0x8c */ { NULL, NULL, 0 },
1146 /* 0x8d */ { NULL, NULL, 0 },
1147 /* 0x8e */ { NULL, NULL, 0 },
1148 /* 0x8f */ { NULL, NULL, 0 },
1149 /* 0x90 */ { NULL, NULL, 0 },
1150 /* 0x91 */ { NULL, NULL, 0 },
1151 /* 0x92 */ { NULL, NULL, 0 },
1152 /* 0x93 */ { NULL, NULL, 0 },
1153 /* 0x94 */ { NULL, NULL, 0 },
1154 /* 0x95 */ { NULL, NULL, 0 },
1155 /* 0x96 */ { NULL, NULL, 0 },
1156 /* 0x97 */ { NULL, NULL, 0 },
1157 /* 0x98 */ { NULL, NULL, 0 },
1158 /* 0x99 */ { NULL, NULL, 0 },
1159 /* 0x9a */ { NULL, NULL, 0 },
1160 /* 0x9b */ { NULL, NULL, 0 },
1161 /* 0x9c */ { NULL, NULL, 0 },
1162 /* 0x9d */ { NULL, NULL, 0 },
1163 /* 0x9e */ { NULL, NULL, 0 },
1164 /* 0x9f */ { NULL, NULL, 0 },
1165 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1166 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1167 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1168 /* 0xa3 */ { NULL, NULL, 0 },
1169 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1170 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1171 /* 0xa6 */ { NULL, NULL, 0 },
1172 /* 0xa7 */ { NULL, NULL, 0 },
1173 /* 0xa8 */ { NULL, NULL, 0 },
1174 /* 0xa9 */ { NULL, NULL, 0 },
1175 /* 0xaa */ { NULL, NULL, 0 },
1176 /* 0xab */ { NULL, NULL, 0 },
1177 /* 0xac */ { NULL, NULL, 0 },
1178 /* 0xad */ { NULL, NULL, 0 },
1179 /* 0xae */ { NULL, NULL, 0 },
1180 /* 0xaf */ { NULL, NULL, 0 },
1181 /* 0xb0 */ { NULL, NULL, 0 },
1182 /* 0xb1 */ { NULL, NULL, 0 },
1183 /* 0xb2 */ { NULL, NULL, 0 },
1184 /* 0xb3 */ { NULL, NULL, 0 },
1185 /* 0xb4 */ { NULL, NULL, 0 },
1186 /* 0xb5 */ { NULL, NULL, 0 },
1187 /* 0xb6 */ { NULL, NULL, 0 },
1188 /* 0xb7 */ { NULL, NULL, 0 },
1189 /* 0xb8 */ { NULL, NULL, 0 },
1190 /* 0xb9 */ { NULL, NULL, 0 },
1191 /* 0xba */ { NULL, NULL, 0 },
1192 /* 0xbb */ { NULL, NULL, 0 },
1193 /* 0xbc */ { NULL, NULL, 0 },
1194 /* 0xbd */ { NULL, NULL, 0 },
1195 /* 0xbe */ { NULL, NULL, 0 },
1196 /* 0xbf */ { NULL, NULL, 0 },
1197 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1198 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1199 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1200 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1201 /* 0xc4 */ { NULL, NULL, 0 },
1202 /* 0xc5 */ { NULL, NULL, 0 },
1203 /* 0xc6 */ { NULL, NULL, 0 },
1204 /* 0xc7 */ { NULL, NULL, 0 },
1205 /* 0xc8 */ { NULL, NULL, 0 },
1206 /* 0xc9 */ { NULL, NULL, 0 },
1207 /* 0xca */ { NULL, NULL, 0 },
1208 /* 0xcb */ { NULL, NULL, 0 },
1209 /* 0xcc */ { NULL, NULL, 0 },
1210 /* 0xcd */ { NULL, NULL, 0 },
1211 /* 0xce */ { NULL, NULL, 0 },
1212 /* 0xcf */ { NULL, NULL, 0 },
1213 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1214 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1215 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1216 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1217 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1218 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1219 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1220 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1221 /* 0xd8 */ { NULL, NULL, 0 },
1222 /* 0xd9 */ { NULL, NULL, 0 },
1223 /* 0xda */ { NULL, NULL, 0 },
1224 /* 0xdb */ { NULL, NULL, 0 },
1225 /* 0xdc */ { NULL, NULL, 0 },
1226 /* 0xdd */ { NULL, NULL, 0 },
1227 /* 0xde */ { NULL, NULL, 0 },
1228 /* 0xdf */ { NULL, NULL, 0 },
1229 /* 0xe0 */ { NULL, NULL, 0 },
1230 /* 0xe1 */ { NULL, NULL, 0 },
1231 /* 0xe2 */ { NULL, NULL, 0 },
1232 /* 0xe3 */ { NULL, NULL, 0 },
1233 /* 0xe4 */ { NULL, NULL, 0 },
1234 /* 0xe5 */ { NULL, NULL, 0 },
1235 /* 0xe6 */ { NULL, NULL, 0 },
1236 /* 0xe7 */ { NULL, NULL, 0 },
1237 /* 0xe8 */ { NULL, NULL, 0 },
1238 /* 0xe9 */ { NULL, NULL, 0 },
1239 /* 0xea */ { NULL, NULL, 0 },
1240 /* 0xeb */ { NULL, NULL, 0 },
1241 /* 0xec */ { NULL, NULL, 0 },
1242 /* 0xed */ { NULL, NULL, 0 },
1243 /* 0xee */ { NULL, NULL, 0 },
1244 /* 0xef */ { NULL, NULL, 0 },
1245 /* 0xf0 */ { NULL, NULL, 0 },
1246 /* 0xf1 */ { NULL, NULL, 0 },
1247 /* 0xf2 */ { NULL, NULL, 0 },
1248 /* 0xf3 */ { NULL, NULL, 0 },
1249 /* 0xf4 */ { NULL, NULL, 0 },
1250 /* 0xf5 */ { NULL, NULL, 0 },
1251 /* 0xf6 */ { NULL, NULL, 0 },
1252 /* 0xf7 */ { NULL, NULL, 0 },
1253 /* 0xf8 */ { NULL, NULL, 0 },
1254 /* 0xf9 */ { NULL, NULL, 0 },
1255 /* 0xfa */ { NULL, NULL, 0 },
1256 /* 0xfb */ { NULL, NULL, 0 },
1257 /* 0xfc */ { NULL, NULL, 0 },
1258 /* 0xfd */ { NULL, NULL, 0 },
1259 /* 0xfe */ { NULL, NULL, 0 },
1260 /* 0xff */ { NULL, NULL, 0 }
1264 /*******************************************************************
1265 allocate and initialize a reply packet
1266 ********************************************************************/
1268 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1269 const char *inbuf, char **outbuf, uint8_t num_words,
1273 * Protect against integer wrap
1275 if ((num_bytes > 0xffffff)
1276 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1278 if (asprintf(&msg, "num_bytes too large: %u",
1279 (unsigned)num_bytes) == -1) {
1280 msg = discard_const_p(char, "num_bytes too large");
1285 *outbuf = talloc_array(mem_ctx, char,
1286 smb_size + num_words*2 + num_bytes);
1287 if (*outbuf == NULL) {
1291 construct_reply_common(req, inbuf, *outbuf);
1292 srv_set_message(*outbuf, num_words, num_bytes, false);
1294 * Zero out the word area, the caller has to take care of the bcc area
1297 if (num_words != 0) {
1298 memset(*outbuf + smb_vwv0, 0, num_words*2);
1304 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1307 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1309 smb_panic("could not allocate output buffer\n");
1311 req->outbuf = (uint8_t *)outbuf;
1315 /*******************************************************************
1316 Dump a packet to a file.
1317 ********************************************************************/
1319 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1323 if (DEBUGLEVEL < 50) {
1327 if (len < 4) len = smb_len(data)+4;
1328 for (i=1;i<100;i++) {
1329 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1330 type ? "req" : "resp") == -1) {
1333 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1334 if (fd != -1 || errno != EEXIST) break;
1337 ssize_t ret = write(fd, data, len);
1339 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1341 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1346 /****************************************************************************
1347 Prepare everything for calling the actual request function, and potentially
1348 call the request function via the "new" interface.
1350 Return False if the "legacy" function needs to be called, everything is
1353 Return True if we're done.
1355 I know this API sucks, but it is the one with the least code change I could
1357 ****************************************************************************/
1359 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1363 connection_struct *conn = NULL;
1364 struct smbd_server_connection *sconn = req->sconn;
1369 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1370 * so subtract 4 from it. */
1371 if (!valid_smb_header(req->inbuf)
1372 || (size < (smb_size - 4))) {
1373 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1374 smb_len(req->inbuf)));
1375 exit_server_cleanly("Non-SMB packet");
1378 if (smb_messages[type].fn == NULL) {
1379 DEBUG(0,("Unknown message type %d!\n",type));
1380 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1381 reply_unknown_new(req, type);
1385 flags = smb_messages[type].flags;
1387 /* In share mode security we must ignore the vuid. */
1388 session_tag = (lp_security() == SEC_SHARE)
1389 ? UID_FIELD_INVALID : req->vuid;
1392 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1393 (int)sys_getpid(), (unsigned long)conn));
1395 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1397 /* Ensure this value is replaced in the incoming packet. */
1398 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1401 * Ensure the correct username is in current_user_info. This is a
1402 * really ugly bugfix for problems with multiple session_setup_and_X's
1403 * being done and allowing %U and %G substitutions to work correctly.
1404 * There is a reason this code is done here, don't move it unless you
1405 * know what you're doing... :-).
1409 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1410 user_struct *vuser = NULL;
1412 sconn->smb1.sessions.last_session_tag = session_tag;
1413 if(session_tag != UID_FIELD_INVALID) {
1414 vuser = get_valid_user_struct(sconn, session_tag);
1416 set_current_user_info(
1417 vuser->session_info->unix_info->sanitized_username,
1418 vuser->session_info->unix_info->unix_name,
1419 vuser->session_info->info->domain_name);
1424 /* Does this call need to be run as the connected user? */
1425 if (flags & AS_USER) {
1427 /* Does this call need a valid tree connection? */
1430 * Amazingly, the error code depends on the command
1433 if (type == SMBntcreateX) {
1434 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1436 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1441 if (!change_to_user(conn,session_tag)) {
1442 DEBUG(0, ("Error: Could not change to user. Removing "
1443 "deferred open, mid=%llu.\n",
1444 (unsigned long long)req->mid));
1445 reply_force_doserror(req, ERRSRV, ERRbaduid);
1449 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1451 /* Does it need write permission? */
1452 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1453 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1457 /* IPC services are limited */
1458 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1459 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1463 /* This call needs to be run as root */
1464 change_to_root_user();
1467 /* load service specific parameters */
1469 if (req->encrypted) {
1470 conn->encrypted_tid = true;
1471 /* encrypted required from now on. */
1472 conn->encrypt_level = Required;
1473 } else if (ENCRYPTION_REQUIRED(conn)) {
1474 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1475 exit_server_cleanly("encryption required "
1481 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1482 (flags & (AS_USER|DO_CHDIR)
1484 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1487 conn->num_smb_operations++;
1490 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1492 if (raddr == NULL) {
1493 reply_nterror(req, NT_STATUS_NO_MEMORY);
1497 /* does this protocol need to be run as guest? */
1498 if ((flags & AS_GUEST)
1499 && (!change_to_guest() ||
1500 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1501 sconn->remote_hostname,
1503 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1507 smb_messages[type].fn(req);
1511 /****************************************************************************
1512 Construct a reply to the incoming packet.
1513 ****************************************************************************/
1515 static void construct_reply(struct smbd_server_connection *sconn,
1516 char *inbuf, int size, size_t unread_bytes,
1517 uint32_t seqnum, bool encrypted,
1518 struct smb_perfcount_data *deferred_pcd)
1520 connection_struct *conn;
1521 struct smb_request *req;
1523 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1524 smb_panic("could not allocate smb_request");
1527 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1528 encrypted, seqnum)) {
1529 exit_server_cleanly("Invalid SMB request");
1532 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1534 /* we popped this message off the queue - keep original perf data */
1536 req->pcd = *deferred_pcd;
1538 SMB_PERFCOUNT_START(&req->pcd);
1539 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1540 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1543 conn = switch_message(req->cmd, req, size);
1545 if (req->unread_bytes) {
1546 /* writeX failed. drain socket. */
1547 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1548 req->unread_bytes) {
1549 smb_panic("failed to drain pending bytes");
1551 req->unread_bytes = 0;
1559 if (req->outbuf == NULL) {
1563 if (CVAL(req->outbuf,0) == 0) {
1564 show_msg((char *)req->outbuf);
1567 if (!srv_send_smb(req->sconn,
1568 (char *)req->outbuf,
1569 true, req->seqnum+1,
1570 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1572 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1580 /****************************************************************************
1581 Process an smb from the client
1582 ****************************************************************************/
1583 static void process_smb(struct smbd_server_connection *sconn,
1584 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1585 uint32_t seqnum, bool encrypted,
1586 struct smb_perfcount_data *deferred_pcd)
1588 int msg_type = CVAL(inbuf,0);
1590 DO_PROFILE_INC(smb_count);
1592 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1594 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1595 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1597 if (msg_type != NBSSmessage) {
1599 * NetBIOS session request, keepalive, etc.
1601 reply_special(sconn, (char *)inbuf, nread);
1605 if (sconn->using_smb2) {
1606 /* At this point we're not really using smb2,
1607 * we make the decision here.. */
1608 if (smbd_is_smb2_header(inbuf, nread)) {
1609 smbd_smb2_first_negprot(sconn, inbuf, nread);
1611 } else if (nread >= smb_size && valid_smb_header(inbuf)
1612 && CVAL(inbuf, smb_com) != 0x72) {
1613 /* This is a non-negprot SMB1 packet.
1614 Disable SMB2 from now on. */
1615 sconn->using_smb2 = false;
1619 show_msg((char *)inbuf);
1621 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1622 encrypted, deferred_pcd);
1626 sconn->num_requests++;
1628 /* The timeout_processing function isn't run nearly
1629 often enough to implement 'max log size' without
1630 overrunning the size of the file by many megabytes.
1631 This is especially true if we are running at debug
1632 level 10. Checking every 50 SMBs is a nice
1633 tradeoff of performance vs log file size overrun. */
1635 if ((sconn->num_requests % 50) == 0 &&
1636 need_to_check_log_size()) {
1637 change_to_root_user();
1642 /****************************************************************************
1643 Return a string containing the function name of a SMB command.
1644 ****************************************************************************/
1646 const char *smb_fn_name(int type)
1648 const char *unknown_name = "SMBunknown";
1650 if (smb_messages[type].name == NULL)
1651 return(unknown_name);
1653 return(smb_messages[type].name);
1656 /****************************************************************************
1657 Helper functions for contruct_reply.
1658 ****************************************************************************/
1660 void add_to_common_flags2(uint32 v)
1665 void remove_from_common_flags2(uint32 v)
1667 common_flags2 &= ~v;
1670 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1673 srv_set_message(outbuf,0,0,false);
1675 SCVAL(outbuf, smb_com, req->cmd);
1676 SIVAL(outbuf,smb_rcls,0);
1677 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1678 SSVAL(outbuf,smb_flg2,
1679 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1681 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1683 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1684 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1685 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1686 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1689 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1691 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1695 * How many bytes have we already accumulated up to the current wct field
1699 size_t req_wct_ofs(struct smb_request *req)
1703 if (req->chain_outbuf == NULL) {
1706 buf_size = talloc_get_size(req->chain_outbuf);
1707 if ((buf_size % 4) != 0) {
1708 buf_size += (4 - (buf_size % 4));
1710 return buf_size - 4;
1714 * Hack around reply_nterror & friends not being aware of chained requests,
1715 * generating illegal (i.e. wct==0) chain replies.
1718 static void fixup_chain_error_packet(struct smb_request *req)
1720 uint8_t *outbuf = req->outbuf;
1722 reply_outbuf(req, 2, 0);
1723 memcpy(req->outbuf, outbuf, smb_wct);
1724 TALLOC_FREE(outbuf);
1725 SCVAL(req->outbuf, smb_vwv0, 0xff);
1729 * @brief Find the smb_cmd offset of the last command pushed
1730 * @param[in] buf The buffer we're building up
1731 * @retval Where can we put our next andx cmd?
1733 * While chaining requests, the "next" request we're looking at needs to put
1734 * its SMB_Command before the data the previous request already built up added
1735 * to the chain. Find the offset to the place where we have to put our cmd.
1738 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1743 cmd = CVAL(buf, smb_com);
1745 SMB_ASSERT(is_andx_req(cmd));
1749 while (CVAL(buf, ofs) != 0xff) {
1751 if (!is_andx_req(CVAL(buf, ofs))) {
1756 * ofs is from start of smb header, so add the 4 length
1757 * bytes. The next cmd is right after the wct field.
1759 ofs = SVAL(buf, ofs+2) + 4 + 1;
1761 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1769 * @brief Do the smb chaining at a buffer level
1770 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1771 * @param[in] smb_command The command that we want to issue
1772 * @param[in] wct How many words?
1773 * @param[in] vwv The words, already in network order
1774 * @param[in] bytes_alignment How shall we align "bytes"?
1775 * @param[in] num_bytes How many bytes?
1776 * @param[in] bytes The data the request ships
1778 * smb_splice_chain() adds the vwv and bytes to the request already present in
1782 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1783 uint8_t wct, const uint16_t *vwv,
1784 size_t bytes_alignment,
1785 uint32_t num_bytes, const uint8_t *bytes)
1788 size_t old_size, new_size;
1790 size_t chain_padding = 0;
1791 size_t bytes_padding = 0;
1794 old_size = talloc_get_size(*poutbuf);
1797 * old_size == smb_wct means we're pushing the first request in for
1801 first_request = (old_size == smb_wct);
1803 if (!first_request && ((old_size % 4) != 0)) {
1805 * Align the wct field of subsequent requests to a 4-byte
1808 chain_padding = 4 - (old_size % 4);
1812 * After the old request comes the new wct field (1 byte), the vwv's
1813 * and the num_bytes field. After at we might need to align the bytes
1814 * given to us to "bytes_alignment", increasing the num_bytes value.
1817 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1819 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1820 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1823 new_size += bytes_padding + num_bytes;
1825 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1826 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1827 (unsigned)new_size));
1831 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1832 if (outbuf == NULL) {
1833 DEBUG(0, ("talloc failed\n"));
1838 if (first_request) {
1839 SCVAL(outbuf, smb_com, smb_command);
1841 size_t andx_cmd_ofs;
1843 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1844 DEBUG(1, ("invalid command chain\n"));
1845 *poutbuf = talloc_realloc(
1846 NULL, *poutbuf, uint8_t, old_size);
1850 if (chain_padding != 0) {
1851 memset(outbuf + old_size, 0, chain_padding);
1852 old_size += chain_padding;
1855 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1856 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1862 * Push the chained request:
1867 SCVAL(outbuf, ofs, wct);
1874 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1875 ofs += sizeof(uint16_t) * wct;
1881 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1882 ofs += sizeof(uint16_t);
1888 if (bytes_padding != 0) {
1889 memset(outbuf + ofs, 0, bytes_padding);
1890 ofs += bytes_padding;
1897 memcpy(outbuf + ofs, bytes, num_bytes);
1902 /****************************************************************************
1903 Construct a chained reply and add it to the already made reply
1904 ****************************************************************************/
1906 void chain_reply(struct smb_request *req)
1908 size_t smblen = smb_len(req->inbuf);
1909 size_t already_used, length_needed;
1911 uint32_t chain_offset; /* uint32_t to avoid overflow */
1914 const uint16_t *vwv;
1918 if (IVAL(req->outbuf, smb_rcls) != 0) {
1919 fixup_chain_error_packet(req);
1923 * Any of the AndX requests and replies have at least a wct of
1924 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1925 * beginning of the SMB header to the next wct field.
1927 * None of the AndX requests put anything valuable in vwv[0] and [1],
1928 * so we can overwrite it here to form the chain.
1931 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1932 if (req->chain_outbuf == NULL) {
1933 req->chain_outbuf = talloc_realloc(
1934 req, req->outbuf, uint8_t,
1935 smb_len(req->outbuf) + 4);
1936 if (req->chain_outbuf == NULL) {
1937 smb_panic("talloc failed");
1945 * Here we assume that this is the end of the chain. For that we need
1946 * to set "next command" to 0xff and the offset to 0. If we later find
1947 * more commands in the chain, this will be overwritten again.
1950 SCVAL(req->outbuf, smb_vwv0, 0xff);
1951 SCVAL(req->outbuf, smb_vwv0+1, 0);
1952 SSVAL(req->outbuf, smb_vwv1, 0);
1954 if (req->chain_outbuf == NULL) {
1956 * In req->chain_outbuf we collect all the replies. Start the
1957 * chain by copying in the first reply.
1959 * We do the realloc because later on we depend on
1960 * talloc_get_size to determine the length of
1961 * chain_outbuf. The reply_xxx routines might have
1962 * over-allocated (reply_pipe_read_and_X used to be such an
1965 req->chain_outbuf = talloc_realloc(
1966 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1967 if (req->chain_outbuf == NULL) {
1968 smb_panic("talloc failed");
1973 * Update smb headers where subsequent chained commands
1974 * may have updated them.
1976 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1977 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1979 if (!smb_splice_chain(&req->chain_outbuf,
1980 CVAL(req->outbuf, smb_com),
1981 CVAL(req->outbuf, smb_wct),
1982 (uint16_t *)(req->outbuf + smb_vwv),
1983 0, smb_buflen(req->outbuf),
1984 (uint8_t *)smb_buf(req->outbuf))) {
1987 TALLOC_FREE(req->outbuf);
1991 * We use the old request's vwv field to grab the next chained command
1992 * and offset into the chained fields.
1995 chain_cmd = CVAL(req->vwv+0, 0);
1996 chain_offset = SVAL(req->vwv+1, 0);
1998 if (chain_cmd == 0xff) {
2000 * End of chain, no more requests from the client. So ship the
2003 smb_setlen((char *)(req->chain_outbuf),
2004 talloc_get_size(req->chain_outbuf) - 4);
2006 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2007 true, req->seqnum+1,
2008 IS_CONN_ENCRYPTED(req->conn)
2011 exit_server_cleanly("chain_reply: srv_send_smb "
2014 TALLOC_FREE(req->chain_outbuf);
2019 /* add a new perfcounter for this element of chain */
2020 SMB_PERFCOUNT_ADD(&req->pcd);
2021 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2022 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2025 * Check if the client tries to fool us. The request so far uses the
2026 * space to the end of the byte buffer in the request just
2027 * processed. The chain_offset can't point into that area. If that was
2028 * the case, we could end up with an endless processing of the chain,
2029 * we would always handle the same request.
2032 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2033 if (chain_offset < already_used) {
2038 * Next check: Make sure the chain offset does not point beyond the
2039 * overall smb request length.
2042 length_needed = chain_offset+1; /* wct */
2043 if (length_needed > smblen) {
2048 * Now comes the pointer magic. Goal here is to set up req->vwv and
2049 * req->buf correctly again to be able to call the subsequent
2050 * switch_message(). The chain offset (the former vwv[1]) points at
2051 * the new wct field.
2054 wct = CVAL(smb_base(req->inbuf), chain_offset);
2057 * Next consistency check: Make the new vwv array fits in the overall
2061 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2062 if (length_needed > smblen) {
2065 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2068 * Now grab the new byte buffer....
2071 buflen = SVAL(vwv+wct, 0);
2074 * .. and check that it fits.
2077 length_needed += buflen;
2078 if (length_needed > smblen) {
2081 buf = (const uint8_t *)(vwv+wct+1);
2083 req->cmd = chain_cmd;
2085 req->vwv = discard_const_p(uint16_t, vwv);
2086 req->buflen = buflen;
2089 switch_message(chain_cmd, req, smblen);
2091 if (req->outbuf == NULL) {
2093 * This happens if the chained command has suspended itself or
2094 * if it has called srv_send_smb() itself.
2100 * We end up here if the chained command was not itself chained or
2101 * suspended, but for example a close() command. We now need to splice
2102 * the chained commands' outbuf into the already built up chain_outbuf
2103 * and ship the result.
2109 * We end up here if there's any error in the chain syntax. Report a
2110 * DOS error, just like Windows does.
2112 reply_force_doserror(req, ERRSRV, ERRerror);
2113 fixup_chain_error_packet(req);
2117 * This scary statement intends to set the
2118 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2119 * to the value req->outbuf carries
2121 SSVAL(req->chain_outbuf, smb_flg2,
2122 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2123 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2126 * Transfer the error codes from the subrequest to the main one
2128 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2129 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2131 if (!smb_splice_chain(&req->chain_outbuf,
2132 CVAL(req->outbuf, smb_com),
2133 CVAL(req->outbuf, smb_wct),
2134 (uint16_t *)(req->outbuf + smb_vwv),
2135 0, smb_buflen(req->outbuf),
2136 (uint8_t *)smb_buf(req->outbuf))) {
2137 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2139 TALLOC_FREE(req->outbuf);
2141 smb_setlen((char *)(req->chain_outbuf),
2142 talloc_get_size(req->chain_outbuf) - 4);
2144 show_msg((char *)(req->chain_outbuf));
2146 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2147 true, req->seqnum+1,
2148 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2150 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2152 TALLOC_FREE(req->chain_outbuf);
2156 /****************************************************************************
2157 Check if services need reloading.
2158 ****************************************************************************/
2160 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2163 if (last_smb_conf_reload_time == 0) {
2164 last_smb_conf_reload_time = t;
2167 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2168 reload_services(sconn->msg_ctx, sconn->sock, True);
2169 last_smb_conf_reload_time = t;
2173 static bool fd_is_readable(int fd)
2177 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2179 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2183 static void smbd_server_connection_write_handler(
2184 struct smbd_server_connection *sconn)
2186 /* TODO: make write nonblocking */
2189 static void smbd_server_connection_read_handler(
2190 struct smbd_server_connection *sconn, int fd)
2192 uint8_t *inbuf = NULL;
2193 size_t inbuf_len = 0;
2194 size_t unread_bytes = 0;
2195 bool encrypted = false;
2196 TALLOC_CTX *mem_ctx = talloc_tos();
2200 bool from_client = (sconn->sock == fd);
2203 smbd_lock_socket(sconn);
2205 if (lp_async_smb_echo_handler()) {
2207 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2209 * This is the super-ugly hack to
2210 * prefer the packets forwarded by the
2211 * echo handler over the ones by the
2214 fd = sconn->smb1.echo_handler.trusted_fd;
2215 } else if (!fd_is_readable(fd)) {
2216 DEBUG(10,("the echo listener was faster\n"));
2217 smbd_unlock_socket(sconn);
2222 /* TODO: make this completely nonblocking */
2223 status = receive_smb_talloc(mem_ctx, sconn, fd,
2224 (char **)(void *)&inbuf,
2228 &inbuf_len, &seqnum,
2229 false /* trusted channel */);
2230 smbd_unlock_socket(sconn);
2232 /* TODO: make this completely nonblocking */
2233 status = receive_smb_talloc(mem_ctx, sconn, fd,
2234 (char **)(void *)&inbuf,
2238 &inbuf_len, &seqnum,
2239 true /* trusted channel */);
2242 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2245 if (NT_STATUS_IS_ERR(status)) {
2246 exit_server_cleanly("failed to receive smb request");
2248 if (!NT_STATUS_IS_OK(status)) {
2253 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2254 seqnum, encrypted, NULL);
2257 static void smbd_server_connection_handler(struct event_context *ev,
2258 struct fd_event *fde,
2262 struct smbd_server_connection *conn = talloc_get_type(private_data,
2263 struct smbd_server_connection);
2265 if (flags & EVENT_FD_WRITE) {
2266 smbd_server_connection_write_handler(conn);
2269 if (flags & EVENT_FD_READ) {
2270 smbd_server_connection_read_handler(conn, conn->sock);
2275 static void smbd_server_echo_handler(struct event_context *ev,
2276 struct fd_event *fde,
2280 struct smbd_server_connection *conn = talloc_get_type(private_data,
2281 struct smbd_server_connection);
2283 if (flags & EVENT_FD_WRITE) {
2284 smbd_server_connection_write_handler(conn);
2287 if (flags & EVENT_FD_READ) {
2288 smbd_server_connection_read_handler(
2289 conn, conn->smb1.echo_handler.trusted_fd);
2294 #ifdef CLUSTER_SUPPORT
2295 /****************************************************************************
2296 received when we should release a specific IP
2297 ****************************************************************************/
2298 static void release_ip(const char *ip, void *priv)
2300 const char *addr = (const char *)priv;
2301 const char *p = addr;
2303 if (strncmp("::ffff:", addr, 7) == 0) {
2307 DEBUG(10, ("Got release IP message for %s, "
2308 "our address is %s\n", ip, p));
2310 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2311 /* we can't afford to do a clean exit - that involves
2312 database writes, which would potentially mean we
2313 are still running after the failover has finished -
2314 we have to get rid of this process ID straight
2316 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2318 /* note we must exit with non-zero status so the unclean handler gets
2319 called in the parent, so that the brl database is tickled */
2324 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2325 struct sockaddr_storage *client)
2328 length = sizeof(*server);
2329 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2332 length = sizeof(*client);
2333 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2341 * Send keepalive packets to our client
2343 static bool keepalive_fn(const struct timeval *now, void *private_data)
2345 struct smbd_server_connection *sconn = smbd_server_conn;
2348 if (sconn->using_smb2) {
2349 /* Don't do keepalives on an SMB2 connection. */
2353 smbd_lock_socket(smbd_server_conn);
2354 ret = send_keepalive(sconn->sock);
2355 smbd_unlock_socket(smbd_server_conn);
2358 char addr[INET6_ADDRSTRLEN];
2360 * Try and give an error message saying what
2363 DEBUG(0, ("send_keepalive failed for client %s. "
2364 "Error %s - exiting\n",
2365 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2373 * Do the recurring check if we're idle
2375 static bool deadtime_fn(const struct timeval *now, void *private_data)
2377 struct smbd_server_connection *sconn =
2378 (struct smbd_server_connection *)private_data;
2380 if ((conn_num_open(sconn) == 0)
2381 || (conn_idle_all(sconn, now->tv_sec))) {
2382 DEBUG( 2, ( "Closing idle connection\n" ) );
2383 messaging_send(sconn->msg_ctx,
2384 messaging_server_id(sconn->msg_ctx),
2385 MSG_SHUTDOWN, &data_blob_null);
2393 * Do the recurring log file and smb.conf reload checks.
2396 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2398 struct smbd_server_connection *sconn = talloc_get_type_abort(
2399 private_data, struct smbd_server_connection);
2401 DEBUG(5, ("housekeeping\n"));
2403 change_to_root_user();
2405 /* update printer queue caches if necessary */
2406 update_monitored_printq_cache(sconn->msg_ctx);
2408 /* check if we need to reload services */
2409 check_reload(sconn, time_mono(NULL));
2411 /* Change machine password if neccessary. */
2412 attempt_machine_password_change();
2415 * Force a log file check.
2417 force_check_log_size();
2422 static int create_unlink_tmp(const char *dir)
2427 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2428 if (fname == NULL) {
2432 fd = mkstemp(fname);
2437 if (unlink(fname) == -1) {
2438 int sys_errno = errno;
2449 * Read an smb packet in the echo handler child, giving the parent
2450 * smbd one second to react once the socket becomes readable.
2453 struct smbd_echo_read_state {
2454 struct tevent_context *ev;
2455 struct smbd_server_connection *sconn;
2462 static void smbd_echo_read_readable(struct tevent_req *subreq);
2463 static void smbd_echo_read_waited(struct tevent_req *subreq);
2465 static struct tevent_req *smbd_echo_read_send(
2466 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2467 struct smbd_server_connection *sconn)
2469 struct tevent_req *req, *subreq;
2470 struct smbd_echo_read_state *state;
2472 req = tevent_req_create(mem_ctx, &state,
2473 struct smbd_echo_read_state);
2478 state->sconn = sconn;
2480 subreq = wait_for_read_send(state, ev, sconn->sock);
2481 if (tevent_req_nomem(subreq, req)) {
2482 return tevent_req_post(req, ev);
2484 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2488 static void smbd_echo_read_readable(struct tevent_req *subreq)
2490 struct tevent_req *req = tevent_req_callback_data(
2491 subreq, struct tevent_req);
2492 struct smbd_echo_read_state *state = tevent_req_data(
2493 req, struct smbd_echo_read_state);
2497 ok = wait_for_read_recv(subreq, &err);
2498 TALLOC_FREE(subreq);
2500 tevent_req_nterror(req, map_nt_error_from_unix(err));
2505 * Give the parent smbd one second to step in
2508 subreq = tevent_wakeup_send(
2509 state, state->ev, timeval_current_ofs(1, 0));
2510 if (tevent_req_nomem(subreq, req)) {
2513 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2516 static void smbd_echo_read_waited(struct tevent_req *subreq)
2518 struct tevent_req *req = tevent_req_callback_data(
2519 subreq, struct tevent_req);
2520 struct smbd_echo_read_state *state = tevent_req_data(
2521 req, struct smbd_echo_read_state);
2522 struct smbd_server_connection *sconn = state->sconn;
2528 ok = tevent_wakeup_recv(subreq);
2529 TALLOC_FREE(subreq);
2531 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2535 ok = smbd_lock_socket_internal(sconn);
2537 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2538 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2542 if (!fd_is_readable(sconn->sock)) {
2543 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2544 (int)sys_getpid()));
2546 ok = smbd_unlock_socket_internal(sconn);
2548 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2549 DEBUG(1, ("%s: failed to unlock socket\n",
2554 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2555 if (tevent_req_nomem(subreq, req)) {
2558 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2562 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2568 false /* trusted_channel*/);
2570 if (tevent_req_nterror(req, status)) {
2571 tevent_req_nterror(req, status);
2572 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2573 (int)sys_getpid(), nt_errstr(status)));
2577 ok = smbd_unlock_socket_internal(sconn);
2579 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2580 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2583 tevent_req_done(req);
2586 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2587 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2589 struct smbd_echo_read_state *state = tevent_req_data(
2590 req, struct smbd_echo_read_state);
2593 if (tevent_req_is_nterror(req, &status)) {
2596 *pbuf = talloc_move(mem_ctx, &state->buf);
2597 *pbuflen = state->buflen;
2598 *pseqnum = state->seqnum;
2599 return NT_STATUS_OK;
2602 struct smbd_echo_state {
2603 struct tevent_context *ev;
2604 struct iovec *pending;
2605 struct smbd_server_connection *sconn;
2608 struct tevent_fd *parent_fde;
2610 struct tevent_req *write_req;
2613 static void smbd_echo_writer_done(struct tevent_req *req);
2615 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2619 if (state->write_req != NULL) {
2623 num_pending = talloc_array_length(state->pending);
2624 if (num_pending == 0) {
2628 state->write_req = writev_send(state, state->ev, NULL,
2629 state->parent_pipe, false,
2630 state->pending, num_pending);
2631 if (state->write_req == NULL) {
2632 DEBUG(1, ("writev_send failed\n"));
2636 talloc_steal(state->write_req, state->pending);
2637 state->pending = NULL;
2639 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2643 static void smbd_echo_writer_done(struct tevent_req *req)
2645 struct smbd_echo_state *state = tevent_req_callback_data(
2646 req, struct smbd_echo_state);
2650 written = writev_recv(req, &err);
2652 state->write_req = NULL;
2653 if (written == -1) {
2654 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2657 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2658 smbd_echo_activate_writer(state);
2661 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2664 struct smb_request req;
2665 uint16_t num_replies;
2670 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2671 DEBUG(10, ("Got netbios keepalive\n"));
2678 if (inbuf_len < smb_size) {
2679 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2682 if (!valid_smb_header(inbuf)) {
2683 DEBUG(10, ("Got invalid SMB header\n"));
2687 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2693 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2694 smb_messages[req.cmd].name
2695 ? smb_messages[req.cmd].name : "unknown"));
2697 if (req.cmd != SMBecho) {
2704 num_replies = SVAL(req.vwv+0, 0);
2705 if (num_replies != 1) {
2706 /* Not a Windows "Hey, you're still there?" request */
2710 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2712 DEBUG(10, ("create_outbuf failed\n"));
2715 req.outbuf = (uint8_t *)outbuf;
2717 SSVAL(req.outbuf, smb_vwv0, num_replies);
2719 if (req.buflen > 0) {
2720 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2723 out_len = smb_len(req.outbuf) + 4;
2725 ok = srv_send_smb(req.sconn,
2729 TALLOC_FREE(outbuf);
2737 static void smbd_echo_exit(struct tevent_context *ev,
2738 struct tevent_fd *fde, uint16_t flags,
2741 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2745 static void smbd_echo_got_packet(struct tevent_req *req);
2747 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2750 struct smbd_echo_state *state;
2751 struct tevent_req *read_req;
2753 state = talloc_zero(sconn, struct smbd_echo_state);
2754 if (state == NULL) {
2755 DEBUG(1, ("talloc failed\n"));
2758 state->sconn = sconn;
2759 state->parent_pipe = parent_pipe;
2760 state->ev = s3_tevent_context_init(state);
2761 if (state->ev == NULL) {
2762 DEBUG(1, ("tevent_context_init failed\n"));
2766 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2767 TEVENT_FD_READ, smbd_echo_exit,
2769 if (state->parent_fde == NULL) {
2770 DEBUG(1, ("tevent_add_fd failed\n"));
2775 read_req = smbd_echo_read_send(state, state->ev, sconn);
2776 if (read_req == NULL) {
2777 DEBUG(1, ("smbd_echo_read_send failed\n"));
2781 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2784 if (tevent_loop_once(state->ev) == -1) {
2785 DEBUG(1, ("tevent_loop_once failed: %s\n",
2793 static void smbd_echo_got_packet(struct tevent_req *req)
2795 struct smbd_echo_state *state = tevent_req_callback_data(
2796 req, struct smbd_echo_state);
2800 uint32_t seqnum = 0;
2803 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2805 if (!NT_STATUS_IS_OK(status)) {
2806 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2807 nt_errstr(status)));
2811 reply = smbd_echo_reply((uint8_t *)buf, buflen, seqnum);
2817 num_pending = talloc_array_length(state->pending);
2818 tmp = talloc_realloc(state, state->pending, struct iovec,
2821 DEBUG(1, ("talloc_realloc failed\n"));
2824 state->pending = tmp;
2826 if (buflen >= smb_size) {
2828 * place the seqnum in the packet so that the main process
2829 * can reply with signing
2831 SIVAL(buf, smb_ss_field, seqnum);
2832 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2835 iov = &state->pending[num_pending];
2836 iov->iov_base = buf;
2837 iov->iov_len = buflen;
2839 DEBUG(10,("echo_handler[%d]: forward to main\n",
2840 (int)sys_getpid()));
2841 smbd_echo_activate_writer(state);
2844 req = smbd_echo_read_send(state, state->ev, state->sconn);
2846 DEBUG(1, ("smbd_echo_read_send failed\n"));
2849 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2854 * Handle SMBecho requests in a forked child process
2856 bool fork_echo_handler(struct smbd_server_connection *sconn)
2858 int listener_pipe[2];
2862 res = pipe(listener_pipe);
2864 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2867 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2868 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2869 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2877 close(listener_pipe[0]);
2878 set_blocking(listener_pipe[1], false);
2880 status = reinit_after_fork(sconn->msg_ctx,
2881 server_event_context(),
2882 procid_self(), false);
2883 if (!NT_STATUS_IS_OK(status)) {
2884 DEBUG(1, ("reinit_after_fork failed: %s\n",
2885 nt_errstr(status)));
2888 smbd_echo_loop(sconn, listener_pipe[1]);
2891 close(listener_pipe[1]);
2892 listener_pipe[1] = -1;
2893 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2895 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2898 * Without smb signing this is the same as the normal smbd
2899 * listener. This needs to change once signing comes in.
2901 sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
2903 sconn->smb1.echo_handler.trusted_fd,
2905 smbd_server_echo_handler,
2907 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2908 DEBUG(1, ("event_add_fd failed\n"));
2915 if (listener_pipe[0] != -1) {
2916 close(listener_pipe[0]);
2918 if (listener_pipe[1] != -1) {
2919 close(listener_pipe[1]);
2921 sconn->smb1.echo_handler.trusted_fd = -1;
2922 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2923 close(sconn->smb1.echo_handler.socket_lock_fd);
2925 sconn->smb1.echo_handler.trusted_fd = -1;
2926 sconn->smb1.echo_handler.socket_lock_fd = -1;
2932 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2933 struct sockaddr_storage *srv,
2934 struct sockaddr_storage *clnt)
2936 struct ctdbd_connection *cconn;
2937 char tmp_addr[INET6_ADDRSTRLEN];
2940 cconn = messaging_ctdbd_connection();
2941 if (cconn == NULL) {
2942 return NT_STATUS_NO_MEMORY;
2945 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2946 addr = talloc_strdup(cconn, tmp_addr);
2948 return NT_STATUS_NO_MEMORY;
2950 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2955 /****************************************************************************
2956 Process commands from the client
2957 ****************************************************************************/
2959 void smbd_process(struct smbd_server_connection *sconn)
2961 TALLOC_CTX *frame = talloc_stackframe();
2962 struct sockaddr_storage ss;
2963 struct sockaddr *sa = NULL;
2964 socklen_t sa_socklen;
2965 struct tsocket_address *local_address = NULL;
2966 struct tsocket_address *remote_address = NULL;
2967 const char *remaddr = NULL;
2971 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
2973 * We're not making the decision here,
2974 * we're just allowing the client
2975 * to decide between SMB1 and SMB2
2976 * with the first negprot
2979 sconn->using_smb2 = true;
2982 /* Ensure child is set to blocking mode */
2983 set_blocking(sconn->sock,True);
2985 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2986 set_socket_options(sconn->sock, lp_socket_options());
2988 sa = (struct sockaddr *)(void *)&ss;
2989 sa_socklen = sizeof(ss);
2990 ret = getpeername(sconn->sock, sa, &sa_socklen);
2992 int level = (errno == ENOTCONN)?2:0;
2993 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2994 exit_server_cleanly("getpeername() failed.\n");
2996 ret = tsocket_address_bsd_from_sockaddr(sconn,
3000 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3001 __location__, strerror(errno)));
3002 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3005 sa = (struct sockaddr *)(void *)&ss;
3006 sa_socklen = sizeof(ss);
3007 ret = getsockname(sconn->sock, sa, &sa_socklen);
3009 int level = (errno == ENOTCONN)?2:0;
3010 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3011 exit_server_cleanly("getsockname() failed.\n");
3013 ret = tsocket_address_bsd_from_sockaddr(sconn,
3017 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3018 __location__, strerror(errno)));
3019 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3022 sconn->local_address = local_address;
3023 sconn->remote_address = remote_address;
3025 if (tsocket_address_is_inet(remote_address, "ip")) {
3026 remaddr = tsocket_address_inet_addr_string(
3027 sconn->remote_address,
3029 if (remaddr == NULL) {
3030 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3031 __location__, strerror(errno)));
3032 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3035 remaddr = "0.0.0.0";
3038 /* this is needed so that we get decent entries
3039 in smbstatus for port 445 connects */
3040 set_remote_machine_name(remaddr, false);
3041 reload_services(sconn->msg_ctx, sconn->sock, true);
3044 * Before the first packet, check the global hosts allow/ hosts deny
3045 * parameters before doing any parsing of packets passed to us by the
3046 * client. This prevents attacks on our parsing code from hosts not in
3047 * the hosts allow list.
3050 ret = get_remote_hostname(remote_address,
3054 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3055 __location__, strerror(errno)));
3056 exit_server_cleanly("get_remote_hostname failed.\n");
3058 if (strequal(rhost, "UNKNOWN")) {
3059 rhost = talloc_strdup(talloc_tos(), remaddr);
3061 sconn->remote_hostname = talloc_move(sconn, &rhost);
3063 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3064 sconn->remote_hostname,
3067 * send a negative session response "not listening on calling
3070 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3071 DEBUG( 1, ("Connection denied from %s to %s\n",
3072 tsocket_address_string(remote_address, talloc_tos()),
3073 tsocket_address_string(local_address, talloc_tos())));
3074 (void)srv_send_smb(sconn,(char *)buf, false,
3076 exit_server_cleanly("connection denied");
3079 DEBUG(10, ("Connection allowed from %s to %s\n",
3080 tsocket_address_string(remote_address, talloc_tos()),
3081 tsocket_address_string(local_address, talloc_tos())));
3085 smb_perfcount_init();
3087 if (!init_account_policy()) {
3088 exit_server("Could not open account policy tdb.\n");
3091 if (*lp_rootdir()) {
3092 if (chroot(lp_rootdir()) != 0) {
3093 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3094 exit_server("Failed to chroot()");
3096 if (chdir("/") == -1) {
3097 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3098 exit_server("Failed to chroot()");
3100 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3103 if (!srv_init_signing(sconn)) {
3104 exit_server("Failed to init smb_signing");
3108 if (!init_oplocks(sconn->msg_ctx))
3109 exit_server("Failed to init oplocks");
3111 /* register our message handlers */
3112 messaging_register(sconn->msg_ctx, NULL,
3113 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3114 messaging_register(sconn->msg_ctx, NULL,
3115 MSG_SMB_CLOSE_FILE, msg_close_file);
3118 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3119 * MSGs to all child processes
3121 messaging_deregister(sconn->msg_ctx,
3123 messaging_register(sconn->msg_ctx, NULL,
3124 MSG_DEBUG, debug_message);
3126 if ((lp_keepalive() != 0)
3127 && !(event_add_idle(server_event_context(), NULL,
3128 timeval_set(lp_keepalive(), 0),
3129 "keepalive", keepalive_fn,
3131 DEBUG(0, ("Could not add keepalive event\n"));
3135 if (!(event_add_idle(server_event_context(), NULL,
3136 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3137 "deadtime", deadtime_fn, sconn))) {
3138 DEBUG(0, ("Could not add deadtime event\n"));
3142 if (!(event_add_idle(server_event_context(), NULL,
3143 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3144 "housekeeping", housekeeping_fn, sconn))) {
3145 DEBUG(0, ("Could not add housekeeping event\n"));
3149 #ifdef CLUSTER_SUPPORT
3151 if (lp_clustering()) {
3153 * We need to tell ctdb about our client's TCP
3154 * connection, so that for failover ctdbd can send
3155 * tickle acks, triggering a reconnection by the
3159 struct sockaddr_storage srv, clnt;
3161 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3163 status = smbd_register_ips(sconn, &srv, &clnt);
3164 if (!NT_STATUS_IS_OK(status)) {
3165 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3166 nt_errstr(status)));
3170 DEBUG(0,("Unable to get tcp info for "
3171 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3178 sconn->nbt.got_session = false;
3180 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3182 sconn->smb1.sessions.done_sesssetup = false;
3183 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3184 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3185 /* users from session setup */
3186 sconn->smb1.sessions.session_userlist = NULL;
3187 /* workgroup from session setup. */
3188 sconn->smb1.sessions.session_workgroup = NULL;
3189 /* this holds info on user ids that are already validated for this VC */
3190 sconn->smb1.sessions.validated_users = NULL;
3191 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3192 sconn->smb1.sessions.num_validated_vuids = 0;
3195 if (!init_dptrs(sconn)) {
3196 exit_server("init_dptrs() failed");
3199 sconn->smb1.fde = event_add_fd(server_event_context(),
3203 smbd_server_connection_handler,
3205 if (!sconn->smb1.fde) {
3206 exit_server("failed to create smbd_server_connection fde");
3214 frame = talloc_stackframe_pool(8192);
3218 status = smbd_server_connection_loop_once(sconn);
3219 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3220 !NT_STATUS_IS_OK(status)) {
3221 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3222 " exiting\n", nt_errstr(status)));
3229 exit_server_cleanly(NULL);
3232 bool req_is_in_chain(struct smb_request *req)
3234 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3236 * We're right now handling a subsequent request, so we must
3242 if (!is_andx_req(req->cmd)) {
3248 * Okay, an illegal request, but definitely not chained :-)
3253 return (CVAL(req->vwv+0, 0) != 0xFF);