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 = (const 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, conn_snum_used, 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 void smbd_conf_updated(struct messaging_context *msg,
931 struct server_id server_id,
934 struct smbd_server_connection *sconn =
935 talloc_get_type_abort(private_data,
936 struct smbd_server_connection);
938 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
939 "updated. Reloading.\n"));
940 change_to_root_user();
941 reload_services(sconn, conn_snum_used, false);
945 * Only allow 5 outstanding trans requests. We're allocating memory, so
949 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
952 for (; list != NULL; list = list->next) {
954 if (list->mid == mid) {
955 return NT_STATUS_INVALID_PARAMETER;
961 return NT_STATUS_INSUFFICIENT_RESOURCES;
968 These flags determine some of the permissions required to do an operation
970 Note that I don't set NEED_WRITE on some write operations because they
971 are used by some brain-dead clients when printing, and I don't want to
972 force write permissions on print services.
974 #define AS_USER (1<<0)
975 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
976 #define TIME_INIT (1<<2)
977 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
978 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
979 #define DO_CHDIR (1<<6)
982 define a list of possible SMB messages and their corresponding
983 functions. Any message that has a NULL function is unimplemented -
984 please feel free to contribute implementations!
986 static const struct smb_message_struct {
988 void (*fn)(struct smb_request *req);
990 } smb_messages[256] = {
992 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
993 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
994 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
995 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
996 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
997 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
998 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
999 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1000 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1001 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1002 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1003 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1004 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1005 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1006 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1007 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1008 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1009 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1010 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1011 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1012 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1013 /* 0x15 */ { NULL, NULL, 0 },
1014 /* 0x16 */ { NULL, NULL, 0 },
1015 /* 0x17 */ { NULL, NULL, 0 },
1016 /* 0x18 */ { NULL, NULL, 0 },
1017 /* 0x19 */ { NULL, NULL, 0 },
1018 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1019 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1020 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1021 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1022 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1023 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1024 /* 0x20 */ { "SMBwritec", NULL,0},
1025 /* 0x21 */ { NULL, NULL, 0 },
1026 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1027 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1028 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1029 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1030 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1031 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1032 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1033 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1034 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1035 /* 0x2b */ { "SMBecho",reply_echo,0},
1036 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1037 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1038 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1039 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1040 /* 0x30 */ { NULL, NULL, 0 },
1041 /* 0x31 */ { NULL, NULL, 0 },
1042 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1043 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1044 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1045 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1046 /* 0x36 */ { NULL, NULL, 0 },
1047 /* 0x37 */ { NULL, NULL, 0 },
1048 /* 0x38 */ { NULL, NULL, 0 },
1049 /* 0x39 */ { NULL, NULL, 0 },
1050 /* 0x3a */ { NULL, NULL, 0 },
1051 /* 0x3b */ { NULL, NULL, 0 },
1052 /* 0x3c */ { NULL, NULL, 0 },
1053 /* 0x3d */ { NULL, NULL, 0 },
1054 /* 0x3e */ { NULL, NULL, 0 },
1055 /* 0x3f */ { NULL, NULL, 0 },
1056 /* 0x40 */ { NULL, NULL, 0 },
1057 /* 0x41 */ { NULL, NULL, 0 },
1058 /* 0x42 */ { NULL, NULL, 0 },
1059 /* 0x43 */ { NULL, NULL, 0 },
1060 /* 0x44 */ { NULL, NULL, 0 },
1061 /* 0x45 */ { NULL, NULL, 0 },
1062 /* 0x46 */ { NULL, NULL, 0 },
1063 /* 0x47 */ { NULL, NULL, 0 },
1064 /* 0x48 */ { NULL, NULL, 0 },
1065 /* 0x49 */ { NULL, NULL, 0 },
1066 /* 0x4a */ { NULL, NULL, 0 },
1067 /* 0x4b */ { NULL, NULL, 0 },
1068 /* 0x4c */ { NULL, NULL, 0 },
1069 /* 0x4d */ { NULL, NULL, 0 },
1070 /* 0x4e */ { NULL, NULL, 0 },
1071 /* 0x4f */ { NULL, NULL, 0 },
1072 /* 0x50 */ { NULL, NULL, 0 },
1073 /* 0x51 */ { NULL, NULL, 0 },
1074 /* 0x52 */ { NULL, NULL, 0 },
1075 /* 0x53 */ { NULL, NULL, 0 },
1076 /* 0x54 */ { NULL, NULL, 0 },
1077 /* 0x55 */ { NULL, NULL, 0 },
1078 /* 0x56 */ { NULL, NULL, 0 },
1079 /* 0x57 */ { NULL, NULL, 0 },
1080 /* 0x58 */ { NULL, NULL, 0 },
1081 /* 0x59 */ { NULL, NULL, 0 },
1082 /* 0x5a */ { NULL, NULL, 0 },
1083 /* 0x5b */ { NULL, NULL, 0 },
1084 /* 0x5c */ { NULL, NULL, 0 },
1085 /* 0x5d */ { NULL, NULL, 0 },
1086 /* 0x5e */ { NULL, NULL, 0 },
1087 /* 0x5f */ { NULL, NULL, 0 },
1088 /* 0x60 */ { NULL, NULL, 0 },
1089 /* 0x61 */ { NULL, NULL, 0 },
1090 /* 0x62 */ { NULL, NULL, 0 },
1091 /* 0x63 */ { NULL, NULL, 0 },
1092 /* 0x64 */ { NULL, NULL, 0 },
1093 /* 0x65 */ { NULL, NULL, 0 },
1094 /* 0x66 */ { NULL, NULL, 0 },
1095 /* 0x67 */ { NULL, NULL, 0 },
1096 /* 0x68 */ { NULL, NULL, 0 },
1097 /* 0x69 */ { NULL, NULL, 0 },
1098 /* 0x6a */ { NULL, NULL, 0 },
1099 /* 0x6b */ { NULL, NULL, 0 },
1100 /* 0x6c */ { NULL, NULL, 0 },
1101 /* 0x6d */ { NULL, NULL, 0 },
1102 /* 0x6e */ { NULL, NULL, 0 },
1103 /* 0x6f */ { NULL, NULL, 0 },
1104 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1105 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1106 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1107 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1108 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1109 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1110 /* 0x76 */ { NULL, NULL, 0 },
1111 /* 0x77 */ { NULL, NULL, 0 },
1112 /* 0x78 */ { NULL, NULL, 0 },
1113 /* 0x79 */ { NULL, NULL, 0 },
1114 /* 0x7a */ { NULL, NULL, 0 },
1115 /* 0x7b */ { NULL, NULL, 0 },
1116 /* 0x7c */ { NULL, NULL, 0 },
1117 /* 0x7d */ { NULL, NULL, 0 },
1118 /* 0x7e */ { NULL, NULL, 0 },
1119 /* 0x7f */ { NULL, NULL, 0 },
1120 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1121 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1122 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1123 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1124 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1125 /* 0x85 */ { NULL, NULL, 0 },
1126 /* 0x86 */ { NULL, NULL, 0 },
1127 /* 0x87 */ { NULL, NULL, 0 },
1128 /* 0x88 */ { NULL, NULL, 0 },
1129 /* 0x89 */ { NULL, NULL, 0 },
1130 /* 0x8a */ { NULL, NULL, 0 },
1131 /* 0x8b */ { NULL, NULL, 0 },
1132 /* 0x8c */ { NULL, NULL, 0 },
1133 /* 0x8d */ { NULL, NULL, 0 },
1134 /* 0x8e */ { NULL, NULL, 0 },
1135 /* 0x8f */ { NULL, NULL, 0 },
1136 /* 0x90 */ { NULL, NULL, 0 },
1137 /* 0x91 */ { NULL, NULL, 0 },
1138 /* 0x92 */ { NULL, NULL, 0 },
1139 /* 0x93 */ { NULL, NULL, 0 },
1140 /* 0x94 */ { NULL, NULL, 0 },
1141 /* 0x95 */ { NULL, NULL, 0 },
1142 /* 0x96 */ { NULL, NULL, 0 },
1143 /* 0x97 */ { NULL, NULL, 0 },
1144 /* 0x98 */ { NULL, NULL, 0 },
1145 /* 0x99 */ { NULL, NULL, 0 },
1146 /* 0x9a */ { NULL, NULL, 0 },
1147 /* 0x9b */ { NULL, NULL, 0 },
1148 /* 0x9c */ { NULL, NULL, 0 },
1149 /* 0x9d */ { NULL, NULL, 0 },
1150 /* 0x9e */ { NULL, NULL, 0 },
1151 /* 0x9f */ { NULL, NULL, 0 },
1152 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1153 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1154 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1155 /* 0xa3 */ { NULL, NULL, 0 },
1156 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1157 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1158 /* 0xa6 */ { NULL, NULL, 0 },
1159 /* 0xa7 */ { NULL, NULL, 0 },
1160 /* 0xa8 */ { NULL, NULL, 0 },
1161 /* 0xa9 */ { NULL, NULL, 0 },
1162 /* 0xaa */ { NULL, NULL, 0 },
1163 /* 0xab */ { NULL, NULL, 0 },
1164 /* 0xac */ { NULL, NULL, 0 },
1165 /* 0xad */ { NULL, NULL, 0 },
1166 /* 0xae */ { NULL, NULL, 0 },
1167 /* 0xaf */ { NULL, NULL, 0 },
1168 /* 0xb0 */ { NULL, NULL, 0 },
1169 /* 0xb1 */ { NULL, NULL, 0 },
1170 /* 0xb2 */ { NULL, NULL, 0 },
1171 /* 0xb3 */ { NULL, NULL, 0 },
1172 /* 0xb4 */ { NULL, NULL, 0 },
1173 /* 0xb5 */ { NULL, NULL, 0 },
1174 /* 0xb6 */ { NULL, NULL, 0 },
1175 /* 0xb7 */ { NULL, NULL, 0 },
1176 /* 0xb8 */ { NULL, NULL, 0 },
1177 /* 0xb9 */ { NULL, NULL, 0 },
1178 /* 0xba */ { NULL, NULL, 0 },
1179 /* 0xbb */ { NULL, NULL, 0 },
1180 /* 0xbc */ { NULL, NULL, 0 },
1181 /* 0xbd */ { NULL, NULL, 0 },
1182 /* 0xbe */ { NULL, NULL, 0 },
1183 /* 0xbf */ { NULL, NULL, 0 },
1184 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1185 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1186 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1187 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1188 /* 0xc4 */ { NULL, NULL, 0 },
1189 /* 0xc5 */ { NULL, NULL, 0 },
1190 /* 0xc6 */ { NULL, NULL, 0 },
1191 /* 0xc7 */ { NULL, NULL, 0 },
1192 /* 0xc8 */ { NULL, NULL, 0 },
1193 /* 0xc9 */ { NULL, NULL, 0 },
1194 /* 0xca */ { NULL, NULL, 0 },
1195 /* 0xcb */ { NULL, NULL, 0 },
1196 /* 0xcc */ { NULL, NULL, 0 },
1197 /* 0xcd */ { NULL, NULL, 0 },
1198 /* 0xce */ { NULL, NULL, 0 },
1199 /* 0xcf */ { NULL, NULL, 0 },
1200 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1201 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1202 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1203 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1204 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1205 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1206 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1207 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1208 /* 0xd8 */ { NULL, NULL, 0 },
1209 /* 0xd9 */ { NULL, NULL, 0 },
1210 /* 0xda */ { NULL, NULL, 0 },
1211 /* 0xdb */ { NULL, NULL, 0 },
1212 /* 0xdc */ { NULL, NULL, 0 },
1213 /* 0xdd */ { NULL, NULL, 0 },
1214 /* 0xde */ { NULL, NULL, 0 },
1215 /* 0xdf */ { NULL, NULL, 0 },
1216 /* 0xe0 */ { NULL, NULL, 0 },
1217 /* 0xe1 */ { NULL, NULL, 0 },
1218 /* 0xe2 */ { NULL, NULL, 0 },
1219 /* 0xe3 */ { NULL, NULL, 0 },
1220 /* 0xe4 */ { NULL, NULL, 0 },
1221 /* 0xe5 */ { NULL, NULL, 0 },
1222 /* 0xe6 */ { NULL, NULL, 0 },
1223 /* 0xe7 */ { NULL, NULL, 0 },
1224 /* 0xe8 */ { NULL, NULL, 0 },
1225 /* 0xe9 */ { NULL, NULL, 0 },
1226 /* 0xea */ { NULL, NULL, 0 },
1227 /* 0xeb */ { NULL, NULL, 0 },
1228 /* 0xec */ { NULL, NULL, 0 },
1229 /* 0xed */ { NULL, NULL, 0 },
1230 /* 0xee */ { NULL, NULL, 0 },
1231 /* 0xef */ { NULL, NULL, 0 },
1232 /* 0xf0 */ { NULL, NULL, 0 },
1233 /* 0xf1 */ { NULL, NULL, 0 },
1234 /* 0xf2 */ { NULL, NULL, 0 },
1235 /* 0xf3 */ { NULL, NULL, 0 },
1236 /* 0xf4 */ { NULL, NULL, 0 },
1237 /* 0xf5 */ { NULL, NULL, 0 },
1238 /* 0xf6 */ { NULL, NULL, 0 },
1239 /* 0xf7 */ { NULL, NULL, 0 },
1240 /* 0xf8 */ { NULL, NULL, 0 },
1241 /* 0xf9 */ { NULL, NULL, 0 },
1242 /* 0xfa */ { NULL, NULL, 0 },
1243 /* 0xfb */ { NULL, NULL, 0 },
1244 /* 0xfc */ { NULL, NULL, 0 },
1245 /* 0xfd */ { NULL, NULL, 0 },
1246 /* 0xfe */ { NULL, NULL, 0 },
1247 /* 0xff */ { NULL, NULL, 0 }
1251 /*******************************************************************
1252 allocate and initialize a reply packet
1253 ********************************************************************/
1255 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1256 const char *inbuf, char **outbuf, uint8_t num_words,
1260 * Protect against integer wrap
1262 if ((num_bytes > 0xffffff)
1263 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1265 if (asprintf(&msg, "num_bytes too large: %u",
1266 (unsigned)num_bytes) == -1) {
1267 msg = discard_const_p(char, "num_bytes too large");
1272 *outbuf = talloc_array(mem_ctx, char,
1273 smb_size + num_words*2 + num_bytes);
1274 if (*outbuf == NULL) {
1278 construct_reply_common(req, inbuf, *outbuf);
1279 srv_set_message(*outbuf, num_words, num_bytes, false);
1281 * Zero out the word area, the caller has to take care of the bcc area
1284 if (num_words != 0) {
1285 memset(*outbuf + smb_vwv0, 0, num_words*2);
1291 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1294 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1296 smb_panic("could not allocate output buffer\n");
1298 req->outbuf = (uint8_t *)outbuf;
1302 /*******************************************************************
1303 Dump a packet to a file.
1304 ********************************************************************/
1306 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1310 if (DEBUGLEVEL < 50) {
1314 if (len < 4) len = smb_len(data)+4;
1315 for (i=1;i<100;i++) {
1316 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1317 type ? "req" : "resp") == -1) {
1320 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1321 if (fd != -1 || errno != EEXIST) break;
1324 ssize_t ret = write(fd, data, len);
1326 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1328 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1333 /****************************************************************************
1334 Prepare everything for calling the actual request function, and potentially
1335 call the request function via the "new" interface.
1337 Return False if the "legacy" function needs to be called, everything is
1340 Return True if we're done.
1342 I know this API sucks, but it is the one with the least code change I could
1344 ****************************************************************************/
1346 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1350 connection_struct *conn = NULL;
1351 struct smbd_server_connection *sconn = req->sconn;
1356 if (smb_messages[type].fn == NULL) {
1357 DEBUG(0,("Unknown message type %d!\n",type));
1358 smb_dump("Unknown", 1, (const char *)req->inbuf, size);
1359 reply_unknown_new(req, type);
1363 flags = smb_messages[type].flags;
1365 /* In share mode security we must ignore the vuid. */
1366 session_tag = (lp_security() == SEC_SHARE)
1367 ? UID_FIELD_INVALID : req->vuid;
1370 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1371 (int)sys_getpid(), (unsigned long)conn));
1373 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf, size);
1375 /* Ensure this value is replaced in the incoming packet. */
1376 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1379 * Ensure the correct username is in current_user_info. This is a
1380 * really ugly bugfix for problems with multiple session_setup_and_X's
1381 * being done and allowing %U and %G substitutions to work correctly.
1382 * There is a reason this code is done here, don't move it unless you
1383 * know what you're doing... :-).
1387 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1388 user_struct *vuser = NULL;
1390 sconn->smb1.sessions.last_session_tag = session_tag;
1391 if(session_tag != UID_FIELD_INVALID) {
1392 vuser = get_valid_user_struct(sconn, session_tag);
1394 set_current_user_info(
1395 vuser->session_info->unix_info->sanitized_username,
1396 vuser->session_info->unix_info->unix_name,
1397 vuser->session_info->info->domain_name);
1402 /* Does this call need to be run as the connected user? */
1403 if (flags & AS_USER) {
1405 /* Does this call need a valid tree connection? */
1408 * Amazingly, the error code depends on the command
1411 if (type == SMBntcreateX) {
1412 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1414 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1419 if (!change_to_user(conn,session_tag)) {
1420 DEBUG(0, ("Error: Could not change to user. Removing "
1421 "deferred open, mid=%llu.\n",
1422 (unsigned long long)req->mid));
1423 reply_force_doserror(req, ERRSRV, ERRbaduid);
1427 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1429 /* Does it need write permission? */
1430 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1431 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1435 /* IPC services are limited */
1436 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1437 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1441 /* This call needs to be run as root */
1442 change_to_root_user();
1445 /* load service specific parameters */
1447 if (req->encrypted) {
1448 conn->encrypted_tid = true;
1449 /* encrypted required from now on. */
1450 conn->encrypt_level = Required;
1451 } else if (ENCRYPTION_REQUIRED(conn)) {
1452 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1453 exit_server_cleanly("encryption required "
1459 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1460 (flags & (AS_USER|DO_CHDIR)
1462 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1465 conn->num_smb_operations++;
1468 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1470 if (raddr == NULL) {
1471 reply_nterror(req, NT_STATUS_NO_MEMORY);
1475 /* does this protocol need to be run as guest? */
1476 if ((flags & AS_GUEST)
1477 && (!change_to_guest() ||
1478 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1479 sconn->remote_hostname,
1481 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1485 smb_messages[type].fn(req);
1489 /****************************************************************************
1490 Construct a reply to the incoming packet.
1491 ****************************************************************************/
1493 static void construct_reply(struct smbd_server_connection *sconn,
1494 char *inbuf, int size, size_t unread_bytes,
1495 uint32_t seqnum, bool encrypted,
1496 struct smb_perfcount_data *deferred_pcd)
1498 connection_struct *conn;
1499 struct smb_request *req;
1501 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1502 smb_panic("could not allocate smb_request");
1505 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1506 encrypted, seqnum)) {
1507 exit_server_cleanly("Invalid SMB request");
1510 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1512 /* we popped this message off the queue - keep original perf data */
1514 req->pcd = *deferred_pcd;
1516 SMB_PERFCOUNT_START(&req->pcd);
1517 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1518 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1521 conn = switch_message(req->cmd, req, size);
1523 if (req->unread_bytes) {
1524 /* writeX failed. drain socket. */
1525 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1526 req->unread_bytes) {
1527 smb_panic("failed to drain pending bytes");
1529 req->unread_bytes = 0;
1537 if (req->outbuf == NULL) {
1541 if (CVAL(req->outbuf,0) == 0) {
1542 show_msg((char *)req->outbuf);
1545 if (!srv_send_smb(req->sconn,
1546 (char *)req->outbuf,
1547 true, req->seqnum+1,
1548 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1550 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1558 /****************************************************************************
1559 Process an smb from the client
1560 ****************************************************************************/
1561 static void process_smb(struct smbd_server_connection *sconn,
1562 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1563 uint32_t seqnum, bool encrypted,
1564 struct smb_perfcount_data *deferred_pcd)
1566 int msg_type = CVAL(inbuf,0);
1568 DO_PROFILE_INC(smb_count);
1570 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1572 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1573 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1575 if (msg_type != NBSSmessage) {
1577 * NetBIOS session request, keepalive, etc.
1579 reply_special(sconn, (char *)inbuf, nread);
1583 if (sconn->using_smb2) {
1584 /* At this point we're not really using smb2,
1585 * we make the decision here.. */
1586 if (smbd_is_smb2_header(inbuf, nread)) {
1587 smbd_smb2_first_negprot(sconn, inbuf, nread);
1589 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1590 && CVAL(inbuf, smb_com) != 0x72) {
1591 /* This is a non-negprot SMB1 packet.
1592 Disable SMB2 from now on. */
1593 sconn->using_smb2 = false;
1597 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1598 * so subtract 4 from it. */
1599 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1600 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1603 /* special magic for immediate exit */
1605 (IVAL(inbuf, 4) == 0x74697865) &&
1606 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1607 uint8_t exitcode = CVAL(inbuf, 8);
1608 DEBUG(1, ("Exiting immediately with code %d\n",
1613 exit_server_cleanly("Non-SMB packet");
1616 show_msg((char *)inbuf);
1618 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1619 encrypted, deferred_pcd);
1623 sconn->num_requests++;
1625 /* The timeout_processing function isn't run nearly
1626 often enough to implement 'max log size' without
1627 overrunning the size of the file by many megabytes.
1628 This is especially true if we are running at debug
1629 level 10. Checking every 50 SMBs is a nice
1630 tradeoff of performance vs log file size overrun. */
1632 if ((sconn->num_requests % 50) == 0 &&
1633 need_to_check_log_size()) {
1634 change_to_root_user();
1639 /****************************************************************************
1640 Return a string containing the function name of a SMB command.
1641 ****************************************************************************/
1643 const char *smb_fn_name(int type)
1645 const char *unknown_name = "SMBunknown";
1647 if (smb_messages[type].name == NULL)
1648 return(unknown_name);
1650 return(smb_messages[type].name);
1653 /****************************************************************************
1654 Helper functions for contruct_reply.
1655 ****************************************************************************/
1657 void add_to_common_flags2(uint32 v)
1662 void remove_from_common_flags2(uint32 v)
1664 common_flags2 &= ~v;
1667 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1670 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1671 uint16_t out_flags2 = common_flags2;
1673 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1674 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1675 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1677 srv_set_message(outbuf,0,0,false);
1679 SCVAL(outbuf, smb_com, req->cmd);
1680 SIVAL(outbuf,smb_rcls,0);
1681 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1682 SSVAL(outbuf,smb_flg2, out_flags2);
1683 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1684 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1686 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1687 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1688 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1689 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1692 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1694 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1698 * How many bytes have we already accumulated up to the current wct field
1702 size_t req_wct_ofs(struct smb_request *req)
1706 if (req->chain_outbuf == NULL) {
1709 buf_size = talloc_get_size(req->chain_outbuf);
1710 if ((buf_size % 4) != 0) {
1711 buf_size += (4 - (buf_size % 4));
1713 return buf_size - 4;
1717 * Hack around reply_nterror & friends not being aware of chained requests,
1718 * generating illegal (i.e. wct==0) chain replies.
1721 static void fixup_chain_error_packet(struct smb_request *req)
1723 uint8_t *outbuf = req->outbuf;
1725 reply_outbuf(req, 2, 0);
1726 memcpy(req->outbuf, outbuf, smb_wct);
1727 TALLOC_FREE(outbuf);
1728 SCVAL(req->outbuf, smb_vwv0, 0xff);
1732 * @brief Find the smb_cmd offset of the last command pushed
1733 * @param[in] buf The buffer we're building up
1734 * @retval Where can we put our next andx cmd?
1736 * While chaining requests, the "next" request we're looking at needs to put
1737 * its SMB_Command before the data the previous request already built up added
1738 * to the chain. Find the offset to the place where we have to put our cmd.
1741 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1746 cmd = CVAL(buf, smb_com);
1748 if (!is_andx_req(cmd)) {
1754 while (CVAL(buf, ofs) != 0xff) {
1756 if (!is_andx_req(CVAL(buf, ofs))) {
1761 * ofs is from start of smb header, so add the 4 length
1762 * bytes. The next cmd is right after the wct field.
1764 ofs = SVAL(buf, ofs+2) + 4 + 1;
1766 if (ofs+4 >= talloc_get_size(buf)) {
1776 * @brief Do the smb chaining at a buffer level
1777 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1778 * @param[in] andx_buf Buffer to be appended
1781 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1783 uint8_t smb_command = CVAL(andx_buf, smb_com);
1784 uint8_t wct = CVAL(andx_buf, smb_wct);
1785 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1786 size_t bytes_alignment = 0;
1787 uint32_t num_bytes = smb_buflen(andx_buf);
1788 const uint8_t *bytes = (const uint8_t *)smb_buf(andx_buf);
1791 size_t old_size, new_size;
1793 size_t chain_padding = 0;
1794 size_t bytes_padding = 0;
1797 old_size = talloc_get_size(*poutbuf);
1800 * old_size == smb_wct means we're pushing the first request in for
1804 first_request = (old_size == smb_wct);
1806 if (!first_request && ((old_size % 4) != 0)) {
1808 * Align the wct field of subsequent requests to a 4-byte
1811 chain_padding = 4 - (old_size % 4);
1815 * After the old request comes the new wct field (1 byte), the vwv's
1816 * and the num_bytes field. After at we might need to align the bytes
1817 * given to us to "bytes_alignment", increasing the num_bytes value.
1820 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1822 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1823 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1826 new_size += bytes_padding + num_bytes;
1828 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1829 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
1830 (unsigned)new_size));
1834 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1835 if (outbuf == NULL) {
1836 DEBUG(0, ("talloc failed\n"));
1841 if (first_request) {
1842 SCVAL(outbuf, smb_com, smb_command);
1844 size_t andx_cmd_ofs;
1846 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1847 DEBUG(1, ("invalid command chain\n"));
1848 *poutbuf = talloc_realloc(
1849 NULL, *poutbuf, uint8_t, old_size);
1853 if (chain_padding != 0) {
1854 memset(outbuf + old_size, 0, chain_padding);
1855 old_size += chain_padding;
1858 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1859 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1865 * Push the chained request:
1870 SCVAL(outbuf, ofs, wct);
1877 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1878 ofs += sizeof(uint16_t) * wct;
1884 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1885 ofs += sizeof(uint16_t);
1891 if (bytes_padding != 0) {
1892 memset(outbuf + ofs, 0, bytes_padding);
1893 ofs += bytes_padding;
1900 memcpy(outbuf + ofs, bytes, num_bytes);
1905 /****************************************************************************
1906 Construct a chained reply and add it to the already made reply
1907 ****************************************************************************/
1909 void chain_reply(struct smb_request *req)
1911 size_t smblen = smb_len(req->inbuf);
1912 size_t already_used, length_needed;
1914 uint32_t chain_offset; /* uint32_t to avoid overflow */
1917 const uint16_t *vwv;
1921 if (IVAL(req->outbuf, smb_rcls) != 0) {
1922 fixup_chain_error_packet(req);
1926 * Any of the AndX requests and replies have at least a wct of
1927 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1928 * beginning of the SMB header to the next wct field.
1930 * None of the AndX requests put anything valuable in vwv[0] and [1],
1931 * so we can overwrite it here to form the chain.
1934 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1935 if (req->chain_outbuf == NULL) {
1936 req->chain_outbuf = talloc_realloc(
1937 req, req->outbuf, uint8_t,
1938 smb_len(req->outbuf) + 4);
1939 if (req->chain_outbuf == NULL) {
1940 smb_panic("talloc failed");
1948 * Here we assume that this is the end of the chain. For that we need
1949 * to set "next command" to 0xff and the offset to 0. If we later find
1950 * more commands in the chain, this will be overwritten again.
1953 SCVAL(req->outbuf, smb_vwv0, 0xff);
1954 SCVAL(req->outbuf, smb_vwv0+1, 0);
1955 SSVAL(req->outbuf, smb_vwv1, 0);
1957 if (req->chain_outbuf == NULL) {
1959 * In req->chain_outbuf we collect all the replies. Start the
1960 * chain by copying in the first reply.
1962 * We do the realloc because later on we depend on
1963 * talloc_get_size to determine the length of
1964 * chain_outbuf. The reply_xxx routines might have
1965 * over-allocated (reply_pipe_read_and_X used to be such an
1968 req->chain_outbuf = talloc_realloc(
1969 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1970 if (req->chain_outbuf == NULL) {
1971 smb_panic("talloc failed");
1976 * Update smb headers where subsequent chained commands
1977 * may have updated them.
1979 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1980 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1982 if (!smb_splice_chain(&req->chain_outbuf, req->outbuf)) {
1985 TALLOC_FREE(req->outbuf);
1989 * We use the old request's vwv field to grab the next chained command
1990 * and offset into the chained fields.
1993 chain_cmd = CVAL(req->vwv+0, 0);
1994 chain_offset = SVAL(req->vwv+1, 0);
1996 if (chain_cmd == 0xff) {
1998 * End of chain, no more requests from the client. So ship the
2001 smb_setlen((char *)(req->chain_outbuf),
2002 talloc_get_size(req->chain_outbuf) - 4);
2004 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2005 true, req->seqnum+1,
2006 IS_CONN_ENCRYPTED(req->conn)
2009 exit_server_cleanly("chain_reply: srv_send_smb "
2012 TALLOC_FREE(req->chain_outbuf);
2017 /* add a new perfcounter for this element of chain */
2018 SMB_PERFCOUNT_ADD(&req->pcd);
2019 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2020 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2023 * Check if the client tries to fool us. The chain offset
2024 * needs to point beyond the current request in the chain, it
2025 * needs to strictly grow. Otherwise we might be tricked into
2026 * an endless loop always processing the same request over and
2027 * over again. We used to assume that vwv and the byte buffer
2028 * array in a chain are always attached, but OS/2 the
2029 * Write&X/Read&X chain puts the Read&X vwv array right behind
2030 * the Write&X vwv chain. The Write&X bcc array is put behind
2031 * the Read&X vwv array. So now we check whether the chain
2032 * offset points strictly behind the previous vwv
2033 * array. req->buf points right after the vwv array of the
2034 * previous request. See
2035 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2039 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2040 if (chain_offset <= already_used) {
2045 * Next check: Make sure the chain offset does not point beyond the
2046 * overall smb request length.
2049 length_needed = chain_offset+1; /* wct */
2050 if (length_needed > smblen) {
2055 * Now comes the pointer magic. Goal here is to set up req->vwv and
2056 * req->buf correctly again to be able to call the subsequent
2057 * switch_message(). The chain offset (the former vwv[1]) points at
2058 * the new wct field.
2061 wct = CVAL(smb_base(req->inbuf), chain_offset);
2064 * Next consistency check: Make the new vwv array fits in the overall
2068 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2069 if (length_needed > smblen) {
2072 vwv = (const uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2075 * Now grab the new byte buffer....
2078 buflen = SVAL(vwv+wct, 0);
2081 * .. and check that it fits.
2084 length_needed += buflen;
2085 if (length_needed > smblen) {
2088 buf = (const uint8_t *)(vwv+wct+1);
2090 req->cmd = chain_cmd;
2092 req->vwv = discard_const_p(uint16_t, vwv);
2093 req->buflen = buflen;
2096 switch_message(chain_cmd, req, smblen);
2098 if (req->outbuf == NULL) {
2100 * This happens if the chained command has suspended itself or
2101 * if it has called srv_send_smb() itself.
2107 * We end up here if the chained command was not itself chained or
2108 * suspended, but for example a close() command. We now need to splice
2109 * the chained commands' outbuf into the already built up chain_outbuf
2110 * and ship the result.
2116 * We end up here if there's any error in the chain syntax. Report a
2117 * DOS error, just like Windows does.
2119 reply_force_doserror(req, ERRSRV, ERRerror);
2120 fixup_chain_error_packet(req);
2124 * This scary statement intends to set the
2125 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2126 * to the value req->outbuf carries
2128 SSVAL(req->chain_outbuf, smb_flg2,
2129 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2130 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2133 * Transfer the error codes from the subrequest to the main one
2135 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2136 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2138 if (!smb_splice_chain(&req->chain_outbuf, req->outbuf)) {
2139 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2141 TALLOC_FREE(req->outbuf);
2143 smb_setlen((char *)(req->chain_outbuf),
2144 talloc_get_size(req->chain_outbuf) - 4);
2146 show_msg((char *)(req->chain_outbuf));
2148 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2149 true, req->seqnum+1,
2150 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2152 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2154 TALLOC_FREE(req->chain_outbuf);
2158 /****************************************************************************
2159 Check if services need reloading.
2160 ****************************************************************************/
2162 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2165 if (last_smb_conf_reload_time == 0) {
2166 last_smb_conf_reload_time = t;
2169 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2170 reload_services(sconn, conn_snum_used, true);
2171 last_smb_conf_reload_time = t;
2175 static bool fd_is_readable(int fd)
2179 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2181 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2185 static void smbd_server_connection_write_handler(
2186 struct smbd_server_connection *sconn)
2188 /* TODO: make write nonblocking */
2191 static void smbd_server_connection_read_handler(
2192 struct smbd_server_connection *sconn, int fd)
2194 uint8_t *inbuf = NULL;
2195 size_t inbuf_len = 0;
2196 size_t unread_bytes = 0;
2197 bool encrypted = false;
2198 TALLOC_CTX *mem_ctx = talloc_tos();
2204 if (lp_async_smb_echo_handler()
2205 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2207 * This is the super-ugly hack to prefer the packets
2208 * forwarded by the echo handler over the ones by the
2211 fd = sconn->smb1.echo_handler.trusted_fd;
2214 from_client = (sconn->sock == fd);
2217 smbd_lock_socket(sconn);
2219 if (!fd_is_readable(fd)) {
2220 DEBUG(10,("the echo listener was faster\n"));
2221 smbd_unlock_socket(sconn);
2226 /* TODO: make this completely nonblocking */
2227 status = receive_smb_talloc(mem_ctx, sconn, fd,
2228 (char **)(void *)&inbuf,
2232 &inbuf_len, &seqnum,
2233 false /* trusted channel */);
2236 smbd_unlock_socket(sconn);
2239 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2242 if (NT_STATUS_IS_ERR(status)) {
2243 exit_server_cleanly("failed to receive smb request");
2245 if (!NT_STATUS_IS_OK(status)) {
2250 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2251 seqnum, encrypted, NULL);
2254 static void smbd_server_connection_handler(struct event_context *ev,
2255 struct fd_event *fde,
2259 struct smbd_server_connection *conn = talloc_get_type(private_data,
2260 struct smbd_server_connection);
2262 if (flags & EVENT_FD_WRITE) {
2263 smbd_server_connection_write_handler(conn);
2266 if (flags & EVENT_FD_READ) {
2267 smbd_server_connection_read_handler(conn, conn->sock);
2272 static void smbd_server_echo_handler(struct event_context *ev,
2273 struct fd_event *fde,
2277 struct smbd_server_connection *conn = talloc_get_type(private_data,
2278 struct smbd_server_connection);
2280 if (flags & EVENT_FD_WRITE) {
2281 smbd_server_connection_write_handler(conn);
2284 if (flags & EVENT_FD_READ) {
2285 smbd_server_connection_read_handler(
2286 conn, conn->smb1.echo_handler.trusted_fd);
2291 #ifdef CLUSTER_SUPPORT
2292 /****************************************************************************
2293 received when we should release a specific IP
2294 ****************************************************************************/
2295 static void release_ip(const char *ip, void *priv)
2297 const char *addr = (const char *)priv;
2298 const char *p = addr;
2300 if (strncmp("::ffff:", addr, 7) == 0) {
2304 DEBUG(10, ("Got release IP message for %s, "
2305 "our address is %s\n", ip, p));
2307 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2308 /* we can't afford to do a clean exit - that involves
2309 database writes, which would potentially mean we
2310 are still running after the failover has finished -
2311 we have to get rid of this process ID straight
2313 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2315 /* note we must exit with non-zero status so the unclean handler gets
2316 called in the parent, so that the brl database is tickled */
2321 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2322 struct sockaddr_storage *client)
2325 length = sizeof(*server);
2326 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2329 length = sizeof(*client);
2330 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2338 * Send keepalive packets to our client
2340 static bool keepalive_fn(const struct timeval *now, void *private_data)
2342 struct smbd_server_connection *sconn = talloc_get_type_abort(
2343 private_data, struct smbd_server_connection);
2346 if (sconn->using_smb2) {
2347 /* Don't do keepalives on an SMB2 connection. */
2351 smbd_lock_socket(sconn);
2352 ret = send_keepalive(sconn->sock);
2353 smbd_unlock_socket(sconn);
2356 char addr[INET6_ADDRSTRLEN];
2358 * Try and give an error message saying what
2361 DEBUG(0, ("send_keepalive failed for client %s. "
2362 "Error %s - exiting\n",
2363 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2371 * Do the recurring check if we're idle
2373 static bool deadtime_fn(const struct timeval *now, void *private_data)
2375 struct smbd_server_connection *sconn =
2376 (struct smbd_server_connection *)private_data;
2378 if ((conn_num_open(sconn) == 0)
2379 || (conn_idle_all(sconn, now->tv_sec))) {
2380 DEBUG( 2, ( "Closing idle connection\n" ) );
2381 messaging_send(sconn->msg_ctx,
2382 messaging_server_id(sconn->msg_ctx),
2383 MSG_SHUTDOWN, &data_blob_null);
2391 * Do the recurring log file and smb.conf reload checks.
2394 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2396 struct smbd_server_connection *sconn = talloc_get_type_abort(
2397 private_data, struct smbd_server_connection);
2399 DEBUG(5, ("housekeeping\n"));
2401 change_to_root_user();
2403 /* update printer queue caches if necessary */
2404 update_monitored_printq_cache(sconn->msg_ctx);
2406 /* check if we need to reload services */
2407 check_reload(sconn, time_mono(NULL));
2409 /* Change machine password if neccessary. */
2410 attempt_machine_password_change();
2413 * Force a log file check.
2415 force_check_log_size();
2421 * Read an smb packet in the echo handler child, giving the parent
2422 * smbd one second to react once the socket becomes readable.
2425 struct smbd_echo_read_state {
2426 struct tevent_context *ev;
2427 struct smbd_server_connection *sconn;
2434 static void smbd_echo_read_readable(struct tevent_req *subreq);
2435 static void smbd_echo_read_waited(struct tevent_req *subreq);
2437 static struct tevent_req *smbd_echo_read_send(
2438 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2439 struct smbd_server_connection *sconn)
2441 struct tevent_req *req, *subreq;
2442 struct smbd_echo_read_state *state;
2444 req = tevent_req_create(mem_ctx, &state,
2445 struct smbd_echo_read_state);
2450 state->sconn = sconn;
2452 subreq = wait_for_read_send(state, ev, sconn->sock);
2453 if (tevent_req_nomem(subreq, req)) {
2454 return tevent_req_post(req, ev);
2456 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2460 static void smbd_echo_read_readable(struct tevent_req *subreq)
2462 struct tevent_req *req = tevent_req_callback_data(
2463 subreq, struct tevent_req);
2464 struct smbd_echo_read_state *state = tevent_req_data(
2465 req, struct smbd_echo_read_state);
2469 ok = wait_for_read_recv(subreq, &err);
2470 TALLOC_FREE(subreq);
2472 tevent_req_nterror(req, map_nt_error_from_unix(err));
2477 * Give the parent smbd one second to step in
2480 subreq = tevent_wakeup_send(
2481 state, state->ev, timeval_current_ofs(1, 0));
2482 if (tevent_req_nomem(subreq, req)) {
2485 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2488 static void smbd_echo_read_waited(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);
2494 struct smbd_server_connection *sconn = state->sconn;
2500 ok = tevent_wakeup_recv(subreq);
2501 TALLOC_FREE(subreq);
2503 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2507 ok = smbd_lock_socket_internal(sconn);
2509 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2510 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2514 if (!fd_is_readable(sconn->sock)) {
2515 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2516 (int)sys_getpid()));
2518 ok = smbd_unlock_socket_internal(sconn);
2520 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2521 DEBUG(1, ("%s: failed to unlock socket\n",
2526 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2527 if (tevent_req_nomem(subreq, req)) {
2530 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2534 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2540 false /* trusted_channel*/);
2542 if (tevent_req_nterror(req, status)) {
2543 tevent_req_nterror(req, status);
2544 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2545 (int)sys_getpid(), nt_errstr(status)));
2549 ok = smbd_unlock_socket_internal(sconn);
2551 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2552 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2555 tevent_req_done(req);
2558 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2559 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2561 struct smbd_echo_read_state *state = tevent_req_data(
2562 req, struct smbd_echo_read_state);
2565 if (tevent_req_is_nterror(req, &status)) {
2568 *pbuf = talloc_move(mem_ctx, &state->buf);
2569 *pbuflen = state->buflen;
2570 *pseqnum = state->seqnum;
2571 return NT_STATUS_OK;
2574 struct smbd_echo_state {
2575 struct tevent_context *ev;
2576 struct iovec *pending;
2577 struct smbd_server_connection *sconn;
2580 struct tevent_fd *parent_fde;
2582 struct tevent_req *write_req;
2585 static void smbd_echo_writer_done(struct tevent_req *req);
2587 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2591 if (state->write_req != NULL) {
2595 num_pending = talloc_array_length(state->pending);
2596 if (num_pending == 0) {
2600 state->write_req = writev_send(state, state->ev, NULL,
2601 state->parent_pipe, false,
2602 state->pending, num_pending);
2603 if (state->write_req == NULL) {
2604 DEBUG(1, ("writev_send failed\n"));
2608 talloc_steal(state->write_req, state->pending);
2609 state->pending = NULL;
2611 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2615 static void smbd_echo_writer_done(struct tevent_req *req)
2617 struct smbd_echo_state *state = tevent_req_callback_data(
2618 req, struct smbd_echo_state);
2622 written = writev_recv(req, &err);
2624 state->write_req = NULL;
2625 if (written == -1) {
2626 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2629 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2630 smbd_echo_activate_writer(state);
2633 static bool smbd_echo_reply(struct smbd_echo_state *state,
2634 uint8_t *inbuf, size_t inbuf_len,
2637 struct smb_request req;
2638 uint16_t num_replies;
2642 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2643 DEBUG(10, ("Got netbios keepalive\n"));
2650 if (inbuf_len < smb_size) {
2651 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2654 if (!valid_smb_header(state->sconn, inbuf)) {
2655 DEBUG(10, ("Got invalid SMB header\n"));
2659 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2665 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2666 smb_messages[req.cmd].name
2667 ? smb_messages[req.cmd].name : "unknown"));
2669 if (req.cmd != SMBecho) {
2676 num_replies = SVAL(req.vwv+0, 0);
2677 if (num_replies != 1) {
2678 /* Not a Windows "Hey, you're still there?" request */
2682 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2684 DEBUG(10, ("create_outbuf failed\n"));
2687 req.outbuf = (uint8_t *)outbuf;
2689 SSVAL(req.outbuf, smb_vwv0, num_replies);
2691 if (req.buflen > 0) {
2692 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2695 ok = srv_send_smb(req.sconn,
2699 TALLOC_FREE(outbuf);
2707 static void smbd_echo_exit(struct tevent_context *ev,
2708 struct tevent_fd *fde, uint16_t flags,
2711 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2715 static void smbd_echo_got_packet(struct tevent_req *req);
2717 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2720 struct smbd_echo_state *state;
2721 struct tevent_req *read_req;
2723 state = talloc_zero(sconn, struct smbd_echo_state);
2724 if (state == NULL) {
2725 DEBUG(1, ("talloc failed\n"));
2728 state->sconn = sconn;
2729 state->parent_pipe = parent_pipe;
2730 state->ev = s3_tevent_context_init(state);
2731 if (state->ev == NULL) {
2732 DEBUG(1, ("tevent_context_init failed\n"));
2736 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2737 TEVENT_FD_READ, smbd_echo_exit,
2739 if (state->parent_fde == NULL) {
2740 DEBUG(1, ("tevent_add_fd failed\n"));
2745 read_req = smbd_echo_read_send(state, state->ev, sconn);
2746 if (read_req == NULL) {
2747 DEBUG(1, ("smbd_echo_read_send failed\n"));
2751 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2754 if (tevent_loop_once(state->ev) == -1) {
2755 DEBUG(1, ("tevent_loop_once failed: %s\n",
2763 static void smbd_echo_got_packet(struct tevent_req *req)
2765 struct smbd_echo_state *state = tevent_req_callback_data(
2766 req, struct smbd_echo_state);
2770 uint32_t seqnum = 0;
2773 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2775 if (!NT_STATUS_IS_OK(status)) {
2776 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2777 nt_errstr(status)));
2781 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2787 num_pending = talloc_array_length(state->pending);
2788 tmp = talloc_realloc(state, state->pending, struct iovec,
2791 DEBUG(1, ("talloc_realloc failed\n"));
2794 state->pending = tmp;
2796 if (buflen >= smb_size) {
2798 * place the seqnum in the packet so that the main process
2799 * can reply with signing
2801 SIVAL(buf, smb_ss_field, seqnum);
2802 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2805 iov = &state->pending[num_pending];
2806 iov->iov_base = buf;
2807 iov->iov_len = buflen;
2809 DEBUG(10,("echo_handler[%d]: forward to main\n",
2810 (int)sys_getpid()));
2811 smbd_echo_activate_writer(state);
2814 req = smbd_echo_read_send(state, state->ev, state->sconn);
2816 DEBUG(1, ("smbd_echo_read_send failed\n"));
2819 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2824 * Handle SMBecho requests in a forked child process
2826 bool fork_echo_handler(struct smbd_server_connection *sconn)
2828 int listener_pipe[2];
2832 res = pipe(listener_pipe);
2834 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2837 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2838 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2839 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2847 close(listener_pipe[0]);
2848 set_blocking(listener_pipe[1], false);
2850 status = reinit_after_fork(sconn->msg_ctx,
2853 if (!NT_STATUS_IS_OK(status)) {
2854 DEBUG(1, ("reinit_after_fork failed: %s\n",
2855 nt_errstr(status)));
2858 smbd_echo_loop(sconn, listener_pipe[1]);
2861 close(listener_pipe[1]);
2862 listener_pipe[1] = -1;
2863 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2865 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2868 * Without smb signing this is the same as the normal smbd
2869 * listener. This needs to change once signing comes in.
2871 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
2873 sconn->smb1.echo_handler.trusted_fd,
2875 smbd_server_echo_handler,
2877 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2878 DEBUG(1, ("event_add_fd failed\n"));
2885 if (listener_pipe[0] != -1) {
2886 close(listener_pipe[0]);
2888 if (listener_pipe[1] != -1) {
2889 close(listener_pipe[1]);
2891 sconn->smb1.echo_handler.trusted_fd = -1;
2892 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2893 close(sconn->smb1.echo_handler.socket_lock_fd);
2895 sconn->smb1.echo_handler.trusted_fd = -1;
2896 sconn->smb1.echo_handler.socket_lock_fd = -1;
2902 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2903 struct sockaddr_storage *srv,
2904 struct sockaddr_storage *clnt)
2906 struct ctdbd_connection *cconn;
2907 char tmp_addr[INET6_ADDRSTRLEN];
2910 cconn = messaging_ctdbd_connection();
2911 if (cconn == NULL) {
2912 return NT_STATUS_NO_MEMORY;
2915 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2916 addr = talloc_strdup(cconn, tmp_addr);
2918 return NT_STATUS_NO_MEMORY;
2920 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2925 static bool uid_in_use(const struct user_struct *user, uid_t uid)
2928 if (user->session_info &&
2929 (user->session_info->unix_token->uid == uid)) {
2937 static bool gid_in_use(const struct user_struct *user, gid_t gid)
2940 if (user->session_info != NULL) {
2942 struct security_unix_token *utok;
2944 utok = user->session_info->unix_token;
2945 if (utok->gid == gid) {
2948 for(i=0; i<utok->ngroups; i++) {
2949 if (utok->groups[i] == gid) {
2959 static bool sid_in_use(const struct user_struct *user,
2960 const struct dom_sid *psid)
2963 struct security_token *tok;
2965 if (user->session_info == NULL) {
2968 tok = user->session_info->security_token;
2971 * Not sure session_info->security_token can
2972 * ever be NULL. This check might be not
2977 if (security_token_has_sid(tok, psid)) {
2985 static bool id_in_use(const struct user_struct *user,
2986 const struct id_cache_ref *id)
2990 return uid_in_use(user, id->id.uid);
2992 return gid_in_use(user, id->id.gid);
2994 return sid_in_use(user, &id->id.sid);
3001 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3004 struct server_id server_id,
3007 const char *msg = (data && data->data)
3008 ? (const char *)data->data : "<NULL>";
3009 struct user_struct *validated_users;
3010 struct id_cache_ref id;
3011 struct smbd_server_connection *sconn =
3012 talloc_get_type_abort(private_data,
3013 struct smbd_server_connection);
3015 validated_users = sconn->smb1.sessions.validated_users;
3017 if (!id_cache_ref_parse(msg, &id)) {
3018 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3022 if (id_in_use(validated_users, &id)) {
3023 exit_server_cleanly(msg);
3025 id_cache_delete_from_cache(&id);
3028 /****************************************************************************
3029 Process commands from the client
3030 ****************************************************************************/
3032 void smbd_process(struct tevent_context *ev_ctx,
3033 struct smbd_server_connection *sconn)
3035 TALLOC_CTX *frame = talloc_stackframe();
3036 struct sockaddr_storage ss;
3037 struct sockaddr *sa = NULL;
3038 socklen_t sa_socklen;
3039 struct tsocket_address *local_address = NULL;
3040 struct tsocket_address *remote_address = NULL;
3041 const char *locaddr = NULL;
3042 const char *remaddr = NULL;
3046 if (lp_maxprotocol() >= PROTOCOL_SMB2_02) {
3048 * We're not making the decision here,
3049 * we're just allowing the client
3050 * to decide between SMB1 and SMB2
3051 * with the first negprot
3054 sconn->using_smb2 = true;
3057 /* Ensure child is set to blocking mode */
3058 set_blocking(sconn->sock,True);
3060 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3061 set_socket_options(sconn->sock, lp_socket_options());
3063 sa = (struct sockaddr *)(void *)&ss;
3064 sa_socklen = sizeof(ss);
3065 ret = getpeername(sconn->sock, sa, &sa_socklen);
3067 int level = (errno == ENOTCONN)?2:0;
3068 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3069 exit_server_cleanly("getpeername() failed.\n");
3071 ret = tsocket_address_bsd_from_sockaddr(sconn,
3075 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3076 __location__, strerror(errno)));
3077 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3080 sa = (struct sockaddr *)(void *)&ss;
3081 sa_socklen = sizeof(ss);
3082 ret = getsockname(sconn->sock, sa, &sa_socklen);
3084 int level = (errno == ENOTCONN)?2:0;
3085 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3086 exit_server_cleanly("getsockname() failed.\n");
3088 ret = tsocket_address_bsd_from_sockaddr(sconn,
3092 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3093 __location__, strerror(errno)));
3094 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3097 sconn->local_address = local_address;
3098 sconn->remote_address = remote_address;
3100 if (tsocket_address_is_inet(local_address, "ip")) {
3101 locaddr = tsocket_address_inet_addr_string(
3102 sconn->local_address,
3104 if (locaddr == NULL) {
3105 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3106 __location__, strerror(errno)));
3107 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3110 locaddr = "0.0.0.0";
3113 if (tsocket_address_is_inet(remote_address, "ip")) {
3114 remaddr = tsocket_address_inet_addr_string(
3115 sconn->remote_address,
3117 if (remaddr == NULL) {
3118 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3119 __location__, strerror(errno)));
3120 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3123 remaddr = "0.0.0.0";
3126 /* this is needed so that we get decent entries
3127 in smbstatus for port 445 connects */
3128 set_remote_machine_name(remaddr, false);
3129 reload_services(sconn, conn_snum_used, true);
3132 * Before the first packet, check the global hosts allow/ hosts deny
3133 * parameters before doing any parsing of packets passed to us by the
3134 * client. This prevents attacks on our parsing code from hosts not in
3135 * the hosts allow list.
3138 ret = get_remote_hostname(remote_address,
3142 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3143 __location__, strerror(errno)));
3144 exit_server_cleanly("get_remote_hostname failed.\n");
3146 if (strequal(rhost, "UNKNOWN")) {
3147 rhost = talloc_strdup(talloc_tos(), remaddr);
3149 sconn->remote_hostname = talloc_move(sconn, &rhost);
3151 sub_set_socket_ids(remaddr,
3152 sconn->remote_hostname,
3155 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3156 sconn->remote_hostname,
3159 * send a negative session response "not listening on calling
3162 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3163 DEBUG( 1, ("Connection denied from %s to %s\n",
3164 tsocket_address_string(remote_address, talloc_tos()),
3165 tsocket_address_string(local_address, talloc_tos())));
3166 (void)srv_send_smb(sconn,(char *)buf, false,
3168 exit_server_cleanly("connection denied");
3171 DEBUG(10, ("Connection allowed from %s to %s\n",
3172 tsocket_address_string(remote_address, talloc_tos()),
3173 tsocket_address_string(local_address, talloc_tos())));
3177 smb_perfcount_init();
3179 if (!init_account_policy()) {
3180 exit_server("Could not open account policy tdb.\n");
3183 if (*lp_rootdir()) {
3184 if (chroot(lp_rootdir()) != 0) {
3185 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3186 exit_server("Failed to chroot()");
3188 if (chdir("/") == -1) {
3189 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3190 exit_server("Failed to chroot()");
3192 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3195 if (!srv_init_signing(sconn)) {
3196 exit_server("Failed to init smb_signing");
3200 if (!init_oplocks(sconn))
3201 exit_server("Failed to init oplocks");
3203 /* register our message handlers */
3204 messaging_register(sconn->msg_ctx, sconn,
3205 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3206 messaging_register(sconn->msg_ctx, sconn,
3207 MSG_SMB_CLOSE_FILE, msg_close_file);
3208 messaging_register(sconn->msg_ctx, sconn,
3209 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3211 id_cache_register_msgs(sconn->msg_ctx);
3212 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3213 messaging_register(sconn->msg_ctx, sconn,
3214 ID_CACHE_KILL, smbd_id_cache_kill);
3216 messaging_deregister(sconn->msg_ctx,
3217 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3218 messaging_register(sconn->msg_ctx, sconn,
3219 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3222 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3223 * MSGs to all child processes
3225 messaging_deregister(sconn->msg_ctx,
3227 messaging_register(sconn->msg_ctx, NULL,
3228 MSG_DEBUG, debug_message);
3230 if ((lp_keepalive() != 0)
3231 && !(event_add_idle(ev_ctx, NULL,
3232 timeval_set(lp_keepalive(), 0),
3233 "keepalive", keepalive_fn,
3235 DEBUG(0, ("Could not add keepalive event\n"));
3239 if (!(event_add_idle(ev_ctx, NULL,
3240 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3241 "deadtime", deadtime_fn, sconn))) {
3242 DEBUG(0, ("Could not add deadtime event\n"));
3246 if (!(event_add_idle(ev_ctx, NULL,
3247 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3248 "housekeeping", housekeeping_fn, sconn))) {
3249 DEBUG(0, ("Could not add housekeeping event\n"));
3253 #ifdef CLUSTER_SUPPORT
3255 if (lp_clustering()) {
3257 * We need to tell ctdb about our client's TCP
3258 * connection, so that for failover ctdbd can send
3259 * tickle acks, triggering a reconnection by the
3263 struct sockaddr_storage srv, clnt;
3265 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3267 status = smbd_register_ips(sconn, &srv, &clnt);
3268 if (!NT_STATUS_IS_OK(status)) {
3269 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3270 nt_errstr(status)));
3274 DEBUG(0,("Unable to get tcp info for "
3275 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3282 sconn->nbt.got_session = false;
3284 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3286 sconn->smb1.sessions.done_sesssetup = false;
3287 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3288 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3289 /* users from session setup */
3290 sconn->smb1.sessions.session_userlist = NULL;
3291 /* workgroup from session setup. */
3292 sconn->smb1.sessions.session_workgroup = NULL;
3293 /* this holds info on user ids that are already validated for this VC */
3294 sconn->smb1.sessions.validated_users = NULL;
3295 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3296 sconn->smb1.sessions.num_validated_vuids = 0;
3299 if (!init_dptrs(sconn)) {
3300 exit_server("init_dptrs() failed");
3303 sconn->smb1.fde = event_add_fd(ev_ctx,
3307 smbd_server_connection_handler,
3309 if (!sconn->smb1.fde) {
3310 exit_server("failed to create smbd_server_connection fde");
3316 frame = talloc_stackframe_pool(8192);
3319 if (tevent_loop_once(ev_ctx) == -1) {
3320 if (errno != EINTR) {
3321 DEBUG(3, ("tevent_loop_once failed: %s,"
3322 " exiting\n", strerror(errno) ));
3330 exit_server_cleanly(NULL);
3333 bool req_is_in_chain(struct smb_request *req)
3335 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3337 * We're right now handling a subsequent request, so we must
3343 if (!is_andx_req(req->cmd)) {
3349 * Okay, an illegal request, but definitely not chained :-)
3354 return (CVAL(req->vwv+0, 0) != 0xFF);