s3:smb2_server: pass smbXsrv_connection to smbd_smb2_first_negprot()
[Samba.git] / source3 / smbd / process.c
blobb970f00b9d3385822bc546b36ac04898d5ca6e4b
1 /*
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/>.
21 #include "includes.h"
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"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.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"
42 #include "serverid.h"
43 #include "system/threads.h"
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 smbXsrv_connection *xconn;
51 struct tevent_timer *te;
52 struct smb_perfcount_data pcd;
53 uint32_t seqnum;
54 bool encrypted;
55 bool processed;
56 DATA_BLOB buf;
57 struct deferred_open_record *open_rec;
60 static void construct_reply_common(struct smb_request *req, const char *inbuf,
61 char *outbuf);
62 static struct pending_message_list *get_deferred_open_message_smb(
63 struct smbd_server_connection *sconn, uint64_t mid);
64 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
66 static void smbd_echo_init(struct smbXsrv_connection *xconn)
68 xconn->smb1.echo_handler.trusted_fd = -1;
69 xconn->smb1.echo_handler.socket_lock_fd = -1;
70 #ifdef HAVE_ROBUST_MUTEXES
71 xconn->smb1.echo_handler.socket_mutex = NULL;
72 #endif
75 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
77 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
78 return true;
81 #ifdef HAVE_ROBUST_MUTEXES
82 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
83 return true;
85 #endif
87 return false;
90 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
92 struct smbXsrv_connection *xconn = sconn->conn;
94 if (!smbd_echo_active(xconn)) {
95 return true;
98 xconn->smb1.echo_handler.ref_count++;
100 if (xconn->smb1.echo_handler.ref_count > 1) {
101 return true;
104 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
106 #ifdef HAVE_ROBUST_MUTEXES
107 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
108 int ret = EINTR;
110 while (ret == EINTR) {
111 ret = pthread_mutex_lock(
112 xconn->smb1.echo_handler.socket_mutex);
113 if (ret == 0) {
114 break;
117 if (ret != 0) {
118 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
119 strerror(ret)));
120 return false;
123 #endif
125 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
126 bool ok;
128 do {
129 ok = fcntl_lock(
130 xconn->smb1.echo_handler.socket_lock_fd,
131 F_SETLKW, 0, 0, F_WRLCK);
132 } while (!ok && (errno == EINTR));
134 if (!ok) {
135 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
136 return false;
140 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
142 return true;
145 void smbd_lock_socket(struct smbd_server_connection *sconn)
147 if (!smbd_lock_socket_internal(sconn)) {
148 exit_server_cleanly("failed to lock socket");
152 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
154 struct smbXsrv_connection *xconn = sconn->conn;
156 if (!smbd_echo_active(xconn)) {
157 return true;
160 xconn->smb1.echo_handler.ref_count--;
162 if (xconn->smb1.echo_handler.ref_count > 0) {
163 return true;
166 #ifdef HAVE_ROBUST_MUTEXES
167 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
168 int ret = EINTR;
170 while (ret == EINTR) {
171 ret = pthread_mutex_unlock(
172 xconn->smb1.echo_handler.socket_mutex);
173 if (ret == 0) {
174 break;
177 if (ret != 0) {
178 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
179 strerror(ret)));
180 return false;
183 #endif
185 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
186 bool ok;
188 do {
189 ok = fcntl_lock(
190 xconn->smb1.echo_handler.socket_lock_fd,
191 F_SETLKW, 0, 0, F_UNLCK);
192 } while (!ok && (errno == EINTR));
194 if (!ok) {
195 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
196 return false;
200 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
202 return true;
205 void smbd_unlock_socket(struct smbd_server_connection *sconn)
207 if (!smbd_unlock_socket_internal(sconn)) {
208 exit_server_cleanly("failed to unlock socket");
212 /* Accessor function for smb_read_error for smbd functions. */
214 /****************************************************************************
215 Send an smb to a fd.
216 ****************************************************************************/
218 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
219 bool do_signing, uint32_t seqnum,
220 bool do_encrypt,
221 struct smb_perfcount_data *pcd)
223 struct smbXsrv_connection *xconn = sconn->conn;
224 size_t len = 0;
225 ssize_t ret;
226 char *buf_out = buffer;
228 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
230 * we're not supposed to do any io
232 return true;
235 smbd_lock_socket(sconn);
237 if (do_signing) {
238 /* Sign the outgoing packet if required. */
239 srv_calculate_sign_mac(xconn, buf_out, seqnum);
242 if (do_encrypt) {
243 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
244 if (!NT_STATUS_IS_OK(status)) {
245 DEBUG(0, ("send_smb: SMB encryption failed "
246 "on outgoing packet! Error %s\n",
247 nt_errstr(status) ));
248 ret = -1;
249 goto out;
253 len = smb_len_large(buf_out) + 4;
255 ret = write_data(xconn->transport.sock, buf_out, len);
256 if (ret <= 0) {
257 int saved_errno = errno;
259 * Try and give an error message saying what
260 * client failed.
262 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
263 (int)getpid(), (int)len,
264 smbXsrv_connection_dbg(xconn),
265 (int)ret, strerror(saved_errno)));
266 errno = saved_errno;
268 srv_free_enc_buffer(sconn, buf_out);
269 goto out;
272 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
273 srv_free_enc_buffer(sconn, buf_out);
274 out:
275 SMB_PERFCOUNT_END(pcd);
277 smbd_unlock_socket(sconn);
278 return (ret > 0);
281 /*******************************************************************
282 Setup the word count and byte count for a smb message.
283 ********************************************************************/
285 int srv_set_message(char *buf,
286 int num_words,
287 int num_bytes,
288 bool zero)
290 if (zero && (num_words || num_bytes)) {
291 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
293 SCVAL(buf,smb_wct,num_words);
294 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
295 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
296 return (smb_size + num_words*2 + num_bytes);
299 static bool valid_smb_header(struct smbd_server_connection *sconn,
300 const uint8_t *inbuf)
302 if (is_encrypted_packet(sconn, inbuf)) {
303 return true;
306 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
307 * but it just looks weird to call strncmp for this one.
309 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
312 /* Socket functions for smbd packet processing. */
314 static bool valid_packet_size(size_t len)
317 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
318 * of header. Don't print the error if this fits.... JRA.
321 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
322 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
323 (unsigned long)len));
324 return false;
326 return true;
329 static NTSTATUS read_packet_remainder(int fd, char *buffer,
330 unsigned int timeout, ssize_t len)
332 NTSTATUS status;
334 if (len <= 0) {
335 return NT_STATUS_OK;
338 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
339 if (!NT_STATUS_IS_OK(status)) {
340 char addr[INET6_ADDRSTRLEN];
341 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
342 "error = %s.\n",
343 get_peer_addr(fd, addr, sizeof(addr)),
344 nt_errstr(status)));
346 return status;
349 /****************************************************************************
350 Attempt a zerocopy writeX read. We know here that len > smb_size-4
351 ****************************************************************************/
354 * Unfortunately, earlier versions of smbclient/libsmbclient
355 * don't send this "standard" writeX header. I've fixed this
356 * for 3.2 but we'll use the old method with earlier versions.
357 * Windows and CIFSFS at least use this standard size. Not
358 * sure about MacOSX.
361 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
362 (2*14) + /* word count (including bcc) */ \
363 1 /* pad byte */)
365 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
366 const char lenbuf[4],
367 struct smbd_server_connection *sconn,
368 int sock,
369 char **buffer,
370 unsigned int timeout,
371 size_t *p_unread,
372 size_t *len_ret)
374 /* Size of a WRITEX call (+4 byte len). */
375 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
376 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
377 ssize_t toread;
378 NTSTATUS status;
380 memcpy(writeX_header, lenbuf, 4);
382 status = read_fd_with_timeout(
383 sock, writeX_header + 4,
384 STANDARD_WRITE_AND_X_HEADER_SIZE,
385 STANDARD_WRITE_AND_X_HEADER_SIZE,
386 timeout, NULL);
388 if (!NT_STATUS_IS_OK(status)) {
389 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
390 "error = %s.\n",
391 tsocket_address_string(sconn->remote_address,
392 talloc_tos()),
393 nt_errstr(status)));
394 return status;
398 * Ok - now try and see if this is a possible
399 * valid writeX call.
402 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
404 * If the data offset is beyond what
405 * we've read, drain the extra bytes.
407 uint16_t doff = SVAL(writeX_header,smb_vwv11);
408 ssize_t newlen;
410 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
411 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
412 if (drain_socket(sock, drain) != drain) {
413 smb_panic("receive_smb_raw_talloc_partial_read:"
414 " failed to drain pending bytes");
416 } else {
417 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
420 /* Spoof down the length and null out the bcc. */
421 set_message_bcc(writeX_header, 0);
422 newlen = smb_len(writeX_header);
424 /* Copy the header we've written. */
426 *buffer = (char *)talloc_memdup(mem_ctx,
427 writeX_header,
428 sizeof(writeX_header));
430 if (*buffer == NULL) {
431 DEBUG(0, ("Could not allocate inbuf of length %d\n",
432 (int)sizeof(writeX_header)));
433 return NT_STATUS_NO_MEMORY;
436 /* Work out the remaining bytes. */
437 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
438 *len_ret = newlen + 4;
439 return NT_STATUS_OK;
442 if (!valid_packet_size(len)) {
443 return NT_STATUS_INVALID_PARAMETER;
447 * Not a valid writeX call. Just do the standard
448 * talloc and return.
451 *buffer = talloc_array(mem_ctx, char, len+4);
453 if (*buffer == NULL) {
454 DEBUG(0, ("Could not allocate inbuf of length %d\n",
455 (int)len+4));
456 return NT_STATUS_NO_MEMORY;
459 /* Copy in what we already read. */
460 memcpy(*buffer,
461 writeX_header,
462 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
463 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
465 if(toread > 0) {
466 status = read_packet_remainder(
467 sock,
468 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
469 timeout, toread);
471 if (!NT_STATUS_IS_OK(status)) {
472 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
473 nt_errstr(status)));
474 return status;
478 *len_ret = len + 4;
479 return NT_STATUS_OK;
482 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
483 struct smbd_server_connection *sconn,
484 int sock,
485 char **buffer, unsigned int timeout,
486 size_t *p_unread, size_t *plen)
488 struct smbXsrv_connection *xconn = sconn->conn;
489 char lenbuf[4];
490 size_t len;
491 int min_recv_size = lp_min_receive_file_size();
492 NTSTATUS status;
494 *p_unread = 0;
496 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
497 &len);
498 if (!NT_STATUS_IS_OK(status)) {
499 return status;
502 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
503 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
504 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
505 !srv_is_signing_active(xconn) &&
506 xconn->smb1.echo_handler.trusted_fde == NULL) {
508 return receive_smb_raw_talloc_partial_read(
509 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
510 p_unread, plen);
513 if (!valid_packet_size(len)) {
514 return NT_STATUS_INVALID_PARAMETER;
518 * The +4 here can't wrap, we've checked the length above already.
521 *buffer = talloc_array(mem_ctx, char, len+4);
523 if (*buffer == NULL) {
524 DEBUG(0, ("Could not allocate inbuf of length %d\n",
525 (int)len+4));
526 return NT_STATUS_NO_MEMORY;
529 memcpy(*buffer, lenbuf, sizeof(lenbuf));
531 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
532 if (!NT_STATUS_IS_OK(status)) {
533 return status;
536 *plen = len + 4;
537 return NT_STATUS_OK;
540 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
541 struct smbd_server_connection *sconn,
542 int sock,
543 char **buffer, unsigned int timeout,
544 size_t *p_unread, bool *p_encrypted,
545 size_t *p_len,
546 uint32_t *seqnum,
547 bool trusted_channel)
549 struct smbXsrv_connection *xconn = sconn->conn;
550 size_t len = 0;
551 NTSTATUS status;
553 *p_encrypted = false;
555 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
556 p_unread, &len);
557 if (!NT_STATUS_IS_OK(status)) {
558 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
559 ("receive_smb_raw_talloc failed for client %s "
560 "read error = %s.\n",
561 tsocket_address_string(sconn->remote_address,
562 talloc_tos()),
563 nt_errstr(status)) );
564 return status;
567 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
568 status = srv_decrypt_buffer(sconn, *buffer);
569 if (!NT_STATUS_IS_OK(status)) {
570 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
571 "incoming packet! Error %s\n",
572 nt_errstr(status) ));
573 return status;
575 *p_encrypted = true;
578 /* Check the incoming SMB signature. */
579 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
580 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
581 "incoming packet!\n"));
582 return NT_STATUS_INVALID_NETWORK_RESPONSE;
585 *p_len = len;
586 return NT_STATUS_OK;
590 * Initialize a struct smb_request from an inbuf
593 static bool init_smb_request(struct smb_request *req,
594 struct smbd_server_connection *sconn,
595 struct smbXsrv_connection *xconn,
596 const uint8 *inbuf,
597 size_t unread_bytes, bool encrypted,
598 uint32_t seqnum)
600 struct smbXsrv_tcon *tcon;
601 NTSTATUS status;
602 NTTIME now;
603 size_t req_size = smb_len(inbuf) + 4;
605 /* Ensure we have at least smb_size bytes. */
606 if (req_size < smb_size) {
607 DEBUG(0,("init_smb_request: invalid request size %u\n",
608 (unsigned int)req_size ));
609 return false;
612 req->request_time = timeval_current();
613 now = timeval_to_nttime(&req->request_time);
615 req->cmd = CVAL(inbuf, smb_com);
616 req->flags2 = SVAL(inbuf, smb_flg2);
617 req->smbpid = SVAL(inbuf, smb_pid);
618 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
619 req->seqnum = seqnum;
620 req->vuid = SVAL(inbuf, smb_uid);
621 req->tid = SVAL(inbuf, smb_tid);
622 req->wct = CVAL(inbuf, smb_wct);
623 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
624 req->buflen = smb_buflen(inbuf);
625 req->buf = (const uint8_t *)smb_buf_const(inbuf);
626 req->unread_bytes = unread_bytes;
627 req->encrypted = encrypted;
628 req->sconn = sconn;
629 req->xconn = xconn;
630 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
631 if (NT_STATUS_IS_OK(status)) {
632 req->conn = tcon->compat;
633 } else {
634 req->conn = NULL;
636 req->chain_fsp = NULL;
637 req->smb2req = NULL;
638 req->priv_paths = NULL;
639 req->chain = NULL;
640 smb_init_perfcount_data(&req->pcd);
642 /* Ensure we have at least wct words and 2 bytes of bcc. */
643 if (smb_size + req->wct*2 > req_size) {
644 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
645 (unsigned int)req->wct,
646 (unsigned int)req_size));
647 return false;
649 /* Ensure bcc is correct. */
650 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
651 DEBUG(0,("init_smb_request: invalid bcc number %u "
652 "(wct = %u, size %u)\n",
653 (unsigned int)req->buflen,
654 (unsigned int)req->wct,
655 (unsigned int)req_size));
656 return false;
659 req->outbuf = NULL;
660 return true;
663 static void process_smb(struct smbXsrv_connection *xconn,
664 uint8_t *inbuf, size_t nread, size_t unread_bytes,
665 uint32_t seqnum, bool encrypted,
666 struct smb_perfcount_data *deferred_pcd);
668 static void smbd_deferred_open_timer(struct tevent_context *ev,
669 struct tevent_timer *te,
670 struct timeval _tval,
671 void *private_data)
673 struct pending_message_list *msg = talloc_get_type(private_data,
674 struct pending_message_list);
675 struct smbd_server_connection *sconn = msg->sconn;
676 struct smbXsrv_connection *xconn = msg->xconn;
677 TALLOC_CTX *mem_ctx = talloc_tos();
678 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
679 uint8_t *inbuf;
681 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
682 msg->buf.length);
683 if (inbuf == NULL) {
684 exit_server("smbd_deferred_open_timer: talloc failed\n");
685 return;
688 /* We leave this message on the queue so the open code can
689 know this is a retry. */
690 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
691 (unsigned long long)mid ));
693 /* Mark the message as processed so this is not
694 * re-processed in error. */
695 msg->processed = true;
697 process_smb(xconn, inbuf,
698 msg->buf.length, 0,
699 msg->seqnum, msg->encrypted, &msg->pcd);
701 /* If it's still there and was processed, remove it. */
702 msg = get_deferred_open_message_smb(sconn, mid);
703 if (msg && msg->processed) {
704 remove_deferred_open_message_smb(sconn, mid);
708 /****************************************************************************
709 Function to push a message onto the tail of a linked list of smb messages ready
710 for processing.
711 ****************************************************************************/
713 static bool push_queued_message(struct smb_request *req,
714 struct timeval request_time,
715 struct timeval end_time,
716 struct deferred_open_record *open_rec)
718 int msg_len = smb_len(req->inbuf) + 4;
719 struct pending_message_list *msg;
721 msg = talloc_zero(NULL, struct pending_message_list);
723 if(msg == NULL) {
724 DEBUG(0,("push_message: malloc fail (1)\n"));
725 return False;
727 msg->sconn = req->sconn;
728 msg->xconn = req->xconn;
730 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
731 if(msg->buf.data == NULL) {
732 DEBUG(0,("push_message: malloc fail (2)\n"));
733 TALLOC_FREE(msg);
734 return False;
737 msg->request_time = request_time;
738 msg->seqnum = req->seqnum;
739 msg->encrypted = req->encrypted;
740 msg->processed = false;
741 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
743 if (open_rec) {
744 msg->open_rec = talloc_move(msg, &open_rec);
747 #if 0
748 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
749 msg,
750 end_time,
751 smbd_deferred_open_timer,
752 msg);
753 if (!msg->te) {
754 DEBUG(0,("push_message: event_add_timed failed\n"));
755 TALLOC_FREE(msg);
756 return false;
758 #endif
760 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
761 struct pending_message_list *);
763 DEBUG(10,("push_message: pushed message length %u on "
764 "deferred_open_queue\n", (unsigned int)msg_len));
766 return True;
769 /****************************************************************************
770 Function to delete a sharing violation open message by mid.
771 ****************************************************************************/
773 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
774 uint64_t mid)
776 struct pending_message_list *pml;
778 if (sconn->using_smb2) {
779 remove_deferred_open_message_smb2(sconn, mid);
780 return;
783 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
784 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
785 DEBUG(10,("remove_deferred_open_message_smb: "
786 "deleting mid %llu len %u\n",
787 (unsigned long long)mid,
788 (unsigned int)pml->buf.length ));
789 DLIST_REMOVE(sconn->deferred_open_queue, pml);
790 TALLOC_FREE(pml);
791 return;
796 /****************************************************************************
797 Move a sharing violation open retry message to the front of the list and
798 schedule it for immediate processing.
799 ****************************************************************************/
801 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
802 uint64_t mid)
804 struct pending_message_list *pml;
805 int i = 0;
807 if (sconn->using_smb2) {
808 return schedule_deferred_open_message_smb2(sconn, mid);
811 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
812 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
814 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
815 "msg_mid = %llu\n",
816 i++,
817 (unsigned long long)msg_mid ));
819 if (mid == msg_mid) {
820 struct tevent_timer *te;
822 if (pml->processed) {
823 /* A processed message should not be
824 * rescheduled. */
825 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
826 "message mid %llu was already processed\n",
827 (unsigned long long)msg_mid ));
828 continue;
831 DEBUG(10,("schedule_deferred_open_message_smb: "
832 "scheduling mid %llu\n",
833 (unsigned long long)mid ));
835 te = tevent_add_timer(pml->sconn->ev_ctx,
836 pml,
837 timeval_zero(),
838 smbd_deferred_open_timer,
839 pml);
840 if (!te) {
841 DEBUG(10,("schedule_deferred_open_message_smb: "
842 "event_add_timed() failed, "
843 "skipping mid %llu\n",
844 (unsigned long long)msg_mid ));
847 TALLOC_FREE(pml->te);
848 pml->te = te;
849 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
850 return true;
854 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
855 "find message mid %llu\n",
856 (unsigned long long)mid ));
858 return false;
861 /****************************************************************************
862 Return true if this mid is on the deferred queue and was not yet processed.
863 ****************************************************************************/
865 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
867 struct pending_message_list *pml;
869 if (sconn->using_smb2) {
870 return open_was_deferred_smb2(sconn, mid);
873 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
874 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
875 return True;
878 return False;
881 /****************************************************************************
882 Return the message queued by this mid.
883 ****************************************************************************/
885 static struct pending_message_list *get_deferred_open_message_smb(
886 struct smbd_server_connection *sconn, uint64_t mid)
888 struct pending_message_list *pml;
890 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
891 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
892 return pml;
895 return NULL;
898 /****************************************************************************
899 Get the state data queued by this mid.
900 ****************************************************************************/
902 bool get_deferred_open_message_state(struct smb_request *smbreq,
903 struct timeval *p_request_time,
904 struct deferred_open_record **open_rec)
906 struct pending_message_list *pml;
908 if (smbreq->sconn->using_smb2) {
909 return get_deferred_open_message_state_smb2(smbreq->smb2req,
910 p_request_time,
911 open_rec);
914 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
915 if (!pml) {
916 return false;
918 if (p_request_time) {
919 *p_request_time = pml->request_time;
921 if (open_rec != NULL) {
922 *open_rec = pml->open_rec;
924 return true;
927 /****************************************************************************
928 Function to push a deferred open smb message onto a linked list of local smb
929 messages ready for processing.
930 ****************************************************************************/
932 bool push_deferred_open_message_smb(struct smb_request *req,
933 struct timeval request_time,
934 struct timeval timeout,
935 struct file_id id,
936 struct deferred_open_record *open_rec)
938 struct timeval end_time;
940 if (req->smb2req) {
941 return push_deferred_open_message_smb2(req->smb2req,
942 request_time,
943 timeout,
945 open_rec);
948 if (req->unread_bytes) {
949 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
950 "unread_bytes = %u\n",
951 (unsigned int)req->unread_bytes ));
952 smb_panic("push_deferred_open_message_smb: "
953 "logic error unread_bytes != 0" );
956 end_time = timeval_sum(&request_time, &timeout);
958 DEBUG(10,("push_deferred_open_message_smb: pushing message "
959 "len %u mid %llu timeout time [%u.%06u]\n",
960 (unsigned int) smb_len(req->inbuf)+4,
961 (unsigned long long)req->mid,
962 (unsigned int)end_time.tv_sec,
963 (unsigned int)end_time.tv_usec));
965 return push_queued_message(req, request_time, end_time, open_rec);
968 static void smbd_sig_term_handler(struct tevent_context *ev,
969 struct tevent_signal *se,
970 int signum,
971 int count,
972 void *siginfo,
973 void *private_data)
975 exit_server_cleanly("termination signal");
978 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
980 struct tevent_signal *se;
982 se = tevent_add_signal(sconn->ev_ctx,
983 sconn,
984 SIGTERM, 0,
985 smbd_sig_term_handler,
986 sconn);
987 if (!se) {
988 exit_server("failed to setup SIGTERM handler");
992 static void smbd_sig_hup_handler(struct tevent_context *ev,
993 struct tevent_signal *se,
994 int signum,
995 int count,
996 void *siginfo,
997 void *private_data)
999 struct smbd_server_connection *sconn =
1000 talloc_get_type_abort(private_data,
1001 struct smbd_server_connection);
1003 change_to_root_user();
1004 DEBUG(1,("Reloading services after SIGHUP\n"));
1005 reload_services(sconn, conn_snum_used, false);
1008 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1010 struct tevent_signal *se;
1012 se = tevent_add_signal(sconn->ev_ctx,
1013 sconn,
1014 SIGHUP, 0,
1015 smbd_sig_hup_handler,
1016 sconn);
1017 if (!se) {
1018 exit_server("failed to setup SIGHUP handler");
1022 static void smbd_conf_updated(struct messaging_context *msg,
1023 void *private_data,
1024 uint32_t msg_type,
1025 struct server_id server_id,
1026 DATA_BLOB *data)
1028 struct smbd_server_connection *sconn =
1029 talloc_get_type_abort(private_data,
1030 struct smbd_server_connection);
1032 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1033 "updated. Reloading.\n"));
1034 change_to_root_user();
1035 reload_services(sconn, conn_snum_used, false);
1039 * Only allow 5 outstanding trans requests. We're allocating memory, so
1040 * prevent a DoS.
1043 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1045 int count = 0;
1046 for (; list != NULL; list = list->next) {
1048 if (list->mid == mid) {
1049 return NT_STATUS_INVALID_PARAMETER;
1052 count += 1;
1054 if (count > 5) {
1055 return NT_STATUS_INSUFFICIENT_RESOURCES;
1058 return NT_STATUS_OK;
1062 These flags determine some of the permissions required to do an operation
1064 Note that I don't set NEED_WRITE on some write operations because they
1065 are used by some brain-dead clients when printing, and I don't want to
1066 force write permissions on print services.
1068 #define AS_USER (1<<0)
1069 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1070 #define TIME_INIT (1<<2)
1071 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1072 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1073 #define DO_CHDIR (1<<6)
1076 define a list of possible SMB messages and their corresponding
1077 functions. Any message that has a NULL function is unimplemented -
1078 please feel free to contribute implementations!
1080 static const struct smb_message_struct {
1081 const char *name;
1082 void (*fn)(struct smb_request *req);
1083 int flags;
1084 } smb_messages[256] = {
1086 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1087 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1088 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1089 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1090 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1091 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1092 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1093 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1094 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1095 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1096 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1097 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1098 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1099 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1100 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1101 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1102 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1103 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1104 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1105 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1106 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1107 /* 0x15 */ { NULL, NULL, 0 },
1108 /* 0x16 */ { NULL, NULL, 0 },
1109 /* 0x17 */ { NULL, NULL, 0 },
1110 /* 0x18 */ { NULL, NULL, 0 },
1111 /* 0x19 */ { NULL, NULL, 0 },
1112 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1113 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1114 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1115 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1116 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1117 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1118 /* 0x20 */ { "SMBwritec", NULL,0},
1119 /* 0x21 */ { NULL, NULL, 0 },
1120 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1121 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1122 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1123 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1124 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1125 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1126 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1127 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1128 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1129 /* 0x2b */ { "SMBecho",reply_echo,0},
1130 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1131 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1132 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1133 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1134 /* 0x30 */ { NULL, NULL, 0 },
1135 /* 0x31 */ { NULL, NULL, 0 },
1136 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1137 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1138 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1139 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1140 /* 0x36 */ { NULL, NULL, 0 },
1141 /* 0x37 */ { NULL, NULL, 0 },
1142 /* 0x38 */ { NULL, NULL, 0 },
1143 /* 0x39 */ { NULL, NULL, 0 },
1144 /* 0x3a */ { NULL, NULL, 0 },
1145 /* 0x3b */ { NULL, NULL, 0 },
1146 /* 0x3c */ { NULL, NULL, 0 },
1147 /* 0x3d */ { NULL, NULL, 0 },
1148 /* 0x3e */ { NULL, NULL, 0 },
1149 /* 0x3f */ { NULL, NULL, 0 },
1150 /* 0x40 */ { NULL, NULL, 0 },
1151 /* 0x41 */ { NULL, NULL, 0 },
1152 /* 0x42 */ { NULL, NULL, 0 },
1153 /* 0x43 */ { NULL, NULL, 0 },
1154 /* 0x44 */ { NULL, NULL, 0 },
1155 /* 0x45 */ { NULL, NULL, 0 },
1156 /* 0x46 */ { NULL, NULL, 0 },
1157 /* 0x47 */ { NULL, NULL, 0 },
1158 /* 0x48 */ { NULL, NULL, 0 },
1159 /* 0x49 */ { NULL, NULL, 0 },
1160 /* 0x4a */ { NULL, NULL, 0 },
1161 /* 0x4b */ { NULL, NULL, 0 },
1162 /* 0x4c */ { NULL, NULL, 0 },
1163 /* 0x4d */ { NULL, NULL, 0 },
1164 /* 0x4e */ { NULL, NULL, 0 },
1165 /* 0x4f */ { NULL, NULL, 0 },
1166 /* 0x50 */ { NULL, NULL, 0 },
1167 /* 0x51 */ { NULL, NULL, 0 },
1168 /* 0x52 */ { NULL, NULL, 0 },
1169 /* 0x53 */ { NULL, NULL, 0 },
1170 /* 0x54 */ { NULL, NULL, 0 },
1171 /* 0x55 */ { NULL, NULL, 0 },
1172 /* 0x56 */ { NULL, NULL, 0 },
1173 /* 0x57 */ { NULL, NULL, 0 },
1174 /* 0x58 */ { NULL, NULL, 0 },
1175 /* 0x59 */ { NULL, NULL, 0 },
1176 /* 0x5a */ { NULL, NULL, 0 },
1177 /* 0x5b */ { NULL, NULL, 0 },
1178 /* 0x5c */ { NULL, NULL, 0 },
1179 /* 0x5d */ { NULL, NULL, 0 },
1180 /* 0x5e */ { NULL, NULL, 0 },
1181 /* 0x5f */ { NULL, NULL, 0 },
1182 /* 0x60 */ { NULL, NULL, 0 },
1183 /* 0x61 */ { NULL, NULL, 0 },
1184 /* 0x62 */ { NULL, NULL, 0 },
1185 /* 0x63 */ { NULL, NULL, 0 },
1186 /* 0x64 */ { NULL, NULL, 0 },
1187 /* 0x65 */ { NULL, NULL, 0 },
1188 /* 0x66 */ { NULL, NULL, 0 },
1189 /* 0x67 */ { NULL, NULL, 0 },
1190 /* 0x68 */ { NULL, NULL, 0 },
1191 /* 0x69 */ { NULL, NULL, 0 },
1192 /* 0x6a */ { NULL, NULL, 0 },
1193 /* 0x6b */ { NULL, NULL, 0 },
1194 /* 0x6c */ { NULL, NULL, 0 },
1195 /* 0x6d */ { NULL, NULL, 0 },
1196 /* 0x6e */ { NULL, NULL, 0 },
1197 /* 0x6f */ { NULL, NULL, 0 },
1198 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1199 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1200 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1201 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1202 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1203 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1204 /* 0x76 */ { NULL, NULL, 0 },
1205 /* 0x77 */ { NULL, NULL, 0 },
1206 /* 0x78 */ { NULL, NULL, 0 },
1207 /* 0x79 */ { NULL, NULL, 0 },
1208 /* 0x7a */ { NULL, NULL, 0 },
1209 /* 0x7b */ { NULL, NULL, 0 },
1210 /* 0x7c */ { NULL, NULL, 0 },
1211 /* 0x7d */ { NULL, NULL, 0 },
1212 /* 0x7e */ { NULL, NULL, 0 },
1213 /* 0x7f */ { NULL, NULL, 0 },
1214 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1215 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1216 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1217 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1218 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1219 /* 0x85 */ { NULL, NULL, 0 },
1220 /* 0x86 */ { NULL, NULL, 0 },
1221 /* 0x87 */ { NULL, NULL, 0 },
1222 /* 0x88 */ { NULL, NULL, 0 },
1223 /* 0x89 */ { NULL, NULL, 0 },
1224 /* 0x8a */ { NULL, NULL, 0 },
1225 /* 0x8b */ { NULL, NULL, 0 },
1226 /* 0x8c */ { NULL, NULL, 0 },
1227 /* 0x8d */ { NULL, NULL, 0 },
1228 /* 0x8e */ { NULL, NULL, 0 },
1229 /* 0x8f */ { NULL, NULL, 0 },
1230 /* 0x90 */ { NULL, NULL, 0 },
1231 /* 0x91 */ { NULL, NULL, 0 },
1232 /* 0x92 */ { NULL, NULL, 0 },
1233 /* 0x93 */ { NULL, NULL, 0 },
1234 /* 0x94 */ { NULL, NULL, 0 },
1235 /* 0x95 */ { NULL, NULL, 0 },
1236 /* 0x96 */ { NULL, NULL, 0 },
1237 /* 0x97 */ { NULL, NULL, 0 },
1238 /* 0x98 */ { NULL, NULL, 0 },
1239 /* 0x99 */ { NULL, NULL, 0 },
1240 /* 0x9a */ { NULL, NULL, 0 },
1241 /* 0x9b */ { NULL, NULL, 0 },
1242 /* 0x9c */ { NULL, NULL, 0 },
1243 /* 0x9d */ { NULL, NULL, 0 },
1244 /* 0x9e */ { NULL, NULL, 0 },
1245 /* 0x9f */ { NULL, NULL, 0 },
1246 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1247 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1248 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1249 /* 0xa3 */ { NULL, NULL, 0 },
1250 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1251 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1252 /* 0xa6 */ { NULL, NULL, 0 },
1253 /* 0xa7 */ { NULL, NULL, 0 },
1254 /* 0xa8 */ { NULL, NULL, 0 },
1255 /* 0xa9 */ { NULL, NULL, 0 },
1256 /* 0xaa */ { NULL, NULL, 0 },
1257 /* 0xab */ { NULL, NULL, 0 },
1258 /* 0xac */ { NULL, NULL, 0 },
1259 /* 0xad */ { NULL, NULL, 0 },
1260 /* 0xae */ { NULL, NULL, 0 },
1261 /* 0xaf */ { NULL, NULL, 0 },
1262 /* 0xb0 */ { NULL, NULL, 0 },
1263 /* 0xb1 */ { NULL, NULL, 0 },
1264 /* 0xb2 */ { NULL, NULL, 0 },
1265 /* 0xb3 */ { NULL, NULL, 0 },
1266 /* 0xb4 */ { NULL, NULL, 0 },
1267 /* 0xb5 */ { NULL, NULL, 0 },
1268 /* 0xb6 */ { NULL, NULL, 0 },
1269 /* 0xb7 */ { NULL, NULL, 0 },
1270 /* 0xb8 */ { NULL, NULL, 0 },
1271 /* 0xb9 */ { NULL, NULL, 0 },
1272 /* 0xba */ { NULL, NULL, 0 },
1273 /* 0xbb */ { NULL, NULL, 0 },
1274 /* 0xbc */ { NULL, NULL, 0 },
1275 /* 0xbd */ { NULL, NULL, 0 },
1276 /* 0xbe */ { NULL, NULL, 0 },
1277 /* 0xbf */ { NULL, NULL, 0 },
1278 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1279 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1280 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1281 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1282 /* 0xc4 */ { NULL, NULL, 0 },
1283 /* 0xc5 */ { NULL, NULL, 0 },
1284 /* 0xc6 */ { NULL, NULL, 0 },
1285 /* 0xc7 */ { NULL, NULL, 0 },
1286 /* 0xc8 */ { NULL, NULL, 0 },
1287 /* 0xc9 */ { NULL, NULL, 0 },
1288 /* 0xca */ { NULL, NULL, 0 },
1289 /* 0xcb */ { NULL, NULL, 0 },
1290 /* 0xcc */ { NULL, NULL, 0 },
1291 /* 0xcd */ { NULL, NULL, 0 },
1292 /* 0xce */ { NULL, NULL, 0 },
1293 /* 0xcf */ { NULL, NULL, 0 },
1294 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1295 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1296 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1297 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1298 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1299 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1300 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1301 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1302 /* 0xd8 */ { NULL, NULL, 0 },
1303 /* 0xd9 */ { NULL, NULL, 0 },
1304 /* 0xda */ { NULL, NULL, 0 },
1305 /* 0xdb */ { NULL, NULL, 0 },
1306 /* 0xdc */ { NULL, NULL, 0 },
1307 /* 0xdd */ { NULL, NULL, 0 },
1308 /* 0xde */ { NULL, NULL, 0 },
1309 /* 0xdf */ { NULL, NULL, 0 },
1310 /* 0xe0 */ { NULL, NULL, 0 },
1311 /* 0xe1 */ { NULL, NULL, 0 },
1312 /* 0xe2 */ { NULL, NULL, 0 },
1313 /* 0xe3 */ { NULL, NULL, 0 },
1314 /* 0xe4 */ { NULL, NULL, 0 },
1315 /* 0xe5 */ { NULL, NULL, 0 },
1316 /* 0xe6 */ { NULL, NULL, 0 },
1317 /* 0xe7 */ { NULL, NULL, 0 },
1318 /* 0xe8 */ { NULL, NULL, 0 },
1319 /* 0xe9 */ { NULL, NULL, 0 },
1320 /* 0xea */ { NULL, NULL, 0 },
1321 /* 0xeb */ { NULL, NULL, 0 },
1322 /* 0xec */ { NULL, NULL, 0 },
1323 /* 0xed */ { NULL, NULL, 0 },
1324 /* 0xee */ { NULL, NULL, 0 },
1325 /* 0xef */ { NULL, NULL, 0 },
1326 /* 0xf0 */ { NULL, NULL, 0 },
1327 /* 0xf1 */ { NULL, NULL, 0 },
1328 /* 0xf2 */ { NULL, NULL, 0 },
1329 /* 0xf3 */ { NULL, NULL, 0 },
1330 /* 0xf4 */ { NULL, NULL, 0 },
1331 /* 0xf5 */ { NULL, NULL, 0 },
1332 /* 0xf6 */ { NULL, NULL, 0 },
1333 /* 0xf7 */ { NULL, NULL, 0 },
1334 /* 0xf8 */ { NULL, NULL, 0 },
1335 /* 0xf9 */ { NULL, NULL, 0 },
1336 /* 0xfa */ { NULL, NULL, 0 },
1337 /* 0xfb */ { NULL, NULL, 0 },
1338 /* 0xfc */ { NULL, NULL, 0 },
1339 /* 0xfd */ { NULL, NULL, 0 },
1340 /* 0xfe */ { NULL, NULL, 0 },
1341 /* 0xff */ { NULL, NULL, 0 }
1345 /*******************************************************************
1346 allocate and initialize a reply packet
1347 ********************************************************************/
1349 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1350 const char *inbuf, char **outbuf, uint8_t num_words,
1351 uint32_t num_bytes)
1353 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1356 * Protect against integer wrap.
1357 * The SMB layer reply can be up to 0xFFFFFF bytes.
1359 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1360 char *msg;
1361 if (asprintf(&msg, "num_bytes too large: %u",
1362 (unsigned)num_bytes) == -1) {
1363 msg = discard_const_p(char, "num_bytes too large");
1365 smb_panic(msg);
1369 * Here we include the NBT header for now.
1371 *outbuf = talloc_array(mem_ctx, char,
1372 NBT_HDR_SIZE + smb_len);
1373 if (*outbuf == NULL) {
1374 return false;
1377 construct_reply_common(req, inbuf, *outbuf);
1378 srv_set_message(*outbuf, num_words, num_bytes, false);
1380 * Zero out the word area, the caller has to take care of the bcc area
1381 * himself
1383 if (num_words != 0) {
1384 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1387 return true;
1390 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1392 char *outbuf;
1393 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1394 num_bytes)) {
1395 smb_panic("could not allocate output buffer\n");
1397 req->outbuf = (uint8_t *)outbuf;
1401 /*******************************************************************
1402 Dump a packet to a file.
1403 ********************************************************************/
1405 static void smb_dump(const char *name, int type, const char *data)
1407 size_t len;
1408 int fd, i;
1409 char *fname = NULL;
1410 if (DEBUGLEVEL < 50) {
1411 return;
1414 len = smb_len_tcp(data)+4;
1415 for (i=1;i<100;i++) {
1416 fname = talloc_asprintf(talloc_tos(),
1417 "/tmp/%s.%d.%s",
1418 name,
1420 type ? "req" : "resp");
1421 if (fname == NULL) {
1422 return;
1424 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1425 if (fd != -1 || errno != EEXIST) break;
1426 TALLOC_FREE(fname);
1428 if (fd != -1) {
1429 ssize_t ret = write(fd, data, len);
1430 if (ret != len)
1431 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1432 close(fd);
1433 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1435 TALLOC_FREE(fname);
1438 /****************************************************************************
1439 Prepare everything for calling the actual request function, and potentially
1440 call the request function via the "new" interface.
1442 Return False if the "legacy" function needs to be called, everything is
1443 prepared.
1445 Return True if we're done.
1447 I know this API sucks, but it is the one with the least code change I could
1448 find.
1449 ****************************************************************************/
1451 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1453 int flags;
1454 uint64_t session_tag;
1455 connection_struct *conn = NULL;
1456 struct smbXsrv_connection *xconn = req->xconn;
1457 NTTIME now = timeval_to_nttime(&req->request_time);
1458 struct smbXsrv_session *session = NULL;
1459 NTSTATUS status;
1461 errno = 0;
1463 if (smb_messages[type].fn == NULL) {
1464 DEBUG(0,("Unknown message type %d!\n",type));
1465 smb_dump("Unknown", 1, (const char *)req->inbuf);
1466 reply_unknown_new(req, type);
1467 return NULL;
1470 flags = smb_messages[type].flags;
1472 /* In share mode security we must ignore the vuid. */
1473 session_tag = req->vuid;
1474 conn = req->conn;
1476 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1477 (int)getpid(), (unsigned long)conn));
1479 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1481 /* Ensure this value is replaced in the incoming packet. */
1482 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1485 * Ensure the correct username is in current_user_info. This is a
1486 * really ugly bugfix for problems with multiple session_setup_and_X's
1487 * being done and allowing %U and %G substitutions to work correctly.
1488 * There is a reason this code is done here, don't move it unless you
1489 * know what you're doing... :-).
1490 * JRA.
1494 * lookup an existing session
1496 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1497 * here, the main check is still in change_to_user()
1499 status = smb1srv_session_lookup(xconn,
1500 session_tag,
1501 now,
1502 &session);
1503 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1504 switch (type) {
1505 case SMBsesssetupX:
1506 status = NT_STATUS_OK;
1507 break;
1508 default:
1509 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1510 (unsigned long long)session_tag,
1511 (unsigned long long)req->mid));
1512 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1513 return conn;
1517 if (session_tag != xconn->last_session_id) {
1518 struct user_struct *vuser = NULL;
1520 xconn->last_session_id = session_tag;
1521 if (session) {
1522 vuser = session->compat;
1524 if (vuser) {
1525 set_current_user_info(
1526 vuser->session_info->unix_info->sanitized_username,
1527 vuser->session_info->unix_info->unix_name,
1528 vuser->session_info->info->domain_name);
1532 /* Does this call need to be run as the connected user? */
1533 if (flags & AS_USER) {
1535 /* Does this call need a valid tree connection? */
1536 if (!conn) {
1538 * Amazingly, the error code depends on the command
1539 * (from Samba4).
1541 if (type == SMBntcreateX) {
1542 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1543 } else {
1544 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1546 return NULL;
1549 if (!change_to_user(conn,session_tag)) {
1550 DEBUG(0, ("Error: Could not change to user. Removing "
1551 "deferred open, mid=%llu.\n",
1552 (unsigned long long)req->mid));
1553 reply_force_doserror(req, ERRSRV, ERRbaduid);
1554 return conn;
1557 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1559 /* Does it need write permission? */
1560 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1561 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1562 return conn;
1565 /* IPC services are limited */
1566 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1567 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1568 return conn;
1570 } else {
1571 /* This call needs to be run as root */
1572 change_to_root_user();
1575 /* load service specific parameters */
1576 if (conn) {
1577 if (req->encrypted) {
1578 conn->encrypted_tid = true;
1579 /* encrypted required from now on. */
1580 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1581 } else if (ENCRYPTION_REQUIRED(conn)) {
1582 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1583 DEBUG(1,("service[%s] requires encryption"
1584 "%s ACCESS_DENIED. mid=%llu\n",
1585 lp_servicename(talloc_tos(), SNUM(conn)),
1586 smb_fn_name(type),
1587 (unsigned long long)req->mid));
1588 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1589 return conn;
1593 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1594 (flags & (AS_USER|DO_CHDIR)
1595 ?True:False))) {
1596 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1597 return conn;
1599 conn->num_smb_operations++;
1603 * Does this protocol need to be run as guest? (Only archane
1604 * messenger service requests have this...)
1606 if (flags & AS_GUEST) {
1607 char *raddr;
1608 bool ok;
1610 if (!change_to_guest()) {
1611 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1612 return conn;
1615 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1616 talloc_tos());
1617 if (raddr == NULL) {
1618 reply_nterror(req, NT_STATUS_NO_MEMORY);
1619 return conn;
1623 * Haven't we checked this in smbd_process already???
1626 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1627 xconn->remote_hostname, raddr);
1628 TALLOC_FREE(raddr);
1630 if (!ok) {
1631 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1632 return conn;
1636 smb_messages[type].fn(req);
1637 return req->conn;
1640 /****************************************************************************
1641 Construct a reply to the incoming packet.
1642 ****************************************************************************/
1644 static void construct_reply(struct smbd_server_connection *sconn,
1645 char *inbuf, int size, size_t unread_bytes,
1646 uint32_t seqnum, bool encrypted,
1647 struct smb_perfcount_data *deferred_pcd)
1649 struct smbXsrv_connection *xconn = sconn->conn;
1650 struct smb_request *req;
1652 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1653 smb_panic("could not allocate smb_request");
1656 if (!init_smb_request(req, sconn, xconn, (uint8 *)inbuf, unread_bytes,
1657 encrypted, seqnum)) {
1658 exit_server_cleanly("Invalid SMB request");
1661 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1663 /* we popped this message off the queue - keep original perf data */
1664 if (deferred_pcd)
1665 req->pcd = *deferred_pcd;
1666 else {
1667 SMB_PERFCOUNT_START(&req->pcd);
1668 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1669 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1672 req->conn = switch_message(req->cmd, req);
1674 if (req->outbuf == NULL) {
1676 * Request has suspended itself, will come
1677 * back here.
1679 return;
1681 if (CVAL(req->outbuf,0) == 0) {
1682 show_msg((char *)req->outbuf);
1684 smb_request_done(req);
1687 static void construct_reply_chain(struct smbd_server_connection *sconn,
1688 char *inbuf, int size, uint32_t seqnum,
1689 bool encrypted,
1690 struct smb_perfcount_data *deferred_pcd)
1692 struct smb_request **reqs = NULL;
1693 struct smb_request *req;
1694 unsigned num_reqs;
1695 bool ok;
1697 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1698 seqnum, &reqs, &num_reqs);
1699 if (!ok) {
1700 char errbuf[smb_size];
1701 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1702 __LINE__, __FILE__);
1703 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1704 NULL)) {
1705 exit_server_cleanly("construct_reply_chain: "
1706 "srv_send_smb failed.");
1708 return;
1711 req = reqs[0];
1712 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1714 req->conn = switch_message(req->cmd, req);
1716 if (req->outbuf == NULL) {
1718 * Request has suspended itself, will come
1719 * back here.
1721 return;
1723 smb_request_done(req);
1727 * To be called from an async SMB handler that is potentially chained
1728 * when it is finished for shipping.
1731 void smb_request_done(struct smb_request *req)
1733 struct smb_request **reqs = NULL;
1734 struct smb_request *first_req;
1735 size_t i, num_reqs, next_index;
1736 NTSTATUS status;
1738 if (req->chain == NULL) {
1739 first_req = req;
1740 goto shipit;
1743 reqs = req->chain;
1744 num_reqs = talloc_array_length(reqs);
1746 for (i=0; i<num_reqs; i++) {
1747 if (reqs[i] == req) {
1748 break;
1751 if (i == num_reqs) {
1753 * Invalid chain, should not happen
1755 status = NT_STATUS_INTERNAL_ERROR;
1756 goto error;
1758 next_index = i+1;
1760 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1761 struct smb_request *next = reqs[next_index];
1762 struct smbXsrv_tcon *tcon;
1763 NTTIME now = timeval_to_nttime(&req->request_time);
1765 next->vuid = SVAL(req->outbuf, smb_uid);
1766 next->tid = SVAL(req->outbuf, smb_tid);
1767 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1768 now, &tcon);
1769 if (NT_STATUS_IS_OK(status)) {
1770 req->conn = tcon->compat;
1771 } else {
1772 req->conn = NULL;
1774 next->chain_fsp = req->chain_fsp;
1775 next->inbuf = req->inbuf;
1777 req = next;
1778 req->conn = switch_message(req->cmd, req);
1780 if (req->outbuf == NULL) {
1782 * Request has suspended itself, will come
1783 * back here.
1785 return;
1787 next_index += 1;
1790 first_req = reqs[0];
1792 for (i=1; i<next_index; i++) {
1793 bool ok;
1795 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1796 if (!ok) {
1797 status = NT_STATUS_INTERNAL_ERROR;
1798 goto error;
1802 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1803 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1806 * This scary statement intends to set the
1807 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1808 * to the value last_req->outbuf carries
1810 SSVAL(first_req->outbuf, smb_flg2,
1811 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1812 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1815 * Transfer the error codes from the subrequest to the main one
1817 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1818 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1820 _smb_setlen_large(
1821 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1823 shipit:
1824 if (!srv_send_smb(first_req->sconn,
1825 (char *)first_req->outbuf,
1826 true, first_req->seqnum+1,
1827 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1828 &first_req->pcd)) {
1829 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1830 "failed.");
1832 TALLOC_FREE(req); /* non-chained case */
1833 TALLOC_FREE(reqs); /* chained case */
1834 return;
1836 error:
1838 char errbuf[smb_size];
1839 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1840 if (!srv_send_smb(req->sconn, errbuf, true,
1841 req->seqnum+1, req->encrypted,
1842 NULL)) {
1843 exit_server_cleanly("construct_reply_chain: "
1844 "srv_send_smb failed.");
1847 TALLOC_FREE(req); /* non-chained case */
1848 TALLOC_FREE(reqs); /* chained case */
1851 /****************************************************************************
1852 Process an smb from the client
1853 ****************************************************************************/
1854 static void process_smb(struct smbXsrv_connection *xconn,
1855 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1856 uint32_t seqnum, bool encrypted,
1857 struct smb_perfcount_data *deferred_pcd)
1859 struct smbd_server_connection *sconn = xconn->sconn;
1860 int msg_type = CVAL(inbuf,0);
1862 DO_PROFILE_INC(smb_count);
1864 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1865 smb_len(inbuf) ) );
1866 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1867 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1869 if (msg_type != NBSSmessage) {
1871 * NetBIOS session request, keepalive, etc.
1873 reply_special(sconn, (char *)inbuf, nread);
1874 goto done;
1877 if (sconn->using_smb2) {
1878 /* At this point we're not really using smb2,
1879 * we make the decision here.. */
1880 if (smbd_is_smb2_header(inbuf, nread)) {
1881 smbd_smb2_first_negprot(xconn, inbuf, nread);
1882 return;
1883 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1884 && CVAL(inbuf, smb_com) != 0x72) {
1885 /* This is a non-negprot SMB1 packet.
1886 Disable SMB2 from now on. */
1887 sconn->using_smb2 = false;
1891 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1892 * so subtract 4 from it. */
1893 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1894 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1895 smb_len(inbuf)));
1897 /* special magic for immediate exit */
1898 if ((nread == 9) &&
1899 (IVAL(inbuf, 4) == 0x74697865) &&
1900 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1901 uint8_t exitcode = CVAL(inbuf, 8);
1902 DEBUG(1, ("Exiting immediately with code %d\n",
1903 (int)exitcode));
1904 exit(exitcode);
1907 exit_server_cleanly("Non-SMB packet");
1910 show_msg((char *)inbuf);
1912 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1913 construct_reply_chain(sconn, (char *)inbuf, nread,
1914 seqnum, encrypted, deferred_pcd);
1915 } else {
1916 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1917 seqnum, encrypted, deferred_pcd);
1920 sconn->trans_num++;
1922 done:
1923 sconn->num_requests++;
1925 /* The timeout_processing function isn't run nearly
1926 often enough to implement 'max log size' without
1927 overrunning the size of the file by many megabytes.
1928 This is especially true if we are running at debug
1929 level 10. Checking every 50 SMBs is a nice
1930 tradeoff of performance vs log file size overrun. */
1932 if ((sconn->num_requests % 50) == 0 &&
1933 need_to_check_log_size()) {
1934 change_to_root_user();
1935 check_log_size();
1939 /****************************************************************************
1940 Return a string containing the function name of a SMB command.
1941 ****************************************************************************/
1943 const char *smb_fn_name(int type)
1945 const char *unknown_name = "SMBunknown";
1947 if (smb_messages[type].name == NULL)
1948 return(unknown_name);
1950 return(smb_messages[type].name);
1953 /****************************************************************************
1954 Helper functions for contruct_reply.
1955 ****************************************************************************/
1957 void add_to_common_flags2(uint32 v)
1959 common_flags2 |= v;
1962 void remove_from_common_flags2(uint32 v)
1964 common_flags2 &= ~v;
1967 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1968 char *outbuf)
1970 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1971 uint16_t out_flags2 = common_flags2;
1973 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1974 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1975 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1977 srv_set_message(outbuf,0,0,false);
1979 SCVAL(outbuf, smb_com, req->cmd);
1980 SIVAL(outbuf,smb_rcls,0);
1981 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1982 SSVAL(outbuf,smb_flg2, out_flags2);
1983 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1984 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1986 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1987 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1988 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1989 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1992 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1994 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1998 * @brief Find the smb_cmd offset of the last command pushed
1999 * @param[in] buf The buffer we're building up
2000 * @retval Where can we put our next andx cmd?
2002 * While chaining requests, the "next" request we're looking at needs to put
2003 * its SMB_Command before the data the previous request already built up added
2004 * to the chain. Find the offset to the place where we have to put our cmd.
2007 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2009 uint8_t cmd;
2010 size_t ofs;
2012 cmd = CVAL(buf, smb_com);
2014 if (!is_andx_req(cmd)) {
2015 return false;
2018 ofs = smb_vwv0;
2020 while (CVAL(buf, ofs) != 0xff) {
2022 if (!is_andx_req(CVAL(buf, ofs))) {
2023 return false;
2027 * ofs is from start of smb header, so add the 4 length
2028 * bytes. The next cmd is right after the wct field.
2030 ofs = SVAL(buf, ofs+2) + 4 + 1;
2032 if (ofs+4 >= talloc_get_size(buf)) {
2033 return false;
2037 *pofs = ofs;
2038 return true;
2042 * @brief Do the smb chaining at a buffer level
2043 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2044 * @param[in] andx_buf Buffer to be appended
2047 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2049 uint8_t smb_command = CVAL(andx_buf, smb_com);
2050 uint8_t wct = CVAL(andx_buf, smb_wct);
2051 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2052 uint32_t num_bytes = smb_buflen(andx_buf);
2053 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2055 uint8_t *outbuf;
2056 size_t old_size, new_size;
2057 size_t ofs;
2058 size_t chain_padding = 0;
2059 size_t andx_cmd_ofs;
2062 old_size = talloc_get_size(*poutbuf);
2064 if ((old_size % 4) != 0) {
2066 * Align the wct field of subsequent requests to a 4-byte
2067 * boundary
2069 chain_padding = 4 - (old_size % 4);
2073 * After the old request comes the new wct field (1 byte), the vwv's
2074 * and the num_bytes field.
2077 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2078 new_size += num_bytes;
2080 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2081 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2082 (unsigned)new_size));
2083 return false;
2086 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2087 if (outbuf == NULL) {
2088 DEBUG(0, ("talloc failed\n"));
2089 return false;
2091 *poutbuf = outbuf;
2093 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2094 DEBUG(1, ("invalid command chain\n"));
2095 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2096 return false;
2099 if (chain_padding != 0) {
2100 memset(outbuf + old_size, 0, chain_padding);
2101 old_size += chain_padding;
2104 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2105 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2107 ofs = old_size;
2110 * Push the chained request:
2112 * wct field
2115 SCVAL(outbuf, ofs, wct);
2116 ofs += 1;
2119 * vwv array
2122 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2125 * HACK ALERT
2127 * Read&X has an offset into its data buffer at
2128 * vwv[6]. reply_read_andx has no idea anymore that it's
2129 * running from within a chain, so we have to fix up the
2130 * offset here.
2132 * Although it looks disgusting at this place, I want to keep
2133 * it here. The alternative would be to push knowledge about
2134 * the andx chain down into read&x again.
2137 if (smb_command == SMBreadX) {
2138 uint8_t *bytes_addr;
2140 if (wct < 7) {
2142 * Invalid read&x response
2144 return false;
2147 bytes_addr = outbuf + ofs /* vwv start */
2148 + sizeof(uint16_t) * wct /* vwv array */
2149 + sizeof(uint16_t); /* bcc */
2151 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2152 bytes_addr - outbuf - 4);
2155 ofs += sizeof(uint16_t) * wct;
2158 * bcc (byte count)
2161 SSVAL(outbuf, ofs, num_bytes);
2162 ofs += sizeof(uint16_t);
2165 * The bytes field
2168 memcpy(outbuf + ofs, bytes, num_bytes);
2170 return true;
2173 bool smb1_is_chain(const uint8_t *buf)
2175 uint8_t cmd, wct, andx_cmd;
2177 cmd = CVAL(buf, smb_com);
2178 if (!is_andx_req(cmd)) {
2179 return false;
2181 wct = CVAL(buf, smb_wct);
2182 if (wct < 2) {
2183 return false;
2185 andx_cmd = CVAL(buf, smb_vwv);
2186 return (andx_cmd != 0xFF);
2189 bool smb1_walk_chain(const uint8_t *buf,
2190 bool (*fn)(uint8_t cmd,
2191 uint8_t wct, const uint16_t *vwv,
2192 uint16_t num_bytes, const uint8_t *bytes,
2193 void *private_data),
2194 void *private_data)
2196 size_t smblen = smb_len(buf);
2197 const char *smb_buf = smb_base(buf);
2198 uint8_t cmd, chain_cmd;
2199 uint8_t wct;
2200 const uint16_t *vwv;
2201 uint16_t num_bytes;
2202 const uint8_t *bytes;
2204 cmd = CVAL(buf, smb_com);
2205 wct = CVAL(buf, smb_wct);
2206 vwv = (const uint16_t *)(buf + smb_vwv);
2207 num_bytes = smb_buflen(buf);
2208 bytes = (const uint8_t *)smb_buf_const(buf);
2210 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2211 return false;
2214 if (!is_andx_req(cmd)) {
2215 return true;
2217 if (wct < 2) {
2218 return false;
2221 chain_cmd = CVAL(vwv, 0);
2223 while (chain_cmd != 0xff) {
2224 uint32_t chain_offset; /* uint32_t to avoid overflow */
2225 size_t length_needed;
2226 ptrdiff_t vwv_offset;
2228 chain_offset = SVAL(vwv+1, 0);
2231 * Check if the client tries to fool us. The chain
2232 * offset needs to point beyond the current request in
2233 * the chain, it needs to strictly grow. Otherwise we
2234 * might be tricked into an endless loop always
2235 * processing the same request over and over again. We
2236 * used to assume that vwv and the byte buffer array
2237 * in a chain are always attached, but OS/2 the
2238 * Write&X/Read&X chain puts the Read&X vwv array
2239 * right behind the Write&X vwv chain. The Write&X bcc
2240 * array is put behind the Read&X vwv array. So now we
2241 * check whether the chain offset points strictly
2242 * behind the previous vwv array. req->buf points
2243 * right after the vwv array of the previous
2244 * request. See
2245 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2246 * more information.
2249 vwv_offset = ((const char *)vwv - smb_buf);
2250 if (chain_offset <= vwv_offset) {
2251 return false;
2255 * Next check: Make sure the chain offset does not
2256 * point beyond the overall smb request length.
2259 length_needed = chain_offset+1; /* wct */
2260 if (length_needed > smblen) {
2261 return false;
2265 * Now comes the pointer magic. Goal here is to set up
2266 * vwv and buf correctly again. The chain offset (the
2267 * former vwv[1]) points at the new wct field.
2270 wct = CVAL(smb_buf, chain_offset);
2272 if (is_andx_req(chain_cmd) && (wct < 2)) {
2273 return false;
2277 * Next consistency check: Make the new vwv array fits
2278 * in the overall smb request.
2281 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2282 if (length_needed > smblen) {
2283 return false;
2285 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2288 * Now grab the new byte buffer....
2291 num_bytes = SVAL(vwv+wct, 0);
2294 * .. and check that it fits.
2297 length_needed += num_bytes;
2298 if (length_needed > smblen) {
2299 return false;
2301 bytes = (const uint8_t *)(vwv+wct+1);
2303 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2304 return false;
2307 if (!is_andx_req(chain_cmd)) {
2308 return true;
2310 chain_cmd = CVAL(vwv, 0);
2312 return true;
2315 static bool smb1_chain_length_cb(uint8_t cmd,
2316 uint8_t wct, const uint16_t *vwv,
2317 uint16_t num_bytes, const uint8_t *bytes,
2318 void *private_data)
2320 unsigned *count = (unsigned *)private_data;
2321 *count += 1;
2322 return true;
2325 unsigned smb1_chain_length(const uint8_t *buf)
2327 unsigned count = 0;
2329 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2330 return 0;
2332 return count;
2335 struct smb1_parse_chain_state {
2336 TALLOC_CTX *mem_ctx;
2337 const uint8_t *buf;
2338 struct smbd_server_connection *sconn;
2339 struct smbXsrv_connection *xconn;
2340 bool encrypted;
2341 uint32_t seqnum;
2343 struct smb_request **reqs;
2344 unsigned num_reqs;
2347 static bool smb1_parse_chain_cb(uint8_t cmd,
2348 uint8_t wct, const uint16_t *vwv,
2349 uint16_t num_bytes, const uint8_t *bytes,
2350 void *private_data)
2352 struct smb1_parse_chain_state *state =
2353 (struct smb1_parse_chain_state *)private_data;
2354 struct smb_request **reqs;
2355 struct smb_request *req;
2356 bool ok;
2358 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2359 struct smb_request *, state->num_reqs+1);
2360 if (reqs == NULL) {
2361 return false;
2363 state->reqs = reqs;
2365 req = talloc(reqs, struct smb_request);
2366 if (req == NULL) {
2367 return false;
2370 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2371 state->encrypted, state->seqnum);
2372 if (!ok) {
2373 return false;
2375 req->cmd = cmd;
2376 req->wct = wct;
2377 req->vwv = vwv;
2378 req->buflen = num_bytes;
2379 req->buf = bytes;
2381 reqs[state->num_reqs] = req;
2382 state->num_reqs += 1;
2383 return true;
2386 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2387 struct smbd_server_connection *sconn,
2388 bool encrypted, uint32_t seqnum,
2389 struct smb_request ***reqs, unsigned *num_reqs)
2391 struct smbXsrv_connection *xconn = sconn->conn;
2392 struct smb1_parse_chain_state state;
2393 unsigned i;
2395 state.mem_ctx = mem_ctx;
2396 state.buf = buf;
2397 state.sconn = sconn;
2398 state.xconn = xconn;
2399 state.encrypted = encrypted;
2400 state.seqnum = seqnum;
2401 state.reqs = NULL;
2402 state.num_reqs = 0;
2404 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2405 TALLOC_FREE(state.reqs);
2406 return false;
2408 for (i=0; i<state.num_reqs; i++) {
2409 state.reqs[i]->chain = state.reqs;
2411 *reqs = state.reqs;
2412 *num_reqs = state.num_reqs;
2413 return true;
2416 /****************************************************************************
2417 Check if services need reloading.
2418 ****************************************************************************/
2420 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2423 if (last_smb_conf_reload_time == 0) {
2424 last_smb_conf_reload_time = t;
2427 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2428 reload_services(sconn, conn_snum_used, true);
2429 last_smb_conf_reload_time = t;
2433 static bool fd_is_readable(int fd)
2435 int ret, revents;
2437 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2439 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2443 static void smbd_server_connection_write_handler(
2444 struct smbXsrv_connection *xconn)
2446 /* TODO: make write nonblocking */
2449 static void smbd_server_connection_read_handler(
2450 struct smbXsrv_connection *xconn, int fd)
2452 struct smbd_server_connection *sconn = xconn->sconn;
2453 uint8_t *inbuf = NULL;
2454 size_t inbuf_len = 0;
2455 size_t unread_bytes = 0;
2456 bool encrypted = false;
2457 TALLOC_CTX *mem_ctx = talloc_tos();
2458 NTSTATUS status;
2459 uint32_t seqnum;
2461 bool async_echo = lp_async_smb_echo_handler();
2462 bool from_client = false;
2464 if (async_echo) {
2465 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2467 * This is the super-ugly hack to prefer the packets
2468 * forwarded by the echo handler over the ones by the
2469 * client directly
2471 fd = xconn->smb1.echo_handler.trusted_fd;
2475 from_client = (xconn->transport.sock == fd);
2477 if (async_echo && from_client) {
2478 smbd_lock_socket(sconn);
2480 if (!fd_is_readable(fd)) {
2481 DEBUG(10,("the echo listener was faster\n"));
2482 smbd_unlock_socket(sconn);
2483 return;
2487 /* TODO: make this completely nonblocking */
2488 status = receive_smb_talloc(mem_ctx, sconn, fd,
2489 (char **)(void *)&inbuf,
2490 0, /* timeout */
2491 &unread_bytes,
2492 &encrypted,
2493 &inbuf_len, &seqnum,
2494 !from_client /* trusted channel */);
2496 if (async_echo && from_client) {
2497 smbd_unlock_socket(sconn);
2500 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2501 goto process;
2503 if (NT_STATUS_IS_ERR(status)) {
2504 exit_server_cleanly("failed to receive smb request");
2506 if (!NT_STATUS_IS_OK(status)) {
2507 return;
2510 process:
2511 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2512 seqnum, encrypted, NULL);
2515 static void smbd_server_connection_handler(struct tevent_context *ev,
2516 struct tevent_fd *fde,
2517 uint16_t flags,
2518 void *private_data)
2520 struct smbXsrv_connection *xconn =
2521 talloc_get_type_abort(private_data,
2522 struct smbXsrv_connection);
2524 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2526 * we're not supposed to do any io
2528 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2529 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2530 return;
2533 if (flags & TEVENT_FD_WRITE) {
2534 smbd_server_connection_write_handler(xconn);
2535 return;
2537 if (flags & TEVENT_FD_READ) {
2538 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2539 return;
2543 static void smbd_server_echo_handler(struct tevent_context *ev,
2544 struct tevent_fd *fde,
2545 uint16_t flags,
2546 void *private_data)
2548 struct smbXsrv_connection *xconn =
2549 talloc_get_type_abort(private_data,
2550 struct smbXsrv_connection);
2552 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2554 * we're not supposed to do any io
2556 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2557 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2558 return;
2561 if (flags & TEVENT_FD_WRITE) {
2562 smbd_server_connection_write_handler(xconn);
2563 return;
2565 if (flags & TEVENT_FD_READ) {
2566 smbd_server_connection_read_handler(
2567 xconn, xconn->smb1.echo_handler.trusted_fd);
2568 return;
2572 struct smbd_release_ip_state {
2573 struct smbXsrv_connection *xconn;
2574 struct tevent_immediate *im;
2575 char addr[INET6_ADDRSTRLEN];
2578 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2579 struct tevent_immediate *im,
2580 void *private_data)
2582 struct smbd_release_ip_state *state =
2583 talloc_get_type_abort(private_data,
2584 struct smbd_release_ip_state);
2585 struct smbXsrv_connection *xconn = state->xconn;
2586 struct smbd_server_connection *sconn = xconn->sconn;
2588 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2590 * smbd_server_connection_terminate() already triggered ?
2592 return;
2595 smbd_server_connection_terminate(sconn, "CTDB_SRVID_RELEASE_IP");
2598 /****************************************************************************
2599 received when we should release a specific IP
2600 ****************************************************************************/
2601 static bool release_ip(const char *ip, void *priv)
2603 struct smbd_release_ip_state *state =
2604 talloc_get_type_abort(priv,
2605 struct smbd_release_ip_state);
2606 struct smbXsrv_connection *xconn = state->xconn;
2607 const char *addr = state->addr;
2608 const char *p = addr;
2610 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2611 /* avoid recursion */
2612 return false;
2615 if (strncmp("::ffff:", addr, 7) == 0) {
2616 p = addr + 7;
2619 DEBUG(10, ("Got release IP message for %s, "
2620 "our address is %s\n", ip, p));
2622 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2623 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2624 ip));
2626 * With SMB2 we should do a clean disconnect,
2627 * the previous_session_id in the session setup
2628 * will cleanup the old session, tcons and opens.
2630 * A clean disconnect is needed in order to support
2631 * durable handles.
2633 * Note: typically this is never triggered
2634 * as we got a TCP RST (triggered by ctdb event scripts)
2635 * before we get CTDB_SRVID_RELEASE_IP.
2637 * We used to call _exit(1) here, but as this was mostly never
2638 * triggered and has implication on our process model,
2639 * we can just use smbd_server_connection_terminate()
2640 * (also for SMB1).
2642 * We don't call smbd_server_connection_terminate() directly
2643 * as we might be called from within ctdbd_migrate(),
2644 * we need to defer our action to the next event loop
2646 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2647 smbd_release_ip_immediate, state);
2650 * Make sure we don't get any io on the connection.
2652 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2653 return true;
2656 return false;
2659 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2660 struct sockaddr_storage *srv,
2661 struct sockaddr_storage *clnt)
2663 struct smbd_release_ip_state *state;
2664 struct ctdbd_connection *cconn;
2666 cconn = messaging_ctdbd_connection();
2667 if (cconn == NULL) {
2668 return NT_STATUS_NO_MEMORY;
2671 state = talloc_zero(xconn, struct smbd_release_ip_state);
2672 if (state == NULL) {
2673 return NT_STATUS_NO_MEMORY;
2675 state->xconn = xconn;
2676 state->im = tevent_create_immediate(state);
2677 if (state->im == NULL) {
2678 return NT_STATUS_NO_MEMORY;
2680 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2681 return NT_STATUS_NO_MEMORY;
2684 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2687 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2688 void *private_data, uint32_t msg_type,
2689 struct server_id server_id, DATA_BLOB *data)
2691 struct smbd_server_connection *sconn = talloc_get_type_abort(
2692 private_data, struct smbd_server_connection);
2693 const char *ip = (char *) data->data;
2694 char *client_ip;
2696 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2698 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2699 talloc_tos());
2700 if (client_ip == NULL) {
2701 return;
2704 if (strequal(ip, client_ip)) {
2705 DEBUG(1, ("Got kill client message for %s - "
2706 "exiting immediately\n", ip));
2707 exit_server_cleanly("Forced disconnect for client");
2710 TALLOC_FREE(client_ip);
2714 * Send keepalive packets to our client
2716 static bool keepalive_fn(const struct timeval *now, void *private_data)
2718 struct smbd_server_connection *sconn = talloc_get_type_abort(
2719 private_data, struct smbd_server_connection);
2720 struct smbXsrv_connection *xconn = sconn->conn;
2721 bool ret;
2723 if (sconn->using_smb2) {
2724 /* Don't do keepalives on an SMB2 connection. */
2725 return false;
2728 smbd_lock_socket(sconn);
2729 ret = send_keepalive(xconn->transport.sock);
2730 smbd_unlock_socket(sconn);
2732 if (!ret) {
2733 int saved_errno = errno;
2735 * Try and give an error message saying what
2736 * client failed.
2738 DEBUG(0, ("send_keepalive failed for client %s. "
2739 "Error %s - exiting\n",
2740 smbXsrv_connection_dbg(xconn),
2741 strerror(saved_errno)));
2742 errno = saved_errno;
2743 return False;
2745 return True;
2749 * Do the recurring check if we're idle
2751 static bool deadtime_fn(const struct timeval *now, void *private_data)
2753 struct smbd_server_connection *sconn =
2754 (struct smbd_server_connection *)private_data;
2756 if ((conn_num_open(sconn) == 0)
2757 || (conn_idle_all(sconn, now->tv_sec))) {
2758 DEBUG( 2, ( "Closing idle connection\n" ) );
2759 messaging_send(sconn->msg_ctx,
2760 messaging_server_id(sconn->msg_ctx),
2761 MSG_SHUTDOWN, &data_blob_null);
2762 return False;
2765 return True;
2769 * Do the recurring log file and smb.conf reload checks.
2772 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2774 struct smbd_server_connection *sconn = talloc_get_type_abort(
2775 private_data, struct smbd_server_connection);
2777 DEBUG(5, ("housekeeping\n"));
2779 change_to_root_user();
2781 /* update printer queue caches if necessary */
2782 update_monitored_printq_cache(sconn->msg_ctx);
2784 /* check if we need to reload services */
2785 check_reload(sconn, time_mono(NULL));
2788 * Force a log file check.
2790 force_check_log_size();
2791 check_log_size();
2792 return true;
2796 * Read an smb packet in the echo handler child, giving the parent
2797 * smbd one second to react once the socket becomes readable.
2800 struct smbd_echo_read_state {
2801 struct tevent_context *ev;
2802 struct smbd_server_connection *sconn;
2804 char *buf;
2805 size_t buflen;
2806 uint32_t seqnum;
2809 static void smbd_echo_read_readable(struct tevent_req *subreq);
2810 static void smbd_echo_read_waited(struct tevent_req *subreq);
2812 static struct tevent_req *smbd_echo_read_send(
2813 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2814 struct smbd_server_connection *sconn)
2816 struct tevent_req *req, *subreq;
2817 struct smbd_echo_read_state *state;
2818 struct smbXsrv_connection *xconn = sconn->conn;
2820 req = tevent_req_create(mem_ctx, &state,
2821 struct smbd_echo_read_state);
2822 if (req == NULL) {
2823 return NULL;
2825 state->ev = ev;
2826 state->sconn = sconn;
2828 subreq = wait_for_read_send(state, ev, xconn->transport.sock);
2829 if (tevent_req_nomem(subreq, req)) {
2830 return tevent_req_post(req, ev);
2832 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2833 return req;
2836 static void smbd_echo_read_readable(struct tevent_req *subreq)
2838 struct tevent_req *req = tevent_req_callback_data(
2839 subreq, struct tevent_req);
2840 struct smbd_echo_read_state *state = tevent_req_data(
2841 req, struct smbd_echo_read_state);
2842 bool ok;
2843 int err;
2845 ok = wait_for_read_recv(subreq, &err);
2846 TALLOC_FREE(subreq);
2847 if (!ok) {
2848 tevent_req_nterror(req, map_nt_error_from_unix(err));
2849 return;
2853 * Give the parent smbd one second to step in
2856 subreq = tevent_wakeup_send(
2857 state, state->ev, timeval_current_ofs(1, 0));
2858 if (tevent_req_nomem(subreq, req)) {
2859 return;
2861 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2864 static void smbd_echo_read_waited(struct tevent_req *subreq)
2866 struct tevent_req *req = tevent_req_callback_data(
2867 subreq, struct tevent_req);
2868 struct smbd_echo_read_state *state = tevent_req_data(
2869 req, struct smbd_echo_read_state);
2870 struct smbd_server_connection *sconn = state->sconn;
2871 struct smbXsrv_connection *xconn = sconn->conn;
2872 bool ok;
2873 NTSTATUS status;
2874 size_t unread = 0;
2875 bool encrypted;
2877 ok = tevent_wakeup_recv(subreq);
2878 TALLOC_FREE(subreq);
2879 if (!ok) {
2880 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2881 return;
2884 ok = smbd_lock_socket_internal(sconn);
2885 if (!ok) {
2886 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2887 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2888 return;
2891 if (!fd_is_readable(xconn->transport.sock)) {
2892 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2893 (int)getpid()));
2895 ok = smbd_unlock_socket_internal(sconn);
2896 if (!ok) {
2897 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2898 DEBUG(1, ("%s: failed to unlock socket\n",
2899 __location__));
2900 return;
2903 subreq = wait_for_read_send(state, state->ev,
2904 xconn->transport.sock);
2905 if (tevent_req_nomem(subreq, req)) {
2906 return;
2908 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2909 return;
2912 status = receive_smb_talloc(state, sconn,
2913 xconn->transport.sock,
2914 &state->buf,
2915 0 /* timeout */,
2916 &unread,
2917 &encrypted,
2918 &state->buflen,
2919 &state->seqnum,
2920 false /* trusted_channel*/);
2922 if (tevent_req_nterror(req, status)) {
2923 tevent_req_nterror(req, status);
2924 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2925 (int)getpid(), nt_errstr(status)));
2926 return;
2929 ok = smbd_unlock_socket_internal(sconn);
2930 if (!ok) {
2931 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2932 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2933 return;
2935 tevent_req_done(req);
2938 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2939 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2941 struct smbd_echo_read_state *state = tevent_req_data(
2942 req, struct smbd_echo_read_state);
2943 NTSTATUS status;
2945 if (tevent_req_is_nterror(req, &status)) {
2946 return status;
2948 *pbuf = talloc_move(mem_ctx, &state->buf);
2949 *pbuflen = state->buflen;
2950 *pseqnum = state->seqnum;
2951 return NT_STATUS_OK;
2954 struct smbd_echo_state {
2955 struct tevent_context *ev;
2956 struct iovec *pending;
2957 struct smbd_server_connection *sconn;
2958 struct smbXsrv_connection *xconn;
2959 int parent_pipe;
2961 struct tevent_fd *parent_fde;
2963 struct tevent_req *write_req;
2966 static void smbd_echo_writer_done(struct tevent_req *req);
2968 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2970 int num_pending;
2972 if (state->write_req != NULL) {
2973 return;
2976 num_pending = talloc_array_length(state->pending);
2977 if (num_pending == 0) {
2978 return;
2981 state->write_req = writev_send(state, state->ev, NULL,
2982 state->parent_pipe, false,
2983 state->pending, num_pending);
2984 if (state->write_req == NULL) {
2985 DEBUG(1, ("writev_send failed\n"));
2986 exit(1);
2989 talloc_steal(state->write_req, state->pending);
2990 state->pending = NULL;
2992 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2993 state);
2996 static void smbd_echo_writer_done(struct tevent_req *req)
2998 struct smbd_echo_state *state = tevent_req_callback_data(
2999 req, struct smbd_echo_state);
3000 ssize_t written;
3001 int err;
3003 written = writev_recv(req, &err);
3004 TALLOC_FREE(req);
3005 state->write_req = NULL;
3006 if (written == -1) {
3007 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3008 exit(1);
3010 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3011 smbd_echo_activate_writer(state);
3014 static bool smbd_echo_reply(struct smbd_echo_state *state,
3015 uint8_t *inbuf, size_t inbuf_len,
3016 uint32_t seqnum)
3018 struct smb_request req;
3019 uint16_t num_replies;
3020 char *outbuf;
3021 bool ok;
3023 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3024 DEBUG(10, ("Got netbios keepalive\n"));
3026 * Just swallow it
3028 return true;
3031 if (inbuf_len < smb_size) {
3032 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3033 return false;
3035 if (!valid_smb_header(state->sconn, inbuf)) {
3036 DEBUG(10, ("Got invalid SMB header\n"));
3037 return false;
3040 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3041 seqnum)) {
3042 return false;
3044 req.inbuf = inbuf;
3046 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3047 smb_messages[req.cmd].name
3048 ? smb_messages[req.cmd].name : "unknown"));
3050 if (req.cmd != SMBecho) {
3051 return false;
3053 if (req.wct < 1) {
3054 return false;
3057 num_replies = SVAL(req.vwv+0, 0);
3058 if (num_replies != 1) {
3059 /* Not a Windows "Hey, you're still there?" request */
3060 return false;
3063 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3064 1, req.buflen)) {
3065 DEBUG(10, ("create_outbuf failed\n"));
3066 return false;
3068 req.outbuf = (uint8_t *)outbuf;
3070 SSVAL(req.outbuf, smb_vwv0, num_replies);
3072 if (req.buflen > 0) {
3073 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3076 ok = srv_send_smb(req.sconn,
3077 (char *)outbuf,
3078 true, seqnum+1,
3079 false, &req.pcd);
3080 TALLOC_FREE(outbuf);
3081 if (!ok) {
3082 exit(1);
3085 return true;
3088 static void smbd_echo_exit(struct tevent_context *ev,
3089 struct tevent_fd *fde, uint16_t flags,
3090 void *private_data)
3092 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3093 exit(0);
3096 static void smbd_echo_got_packet(struct tevent_req *req);
3098 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3099 int parent_pipe)
3101 struct smbXsrv_connection *xconn = sconn->conn;
3102 struct smbd_echo_state *state;
3103 struct tevent_req *read_req;
3105 state = talloc_zero(sconn, struct smbd_echo_state);
3106 if (state == NULL) {
3107 DEBUG(1, ("talloc failed\n"));
3108 return;
3110 state->sconn = sconn;
3111 state->xconn = xconn;
3112 state->parent_pipe = parent_pipe;
3113 state->ev = s3_tevent_context_init(state);
3114 if (state->ev == NULL) {
3115 DEBUG(1, ("tevent_context_init failed\n"));
3116 TALLOC_FREE(state);
3117 return;
3119 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3120 TEVENT_FD_READ, smbd_echo_exit,
3121 state);
3122 if (state->parent_fde == NULL) {
3123 DEBUG(1, ("tevent_add_fd failed\n"));
3124 TALLOC_FREE(state);
3125 return;
3128 read_req = smbd_echo_read_send(state, state->ev, sconn);
3129 if (read_req == NULL) {
3130 DEBUG(1, ("smbd_echo_read_send failed\n"));
3131 TALLOC_FREE(state);
3132 return;
3134 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3136 while (true) {
3137 if (tevent_loop_once(state->ev) == -1) {
3138 DEBUG(1, ("tevent_loop_once failed: %s\n",
3139 strerror(errno)));
3140 break;
3143 TALLOC_FREE(state);
3146 static void smbd_echo_got_packet(struct tevent_req *req)
3148 struct smbd_echo_state *state = tevent_req_callback_data(
3149 req, struct smbd_echo_state);
3150 NTSTATUS status;
3151 char *buf = NULL;
3152 size_t buflen = 0;
3153 uint32_t seqnum = 0;
3154 bool reply;
3156 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3157 TALLOC_FREE(req);
3158 if (!NT_STATUS_IS_OK(status)) {
3159 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3160 nt_errstr(status)));
3161 exit(1);
3164 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3165 if (!reply) {
3166 size_t num_pending;
3167 struct iovec *tmp;
3168 struct iovec *iov;
3170 num_pending = talloc_array_length(state->pending);
3171 tmp = talloc_realloc(state, state->pending, struct iovec,
3172 num_pending+1);
3173 if (tmp == NULL) {
3174 DEBUG(1, ("talloc_realloc failed\n"));
3175 exit(1);
3177 state->pending = tmp;
3179 if (buflen >= smb_size) {
3181 * place the seqnum in the packet so that the main process
3182 * can reply with signing
3184 SIVAL(buf, smb_ss_field, seqnum);
3185 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3188 iov = &state->pending[num_pending];
3189 iov->iov_base = talloc_move(state->pending, &buf);
3190 iov->iov_len = buflen;
3192 DEBUG(10,("echo_handler[%d]: forward to main\n",
3193 (int)getpid()));
3194 smbd_echo_activate_writer(state);
3197 req = smbd_echo_read_send(state, state->ev, state->sconn);
3198 if (req == NULL) {
3199 DEBUG(1, ("smbd_echo_read_send failed\n"));
3200 exit(1);
3202 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3207 * Handle SMBecho requests in a forked child process
3209 bool fork_echo_handler(struct smbd_server_connection *sconn)
3211 struct smbXsrv_connection *xconn = sconn->conn;
3212 int listener_pipe[2];
3213 int res;
3214 pid_t child;
3215 bool use_mutex = false;
3217 res = pipe(listener_pipe);
3218 if (res == -1) {
3219 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3220 return false;
3223 #ifdef HAVE_ROBUST_MUTEXES
3224 use_mutex = tdb_runtime_check_for_robust_mutexes();
3226 if (use_mutex) {
3227 pthread_mutexattr_t a;
3229 xconn->smb1.echo_handler.socket_mutex =
3230 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3231 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3232 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3233 strerror(errno)));
3234 goto fail;
3237 res = pthread_mutexattr_init(&a);
3238 if (res != 0) {
3239 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3240 strerror(res)));
3241 goto fail;
3243 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3244 if (res != 0) {
3245 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3246 strerror(res)));
3247 pthread_mutexattr_destroy(&a);
3248 goto fail;
3250 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3251 if (res != 0) {
3252 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3253 strerror(res)));
3254 pthread_mutexattr_destroy(&a);
3255 goto fail;
3257 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3258 if (res != 0) {
3259 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3260 "%s\n", strerror(res)));
3261 pthread_mutexattr_destroy(&a);
3262 goto fail;
3264 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3265 &a);
3266 pthread_mutexattr_destroy(&a);
3267 if (res != 0) {
3268 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3269 strerror(res)));
3270 goto fail;
3273 #endif
3275 if (!use_mutex) {
3276 xconn->smb1.echo_handler.socket_lock_fd =
3277 create_unlink_tmp(lp_lock_directory());
3278 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3279 DEBUG(1, ("Could not create lock fd: %s\n",
3280 strerror(errno)));
3281 goto fail;
3285 child = fork();
3286 if (child == 0) {
3287 NTSTATUS status;
3289 close(listener_pipe[0]);
3290 set_blocking(listener_pipe[1], false);
3292 status = reinit_after_fork(sconn->msg_ctx,
3293 sconn->ev_ctx,
3294 true);
3295 if (!NT_STATUS_IS_OK(status)) {
3296 DEBUG(1, ("reinit_after_fork failed: %s\n",
3297 nt_errstr(status)));
3298 exit(1);
3300 smbd_echo_loop(sconn, listener_pipe[1]);
3301 exit(0);
3303 close(listener_pipe[1]);
3304 listener_pipe[1] = -1;
3305 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3307 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3310 * Without smb signing this is the same as the normal smbd
3311 * listener. This needs to change once signing comes in.
3313 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3314 xconn,
3315 xconn->smb1.echo_handler.trusted_fd,
3316 TEVENT_FD_READ,
3317 smbd_server_echo_handler,
3318 xconn);
3319 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3320 DEBUG(1, ("event_add_fd failed\n"));
3321 goto fail;
3324 return true;
3326 fail:
3327 if (listener_pipe[0] != -1) {
3328 close(listener_pipe[0]);
3330 if (listener_pipe[1] != -1) {
3331 close(listener_pipe[1]);
3333 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3334 close(xconn->smb1.echo_handler.socket_lock_fd);
3336 #ifdef HAVE_ROBUST_MUTEXES
3337 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3338 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3339 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3341 #endif
3342 smbd_echo_init(xconn);
3344 return false;
3347 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3349 while (user) {
3350 if (user->session_info &&
3351 (user->session_info->unix_token->uid == uid)) {
3352 return true;
3354 user = user->next;
3356 return false;
3359 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3361 while (user) {
3362 if (user->session_info != NULL) {
3363 int i;
3364 struct security_unix_token *utok;
3366 utok = user->session_info->unix_token;
3367 if (utok->gid == gid) {
3368 return true;
3370 for(i=0; i<utok->ngroups; i++) {
3371 if (utok->groups[i] == gid) {
3372 return true;
3376 user = user->next;
3378 return false;
3381 static bool sid_in_use(const struct user_struct *user,
3382 const struct dom_sid *psid)
3384 while (user) {
3385 struct security_token *tok;
3387 if (user->session_info == NULL) {
3388 continue;
3390 tok = user->session_info->security_token;
3391 if (tok == NULL) {
3393 * Not sure session_info->security_token can
3394 * ever be NULL. This check might be not
3395 * necessary.
3397 continue;
3399 if (security_token_has_sid(tok, psid)) {
3400 return true;
3402 user = user->next;
3404 return false;
3407 static bool id_in_use(const struct user_struct *user,
3408 const struct id_cache_ref *id)
3410 switch(id->type) {
3411 case UID:
3412 return uid_in_use(user, id->id.uid);
3413 case GID:
3414 return gid_in_use(user, id->id.gid);
3415 case SID:
3416 return sid_in_use(user, &id->id.sid);
3417 default:
3418 break;
3420 return false;
3423 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3424 void *private_data,
3425 uint32_t msg_type,
3426 struct server_id server_id,
3427 DATA_BLOB* data)
3429 const char *msg = (data && data->data)
3430 ? (const char *)data->data : "<NULL>";
3431 struct id_cache_ref id;
3432 struct smbd_server_connection *sconn =
3433 talloc_get_type_abort(private_data,
3434 struct smbd_server_connection);
3436 if (!id_cache_ref_parse(msg, &id)) {
3437 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3438 return;
3441 if (id_in_use(sconn->users, &id)) {
3442 exit_server_cleanly(msg);
3444 id_cache_delete_from_cache(&id);
3447 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3448 enum protocol_types protocol)
3450 NTSTATUS status;
3452 set_Protocol(protocol);
3453 conn->protocol = protocol;
3455 if (protocol >= PROTOCOL_SMB2_02) {
3456 status = smb2srv_session_table_init(conn);
3457 if (!NT_STATUS_IS_OK(status)) {
3458 return status;
3461 status = smb2srv_open_table_init(conn);
3462 if (!NT_STATUS_IS_OK(status)) {
3463 return status;
3465 } else {
3466 status = smb1srv_session_table_init(conn);
3467 if (!NT_STATUS_IS_OK(status)) {
3468 return status;
3471 status = smb1srv_tcon_table_init(conn);
3472 if (!NT_STATUS_IS_OK(status)) {
3473 return status;
3476 status = smb1srv_open_table_init(conn);
3477 if (!NT_STATUS_IS_OK(status)) {
3478 return status;
3482 return NT_STATUS_OK;
3485 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3486 void *private_data)
3488 struct smbXsrv_connection *conn =
3489 talloc_get_type_abort(private_data,
3490 struct smbXsrv_connection);
3492 switch (point) {
3493 case TEVENT_TRACE_BEFORE_WAIT:
3495 * This just removes compiler warning
3496 * without profile support
3498 conn->smbd_idle_profstamp = 0;
3499 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3500 break;
3501 case TEVENT_TRACE_AFTER_WAIT:
3502 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3503 break;
3504 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3505 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3506 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3507 break;
3508 #endif
3513 * Create a debug string for the connection
3515 * This is allocated to talloc_tos() or a string constant
3516 * in certain corner cases. The returned string should
3517 * hence not be free'd directly but only via the talloc stack.
3519 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3521 const char *ret;
3524 * TODO: this can be improved later
3525 * maybe including the client guid or more
3527 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3528 if (ret == NULL) {
3529 return "<tsocket_address_string() failed>";
3532 return ret;
3535 /****************************************************************************
3536 Process commands from the client
3537 ****************************************************************************/
3539 void smbd_process(struct tevent_context *ev_ctx,
3540 struct messaging_context *msg_ctx,
3541 int sock_fd,
3542 bool interactive)
3544 TALLOC_CTX *frame = talloc_stackframe();
3545 struct smbXsrv_connection *xconn;
3546 struct smbd_server_connection *sconn;
3547 struct sockaddr_storage ss_srv;
3548 void *sp_srv = (void *)&ss_srv;
3549 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3550 struct sockaddr_storage ss_clnt;
3551 void *sp_clnt = (void *)&ss_clnt;
3552 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3553 socklen_t sa_socklen;
3554 struct tsocket_address *local_address = NULL;
3555 struct tsocket_address *remote_address = NULL;
3556 const char *locaddr = NULL;
3557 const char *remaddr = NULL;
3558 char *rhost;
3559 int ret;
3560 int tmp;
3562 xconn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3563 if (xconn == NULL) {
3564 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3565 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3568 xconn->ev_ctx = ev_ctx;
3569 xconn->msg_ctx = msg_ctx;
3570 xconn->transport.sock = sock_fd;
3571 smbd_echo_init(xconn);
3573 sconn = talloc_zero(xconn, struct smbd_server_connection);
3574 if (!sconn) {
3575 exit_server("failed to create smbd_server_connection");
3578 xconn->sconn = sconn;
3579 sconn->conn = xconn;
3582 * TODO: remove this...:-)
3584 global_smbXsrv_connection = xconn;
3586 sconn->ev_ctx = ev_ctx;
3587 sconn->msg_ctx = msg_ctx;
3589 if (!interactive) {
3590 smbd_setup_sig_term_handler(sconn);
3591 smbd_setup_sig_hup_handler(sconn);
3593 if (!serverid_register(messaging_server_id(msg_ctx),
3594 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3595 |FLAG_MSG_DBWRAP
3596 |FLAG_MSG_PRINT_GENERAL)) {
3597 exit_server_cleanly("Could not register myself in "
3598 "serverid.tdb");
3602 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3604 * We're not making the decision here,
3605 * we're just allowing the client
3606 * to decide between SMB1 and SMB2
3607 * with the first negprot
3608 * packet.
3610 sconn->using_smb2 = true;
3613 /* Ensure child is set to blocking mode */
3614 set_blocking(sock_fd,True);
3616 set_socket_options(sock_fd, "SO_KEEPALIVE");
3617 set_socket_options(sock_fd, lp_socket_options());
3619 sa_socklen = sizeof(ss_clnt);
3620 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3621 if (ret != 0) {
3622 int level = (errno == ENOTCONN)?2:0;
3623 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3624 exit_server_cleanly("getpeername() failed.\n");
3626 ret = tsocket_address_bsd_from_sockaddr(sconn,
3627 sa_clnt, sa_socklen,
3628 &remote_address);
3629 if (ret != 0) {
3630 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3631 __location__, strerror(errno)));
3632 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3635 sa_socklen = sizeof(ss_srv);
3636 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3637 if (ret != 0) {
3638 int level = (errno == ENOTCONN)?2:0;
3639 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3640 exit_server_cleanly("getsockname() failed.\n");
3642 ret = tsocket_address_bsd_from_sockaddr(sconn,
3643 sa_srv, sa_socklen,
3644 &local_address);
3645 if (ret != 0) {
3646 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3647 __location__, strerror(errno)));
3648 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3651 sconn->local_address = local_address;
3652 sconn->remote_address = remote_address;
3654 if (tsocket_address_is_inet(local_address, "ip")) {
3655 locaddr = tsocket_address_inet_addr_string(
3656 sconn->local_address,
3657 talloc_tos());
3658 if (locaddr == NULL) {
3659 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3660 __location__, strerror(errno)));
3661 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3663 } else {
3664 locaddr = "0.0.0.0";
3667 if (tsocket_address_is_inet(remote_address, "ip")) {
3668 remaddr = tsocket_address_inet_addr_string(
3669 sconn->remote_address,
3670 talloc_tos());
3671 if (remaddr == NULL) {
3672 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3673 __location__, strerror(errno)));
3674 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3676 } else {
3677 remaddr = "0.0.0.0";
3680 /* this is needed so that we get decent entries
3681 in smbstatus for port 445 connects */
3682 set_remote_machine_name(remaddr, false);
3683 reload_services(sconn, conn_snum_used, true);
3686 * Before the first packet, check the global hosts allow/ hosts deny
3687 * parameters before doing any parsing of packets passed to us by the
3688 * client. This prevents attacks on our parsing code from hosts not in
3689 * the hosts allow list.
3692 ret = get_remote_hostname(remote_address,
3693 &rhost,
3694 talloc_tos());
3695 if (ret < 0) {
3696 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3697 __location__, strerror(errno)));
3698 exit_server_cleanly("get_remote_hostname failed.\n");
3700 if (strequal(rhost, "UNKNOWN")) {
3701 rhost = talloc_strdup(talloc_tos(), remaddr);
3703 sconn->remote_hostname = talloc_move(sconn, &rhost);
3705 sub_set_socket_ids(remaddr,
3706 sconn->remote_hostname,
3707 locaddr);
3709 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3710 sconn->remote_hostname,
3711 remaddr)) {
3713 * send a negative session response "not listening on calling
3714 * name"
3716 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3717 DEBUG( 1, ("Connection denied from %s to %s\n",
3718 tsocket_address_string(remote_address, talloc_tos()),
3719 tsocket_address_string(local_address, talloc_tos())));
3720 (void)srv_send_smb(sconn,(char *)buf, false,
3721 0, false, NULL);
3722 exit_server_cleanly("connection denied");
3725 DEBUG(10, ("Connection allowed from %s to %s\n",
3726 tsocket_address_string(remote_address, talloc_tos()),
3727 tsocket_address_string(local_address, talloc_tos())));
3729 if (lp_preload_modules()) {
3730 smb_load_modules(lp_preload_modules());
3733 smb_perfcount_init();
3735 if (!init_account_policy()) {
3736 exit_server("Could not open account policy tdb.\n");
3739 if (*lp_root_directory(talloc_tos())) {
3740 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3741 DEBUG(0,("Failed to change root to %s\n",
3742 lp_root_directory(talloc_tos())));
3743 exit_server("Failed to chroot()");
3745 if (chdir("/") == -1) {
3746 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3747 exit_server("Failed to chroot()");
3749 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3752 if (!srv_init_signing(xconn)) {
3753 exit_server("Failed to init smb_signing");
3756 if (!file_init(sconn)) {
3757 exit_server("file_init() failed");
3760 /* Setup oplocks */
3761 if (!init_oplocks(sconn))
3762 exit_server("Failed to init oplocks");
3764 /* register our message handlers */
3765 messaging_register(sconn->msg_ctx, sconn,
3766 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3767 messaging_register(sconn->msg_ctx, sconn,
3768 MSG_SMB_CLOSE_FILE, msg_close_file);
3769 messaging_register(sconn->msg_ctx, sconn,
3770 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3772 id_cache_register_msgs(sconn->msg_ctx);
3773 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3774 messaging_register(sconn->msg_ctx, sconn,
3775 ID_CACHE_KILL, smbd_id_cache_kill);
3777 messaging_deregister(sconn->msg_ctx,
3778 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3779 messaging_register(sconn->msg_ctx, sconn,
3780 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3782 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3783 NULL);
3784 messaging_register(sconn->msg_ctx, sconn,
3785 MSG_SMB_KILL_CLIENT_IP,
3786 msg_kill_client_ip);
3788 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3791 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3792 * MSGs to all child processes
3794 messaging_deregister(sconn->msg_ctx,
3795 MSG_DEBUG, NULL);
3796 messaging_register(sconn->msg_ctx, NULL,
3797 MSG_DEBUG, debug_message);
3799 if ((lp_keepalive() != 0)
3800 && !(event_add_idle(ev_ctx, NULL,
3801 timeval_set(lp_keepalive(), 0),
3802 "keepalive", keepalive_fn,
3803 sconn))) {
3804 DEBUG(0, ("Could not add keepalive event\n"));
3805 exit(1);
3808 if (!(event_add_idle(ev_ctx, NULL,
3809 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3810 "deadtime", deadtime_fn, sconn))) {
3811 DEBUG(0, ("Could not add deadtime event\n"));
3812 exit(1);
3815 if (!(event_add_idle(ev_ctx, NULL,
3816 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3817 "housekeeping", housekeeping_fn, sconn))) {
3818 DEBUG(0, ("Could not add housekeeping event\n"));
3819 exit(1);
3822 if (lp_clustering()) {
3824 * We need to tell ctdb about our client's TCP
3825 * connection, so that for failover ctdbd can send
3826 * tickle acks, triggering a reconnection by the
3827 * client.
3829 NTSTATUS status;
3831 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3832 if (!NT_STATUS_IS_OK(status)) {
3833 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3834 nt_errstr(status)));
3838 tmp = lp_max_xmit();
3839 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3840 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3842 xconn->smb1.negprot.max_recv = tmp;
3844 xconn->smb1.sessions.done_sesssetup = false;
3845 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3847 if (!init_dptrs(sconn)) {
3848 exit_server("init_dptrs() failed");
3851 xconn->transport.fde = tevent_add_fd(ev_ctx,
3852 xconn,
3853 sock_fd,
3854 TEVENT_FD_READ,
3855 smbd_server_connection_handler,
3856 xconn);
3857 if (!xconn->transport.fde) {
3858 exit_server("failed to create smbd_server_connection fde");
3861 sconn->conn->local_address = sconn->local_address;
3862 sconn->conn->remote_address = sconn->remote_address;
3863 sconn->conn->remote_hostname = sconn->remote_hostname;
3864 sconn->conn->protocol = PROTOCOL_NONE;
3866 TALLOC_FREE(frame);
3868 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, xconn);
3870 while (True) {
3871 frame = talloc_stackframe_pool(8192);
3873 errno = 0;
3874 if (tevent_loop_once(ev_ctx) == -1) {
3875 if (errno != EINTR) {
3876 DEBUG(3, ("tevent_loop_once failed: %s,"
3877 " exiting\n", strerror(errno) ));
3878 break;
3882 TALLOC_FREE(frame);
3885 exit_server_cleanly(NULL);
3888 bool req_is_in_chain(const struct smb_request *req)
3890 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3892 * We're right now handling a subsequent request, so we must
3893 * be in a chain
3895 return true;
3898 if (!is_andx_req(req->cmd)) {
3899 return false;
3902 if (req->wct < 2) {
3904 * Okay, an illegal request, but definitely not chained :-)
3906 return false;
3909 return (CVAL(req->vwv+0, 0) != 0xFF);