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"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
43 extern bool global_machine_password_needs_changing;
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list {
47 struct pending_message_list *next, *prev;
48 struct timeval request_time; /* When was this first issued? */
49 struct smbd_server_connection *sconn;
50 struct timed_event *te;
51 struct smb_perfcount_data pcd;
56 DATA_BLOB private_data;
59 static void construct_reply_common(struct smb_request *req, const char *inbuf,
61 static struct pending_message_list *get_deferred_open_message_smb(
62 struct smbd_server_connection *sconn, uint64_t mid);
64 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
68 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
72 sconn->smb1.echo_handler.ref_count++;
74 if (sconn->smb1.echo_handler.ref_count > 1) {
78 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
82 sconn->smb1.echo_handler.socket_lock_fd,
83 SMB_F_SETLKW, 0, 0, F_WRLCK);
84 } while (!ok && (errno == EINTR));
87 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
91 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
96 void smbd_lock_socket(struct smbd_server_connection *sconn)
98 if (!smbd_lock_socket_internal(sconn)) {
99 exit_server_cleanly("failed to lock socket");
103 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
107 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
111 sconn->smb1.echo_handler.ref_count--;
113 if (sconn->smb1.echo_handler.ref_count > 0) {
119 sconn->smb1.echo_handler.socket_lock_fd,
120 SMB_F_SETLKW, 0, 0, F_UNLCK);
121 } while (!ok && (errno == EINTR));
124 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
128 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
133 void smbd_unlock_socket(struct smbd_server_connection *sconn)
135 if (!smbd_unlock_socket_internal(sconn)) {
136 exit_server_cleanly("failed to unlock socket");
140 /* Accessor function for smb_read_error for smbd functions. */
142 /****************************************************************************
144 ****************************************************************************/
146 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
147 bool do_signing, uint32_t seqnum,
149 struct smb_perfcount_data *pcd)
154 char *buf_out = buffer;
156 smbd_lock_socket(sconn);
159 /* Sign the outgoing packet if required. */
160 srv_calculate_sign_mac(sconn, buf_out, seqnum);
164 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
165 if (!NT_STATUS_IS_OK(status)) {
166 DEBUG(0, ("send_smb: SMB encryption failed "
167 "on outgoing packet! Error %s\n",
168 nt_errstr(status) ));
173 len = smb_len(buf_out) + 4;
175 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
178 char addr[INET6_ADDRSTRLEN];
180 * Try and give an error message saying what
183 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
184 (int)sys_getpid(), (int)len,
185 get_peer_addr(sconn->sock, addr, sizeof(addr)),
186 (int)ret, strerror(errno) ));
188 srv_free_enc_buffer(sconn, buf_out);
192 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
193 srv_free_enc_buffer(sconn, buf_out);
195 SMB_PERFCOUNT_END(pcd);
197 smbd_unlock_socket(sconn);
201 /*******************************************************************
202 Setup the word count and byte count for a smb message.
203 ********************************************************************/
205 int srv_set_message(char *buf,
210 if (zero && (num_words || num_bytes)) {
211 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
213 SCVAL(buf,smb_wct,num_words);
214 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
215 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
216 return (smb_size + num_words*2 + num_bytes);
219 static bool valid_smb_header(struct smbd_server_connection *sconn,
220 const uint8_t *inbuf)
222 if (is_encrypted_packet(sconn, inbuf)) {
226 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
227 * but it just looks weird to call strncmp for this one.
229 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
232 /* Socket functions for smbd packet processing. */
234 static bool valid_packet_size(size_t len)
237 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
238 * of header. Don't print the error if this fits.... JRA.
241 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
242 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
243 (unsigned long)len));
249 static NTSTATUS read_packet_remainder(int fd, char *buffer,
250 unsigned int timeout, ssize_t len)
258 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
259 if (!NT_STATUS_IS_OK(status)) {
260 char addr[INET6_ADDRSTRLEN];
261 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
263 get_peer_addr(fd, addr, sizeof(addr)),
269 /****************************************************************************
270 Attempt a zerocopy writeX read. We know here that len > smb_size-4
271 ****************************************************************************/
274 * Unfortunately, earlier versions of smbclient/libsmbclient
275 * don't send this "standard" writeX header. I've fixed this
276 * for 3.2 but we'll use the old method with earlier versions.
277 * Windows and CIFSFS at least use this standard size. Not
281 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
282 (2*14) + /* word count (including bcc) */ \
285 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
286 const char lenbuf[4],
287 struct smbd_server_connection *sconn,
290 unsigned int timeout,
294 /* Size of a WRITEX call (+4 byte len). */
295 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
296 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
300 memcpy(writeX_header, lenbuf, 4);
302 status = read_fd_with_timeout(
303 sock, writeX_header + 4,
304 STANDARD_WRITE_AND_X_HEADER_SIZE,
305 STANDARD_WRITE_AND_X_HEADER_SIZE,
308 if (!NT_STATUS_IS_OK(status)) {
309 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
311 tsocket_address_string(sconn->remote_address,
318 * Ok - now try and see if this is a possible
322 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
324 * If the data offset is beyond what
325 * we've read, drain the extra bytes.
327 uint16_t doff = SVAL(writeX_header,smb_vwv11);
330 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
331 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
332 if (drain_socket(sock, drain) != drain) {
333 smb_panic("receive_smb_raw_talloc_partial_read:"
334 " failed to drain pending bytes");
337 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
340 /* Spoof down the length and null out the bcc. */
341 set_message_bcc(writeX_header, 0);
342 newlen = smb_len(writeX_header);
344 /* Copy the header we've written. */
346 *buffer = (char *)talloc_memdup(mem_ctx,
348 sizeof(writeX_header));
350 if (*buffer == NULL) {
351 DEBUG(0, ("Could not allocate inbuf of length %d\n",
352 (int)sizeof(writeX_header)));
353 return NT_STATUS_NO_MEMORY;
356 /* Work out the remaining bytes. */
357 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
358 *len_ret = newlen + 4;
362 if (!valid_packet_size(len)) {
363 return NT_STATUS_INVALID_PARAMETER;
367 * Not a valid writeX call. Just do the standard
371 *buffer = talloc_array(mem_ctx, char, len+4);
373 if (*buffer == NULL) {
374 DEBUG(0, ("Could not allocate inbuf of length %d\n",
376 return NT_STATUS_NO_MEMORY;
379 /* Copy in what we already read. */
382 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
383 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
386 status = read_packet_remainder(
388 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
391 if (!NT_STATUS_IS_OK(status)) {
392 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
402 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
403 struct smbd_server_connection *sconn,
405 char **buffer, unsigned int timeout,
406 size_t *p_unread, size_t *plen)
410 int min_recv_size = lp_min_receive_file_size();
415 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
417 if (!NT_STATUS_IS_OK(status)) {
421 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
422 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
423 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
424 !srv_is_signing_active(sconn) &&
425 sconn->smb1.echo_handler.trusted_fde == NULL) {
427 return receive_smb_raw_talloc_partial_read(
428 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
432 if (!valid_packet_size(len)) {
433 return NT_STATUS_INVALID_PARAMETER;
437 * The +4 here can't wrap, we've checked the length above already.
440 *buffer = talloc_array(mem_ctx, char, len+4);
442 if (*buffer == NULL) {
443 DEBUG(0, ("Could not allocate inbuf of length %d\n",
445 return NT_STATUS_NO_MEMORY;
448 memcpy(*buffer, lenbuf, sizeof(lenbuf));
450 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
451 if (!NT_STATUS_IS_OK(status)) {
459 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
460 struct smbd_server_connection *sconn,
462 char **buffer, unsigned int timeout,
463 size_t *p_unread, bool *p_encrypted,
466 bool trusted_channel)
471 *p_encrypted = false;
473 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
475 if (!NT_STATUS_IS_OK(status)) {
476 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
477 ("receive_smb_raw_talloc failed for client %s "
478 "read error = %s.\n",
479 tsocket_address_string(sconn->remote_address,
481 nt_errstr(status)) );
485 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
486 status = srv_decrypt_buffer(sconn, *buffer);
487 if (!NT_STATUS_IS_OK(status)) {
488 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
489 "incoming packet! Error %s\n",
490 nt_errstr(status) ));
496 /* Check the incoming SMB signature. */
497 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
498 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
499 "incoming packet!\n"));
500 return NT_STATUS_INVALID_NETWORK_RESPONSE;
508 * Initialize a struct smb_request from an inbuf
511 static bool init_smb_request(struct smb_request *req,
512 struct smbd_server_connection *sconn,
514 size_t unread_bytes, bool encrypted,
517 size_t req_size = smb_len(inbuf) + 4;
518 /* Ensure we have at least smb_size bytes. */
519 if (req_size < smb_size) {
520 DEBUG(0,("init_smb_request: invalid request size %u\n",
521 (unsigned int)req_size ));
524 req->cmd = CVAL(inbuf, smb_com);
525 req->flags2 = SVAL(inbuf, smb_flg2);
526 req->smbpid = SVAL(inbuf, smb_pid);
527 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
528 req->seqnum = seqnum;
529 req->vuid = SVAL(inbuf, smb_uid);
530 req->tid = SVAL(inbuf, smb_tid);
531 req->wct = CVAL(inbuf, smb_wct);
532 req->vwv = discard_const_p(uint16_t, (inbuf+smb_vwv));
533 req->buflen = smb_buflen(inbuf);
534 req->buf = (const uint8_t *)smb_buf_const(inbuf);
535 req->unread_bytes = unread_bytes;
536 req->encrypted = encrypted;
538 req->conn = conn_find(sconn,req->tid);
539 req->chain_fsp = NULL;
540 req->chain_outbuf = NULL;
543 smb_init_perfcount_data(&req->pcd);
545 /* Ensure we have at least wct words and 2 bytes of bcc. */
546 if (smb_size + req->wct*2 > req_size) {
547 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
548 (unsigned int)req->wct,
549 (unsigned int)req_size));
552 /* Ensure bcc is correct. */
553 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
554 DEBUG(0,("init_smb_request: invalid bcc number %u "
555 "(wct = %u, size %u)\n",
556 (unsigned int)req->buflen,
557 (unsigned int)req->wct,
558 (unsigned int)req_size));
566 static void process_smb(struct smbd_server_connection *conn,
567 uint8_t *inbuf, size_t nread, size_t unread_bytes,
568 uint32_t seqnum, bool encrypted,
569 struct smb_perfcount_data *deferred_pcd);
571 static void smbd_deferred_open_timer(struct event_context *ev,
572 struct timed_event *te,
573 struct timeval _tval,
576 struct pending_message_list *msg = talloc_get_type(private_data,
577 struct pending_message_list);
578 struct smbd_server_connection *sconn = msg->sconn;
579 TALLOC_CTX *mem_ctx = talloc_tos();
580 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
583 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
586 exit_server("smbd_deferred_open_timer: talloc failed\n");
590 /* We leave this message on the queue so the open code can
591 know this is a retry. */
592 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
593 (unsigned long long)mid ));
595 /* Mark the message as processed so this is not
596 * re-processed in error. */
597 msg->processed = true;
599 process_smb(sconn, inbuf,
601 msg->seqnum, msg->encrypted, &msg->pcd);
603 /* If it's still there and was processed, remove it. */
604 msg = get_deferred_open_message_smb(sconn, mid);
605 if (msg && msg->processed) {
606 remove_deferred_open_message_smb(sconn, mid);
610 /****************************************************************************
611 Function to push a message onto the tail of a linked list of smb messages ready
613 ****************************************************************************/
615 static bool push_queued_message(struct smb_request *req,
616 struct timeval request_time,
617 struct timeval end_time,
618 char *private_data, size_t private_len)
620 int msg_len = smb_len(req->inbuf) + 4;
621 struct pending_message_list *msg;
623 msg = talloc_zero(NULL, struct pending_message_list);
626 DEBUG(0,("push_message: malloc fail (1)\n"));
629 msg->sconn = req->sconn;
631 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
632 if(msg->buf.data == NULL) {
633 DEBUG(0,("push_message: malloc fail (2)\n"));
638 msg->request_time = request_time;
639 msg->seqnum = req->seqnum;
640 msg->encrypted = req->encrypted;
641 msg->processed = false;
642 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
645 msg->private_data = data_blob_talloc(msg, private_data,
647 if (msg->private_data.data == NULL) {
648 DEBUG(0,("push_message: malloc fail (3)\n"));
654 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
657 smbd_deferred_open_timer,
660 DEBUG(0,("push_message: event_add_timed failed\n"));
665 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
666 struct pending_message_list *);
668 DEBUG(10,("push_message: pushed message length %u on "
669 "deferred_open_queue\n", (unsigned int)msg_len));
674 /****************************************************************************
675 Function to delete a sharing violation open message by mid.
676 ****************************************************************************/
678 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
681 struct pending_message_list *pml;
683 if (sconn->using_smb2) {
684 remove_deferred_open_message_smb2(sconn, mid);
688 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
689 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
690 DEBUG(10,("remove_deferred_open_message_smb: "
691 "deleting mid %llu len %u\n",
692 (unsigned long long)mid,
693 (unsigned int)pml->buf.length ));
694 DLIST_REMOVE(sconn->deferred_open_queue, pml);
701 /****************************************************************************
702 Move a sharing violation open retry message to the front of the list and
703 schedule it for immediate processing.
704 ****************************************************************************/
706 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
709 struct pending_message_list *pml;
712 if (sconn->using_smb2) {
713 schedule_deferred_open_message_smb2(sconn, mid);
717 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
718 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
720 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
723 (unsigned long long)msg_mid ));
725 if (mid == msg_mid) {
726 struct timed_event *te;
728 if (pml->processed) {
729 /* A processed message should not be
731 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
732 "message mid %llu was already processed\n",
733 (unsigned long long)msg_mid ));
737 DEBUG(10,("schedule_deferred_open_message_smb: "
738 "scheduling mid %llu\n",
739 (unsigned long long)mid ));
741 te = tevent_add_timer(pml->sconn->ev_ctx,
744 smbd_deferred_open_timer,
747 DEBUG(10,("schedule_deferred_open_message_smb: "
748 "event_add_timed() failed, "
749 "skipping mid %llu\n",
750 (unsigned long long)msg_mid ));
753 TALLOC_FREE(pml->te);
755 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
760 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
761 "find message mid %llu\n",
762 (unsigned long long)mid ));
765 /****************************************************************************
766 Return true if this mid is on the deferred queue and was not yet processed.
767 ****************************************************************************/
769 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
771 struct pending_message_list *pml;
773 if (sconn->using_smb2) {
774 return open_was_deferred_smb2(sconn, mid);
777 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
778 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
785 /****************************************************************************
786 Return the message queued by this mid.
787 ****************************************************************************/
789 static struct pending_message_list *get_deferred_open_message_smb(
790 struct smbd_server_connection *sconn, uint64_t mid)
792 struct pending_message_list *pml;
794 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
795 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
802 /****************************************************************************
803 Get the state data queued by this mid.
804 ****************************************************************************/
806 bool get_deferred_open_message_state(struct smb_request *smbreq,
807 struct timeval *p_request_time,
810 struct pending_message_list *pml;
812 if (smbreq->sconn->using_smb2) {
813 return get_deferred_open_message_state_smb2(smbreq->smb2req,
818 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
822 if (p_request_time) {
823 *p_request_time = pml->request_time;
826 *pp_state = (void *)pml->private_data.data;
831 /****************************************************************************
832 Function to push a deferred open smb message onto a linked list of local smb
833 messages ready for processing.
834 ****************************************************************************/
836 bool push_deferred_open_message_smb(struct smb_request *req,
837 struct timeval request_time,
838 struct timeval timeout,
840 char *private_data, size_t priv_len)
842 struct timeval end_time;
845 return push_deferred_open_message_smb2(req->smb2req,
853 if (req->unread_bytes) {
854 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
855 "unread_bytes = %u\n",
856 (unsigned int)req->unread_bytes ));
857 smb_panic("push_deferred_open_message_smb: "
858 "logic error unread_bytes != 0" );
861 end_time = timeval_sum(&request_time, &timeout);
863 DEBUG(10,("push_deferred_open_message_smb: pushing message "
864 "len %u mid %llu timeout time [%u.%06u]\n",
865 (unsigned int) smb_len(req->inbuf)+4,
866 (unsigned long long)req->mid,
867 (unsigned int)end_time.tv_sec,
868 (unsigned int)end_time.tv_usec));
870 return push_queued_message(req, request_time, end_time,
871 private_data, priv_len);
874 static void smbd_sig_term_handler(struct tevent_context *ev,
875 struct tevent_signal *se,
881 exit_server_cleanly("termination signal");
884 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
886 struct tevent_signal *se;
888 se = tevent_add_signal(sconn->ev_ctx,
891 smbd_sig_term_handler,
894 exit_server("failed to setup SIGTERM handler");
898 static void smbd_sig_hup_handler(struct tevent_context *ev,
899 struct tevent_signal *se,
905 struct smbd_server_connection *sconn =
906 talloc_get_type_abort(private_data,
907 struct smbd_server_connection);
909 change_to_root_user();
910 DEBUG(1,("Reloading services after SIGHUP\n"));
911 reload_services(sconn->msg_ctx, sconn->sock, false);
914 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
916 struct tevent_signal *se;
918 se = tevent_add_signal(sconn->ev_ctx,
921 smbd_sig_hup_handler,
924 exit_server("failed to setup SIGHUP handler");
928 static NTSTATUS smbd_server_connection_loop_once(struct tevent_context *ev_ctx,
929 struct smbd_server_connection *conn)
936 timeout = SMBD_SELECT_TIMEOUT * 1000;
939 * Are there any timed events waiting ? If so, ensure we don't
940 * select for longer than it would take to wait for them.
943 event_add_to_poll_args(ev_ctx, conn, &conn->pfds, &num_pfds, &timeout);
945 /* Process a signal and timed events now... */
946 if (run_events_poll(ev_ctx, 0, NULL, 0)) {
947 return NT_STATUS_RETRY;
952 START_PROFILE(smbd_idle);
954 ret = sys_poll(conn->pfds, num_pfds, timeout);
957 END_PROFILE(smbd_idle);
962 if (errno == EINTR) {
963 return NT_STATUS_RETRY;
965 return map_nt_error_from_unix(errno);
968 retry = run_events_poll(ev_ctx, ret, conn->pfds, num_pfds);
970 return NT_STATUS_RETRY;
973 /* Did we timeout ? */
975 return NT_STATUS_RETRY;
978 /* should not be reached */
979 return NT_STATUS_INTERNAL_ERROR;
983 * Only allow 5 outstanding trans requests. We're allocating memory, so
987 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
990 for (; list != NULL; list = list->next) {
992 if (list->mid == mid) {
993 return NT_STATUS_INVALID_PARAMETER;
999 return NT_STATUS_INSUFFICIENT_RESOURCES;
1002 return NT_STATUS_OK;
1006 These flags determine some of the permissions required to do an operation
1008 Note that I don't set NEED_WRITE on some write operations because they
1009 are used by some brain-dead clients when printing, and I don't want to
1010 force write permissions on print services.
1012 #define AS_USER (1<<0)
1013 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1014 #define TIME_INIT (1<<2)
1015 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1016 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1017 #define DO_CHDIR (1<<6)
1020 define a list of possible SMB messages and their corresponding
1021 functions. Any message that has a NULL function is unimplemented -
1022 please feel free to contribute implementations!
1024 static const struct smb_message_struct {
1026 void (*fn)(struct smb_request *req);
1028 } smb_messages[256] = {
1030 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1031 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1032 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1033 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1034 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1035 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1036 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1037 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1038 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1039 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1040 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1041 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1042 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1043 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1044 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1045 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1046 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1047 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1048 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1049 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1050 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1051 /* 0x15 */ { NULL, NULL, 0 },
1052 /* 0x16 */ { NULL, NULL, 0 },
1053 /* 0x17 */ { NULL, NULL, 0 },
1054 /* 0x18 */ { NULL, NULL, 0 },
1055 /* 0x19 */ { NULL, NULL, 0 },
1056 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1057 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1058 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1059 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1060 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1061 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1062 /* 0x20 */ { "SMBwritec", NULL,0},
1063 /* 0x21 */ { NULL, NULL, 0 },
1064 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1065 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1066 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1067 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1068 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1069 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1070 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1071 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1072 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1073 /* 0x2b */ { "SMBecho",reply_echo,0},
1074 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1075 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1076 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1077 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1078 /* 0x30 */ { NULL, NULL, 0 },
1079 /* 0x31 */ { NULL, NULL, 0 },
1080 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1081 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1082 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1083 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1084 /* 0x36 */ { NULL, NULL, 0 },
1085 /* 0x37 */ { NULL, NULL, 0 },
1086 /* 0x38 */ { NULL, NULL, 0 },
1087 /* 0x39 */ { NULL, NULL, 0 },
1088 /* 0x3a */ { NULL, NULL, 0 },
1089 /* 0x3b */ { NULL, NULL, 0 },
1090 /* 0x3c */ { NULL, NULL, 0 },
1091 /* 0x3d */ { NULL, NULL, 0 },
1092 /* 0x3e */ { NULL, NULL, 0 },
1093 /* 0x3f */ { NULL, NULL, 0 },
1094 /* 0x40 */ { NULL, NULL, 0 },
1095 /* 0x41 */ { NULL, NULL, 0 },
1096 /* 0x42 */ { NULL, NULL, 0 },
1097 /* 0x43 */ { NULL, NULL, 0 },
1098 /* 0x44 */ { NULL, NULL, 0 },
1099 /* 0x45 */ { NULL, NULL, 0 },
1100 /* 0x46 */ { NULL, NULL, 0 },
1101 /* 0x47 */ { NULL, NULL, 0 },
1102 /* 0x48 */ { NULL, NULL, 0 },
1103 /* 0x49 */ { NULL, NULL, 0 },
1104 /* 0x4a */ { NULL, NULL, 0 },
1105 /* 0x4b */ { NULL, NULL, 0 },
1106 /* 0x4c */ { NULL, NULL, 0 },
1107 /* 0x4d */ { NULL, NULL, 0 },
1108 /* 0x4e */ { NULL, NULL, 0 },
1109 /* 0x4f */ { NULL, NULL, 0 },
1110 /* 0x50 */ { NULL, NULL, 0 },
1111 /* 0x51 */ { NULL, NULL, 0 },
1112 /* 0x52 */ { NULL, NULL, 0 },
1113 /* 0x53 */ { NULL, NULL, 0 },
1114 /* 0x54 */ { NULL, NULL, 0 },
1115 /* 0x55 */ { NULL, NULL, 0 },
1116 /* 0x56 */ { NULL, NULL, 0 },
1117 /* 0x57 */ { NULL, NULL, 0 },
1118 /* 0x58 */ { NULL, NULL, 0 },
1119 /* 0x59 */ { NULL, NULL, 0 },
1120 /* 0x5a */ { NULL, NULL, 0 },
1121 /* 0x5b */ { NULL, NULL, 0 },
1122 /* 0x5c */ { NULL, NULL, 0 },
1123 /* 0x5d */ { NULL, NULL, 0 },
1124 /* 0x5e */ { NULL, NULL, 0 },
1125 /* 0x5f */ { NULL, NULL, 0 },
1126 /* 0x60 */ { NULL, NULL, 0 },
1127 /* 0x61 */ { NULL, NULL, 0 },
1128 /* 0x62 */ { NULL, NULL, 0 },
1129 /* 0x63 */ { NULL, NULL, 0 },
1130 /* 0x64 */ { NULL, NULL, 0 },
1131 /* 0x65 */ { NULL, NULL, 0 },
1132 /* 0x66 */ { NULL, NULL, 0 },
1133 /* 0x67 */ { NULL, NULL, 0 },
1134 /* 0x68 */ { NULL, NULL, 0 },
1135 /* 0x69 */ { NULL, NULL, 0 },
1136 /* 0x6a */ { NULL, NULL, 0 },
1137 /* 0x6b */ { NULL, NULL, 0 },
1138 /* 0x6c */ { NULL, NULL, 0 },
1139 /* 0x6d */ { NULL, NULL, 0 },
1140 /* 0x6e */ { NULL, NULL, 0 },
1141 /* 0x6f */ { NULL, NULL, 0 },
1142 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1143 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1144 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1145 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1146 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1147 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1148 /* 0x76 */ { NULL, NULL, 0 },
1149 /* 0x77 */ { NULL, NULL, 0 },
1150 /* 0x78 */ { NULL, NULL, 0 },
1151 /* 0x79 */ { NULL, NULL, 0 },
1152 /* 0x7a */ { NULL, NULL, 0 },
1153 /* 0x7b */ { NULL, NULL, 0 },
1154 /* 0x7c */ { NULL, NULL, 0 },
1155 /* 0x7d */ { NULL, NULL, 0 },
1156 /* 0x7e */ { NULL, NULL, 0 },
1157 /* 0x7f */ { NULL, NULL, 0 },
1158 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1159 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1160 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1161 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1162 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1163 /* 0x85 */ { NULL, NULL, 0 },
1164 /* 0x86 */ { NULL, NULL, 0 },
1165 /* 0x87 */ { NULL, NULL, 0 },
1166 /* 0x88 */ { NULL, NULL, 0 },
1167 /* 0x89 */ { NULL, NULL, 0 },
1168 /* 0x8a */ { NULL, NULL, 0 },
1169 /* 0x8b */ { NULL, NULL, 0 },
1170 /* 0x8c */ { NULL, NULL, 0 },
1171 /* 0x8d */ { NULL, NULL, 0 },
1172 /* 0x8e */ { NULL, NULL, 0 },
1173 /* 0x8f */ { NULL, NULL, 0 },
1174 /* 0x90 */ { NULL, NULL, 0 },
1175 /* 0x91 */ { NULL, NULL, 0 },
1176 /* 0x92 */ { NULL, NULL, 0 },
1177 /* 0x93 */ { NULL, NULL, 0 },
1178 /* 0x94 */ { NULL, NULL, 0 },
1179 /* 0x95 */ { NULL, NULL, 0 },
1180 /* 0x96 */ { NULL, NULL, 0 },
1181 /* 0x97 */ { NULL, NULL, 0 },
1182 /* 0x98 */ { NULL, NULL, 0 },
1183 /* 0x99 */ { NULL, NULL, 0 },
1184 /* 0x9a */ { NULL, NULL, 0 },
1185 /* 0x9b */ { NULL, NULL, 0 },
1186 /* 0x9c */ { NULL, NULL, 0 },
1187 /* 0x9d */ { NULL, NULL, 0 },
1188 /* 0x9e */ { NULL, NULL, 0 },
1189 /* 0x9f */ { NULL, NULL, 0 },
1190 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1191 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1192 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1193 /* 0xa3 */ { NULL, NULL, 0 },
1194 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1195 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1196 /* 0xa6 */ { NULL, NULL, 0 },
1197 /* 0xa7 */ { NULL, NULL, 0 },
1198 /* 0xa8 */ { NULL, NULL, 0 },
1199 /* 0xa9 */ { NULL, NULL, 0 },
1200 /* 0xaa */ { NULL, NULL, 0 },
1201 /* 0xab */ { NULL, NULL, 0 },
1202 /* 0xac */ { NULL, NULL, 0 },
1203 /* 0xad */ { NULL, NULL, 0 },
1204 /* 0xae */ { NULL, NULL, 0 },
1205 /* 0xaf */ { NULL, NULL, 0 },
1206 /* 0xb0 */ { NULL, NULL, 0 },
1207 /* 0xb1 */ { NULL, NULL, 0 },
1208 /* 0xb2 */ { NULL, NULL, 0 },
1209 /* 0xb3 */ { NULL, NULL, 0 },
1210 /* 0xb4 */ { NULL, NULL, 0 },
1211 /* 0xb5 */ { NULL, NULL, 0 },
1212 /* 0xb6 */ { NULL, NULL, 0 },
1213 /* 0xb7 */ { NULL, NULL, 0 },
1214 /* 0xb8 */ { NULL, NULL, 0 },
1215 /* 0xb9 */ { NULL, NULL, 0 },
1216 /* 0xba */ { NULL, NULL, 0 },
1217 /* 0xbb */ { NULL, NULL, 0 },
1218 /* 0xbc */ { NULL, NULL, 0 },
1219 /* 0xbd */ { NULL, NULL, 0 },
1220 /* 0xbe */ { NULL, NULL, 0 },
1221 /* 0xbf */ { NULL, NULL, 0 },
1222 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1223 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1224 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1225 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1226 /* 0xc4 */ { NULL, NULL, 0 },
1227 /* 0xc5 */ { NULL, NULL, 0 },
1228 /* 0xc6 */ { NULL, NULL, 0 },
1229 /* 0xc7 */ { NULL, NULL, 0 },
1230 /* 0xc8 */ { NULL, NULL, 0 },
1231 /* 0xc9 */ { NULL, NULL, 0 },
1232 /* 0xca */ { NULL, NULL, 0 },
1233 /* 0xcb */ { NULL, NULL, 0 },
1234 /* 0xcc */ { NULL, NULL, 0 },
1235 /* 0xcd */ { NULL, NULL, 0 },
1236 /* 0xce */ { NULL, NULL, 0 },
1237 /* 0xcf */ { NULL, NULL, 0 },
1238 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1239 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1240 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1241 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1242 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1243 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1244 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1245 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1246 /* 0xd8 */ { NULL, NULL, 0 },
1247 /* 0xd9 */ { NULL, NULL, 0 },
1248 /* 0xda */ { NULL, NULL, 0 },
1249 /* 0xdb */ { NULL, NULL, 0 },
1250 /* 0xdc */ { NULL, NULL, 0 },
1251 /* 0xdd */ { NULL, NULL, 0 },
1252 /* 0xde */ { NULL, NULL, 0 },
1253 /* 0xdf */ { NULL, NULL, 0 },
1254 /* 0xe0 */ { NULL, NULL, 0 },
1255 /* 0xe1 */ { NULL, NULL, 0 },
1256 /* 0xe2 */ { NULL, NULL, 0 },
1257 /* 0xe3 */ { NULL, NULL, 0 },
1258 /* 0xe4 */ { NULL, NULL, 0 },
1259 /* 0xe5 */ { NULL, NULL, 0 },
1260 /* 0xe6 */ { NULL, NULL, 0 },
1261 /* 0xe7 */ { NULL, NULL, 0 },
1262 /* 0xe8 */ { NULL, NULL, 0 },
1263 /* 0xe9 */ { NULL, NULL, 0 },
1264 /* 0xea */ { NULL, NULL, 0 },
1265 /* 0xeb */ { NULL, NULL, 0 },
1266 /* 0xec */ { NULL, NULL, 0 },
1267 /* 0xed */ { NULL, NULL, 0 },
1268 /* 0xee */ { NULL, NULL, 0 },
1269 /* 0xef */ { NULL, NULL, 0 },
1270 /* 0xf0 */ { NULL, NULL, 0 },
1271 /* 0xf1 */ { NULL, NULL, 0 },
1272 /* 0xf2 */ { NULL, NULL, 0 },
1273 /* 0xf3 */ { NULL, NULL, 0 },
1274 /* 0xf4 */ { NULL, NULL, 0 },
1275 /* 0xf5 */ { NULL, NULL, 0 },
1276 /* 0xf6 */ { NULL, NULL, 0 },
1277 /* 0xf7 */ { NULL, NULL, 0 },
1278 /* 0xf8 */ { NULL, NULL, 0 },
1279 /* 0xf9 */ { NULL, NULL, 0 },
1280 /* 0xfa */ { NULL, NULL, 0 },
1281 /* 0xfb */ { NULL, NULL, 0 },
1282 /* 0xfc */ { NULL, NULL, 0 },
1283 /* 0xfd */ { NULL, NULL, 0 },
1284 /* 0xfe */ { NULL, NULL, 0 },
1285 /* 0xff */ { NULL, NULL, 0 }
1289 /*******************************************************************
1290 allocate and initialize a reply packet
1291 ********************************************************************/
1293 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1294 const char *inbuf, char **outbuf, uint8_t num_words,
1298 * Protect against integer wrap
1300 if ((num_bytes > 0xffffff)
1301 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1303 if (asprintf(&msg, "num_bytes too large: %u",
1304 (unsigned)num_bytes) == -1) {
1305 msg = discard_const_p(char, "num_bytes too large");
1310 *outbuf = talloc_array(mem_ctx, char,
1311 smb_size + num_words*2 + num_bytes);
1312 if (*outbuf == NULL) {
1316 construct_reply_common(req, inbuf, *outbuf);
1317 srv_set_message(*outbuf, num_words, num_bytes, false);
1319 * Zero out the word area, the caller has to take care of the bcc area
1322 if (num_words != 0) {
1323 memset(*outbuf + smb_vwv0, 0, num_words*2);
1329 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1332 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1334 smb_panic("could not allocate output buffer\n");
1336 req->outbuf = (uint8_t *)outbuf;
1340 /*******************************************************************
1341 Dump a packet to a file.
1342 ********************************************************************/
1344 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1348 if (DEBUGLEVEL < 50) {
1352 if (len < 4) len = smb_len(data)+4;
1353 for (i=1;i<100;i++) {
1354 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1355 type ? "req" : "resp") == -1) {
1358 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1359 if (fd != -1 || errno != EEXIST) break;
1362 ssize_t ret = write(fd, data, len);
1364 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1366 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1371 /****************************************************************************
1372 Prepare everything for calling the actual request function, and potentially
1373 call the request function via the "new" interface.
1375 Return False if the "legacy" function needs to be called, everything is
1378 Return True if we're done.
1380 I know this API sucks, but it is the one with the least code change I could
1382 ****************************************************************************/
1384 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1388 connection_struct *conn = NULL;
1389 struct smbd_server_connection *sconn = req->sconn;
1394 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1395 * so subtract 4 from it. */
1396 if (!valid_smb_header(sconn, req->inbuf)
1397 || (size < (smb_size - 4))) {
1398 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1399 smb_len(req->inbuf)));
1400 exit_server_cleanly("Non-SMB packet");
1403 if (smb_messages[type].fn == NULL) {
1404 DEBUG(0,("Unknown message type %d!\n",type));
1405 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1406 reply_unknown_new(req, type);
1410 flags = smb_messages[type].flags;
1412 /* In share mode security we must ignore the vuid. */
1413 session_tag = (lp_security() == SEC_SHARE)
1414 ? UID_FIELD_INVALID : req->vuid;
1417 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1418 (int)sys_getpid(), (unsigned long)conn));
1420 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1422 /* Ensure this value is replaced in the incoming packet. */
1423 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1426 * Ensure the correct username is in current_user_info. This is a
1427 * really ugly bugfix for problems with multiple session_setup_and_X's
1428 * being done and allowing %U and %G substitutions to work correctly.
1429 * There is a reason this code is done here, don't move it unless you
1430 * know what you're doing... :-).
1434 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1435 user_struct *vuser = NULL;
1437 sconn->smb1.sessions.last_session_tag = session_tag;
1438 if(session_tag != UID_FIELD_INVALID) {
1439 vuser = get_valid_user_struct(sconn, session_tag);
1441 set_current_user_info(
1442 vuser->session_info->unix_info->sanitized_username,
1443 vuser->session_info->unix_info->unix_name,
1444 vuser->session_info->info->domain_name);
1449 /* Does this call need to be run as the connected user? */
1450 if (flags & AS_USER) {
1452 /* Does this call need a valid tree connection? */
1455 * Amazingly, the error code depends on the command
1458 if (type == SMBntcreateX) {
1459 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1461 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1466 if (!change_to_user(conn,session_tag)) {
1467 DEBUG(0, ("Error: Could not change to user. Removing "
1468 "deferred open, mid=%llu.\n",
1469 (unsigned long long)req->mid));
1470 reply_force_doserror(req, ERRSRV, ERRbaduid);
1474 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1476 /* Does it need write permission? */
1477 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1478 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1482 /* IPC services are limited */
1483 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1484 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1488 /* This call needs to be run as root */
1489 change_to_root_user();
1492 /* load service specific parameters */
1494 if (req->encrypted) {
1495 conn->encrypted_tid = true;
1496 /* encrypted required from now on. */
1497 conn->encrypt_level = Required;
1498 } else if (ENCRYPTION_REQUIRED(conn)) {
1499 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1500 exit_server_cleanly("encryption required "
1506 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1507 (flags & (AS_USER|DO_CHDIR)
1509 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1512 conn->num_smb_operations++;
1515 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1517 if (raddr == NULL) {
1518 reply_nterror(req, NT_STATUS_NO_MEMORY);
1522 /* does this protocol need to be run as guest? */
1523 if ((flags & AS_GUEST)
1524 && (!change_to_guest() ||
1525 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1526 sconn->remote_hostname,
1528 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1532 smb_messages[type].fn(req);
1536 /****************************************************************************
1537 Construct a reply to the incoming packet.
1538 ****************************************************************************/
1540 static void construct_reply(struct smbd_server_connection *sconn,
1541 char *inbuf, int size, size_t unread_bytes,
1542 uint32_t seqnum, bool encrypted,
1543 struct smb_perfcount_data *deferred_pcd)
1545 connection_struct *conn;
1546 struct smb_request *req;
1548 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1549 smb_panic("could not allocate smb_request");
1552 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1553 encrypted, seqnum)) {
1554 exit_server_cleanly("Invalid SMB request");
1557 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1559 /* we popped this message off the queue - keep original perf data */
1561 req->pcd = *deferred_pcd;
1563 SMB_PERFCOUNT_START(&req->pcd);
1564 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1565 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1568 conn = switch_message(req->cmd, req, size);
1570 if (req->unread_bytes) {
1571 /* writeX failed. drain socket. */
1572 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1573 req->unread_bytes) {
1574 smb_panic("failed to drain pending bytes");
1576 req->unread_bytes = 0;
1584 if (req->outbuf == NULL) {
1588 if (CVAL(req->outbuf,0) == 0) {
1589 show_msg((char *)req->outbuf);
1592 if (!srv_send_smb(req->sconn,
1593 (char *)req->outbuf,
1594 true, req->seqnum+1,
1595 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1597 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1605 /****************************************************************************
1606 Process an smb from the client
1607 ****************************************************************************/
1608 static void process_smb(struct smbd_server_connection *sconn,
1609 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1610 uint32_t seqnum, bool encrypted,
1611 struct smb_perfcount_data *deferred_pcd)
1613 int msg_type = CVAL(inbuf,0);
1615 DO_PROFILE_INC(smb_count);
1617 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1619 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1620 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1622 if (msg_type != NBSSmessage) {
1624 * NetBIOS session request, keepalive, etc.
1626 reply_special(sconn, (char *)inbuf, nread);
1630 if (sconn->using_smb2) {
1631 /* At this point we're not really using smb2,
1632 * we make the decision here.. */
1633 if (smbd_is_smb2_header(inbuf, nread)) {
1634 smbd_smb2_first_negprot(sconn, inbuf, nread);
1636 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1637 && CVAL(inbuf, smb_com) != 0x72) {
1638 /* This is a non-negprot SMB1 packet.
1639 Disable SMB2 from now on. */
1640 sconn->using_smb2 = false;
1644 show_msg((char *)inbuf);
1646 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1647 encrypted, deferred_pcd);
1651 sconn->num_requests++;
1653 /* The timeout_processing function isn't run nearly
1654 often enough to implement 'max log size' without
1655 overrunning the size of the file by many megabytes.
1656 This is especially true if we are running at debug
1657 level 10. Checking every 50 SMBs is a nice
1658 tradeoff of performance vs log file size overrun. */
1660 if ((sconn->num_requests % 50) == 0 &&
1661 need_to_check_log_size()) {
1662 change_to_root_user();
1667 /****************************************************************************
1668 Return a string containing the function name of a SMB command.
1669 ****************************************************************************/
1671 const char *smb_fn_name(int type)
1673 const char *unknown_name = "SMBunknown";
1675 if (smb_messages[type].name == NULL)
1676 return(unknown_name);
1678 return(smb_messages[type].name);
1681 /****************************************************************************
1682 Helper functions for contruct_reply.
1683 ****************************************************************************/
1685 void add_to_common_flags2(uint32 v)
1690 void remove_from_common_flags2(uint32 v)
1692 common_flags2 &= ~v;
1695 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1698 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1699 uint16_t out_flags2 = common_flags2;
1701 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1702 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1703 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1705 srv_set_message(outbuf,0,0,false);
1707 SCVAL(outbuf, smb_com, req->cmd);
1708 SIVAL(outbuf,smb_rcls,0);
1709 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1710 SSVAL(outbuf,smb_flg2, out_flags2);
1711 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1712 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1714 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1715 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1716 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1717 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1720 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1722 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1726 * How many bytes have we already accumulated up to the current wct field
1730 size_t req_wct_ofs(struct smb_request *req)
1734 if (req->chain_outbuf == NULL) {
1737 buf_size = talloc_get_size(req->chain_outbuf);
1738 if ((buf_size % 4) != 0) {
1739 buf_size += (4 - (buf_size % 4));
1741 return buf_size - 4;
1745 * Hack around reply_nterror & friends not being aware of chained requests,
1746 * generating illegal (i.e. wct==0) chain replies.
1749 static void fixup_chain_error_packet(struct smb_request *req)
1751 uint8_t *outbuf = req->outbuf;
1753 reply_outbuf(req, 2, 0);
1754 memcpy(req->outbuf, outbuf, smb_wct);
1755 TALLOC_FREE(outbuf);
1756 SCVAL(req->outbuf, smb_vwv0, 0xff);
1760 * @brief Find the smb_cmd offset of the last command pushed
1761 * @param[in] buf The buffer we're building up
1762 * @retval Where can we put our next andx cmd?
1764 * While chaining requests, the "next" request we're looking at needs to put
1765 * its SMB_Command before the data the previous request already built up added
1766 * to the chain. Find the offset to the place where we have to put our cmd.
1769 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1774 cmd = CVAL(buf, smb_com);
1776 SMB_ASSERT(is_andx_req(cmd));
1780 while (CVAL(buf, ofs) != 0xff) {
1782 if (!is_andx_req(CVAL(buf, ofs))) {
1787 * ofs is from start of smb header, so add the 4 length
1788 * bytes. The next cmd is right after the wct field.
1790 ofs = SVAL(buf, ofs+2) + 4 + 1;
1792 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1800 * @brief Do the smb chaining at a buffer level
1801 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1802 * @param[in] smb_command The command that we want to issue
1803 * @param[in] wct How many words?
1804 * @param[in] vwv The words, already in network order
1805 * @param[in] bytes_alignment How shall we align "bytes"?
1806 * @param[in] num_bytes How many bytes?
1807 * @param[in] bytes The data the request ships
1809 * smb_splice_chain() adds the vwv and bytes to the request already present in
1813 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1814 uint8_t wct, const uint16_t *vwv,
1815 size_t bytes_alignment,
1816 uint32_t num_bytes, const uint8_t *bytes)
1819 size_t old_size, new_size;
1821 size_t chain_padding = 0;
1822 size_t bytes_padding = 0;
1825 old_size = talloc_get_size(*poutbuf);
1828 * old_size == smb_wct means we're pushing the first request in for
1832 first_request = (old_size == smb_wct);
1834 if (!first_request && ((old_size % 4) != 0)) {
1836 * Align the wct field of subsequent requests to a 4-byte
1839 chain_padding = 4 - (old_size % 4);
1843 * After the old request comes the new wct field (1 byte), the vwv's
1844 * and the num_bytes field. After at we might need to align the bytes
1845 * given to us to "bytes_alignment", increasing the num_bytes value.
1848 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1850 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1851 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1854 new_size += bytes_padding + num_bytes;
1856 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1857 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1858 (unsigned)new_size));
1862 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1863 if (outbuf == NULL) {
1864 DEBUG(0, ("talloc failed\n"));
1869 if (first_request) {
1870 SCVAL(outbuf, smb_com, smb_command);
1872 size_t andx_cmd_ofs;
1874 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1875 DEBUG(1, ("invalid command chain\n"));
1876 *poutbuf = talloc_realloc(
1877 NULL, *poutbuf, uint8_t, old_size);
1881 if (chain_padding != 0) {
1882 memset(outbuf + old_size, 0, chain_padding);
1883 old_size += chain_padding;
1886 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1887 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1893 * Push the chained request:
1898 SCVAL(outbuf, ofs, wct);
1905 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1906 ofs += sizeof(uint16_t) * wct;
1912 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1913 ofs += sizeof(uint16_t);
1919 if (bytes_padding != 0) {
1920 memset(outbuf + ofs, 0, bytes_padding);
1921 ofs += bytes_padding;
1928 memcpy(outbuf + ofs, bytes, num_bytes);
1933 /****************************************************************************
1934 Construct a chained reply and add it to the already made reply
1935 ****************************************************************************/
1937 void chain_reply(struct smb_request *req)
1939 size_t smblen = smb_len(req->inbuf);
1940 size_t already_used, length_needed;
1942 uint32_t chain_offset; /* uint32_t to avoid overflow */
1945 const uint16_t *vwv;
1949 if (IVAL(req->outbuf, smb_rcls) != 0) {
1950 fixup_chain_error_packet(req);
1954 * Any of the AndX requests and replies have at least a wct of
1955 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1956 * beginning of the SMB header to the next wct field.
1958 * None of the AndX requests put anything valuable in vwv[0] and [1],
1959 * so we can overwrite it here to form the chain.
1962 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1963 if (req->chain_outbuf == NULL) {
1964 req->chain_outbuf = talloc_realloc(
1965 req, req->outbuf, uint8_t,
1966 smb_len(req->outbuf) + 4);
1967 if (req->chain_outbuf == NULL) {
1968 smb_panic("talloc failed");
1976 * Here we assume that this is the end of the chain. For that we need
1977 * to set "next command" to 0xff and the offset to 0. If we later find
1978 * more commands in the chain, this will be overwritten again.
1981 SCVAL(req->outbuf, smb_vwv0, 0xff);
1982 SCVAL(req->outbuf, smb_vwv0+1, 0);
1983 SSVAL(req->outbuf, smb_vwv1, 0);
1985 if (req->chain_outbuf == NULL) {
1987 * In req->chain_outbuf we collect all the replies. Start the
1988 * chain by copying in the first reply.
1990 * We do the realloc because later on we depend on
1991 * talloc_get_size to determine the length of
1992 * chain_outbuf. The reply_xxx routines might have
1993 * over-allocated (reply_pipe_read_and_X used to be such an
1996 req->chain_outbuf = talloc_realloc(
1997 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1998 if (req->chain_outbuf == NULL) {
1999 smb_panic("talloc failed");
2004 * Update smb headers where subsequent chained commands
2005 * may have updated them.
2007 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2008 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2010 if (!smb_splice_chain(&req->chain_outbuf,
2011 CVAL(req->outbuf, smb_com),
2012 CVAL(req->outbuf, smb_wct),
2013 (uint16_t *)(req->outbuf + smb_vwv),
2014 0, smb_buflen(req->outbuf),
2015 (uint8_t *)smb_buf(req->outbuf))) {
2018 TALLOC_FREE(req->outbuf);
2022 * We use the old request's vwv field to grab the next chained command
2023 * and offset into the chained fields.
2026 chain_cmd = CVAL(req->vwv+0, 0);
2027 chain_offset = SVAL(req->vwv+1, 0);
2029 if (chain_cmd == 0xff) {
2031 * End of chain, no more requests from the client. So ship the
2034 smb_setlen((char *)(req->chain_outbuf),
2035 talloc_get_size(req->chain_outbuf) - 4);
2037 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2038 true, req->seqnum+1,
2039 IS_CONN_ENCRYPTED(req->conn)
2042 exit_server_cleanly("chain_reply: srv_send_smb "
2045 TALLOC_FREE(req->chain_outbuf);
2050 /* add a new perfcounter for this element of chain */
2051 SMB_PERFCOUNT_ADD(&req->pcd);
2052 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2053 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2056 * Check if the client tries to fool us. The chain offset
2057 * needs to point beyond the current request in the chain, it
2058 * needs to strictly grow. Otherwise we might be tricked into
2059 * an endless loop always processing the same request over and
2060 * over again. We used to assume that vwv and the byte buffer
2061 * array in a chain are always attached, but OS/2 the
2062 * Write&X/Read&X chain puts the Read&X vwv array right behind
2063 * the Write&X vwv chain. The Write&X bcc array is put behind
2064 * the Read&X vwv array. So now we check whether the chain
2065 * offset points strictly behind the previous vwv
2066 * array. req->buf points right after the vwv array of the
2067 * previous request. See
2068 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2072 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2073 if (chain_offset <= already_used) {
2078 * Next check: Make sure the chain offset does not point beyond the
2079 * overall smb request length.
2082 length_needed = chain_offset+1; /* wct */
2083 if (length_needed > smblen) {
2088 * Now comes the pointer magic. Goal here is to set up req->vwv and
2089 * req->buf correctly again to be able to call the subsequent
2090 * switch_message(). The chain offset (the former vwv[1]) points at
2091 * the new wct field.
2094 wct = CVAL(smb_base(req->inbuf), chain_offset);
2097 * Next consistency check: Make the new vwv array fits in the overall
2101 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2102 if (length_needed > smblen) {
2105 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2108 * Now grab the new byte buffer....
2111 buflen = SVAL(vwv+wct, 0);
2114 * .. and check that it fits.
2117 length_needed += buflen;
2118 if (length_needed > smblen) {
2121 buf = (const uint8_t *)(vwv+wct+1);
2123 req->cmd = chain_cmd;
2125 req->vwv = discard_const_p(uint16_t, vwv);
2126 req->buflen = buflen;
2129 switch_message(chain_cmd, req, smblen);
2131 if (req->outbuf == NULL) {
2133 * This happens if the chained command has suspended itself or
2134 * if it has called srv_send_smb() itself.
2140 * We end up here if the chained command was not itself chained or
2141 * suspended, but for example a close() command. We now need to splice
2142 * the chained commands' outbuf into the already built up chain_outbuf
2143 * and ship the result.
2149 * We end up here if there's any error in the chain syntax. Report a
2150 * DOS error, just like Windows does.
2152 reply_force_doserror(req, ERRSRV, ERRerror);
2153 fixup_chain_error_packet(req);
2157 * This scary statement intends to set the
2158 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2159 * to the value req->outbuf carries
2161 SSVAL(req->chain_outbuf, smb_flg2,
2162 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2163 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2166 * Transfer the error codes from the subrequest to the main one
2168 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2169 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2171 if (!smb_splice_chain(&req->chain_outbuf,
2172 CVAL(req->outbuf, smb_com),
2173 CVAL(req->outbuf, smb_wct),
2174 (uint16_t *)(req->outbuf + smb_vwv),
2175 0, smb_buflen(req->outbuf),
2176 (uint8_t *)smb_buf(req->outbuf))) {
2177 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2179 TALLOC_FREE(req->outbuf);
2181 smb_setlen((char *)(req->chain_outbuf),
2182 talloc_get_size(req->chain_outbuf) - 4);
2184 show_msg((char *)(req->chain_outbuf));
2186 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2187 true, req->seqnum+1,
2188 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2190 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2192 TALLOC_FREE(req->chain_outbuf);
2196 /****************************************************************************
2197 Check if services need reloading.
2198 ****************************************************************************/
2200 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2203 if (last_smb_conf_reload_time == 0) {
2204 last_smb_conf_reload_time = t;
2207 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2208 reload_services(sconn->msg_ctx, sconn->sock, True);
2209 last_smb_conf_reload_time = t;
2213 static bool fd_is_readable(int fd)
2217 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2219 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2223 static void smbd_server_connection_write_handler(
2224 struct smbd_server_connection *sconn)
2226 /* TODO: make write nonblocking */
2229 static void smbd_server_connection_read_handler(
2230 struct smbd_server_connection *sconn, int fd)
2232 uint8_t *inbuf = NULL;
2233 size_t inbuf_len = 0;
2234 size_t unread_bytes = 0;
2235 bool encrypted = false;
2236 TALLOC_CTX *mem_ctx = talloc_tos();
2242 if (lp_async_smb_echo_handler()
2243 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2245 * This is the super-ugly hack to prefer the packets
2246 * forwarded by the echo handler over the ones by the
2249 fd = sconn->smb1.echo_handler.trusted_fd;
2252 from_client = (sconn->sock == fd);
2255 smbd_lock_socket(sconn);
2257 if (!fd_is_readable(fd)) {
2258 DEBUG(10,("the echo listener was faster\n"));
2259 smbd_unlock_socket(sconn);
2264 /* TODO: make this completely nonblocking */
2265 status = receive_smb_talloc(mem_ctx, sconn, fd,
2266 (char **)(void *)&inbuf,
2270 &inbuf_len, &seqnum,
2271 false /* trusted channel */);
2274 smbd_unlock_socket(sconn);
2277 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2280 if (NT_STATUS_IS_ERR(status)) {
2281 exit_server_cleanly("failed to receive smb request");
2283 if (!NT_STATUS_IS_OK(status)) {
2288 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2289 seqnum, encrypted, NULL);
2292 static void smbd_server_connection_handler(struct event_context *ev,
2293 struct fd_event *fde,
2297 struct smbd_server_connection *conn = talloc_get_type(private_data,
2298 struct smbd_server_connection);
2300 if (flags & EVENT_FD_WRITE) {
2301 smbd_server_connection_write_handler(conn);
2304 if (flags & EVENT_FD_READ) {
2305 smbd_server_connection_read_handler(conn, conn->sock);
2310 static void smbd_server_echo_handler(struct event_context *ev,
2311 struct fd_event *fde,
2315 struct smbd_server_connection *conn = talloc_get_type(private_data,
2316 struct smbd_server_connection);
2318 if (flags & EVENT_FD_WRITE) {
2319 smbd_server_connection_write_handler(conn);
2322 if (flags & EVENT_FD_READ) {
2323 smbd_server_connection_read_handler(
2324 conn, conn->smb1.echo_handler.trusted_fd);
2329 #ifdef CLUSTER_SUPPORT
2330 /****************************************************************************
2331 received when we should release a specific IP
2332 ****************************************************************************/
2333 static void release_ip(const char *ip, void *priv)
2335 const char *addr = (const char *)priv;
2336 const char *p = addr;
2338 if (strncmp("::ffff:", addr, 7) == 0) {
2342 DEBUG(10, ("Got release IP message for %s, "
2343 "our address is %s\n", ip, p));
2345 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2346 /* we can't afford to do a clean exit - that involves
2347 database writes, which would potentially mean we
2348 are still running after the failover has finished -
2349 we have to get rid of this process ID straight
2351 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2353 /* note we must exit with non-zero status so the unclean handler gets
2354 called in the parent, so that the brl database is tickled */
2359 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2360 struct sockaddr_storage *client)
2363 length = sizeof(*server);
2364 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2367 length = sizeof(*client);
2368 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2376 * Send keepalive packets to our client
2378 static bool keepalive_fn(const struct timeval *now, void *private_data)
2380 struct smbd_server_connection *sconn = talloc_get_type_abort(
2381 private_data, struct smbd_server_connection);
2384 if (sconn->using_smb2) {
2385 /* Don't do keepalives on an SMB2 connection. */
2389 smbd_lock_socket(sconn);
2390 ret = send_keepalive(sconn->sock);
2391 smbd_unlock_socket(sconn);
2394 char addr[INET6_ADDRSTRLEN];
2396 * Try and give an error message saying what
2399 DEBUG(0, ("send_keepalive failed for client %s. "
2400 "Error %s - exiting\n",
2401 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2409 * Do the recurring check if we're idle
2411 static bool deadtime_fn(const struct timeval *now, void *private_data)
2413 struct smbd_server_connection *sconn =
2414 (struct smbd_server_connection *)private_data;
2416 if ((conn_num_open(sconn) == 0)
2417 || (conn_idle_all(sconn, now->tv_sec))) {
2418 DEBUG( 2, ( "Closing idle connection\n" ) );
2419 messaging_send(sconn->msg_ctx,
2420 messaging_server_id(sconn->msg_ctx),
2421 MSG_SHUTDOWN, &data_blob_null);
2429 * Do the recurring log file and smb.conf reload checks.
2432 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2434 struct smbd_server_connection *sconn = talloc_get_type_abort(
2435 private_data, struct smbd_server_connection);
2437 DEBUG(5, ("housekeeping\n"));
2439 change_to_root_user();
2441 /* update printer queue caches if necessary */
2442 update_monitored_printq_cache(sconn->msg_ctx);
2444 /* check if we need to reload services */
2445 check_reload(sconn, time_mono(NULL));
2447 /* Change machine password if neccessary. */
2448 attempt_machine_password_change();
2451 * Force a log file check.
2453 force_check_log_size();
2459 * Read an smb packet in the echo handler child, giving the parent
2460 * smbd one second to react once the socket becomes readable.
2463 struct smbd_echo_read_state {
2464 struct tevent_context *ev;
2465 struct smbd_server_connection *sconn;
2472 static void smbd_echo_read_readable(struct tevent_req *subreq);
2473 static void smbd_echo_read_waited(struct tevent_req *subreq);
2475 static struct tevent_req *smbd_echo_read_send(
2476 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2477 struct smbd_server_connection *sconn)
2479 struct tevent_req *req, *subreq;
2480 struct smbd_echo_read_state *state;
2482 req = tevent_req_create(mem_ctx, &state,
2483 struct smbd_echo_read_state);
2488 state->sconn = sconn;
2490 subreq = wait_for_read_send(state, ev, sconn->sock);
2491 if (tevent_req_nomem(subreq, req)) {
2492 return tevent_req_post(req, ev);
2494 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2498 static void smbd_echo_read_readable(struct tevent_req *subreq)
2500 struct tevent_req *req = tevent_req_callback_data(
2501 subreq, struct tevent_req);
2502 struct smbd_echo_read_state *state = tevent_req_data(
2503 req, struct smbd_echo_read_state);
2507 ok = wait_for_read_recv(subreq, &err);
2508 TALLOC_FREE(subreq);
2510 tevent_req_nterror(req, map_nt_error_from_unix(err));
2515 * Give the parent smbd one second to step in
2518 subreq = tevent_wakeup_send(
2519 state, state->ev, timeval_current_ofs(1, 0));
2520 if (tevent_req_nomem(subreq, req)) {
2523 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2526 static void smbd_echo_read_waited(struct tevent_req *subreq)
2528 struct tevent_req *req = tevent_req_callback_data(
2529 subreq, struct tevent_req);
2530 struct smbd_echo_read_state *state = tevent_req_data(
2531 req, struct smbd_echo_read_state);
2532 struct smbd_server_connection *sconn = state->sconn;
2538 ok = tevent_wakeup_recv(subreq);
2539 TALLOC_FREE(subreq);
2541 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2545 ok = smbd_lock_socket_internal(sconn);
2547 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2548 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2552 if (!fd_is_readable(sconn->sock)) {
2553 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2554 (int)sys_getpid()));
2556 ok = smbd_unlock_socket_internal(sconn);
2558 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2559 DEBUG(1, ("%s: failed to unlock socket\n",
2564 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2565 if (tevent_req_nomem(subreq, req)) {
2568 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2572 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2578 false /* trusted_channel*/);
2580 if (tevent_req_nterror(req, status)) {
2581 tevent_req_nterror(req, status);
2582 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2583 (int)sys_getpid(), nt_errstr(status)));
2587 ok = smbd_unlock_socket_internal(sconn);
2589 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2590 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2593 tevent_req_done(req);
2596 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2597 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2599 struct smbd_echo_read_state *state = tevent_req_data(
2600 req, struct smbd_echo_read_state);
2603 if (tevent_req_is_nterror(req, &status)) {
2606 *pbuf = talloc_move(mem_ctx, &state->buf);
2607 *pbuflen = state->buflen;
2608 *pseqnum = state->seqnum;
2609 return NT_STATUS_OK;
2612 struct smbd_echo_state {
2613 struct tevent_context *ev;
2614 struct iovec *pending;
2615 struct smbd_server_connection *sconn;
2618 struct tevent_fd *parent_fde;
2620 struct tevent_req *write_req;
2623 static void smbd_echo_writer_done(struct tevent_req *req);
2625 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2629 if (state->write_req != NULL) {
2633 num_pending = talloc_array_length(state->pending);
2634 if (num_pending == 0) {
2638 state->write_req = writev_send(state, state->ev, NULL,
2639 state->parent_pipe, false,
2640 state->pending, num_pending);
2641 if (state->write_req == NULL) {
2642 DEBUG(1, ("writev_send failed\n"));
2646 talloc_steal(state->write_req, state->pending);
2647 state->pending = NULL;
2649 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2653 static void smbd_echo_writer_done(struct tevent_req *req)
2655 struct smbd_echo_state *state = tevent_req_callback_data(
2656 req, struct smbd_echo_state);
2660 written = writev_recv(req, &err);
2662 state->write_req = NULL;
2663 if (written == -1) {
2664 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2667 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2668 smbd_echo_activate_writer(state);
2671 static bool smbd_echo_reply(struct smbd_echo_state *state,
2672 uint8_t *inbuf, size_t inbuf_len,
2675 struct smb_request req;
2676 uint16_t num_replies;
2681 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2682 DEBUG(10, ("Got netbios keepalive\n"));
2689 if (inbuf_len < smb_size) {
2690 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2693 if (!valid_smb_header(state->sconn, inbuf)) {
2694 DEBUG(10, ("Got invalid SMB header\n"));
2698 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2704 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2705 smb_messages[req.cmd].name
2706 ? smb_messages[req.cmd].name : "unknown"));
2708 if (req.cmd != SMBecho) {
2715 num_replies = SVAL(req.vwv+0, 0);
2716 if (num_replies != 1) {
2717 /* Not a Windows "Hey, you're still there?" request */
2721 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2723 DEBUG(10, ("create_outbuf failed\n"));
2726 req.outbuf = (uint8_t *)outbuf;
2728 SSVAL(req.outbuf, smb_vwv0, num_replies);
2730 if (req.buflen > 0) {
2731 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2734 out_len = smb_len(req.outbuf) + 4;
2736 ok = srv_send_smb(req.sconn,
2740 TALLOC_FREE(outbuf);
2748 static void smbd_echo_exit(struct tevent_context *ev,
2749 struct tevent_fd *fde, uint16_t flags,
2752 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2756 static void smbd_echo_got_packet(struct tevent_req *req);
2758 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2761 struct smbd_echo_state *state;
2762 struct tevent_req *read_req;
2764 state = talloc_zero(sconn, struct smbd_echo_state);
2765 if (state == NULL) {
2766 DEBUG(1, ("talloc failed\n"));
2769 state->sconn = sconn;
2770 state->parent_pipe = parent_pipe;
2771 state->ev = s3_tevent_context_init(state);
2772 if (state->ev == NULL) {
2773 DEBUG(1, ("tevent_context_init failed\n"));
2777 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2778 TEVENT_FD_READ, smbd_echo_exit,
2780 if (state->parent_fde == NULL) {
2781 DEBUG(1, ("tevent_add_fd failed\n"));
2786 read_req = smbd_echo_read_send(state, state->ev, sconn);
2787 if (read_req == NULL) {
2788 DEBUG(1, ("smbd_echo_read_send failed\n"));
2792 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2795 if (tevent_loop_once(state->ev) == -1) {
2796 DEBUG(1, ("tevent_loop_once failed: %s\n",
2804 static void smbd_echo_got_packet(struct tevent_req *req)
2806 struct smbd_echo_state *state = tevent_req_callback_data(
2807 req, struct smbd_echo_state);
2811 uint32_t seqnum = 0;
2814 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2816 if (!NT_STATUS_IS_OK(status)) {
2817 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2818 nt_errstr(status)));
2822 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2828 num_pending = talloc_array_length(state->pending);
2829 tmp = talloc_realloc(state, state->pending, struct iovec,
2832 DEBUG(1, ("talloc_realloc failed\n"));
2835 state->pending = tmp;
2837 if (buflen >= smb_size) {
2839 * place the seqnum in the packet so that the main process
2840 * can reply with signing
2842 SIVAL(buf, smb_ss_field, seqnum);
2843 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2846 iov = &state->pending[num_pending];
2847 iov->iov_base = buf;
2848 iov->iov_len = buflen;
2850 DEBUG(10,("echo_handler[%d]: forward to main\n",
2851 (int)sys_getpid()));
2852 smbd_echo_activate_writer(state);
2855 req = smbd_echo_read_send(state, state->ev, state->sconn);
2857 DEBUG(1, ("smbd_echo_read_send failed\n"));
2860 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2865 * Handle SMBecho requests in a forked child process
2867 bool fork_echo_handler(struct smbd_server_connection *sconn)
2869 int listener_pipe[2];
2873 res = pipe(listener_pipe);
2875 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2878 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2879 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2880 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2888 close(listener_pipe[0]);
2889 set_blocking(listener_pipe[1], false);
2891 status = reinit_after_fork(sconn->msg_ctx,
2894 if (!NT_STATUS_IS_OK(status)) {
2895 DEBUG(1, ("reinit_after_fork failed: %s\n",
2896 nt_errstr(status)));
2899 smbd_echo_loop(sconn, listener_pipe[1]);
2902 close(listener_pipe[1]);
2903 listener_pipe[1] = -1;
2904 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2906 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2909 * Without smb signing this is the same as the normal smbd
2910 * listener. This needs to change once signing comes in.
2912 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
2914 sconn->smb1.echo_handler.trusted_fd,
2916 smbd_server_echo_handler,
2918 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2919 DEBUG(1, ("event_add_fd failed\n"));
2926 if (listener_pipe[0] != -1) {
2927 close(listener_pipe[0]);
2929 if (listener_pipe[1] != -1) {
2930 close(listener_pipe[1]);
2932 sconn->smb1.echo_handler.trusted_fd = -1;
2933 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2934 close(sconn->smb1.echo_handler.socket_lock_fd);
2936 sconn->smb1.echo_handler.trusted_fd = -1;
2937 sconn->smb1.echo_handler.socket_lock_fd = -1;
2943 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2944 struct sockaddr_storage *srv,
2945 struct sockaddr_storage *clnt)
2947 struct ctdbd_connection *cconn;
2948 char tmp_addr[INET6_ADDRSTRLEN];
2951 cconn = messaging_ctdbd_connection();
2952 if (cconn == NULL) {
2953 return NT_STATUS_NO_MEMORY;
2956 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2957 addr = talloc_strdup(cconn, tmp_addr);
2959 return NT_STATUS_NO_MEMORY;
2961 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2966 static bool uid_in_use(const struct user_struct *user, uid_t uid)
2969 if (user->session_info &&
2970 (user->session_info->unix_token->uid == uid)) {
2978 static bool gid_in_use(const struct user_struct *user, gid_t gid)
2981 if (user->session_info != NULL) {
2983 struct security_unix_token *utok;
2985 utok = user->session_info->unix_token;
2986 if (utok->gid == gid) {
2989 for(i=0; i<utok->ngroups; i++) {
2990 if (utok->groups[i] == gid) {
3000 static bool sid_in_use(const struct user_struct *user,
3001 const struct dom_sid *psid)
3004 struct security_token *tok;
3006 if (user->session_info == NULL) {
3009 tok = user->session_info->security_token;
3012 * Not sure session_info->security_token can
3013 * ever be NULL. This check might be not
3018 if (security_token_has_sid(tok, psid)) {
3026 static bool id_in_use(const struct user_struct *user,
3027 const struct id_cache_ref *id)
3031 return uid_in_use(user, id->id.uid);
3033 return gid_in_use(user, id->id.gid);
3035 return sid_in_use(user, &id->id.sid);
3042 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3045 struct server_id server_id,
3048 const char *msg = (data && data->data)
3049 ? (const char *)data->data : "<NULL>";
3050 struct user_struct *validated_users;
3051 struct id_cache_ref id;
3052 struct smbd_server_connection *sconn =
3053 talloc_get_type_abort(private_data,
3054 struct smbd_server_connection);
3056 validated_users = sconn->smb1.sessions.validated_users;
3058 if (!id_cache_ref_parse(msg, &id)) {
3059 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3063 if (id_in_use(validated_users, &id)) {
3064 exit_server_cleanly(msg);
3066 id_cache_delete_from_cache(&id);
3069 /****************************************************************************
3070 Process commands from the client
3071 ****************************************************************************/
3073 void smbd_process(struct tevent_context *ev_ctx,
3074 struct smbd_server_connection *sconn)
3076 TALLOC_CTX *frame = talloc_stackframe();
3077 struct sockaddr_storage ss;
3078 struct sockaddr *sa = NULL;
3079 socklen_t sa_socklen;
3080 struct tsocket_address *local_address = NULL;
3081 struct tsocket_address *remote_address = NULL;
3082 const char *locaddr = NULL;
3083 const char *remaddr = NULL;
3087 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
3089 * We're not making the decision here,
3090 * we're just allowing the client
3091 * to decide between SMB1 and SMB2
3092 * with the first negprot
3095 sconn->using_smb2 = true;
3098 /* Ensure child is set to blocking mode */
3099 set_blocking(sconn->sock,True);
3101 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3102 set_socket_options(sconn->sock, lp_socket_options());
3104 sa = (struct sockaddr *)(void *)&ss;
3105 sa_socklen = sizeof(ss);
3106 ret = getpeername(sconn->sock, sa, &sa_socklen);
3108 int level = (errno == ENOTCONN)?2:0;
3109 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3110 exit_server_cleanly("getpeername() failed.\n");
3112 ret = tsocket_address_bsd_from_sockaddr(sconn,
3116 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3117 __location__, strerror(errno)));
3118 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3121 sa = (struct sockaddr *)(void *)&ss;
3122 sa_socklen = sizeof(ss);
3123 ret = getsockname(sconn->sock, sa, &sa_socklen);
3125 int level = (errno == ENOTCONN)?2:0;
3126 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3127 exit_server_cleanly("getsockname() failed.\n");
3129 ret = tsocket_address_bsd_from_sockaddr(sconn,
3133 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3134 __location__, strerror(errno)));
3135 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3138 sconn->local_address = local_address;
3139 sconn->remote_address = remote_address;
3141 if (tsocket_address_is_inet(local_address, "ip")) {
3142 locaddr = tsocket_address_inet_addr_string(
3143 sconn->local_address,
3145 if (locaddr == NULL) {
3146 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3147 __location__, strerror(errno)));
3148 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3151 locaddr = "0.0.0.0";
3154 if (tsocket_address_is_inet(remote_address, "ip")) {
3155 remaddr = tsocket_address_inet_addr_string(
3156 sconn->remote_address,
3158 if (remaddr == NULL) {
3159 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3160 __location__, strerror(errno)));
3161 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3164 remaddr = "0.0.0.0";
3167 /* this is needed so that we get decent entries
3168 in smbstatus for port 445 connects */
3169 set_remote_machine_name(remaddr, false);
3170 reload_services(sconn->msg_ctx, sconn->sock, true);
3173 * Before the first packet, check the global hosts allow/ hosts deny
3174 * parameters before doing any parsing of packets passed to us by the
3175 * client. This prevents attacks on our parsing code from hosts not in
3176 * the hosts allow list.
3179 ret = get_remote_hostname(remote_address,
3183 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3184 __location__, strerror(errno)));
3185 exit_server_cleanly("get_remote_hostname failed.\n");
3187 if (strequal(rhost, "UNKNOWN")) {
3188 rhost = talloc_strdup(talloc_tos(), remaddr);
3190 sconn->remote_hostname = talloc_move(sconn, &rhost);
3192 sub_set_socket_ids(remaddr,
3193 sconn->remote_hostname,
3196 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3197 sconn->remote_hostname,
3200 * send a negative session response "not listening on calling
3203 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3204 DEBUG( 1, ("Connection denied from %s to %s\n",
3205 tsocket_address_string(remote_address, talloc_tos()),
3206 tsocket_address_string(local_address, talloc_tos())));
3207 (void)srv_send_smb(sconn,(char *)buf, false,
3209 exit_server_cleanly("connection denied");
3212 DEBUG(10, ("Connection allowed from %s to %s\n",
3213 tsocket_address_string(remote_address, talloc_tos()),
3214 tsocket_address_string(local_address, talloc_tos())));
3218 smb_perfcount_init();
3220 if (!init_account_policy()) {
3221 exit_server("Could not open account policy tdb.\n");
3224 if (*lp_rootdir()) {
3225 if (chroot(lp_rootdir()) != 0) {
3226 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3227 exit_server("Failed to chroot()");
3229 if (chdir("/") == -1) {
3230 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3231 exit_server("Failed to chroot()");
3233 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3236 if (!srv_init_signing(sconn)) {
3237 exit_server("Failed to init smb_signing");
3241 if (!init_oplocks(sconn))
3242 exit_server("Failed to init oplocks");
3244 /* register our message handlers */
3245 messaging_register(sconn->msg_ctx, sconn,
3246 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3247 messaging_register(sconn->msg_ctx, sconn,
3248 MSG_SMB_CLOSE_FILE, msg_close_file);
3249 messaging_register(sconn->msg_ctx, sconn,
3250 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3252 id_cache_register_msgs(sconn->msg_ctx);
3253 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3254 messaging_register(sconn->msg_ctx, sconn,
3255 ID_CACHE_KILL, smbd_id_cache_kill);
3258 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3259 * MSGs to all child processes
3261 messaging_deregister(sconn->msg_ctx,
3263 messaging_register(sconn->msg_ctx, NULL,
3264 MSG_DEBUG, debug_message);
3266 if ((lp_keepalive() != 0)
3267 && !(event_add_idle(ev_ctx, NULL,
3268 timeval_set(lp_keepalive(), 0),
3269 "keepalive", keepalive_fn,
3271 DEBUG(0, ("Could not add keepalive event\n"));
3275 if (!(event_add_idle(ev_ctx, NULL,
3276 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3277 "deadtime", deadtime_fn, sconn))) {
3278 DEBUG(0, ("Could not add deadtime event\n"));
3282 if (!(event_add_idle(ev_ctx, NULL,
3283 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3284 "housekeeping", housekeeping_fn, sconn))) {
3285 DEBUG(0, ("Could not add housekeeping event\n"));
3289 #ifdef CLUSTER_SUPPORT
3291 if (lp_clustering()) {
3293 * We need to tell ctdb about our client's TCP
3294 * connection, so that for failover ctdbd can send
3295 * tickle acks, triggering a reconnection by the
3299 struct sockaddr_storage srv, clnt;
3301 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3303 status = smbd_register_ips(sconn, &srv, &clnt);
3304 if (!NT_STATUS_IS_OK(status)) {
3305 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3306 nt_errstr(status)));
3310 DEBUG(0,("Unable to get tcp info for "
3311 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3318 sconn->nbt.got_session = false;
3320 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3322 sconn->smb1.sessions.done_sesssetup = false;
3323 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3324 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3325 /* users from session setup */
3326 sconn->smb1.sessions.session_userlist = NULL;
3327 /* workgroup from session setup. */
3328 sconn->smb1.sessions.session_workgroup = NULL;
3329 /* this holds info on user ids that are already validated for this VC */
3330 sconn->smb1.sessions.validated_users = NULL;
3331 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3332 sconn->smb1.sessions.num_validated_vuids = 0;
3335 if (!init_dptrs(sconn)) {
3336 exit_server("init_dptrs() failed");
3339 sconn->smb1.fde = event_add_fd(ev_ctx,
3343 smbd_server_connection_handler,
3345 if (!sconn->smb1.fde) {
3346 exit_server("failed to create smbd_server_connection fde");
3354 frame = talloc_stackframe_pool(8192);
3358 status = smbd_server_connection_loop_once(ev_ctx, sconn);
3359 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3360 !NT_STATUS_IS_OK(status)) {
3361 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3362 " exiting\n", nt_errstr(status)));
3369 exit_server_cleanly(NULL);
3372 bool req_is_in_chain(struct smb_request *req)
3374 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3376 * We're right now handling a subsequent request, so we must
3382 if (!is_andx_req(req->cmd)) {
3388 * Okay, an illegal request, but definitely not chained :-)
3393 return (CVAL(req->vwv+0, 0) != 0xFF);