s4:torture: Remove unused header file
[Samba.git] / source3 / smbd / process.c
blob99693ed1315b98360ca164439b33d061d703b9a2
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 "lib/messages_ctdb.h"
36 #include "smbprofile.h"
37 #include "rpc_server/spoolss/srv_spoolss_nt.h"
38 #include "libsmb/libsmb.h"
39 #include "../lib/util/tevent_ntstatus.h"
40 #include "../libcli/security/dom_sid.h"
41 #include "../libcli/security/security_token.h"
42 #include "lib/id_cache.h"
43 #include "lib/util/sys_rw_data.h"
44 #include "system/threads.h"
45 #include "lib/pthreadpool/pthreadpool_tevent.h"
46 #include "util_event.h"
48 /* Internal message queue for deferred opens. */
49 struct pending_message_list {
50 struct pending_message_list *next, *prev;
51 struct timeval request_time; /* When was this first issued? */
52 struct smbd_server_connection *sconn;
53 struct smbXsrv_connection *xconn;
54 struct tevent_timer *te;
55 struct smb_perfcount_data pcd;
56 uint32_t seqnum;
57 bool encrypted;
58 bool processed;
59 DATA_BLOB buf;
60 struct deferred_open_record *open_rec;
63 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
64 char *outbuf);
65 static struct pending_message_list *get_deferred_open_message_smb(
66 struct smbd_server_connection *sconn, uint64_t mid);
67 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
69 static void smbd_echo_init(struct smbXsrv_connection *xconn)
71 xconn->smb1.echo_handler.trusted_fd = -1;
72 xconn->smb1.echo_handler.socket_lock_fd = -1;
73 #ifdef HAVE_ROBUST_MUTEXES
74 xconn->smb1.echo_handler.socket_mutex = NULL;
75 #endif
78 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
80 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
81 return true;
84 #ifdef HAVE_ROBUST_MUTEXES
85 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
86 return true;
88 #endif
90 return false;
93 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
95 if (!smbd_echo_active(xconn)) {
96 return true;
99 xconn->smb1.echo_handler.ref_count++;
101 if (xconn->smb1.echo_handler.ref_count > 1) {
102 return true;
105 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
107 #ifdef HAVE_ROBUST_MUTEXES
108 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
109 int ret = EINTR;
111 while (ret == EINTR) {
112 ret = pthread_mutex_lock(
113 xconn->smb1.echo_handler.socket_mutex);
114 if (ret == 0) {
115 break;
118 if (ret != 0) {
119 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
120 strerror(ret)));
121 return false;
124 #endif
126 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
127 bool ok;
129 do {
130 ok = fcntl_lock(
131 xconn->smb1.echo_handler.socket_lock_fd,
132 F_SETLKW, 0, 0, F_WRLCK);
133 } while (!ok && (errno == EINTR));
135 if (!ok) {
136 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
137 return false;
141 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
143 return true;
146 void smbd_lock_socket(struct smbXsrv_connection *xconn)
148 if (!smbd_lock_socket_internal(xconn)) {
149 exit_server_cleanly("failed to lock socket");
153 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
155 if (!smbd_echo_active(xconn)) {
156 return true;
159 xconn->smb1.echo_handler.ref_count--;
161 if (xconn->smb1.echo_handler.ref_count > 0) {
162 return true;
165 #ifdef HAVE_ROBUST_MUTEXES
166 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
167 int ret;
168 ret = pthread_mutex_unlock(
169 xconn->smb1.echo_handler.socket_mutex);
170 if (ret != 0) {
171 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
172 strerror(ret)));
173 return false;
176 #endif
178 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
179 bool ok;
181 do {
182 ok = fcntl_lock(
183 xconn->smb1.echo_handler.socket_lock_fd,
184 F_SETLKW, 0, 0, F_UNLCK);
185 } while (!ok && (errno == EINTR));
187 if (!ok) {
188 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
189 return false;
193 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
195 return true;
198 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
200 if (!smbd_unlock_socket_internal(xconn)) {
201 exit_server_cleanly("failed to unlock socket");
205 /* Accessor function for smb_read_error for smbd functions. */
207 /****************************************************************************
208 Send an smb to a fd.
209 ****************************************************************************/
211 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
212 bool do_signing, uint32_t seqnum,
213 bool do_encrypt,
214 struct smb_perfcount_data *pcd)
216 size_t len = 0;
217 ssize_t ret;
218 char *buf_out = buffer;
220 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
222 * we're not supposed to do any io
224 return true;
227 smbd_lock_socket(xconn);
229 if (do_signing) {
230 /* Sign the outgoing packet if required. */
231 srv_calculate_sign_mac(xconn, buf_out, seqnum);
234 if (do_encrypt) {
235 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
236 if (!NT_STATUS_IS_OK(status)) {
237 DEBUG(0, ("send_smb: SMB encryption failed "
238 "on outgoing packet! Error %s\n",
239 nt_errstr(status) ));
240 ret = -1;
241 goto out;
245 len = smb_len_large(buf_out) + 4;
247 ret = write_data(xconn->transport.sock, buf_out, len);
248 if (ret <= 0) {
249 int saved_errno = errno;
251 * Try and give an error message saying what
252 * client failed.
254 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
255 (int)getpid(), (int)len,
256 smbXsrv_connection_dbg(xconn),
257 (int)ret, strerror(saved_errno)));
258 errno = saved_errno;
260 srv_free_enc_buffer(xconn, buf_out);
261 goto out;
264 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
265 srv_free_enc_buffer(xconn, buf_out);
266 out:
267 SMB_PERFCOUNT_END(pcd);
269 smbd_unlock_socket(xconn);
270 return (ret > 0);
273 /*******************************************************************
274 Setup the word count and byte count for a smb message.
275 ********************************************************************/
277 size_t srv_set_message(char *buf,
278 size_t num_words,
279 size_t num_bytes,
280 bool zero)
282 if (zero && (num_words || num_bytes)) {
283 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
285 SCVAL(buf,smb_wct,num_words);
286 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
287 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
288 return (smb_size + num_words*2 + num_bytes);
291 static bool valid_smb_header(const uint8_t *inbuf)
293 if (is_encrypted_packet(inbuf)) {
294 return true;
297 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
298 * but it just looks weird to call strncmp for this one.
300 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
303 /* Socket functions for smbd packet processing. */
305 static bool valid_packet_size(size_t len)
308 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
309 * of header. Don't print the error if this fits.... JRA.
312 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
313 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
314 (unsigned long)len));
315 return false;
317 return true;
320 static NTSTATUS read_packet_remainder(int fd, char *buffer,
321 unsigned int timeout, ssize_t len)
323 NTSTATUS status;
325 if (len <= 0) {
326 return NT_STATUS_OK;
329 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
330 if (!NT_STATUS_IS_OK(status)) {
331 char addr[INET6_ADDRSTRLEN];
332 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
333 "error = %s.\n",
334 get_peer_addr(fd, addr, sizeof(addr)),
335 nt_errstr(status)));
337 return status;
340 /****************************************************************************
341 Attempt a zerocopy writeX read. We know here that len > smb_size-4
342 ****************************************************************************/
345 * Unfortunately, earlier versions of smbclient/libsmbclient
346 * don't send this "standard" writeX header. I've fixed this
347 * for 3.2 but we'll use the old method with earlier versions.
348 * Windows and CIFSFS at least use this standard size. Not
349 * sure about MacOSX.
352 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
353 (2*14) + /* word count (including bcc) */ \
354 1 /* pad byte */)
356 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
357 const char lenbuf[4],
358 struct smbXsrv_connection *xconn,
359 int sock,
360 char **buffer,
361 unsigned int timeout,
362 size_t *p_unread,
363 size_t *len_ret)
365 /* Size of a WRITEX call (+4 byte len). */
366 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
367 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
368 ssize_t toread;
369 NTSTATUS status;
371 memcpy(writeX_header, lenbuf, 4);
373 status = read_fd_with_timeout(
374 sock, writeX_header + 4,
375 STANDARD_WRITE_AND_X_HEADER_SIZE,
376 STANDARD_WRITE_AND_X_HEADER_SIZE,
377 timeout, NULL);
379 if (!NT_STATUS_IS_OK(status)) {
380 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
381 "error = %s.\n",
382 smbXsrv_connection_dbg(xconn),
383 nt_errstr(status)));
384 return status;
388 * Ok - now try and see if this is a possible
389 * valid writeX call.
392 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
394 * If the data offset is beyond what
395 * we've read, drain the extra bytes.
397 uint16_t doff = SVAL(writeX_header,smb_vwv11);
398 ssize_t newlen;
400 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
401 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
402 if (drain_socket(sock, drain) != drain) {
403 smb_panic("receive_smb_raw_talloc_partial_read:"
404 " failed to drain pending bytes");
406 } else {
407 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
410 /* Spoof down the length and null out the bcc. */
411 set_message_bcc(writeX_header, 0);
412 newlen = smb_len(writeX_header);
414 /* Copy the header we've written. */
416 *buffer = (char *)talloc_memdup(mem_ctx,
417 writeX_header,
418 sizeof(writeX_header));
420 if (*buffer == NULL) {
421 DEBUG(0, ("Could not allocate inbuf of length %d\n",
422 (int)sizeof(writeX_header)));
423 return NT_STATUS_NO_MEMORY;
426 /* Work out the remaining bytes. */
427 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
428 *len_ret = newlen + 4;
429 return NT_STATUS_OK;
432 if (!valid_packet_size(len)) {
433 return NT_STATUS_INVALID_PARAMETER;
437 * Not a valid writeX call. Just do the standard
438 * talloc and return.
441 *buffer = talloc_array(mem_ctx, char, len+4);
443 if (*buffer == NULL) {
444 DEBUG(0, ("Could not allocate inbuf of length %d\n",
445 (int)len+4));
446 return NT_STATUS_NO_MEMORY;
449 /* Copy in what we already read. */
450 memcpy(*buffer,
451 writeX_header,
452 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
453 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
455 if(toread > 0) {
456 status = read_packet_remainder(
457 sock,
458 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
459 timeout, toread);
461 if (!NT_STATUS_IS_OK(status)) {
462 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
463 nt_errstr(status)));
464 return status;
468 *len_ret = len + 4;
469 return NT_STATUS_OK;
472 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
473 struct smbXsrv_connection *xconn,
474 int sock,
475 char **buffer, unsigned int timeout,
476 size_t *p_unread, size_t *plen)
478 char lenbuf[4];
479 size_t len;
480 int min_recv_size = lp_min_receive_file_size();
481 NTSTATUS status;
483 *p_unread = 0;
485 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
486 &len);
487 if (!NT_STATUS_IS_OK(status)) {
488 return status;
491 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
492 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
493 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
494 !srv_is_signing_active(xconn) &&
495 xconn->smb1.echo_handler.trusted_fde == NULL) {
497 return receive_smb_raw_talloc_partial_read(
498 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
499 p_unread, plen);
502 if (!valid_packet_size(len)) {
503 return NT_STATUS_INVALID_PARAMETER;
507 * The +4 here can't wrap, we've checked the length above already.
510 *buffer = talloc_array(mem_ctx, char, len+4);
512 if (*buffer == NULL) {
513 DEBUG(0, ("Could not allocate inbuf of length %d\n",
514 (int)len+4));
515 return NT_STATUS_NO_MEMORY;
518 memcpy(*buffer, lenbuf, sizeof(lenbuf));
520 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
521 if (!NT_STATUS_IS_OK(status)) {
522 return status;
525 *plen = len + 4;
526 return NT_STATUS_OK;
529 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
530 struct smbXsrv_connection *xconn,
531 int sock,
532 char **buffer, unsigned int timeout,
533 size_t *p_unread, bool *p_encrypted,
534 size_t *p_len,
535 uint32_t *seqnum,
536 bool trusted_channel)
538 size_t len = 0;
539 NTSTATUS status;
541 *p_encrypted = false;
543 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
544 p_unread, &len);
545 if (!NT_STATUS_IS_OK(status)) {
546 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
547 ("receive_smb_raw_talloc failed for client %s "
548 "read error = %s.\n",
549 smbXsrv_connection_dbg(xconn),
550 nt_errstr(status)) );
551 return status;
554 if (is_encrypted_packet((uint8_t *)*buffer)) {
555 status = srv_decrypt_buffer(xconn, *buffer);
556 if (!NT_STATUS_IS_OK(status)) {
557 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
558 "incoming packet! Error %s\n",
559 nt_errstr(status) ));
560 return status;
562 *p_encrypted = true;
565 /* Check the incoming SMB signature. */
566 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
567 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
568 "incoming packet!\n"));
569 return NT_STATUS_INVALID_NETWORK_RESPONSE;
572 *p_len = len;
573 return NT_STATUS_OK;
577 * Initialize a struct smb_request from an inbuf
580 static bool init_smb_request(struct smb_request *req,
581 struct smbd_server_connection *sconn,
582 struct smbXsrv_connection *xconn,
583 const uint8_t *inbuf,
584 size_t unread_bytes, bool encrypted,
585 uint32_t seqnum)
587 struct smbXsrv_tcon *tcon;
588 NTSTATUS status;
589 NTTIME now;
590 size_t req_size = smb_len(inbuf) + 4;
592 /* Ensure we have at least smb_size bytes. */
593 if (req_size < smb_size) {
594 DEBUG(0,("init_smb_request: invalid request size %u\n",
595 (unsigned int)req_size ));
596 return false;
599 req->request_time = timeval_current();
600 now = timeval_to_nttime(&req->request_time);
602 req->cmd = CVAL(inbuf, smb_com);
603 req->flags2 = SVAL(inbuf, smb_flg2);
604 req->smbpid = SVAL(inbuf, smb_pid);
605 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
606 req->seqnum = seqnum;
607 req->vuid = SVAL(inbuf, smb_uid);
608 req->tid = SVAL(inbuf, smb_tid);
609 req->wct = CVAL(inbuf, smb_wct);
610 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
611 req->buflen = smb_buflen(inbuf);
612 req->buf = (const uint8_t *)smb_buf_const(inbuf);
613 req->unread_bytes = unread_bytes;
614 req->encrypted = encrypted;
615 req->sconn = sconn;
616 req->xconn = xconn;
617 req->conn = NULL;
618 if (xconn != NULL) {
619 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
620 if (NT_STATUS_IS_OK(status)) {
621 req->conn = tcon->compat;
624 req->chain_fsp = NULL;
625 req->smb2req = NULL;
626 req->priv_paths = NULL;
627 req->chain = NULL;
628 req->posix_pathnames = lp_posix_pathnames();
629 smb_init_perfcount_data(&req->pcd);
631 /* Ensure we have at least wct words and 2 bytes of bcc. */
632 if (smb_size + req->wct*2 > req_size) {
633 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
634 (unsigned int)req->wct,
635 (unsigned int)req_size));
636 return false;
638 /* Ensure bcc is correct. */
639 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
640 DEBUG(0,("init_smb_request: invalid bcc number %u "
641 "(wct = %u, size %u)\n",
642 (unsigned int)req->buflen,
643 (unsigned int)req->wct,
644 (unsigned int)req_size));
645 return false;
648 req->outbuf = NULL;
649 return true;
652 static void process_smb(struct smbXsrv_connection *xconn,
653 uint8_t *inbuf, size_t nread, size_t unread_bytes,
654 uint32_t seqnum, bool encrypted,
655 struct smb_perfcount_data *deferred_pcd);
657 static void smbd_deferred_open_timer(struct tevent_context *ev,
658 struct tevent_timer *te,
659 struct timeval _tval,
660 void *private_data)
662 struct pending_message_list *msg = talloc_get_type(private_data,
663 struct pending_message_list);
664 struct smbd_server_connection *sconn = msg->sconn;
665 struct smbXsrv_connection *xconn = msg->xconn;
666 TALLOC_CTX *mem_ctx = talloc_tos();
667 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
668 uint8_t *inbuf;
670 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
671 msg->buf.length);
672 if (inbuf == NULL) {
673 exit_server("smbd_deferred_open_timer: talloc failed\n");
674 return;
677 /* We leave this message on the queue so the open code can
678 know this is a retry. */
679 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
680 (unsigned long long)mid ));
682 /* Mark the message as processed so this is not
683 * re-processed in error. */
684 msg->processed = true;
686 process_smb(xconn, inbuf,
687 msg->buf.length, 0,
688 msg->seqnum, msg->encrypted, &msg->pcd);
690 /* If it's still there and was processed, remove it. */
691 msg = get_deferred_open_message_smb(sconn, mid);
692 if (msg && msg->processed) {
693 remove_deferred_open_message_smb(xconn, mid);
697 /****************************************************************************
698 Function to push a message onto the tail of a linked list of smb messages ready
699 for processing.
700 ****************************************************************************/
702 static bool push_queued_message(struct smb_request *req,
703 struct timeval request_time,
704 struct timeval end_time,
705 struct deferred_open_record *open_rec)
707 int msg_len = smb_len(req->inbuf) + 4;
708 struct pending_message_list *msg;
710 msg = talloc_zero(NULL, struct pending_message_list);
712 if(msg == NULL) {
713 DEBUG(0,("push_message: malloc fail (1)\n"));
714 return False;
716 msg->sconn = req->sconn;
717 msg->xconn = req->xconn;
719 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
720 if(msg->buf.data == NULL) {
721 DEBUG(0,("push_message: malloc fail (2)\n"));
722 TALLOC_FREE(msg);
723 return False;
726 msg->request_time = request_time;
727 msg->seqnum = req->seqnum;
728 msg->encrypted = req->encrypted;
729 msg->processed = false;
730 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
732 if (open_rec) {
733 msg->open_rec = talloc_move(msg, &open_rec);
736 #if 0
737 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
738 msg,
739 end_time,
740 smbd_deferred_open_timer,
741 msg);
742 if (!msg->te) {
743 DEBUG(0,("push_message: event_add_timed failed\n"));
744 TALLOC_FREE(msg);
745 return false;
747 #endif
749 DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
751 DEBUG(10,("push_message: pushed message length %u on "
752 "deferred_open_queue\n", (unsigned int)msg_len));
754 return True;
757 /****************************************************************************
758 Function to delete a sharing violation open message by mid.
759 ****************************************************************************/
761 void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
762 uint64_t mid)
764 struct smbd_server_connection *sconn = xconn->client->sconn;
765 struct pending_message_list *pml;
767 if (sconn->using_smb2) {
768 remove_deferred_open_message_smb2(xconn, mid);
769 return;
772 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
773 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
774 DEBUG(10,("remove_deferred_open_message_smb: "
775 "deleting mid %llu len %u\n",
776 (unsigned long long)mid,
777 (unsigned int)pml->buf.length ));
778 DLIST_REMOVE(sconn->deferred_open_queue, pml);
779 TALLOC_FREE(pml);
780 return;
785 /****************************************************************************
786 Move a sharing violation open retry message to the front of the list and
787 schedule it for immediate processing.
788 ****************************************************************************/
790 bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
791 uint64_t mid)
793 struct smbd_server_connection *sconn = xconn->client->sconn;
794 struct pending_message_list *pml;
795 int i = 0;
797 if (sconn->using_smb2) {
798 return schedule_deferred_open_message_smb2(xconn, mid);
801 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
802 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
804 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
805 "msg_mid = %llu\n",
806 i++,
807 (unsigned long long)msg_mid ));
809 if (mid == msg_mid) {
810 struct tevent_timer *te;
812 if (pml->processed) {
813 /* A processed message should not be
814 * rescheduled. */
815 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
816 "message mid %llu was already processed\n",
817 (unsigned long long)msg_mid ));
818 continue;
821 DEBUG(10,("schedule_deferred_open_message_smb: "
822 "scheduling mid %llu\n",
823 (unsigned long long)mid ));
826 * smbd_deferred_open_timer() calls
827 * process_smb() to redispatch the request
828 * including the required impersonation.
830 * So we can just use the raw tevent_context.
832 te = tevent_add_timer(xconn->client->raw_ev_ctx,
833 pml,
834 timeval_zero(),
835 smbd_deferred_open_timer,
836 pml);
837 if (!te) {
838 DEBUG(10,("schedule_deferred_open_message_smb: "
839 "event_add_timed() failed, "
840 "skipping mid %llu\n",
841 (unsigned long long)msg_mid ));
844 TALLOC_FREE(pml->te);
845 pml->te = te;
846 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
847 return true;
851 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
852 "find message mid %llu\n",
853 (unsigned long long)mid ));
855 return false;
858 /****************************************************************************
859 Return true if this mid is on the deferred queue and was not yet processed.
860 ****************************************************************************/
862 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
864 struct smbd_server_connection *sconn = xconn->client->sconn;
865 struct pending_message_list *pml;
867 if (sconn->using_smb2) {
868 return open_was_deferred_smb2(xconn, mid);
871 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
872 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
873 return True;
876 return False;
879 /****************************************************************************
880 Return the message queued by this mid.
881 ****************************************************************************/
883 static struct pending_message_list *get_deferred_open_message_smb(
884 struct smbd_server_connection *sconn, uint64_t mid)
886 struct pending_message_list *pml;
888 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
889 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
890 return pml;
893 return NULL;
896 /****************************************************************************
897 Get the state data queued by this mid.
898 ****************************************************************************/
900 bool get_deferred_open_message_state(struct smb_request *smbreq,
901 struct timeval *p_request_time,
902 struct deferred_open_record **open_rec)
904 struct pending_message_list *pml;
906 if (smbreq->sconn->using_smb2) {
907 return get_deferred_open_message_state_smb2(smbreq->smb2req,
908 p_request_time,
909 open_rec);
912 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
913 if (!pml) {
914 return false;
916 if (p_request_time) {
917 *p_request_time = pml->request_time;
919 if (open_rec != NULL) {
920 *open_rec = pml->open_rec;
922 return true;
925 /****************************************************************************
926 Function to push a deferred open smb message onto a linked list of local smb
927 messages ready for processing.
928 ****************************************************************************/
930 bool push_deferred_open_message_smb(struct smb_request *req,
931 struct timeval request_time,
932 struct timeval timeout,
933 struct file_id id,
934 struct deferred_open_record *open_rec)
936 struct timeval end_time;
938 if (req->smb2req) {
939 return push_deferred_open_message_smb2(req->smb2req,
940 request_time,
941 timeout,
943 open_rec);
946 if (req->unread_bytes) {
947 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
948 "unread_bytes = %u\n",
949 (unsigned int)req->unread_bytes ));
950 smb_panic("push_deferred_open_message_smb: "
951 "logic error unread_bytes != 0" );
954 end_time = timeval_sum(&request_time, &timeout);
956 DEBUG(10,("push_deferred_open_message_smb: pushing message "
957 "len %u mid %llu timeout time [%u.%06u]\n",
958 (unsigned int) smb_len(req->inbuf)+4,
959 (unsigned long long)req->mid,
960 (unsigned int)end_time.tv_sec,
961 (unsigned int)end_time.tv_usec));
963 return push_queued_message(req, request_time, end_time, open_rec);
966 static void smbd_sig_term_handler(struct tevent_context *ev,
967 struct tevent_signal *se,
968 int signum,
969 int count,
970 void *siginfo,
971 void *private_data)
973 exit_server_cleanly("termination signal");
976 static void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
978 struct tevent_signal *se;
980 se = tevent_add_signal(sconn->ev_ctx,
981 sconn,
982 SIGTERM, 0,
983 smbd_sig_term_handler,
984 sconn);
985 if (!se) {
986 exit_server("failed to setup SIGTERM handler");
990 static void smbd_sig_hup_handler(struct tevent_context *ev,
991 struct tevent_signal *se,
992 int signum,
993 int count,
994 void *siginfo,
995 void *private_data)
997 struct smbd_server_connection *sconn =
998 talloc_get_type_abort(private_data,
999 struct smbd_server_connection);
1001 change_to_root_user();
1002 DEBUG(1,("Reloading services after SIGHUP\n"));
1003 reload_services(sconn, conn_snum_used, false);
1006 static void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1008 struct tevent_signal *se;
1010 se = tevent_add_signal(sconn->ev_ctx,
1011 sconn,
1012 SIGHUP, 0,
1013 smbd_sig_hup_handler,
1014 sconn);
1015 if (!se) {
1016 exit_server("failed to setup SIGHUP handler");
1020 static void smbd_conf_updated(struct messaging_context *msg,
1021 void *private_data,
1022 uint32_t msg_type,
1023 struct server_id server_id,
1024 DATA_BLOB *data)
1026 struct smbd_server_connection *sconn =
1027 talloc_get_type_abort(private_data,
1028 struct smbd_server_connection);
1030 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1031 "updated. Reloading.\n"));
1032 change_to_root_user();
1033 reload_services(sconn, conn_snum_used, false);
1037 * Only allow 5 outstanding trans requests. We're allocating memory, so
1038 * prevent a DoS.
1041 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1043 int count = 0;
1044 for (; list != NULL; list = list->next) {
1046 if (list->mid == mid) {
1047 return NT_STATUS_INVALID_PARAMETER;
1050 count += 1;
1052 if (count > 5) {
1053 return NT_STATUS_INSUFFICIENT_RESOURCES;
1056 return NT_STATUS_OK;
1060 These flags determine some of the permissions required to do an operation
1062 Note that I don't set NEED_WRITE on some write operations because they
1063 are used by some brain-dead clients when printing, and I don't want to
1064 force write permissions on print services.
1066 #define AS_USER (1<<0)
1067 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1068 #define TIME_INIT (1<<2)
1069 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1070 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1071 #define DO_CHDIR (1<<6)
1074 define a list of possible SMB messages and their corresponding
1075 functions. Any message that has a NULL function is unimplemented -
1076 please feel free to contribute implementations!
1078 static const struct smb_message_struct {
1079 const char *name;
1080 void (*fn)(struct smb_request *req);
1081 int flags;
1082 } smb_messages[256] = {
1084 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1085 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1086 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1087 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1088 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1089 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1090 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1091 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1092 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1093 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1094 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1095 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1096 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1097 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1098 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1099 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1100 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1101 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1102 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1103 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1104 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1105 /* 0x15 */ { NULL, NULL, 0 },
1106 /* 0x16 */ { NULL, NULL, 0 },
1107 /* 0x17 */ { NULL, NULL, 0 },
1108 /* 0x18 */ { NULL, NULL, 0 },
1109 /* 0x19 */ { NULL, NULL, 0 },
1110 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1111 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1112 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1113 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1114 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1115 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1116 /* 0x20 */ { "SMBwritec", NULL,0},
1117 /* 0x21 */ { NULL, NULL, 0 },
1118 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1119 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1120 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1121 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1122 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1123 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1124 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1125 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1126 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1127 /* 0x2b */ { "SMBecho",reply_echo,0},
1128 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1129 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1130 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1131 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1132 /* 0x30 */ { NULL, NULL, 0 },
1133 /* 0x31 */ { NULL, NULL, 0 },
1134 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1135 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1136 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1137 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1138 /* 0x36 */ { NULL, NULL, 0 },
1139 /* 0x37 */ { NULL, NULL, 0 },
1140 /* 0x38 */ { NULL, NULL, 0 },
1141 /* 0x39 */ { NULL, NULL, 0 },
1142 /* 0x3a */ { NULL, NULL, 0 },
1143 /* 0x3b */ { NULL, NULL, 0 },
1144 /* 0x3c */ { NULL, NULL, 0 },
1145 /* 0x3d */ { NULL, NULL, 0 },
1146 /* 0x3e */ { NULL, NULL, 0 },
1147 /* 0x3f */ { NULL, NULL, 0 },
1148 /* 0x40 */ { NULL, NULL, 0 },
1149 /* 0x41 */ { NULL, NULL, 0 },
1150 /* 0x42 */ { NULL, NULL, 0 },
1151 /* 0x43 */ { NULL, NULL, 0 },
1152 /* 0x44 */ { NULL, NULL, 0 },
1153 /* 0x45 */ { NULL, NULL, 0 },
1154 /* 0x46 */ { NULL, NULL, 0 },
1155 /* 0x47 */ { NULL, NULL, 0 },
1156 /* 0x48 */ { NULL, NULL, 0 },
1157 /* 0x49 */ { NULL, NULL, 0 },
1158 /* 0x4a */ { NULL, NULL, 0 },
1159 /* 0x4b */ { NULL, NULL, 0 },
1160 /* 0x4c */ { NULL, NULL, 0 },
1161 /* 0x4d */ { NULL, NULL, 0 },
1162 /* 0x4e */ { NULL, NULL, 0 },
1163 /* 0x4f */ { NULL, NULL, 0 },
1164 /* 0x50 */ { NULL, NULL, 0 },
1165 /* 0x51 */ { NULL, NULL, 0 },
1166 /* 0x52 */ { NULL, NULL, 0 },
1167 /* 0x53 */ { NULL, NULL, 0 },
1168 /* 0x54 */ { NULL, NULL, 0 },
1169 /* 0x55 */ { NULL, NULL, 0 },
1170 /* 0x56 */ { NULL, NULL, 0 },
1171 /* 0x57 */ { NULL, NULL, 0 },
1172 /* 0x58 */ { NULL, NULL, 0 },
1173 /* 0x59 */ { NULL, NULL, 0 },
1174 /* 0x5a */ { NULL, NULL, 0 },
1175 /* 0x5b */ { NULL, NULL, 0 },
1176 /* 0x5c */ { NULL, NULL, 0 },
1177 /* 0x5d */ { NULL, NULL, 0 },
1178 /* 0x5e */ { NULL, NULL, 0 },
1179 /* 0x5f */ { NULL, NULL, 0 },
1180 /* 0x60 */ { NULL, NULL, 0 },
1181 /* 0x61 */ { NULL, NULL, 0 },
1182 /* 0x62 */ { NULL, NULL, 0 },
1183 /* 0x63 */ { NULL, NULL, 0 },
1184 /* 0x64 */ { NULL, NULL, 0 },
1185 /* 0x65 */ { NULL, NULL, 0 },
1186 /* 0x66 */ { NULL, NULL, 0 },
1187 /* 0x67 */ { NULL, NULL, 0 },
1188 /* 0x68 */ { NULL, NULL, 0 },
1189 /* 0x69 */ { NULL, NULL, 0 },
1190 /* 0x6a */ { NULL, NULL, 0 },
1191 /* 0x6b */ { NULL, NULL, 0 },
1192 /* 0x6c */ { NULL, NULL, 0 },
1193 /* 0x6d */ { NULL, NULL, 0 },
1194 /* 0x6e */ { NULL, NULL, 0 },
1195 /* 0x6f */ { NULL, NULL, 0 },
1196 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1197 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1198 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1199 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1200 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1201 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1202 /* 0x76 */ { NULL, NULL, 0 },
1203 /* 0x77 */ { NULL, NULL, 0 },
1204 /* 0x78 */ { NULL, NULL, 0 },
1205 /* 0x79 */ { NULL, NULL, 0 },
1206 /* 0x7a */ { NULL, NULL, 0 },
1207 /* 0x7b */ { NULL, NULL, 0 },
1208 /* 0x7c */ { NULL, NULL, 0 },
1209 /* 0x7d */ { NULL, NULL, 0 },
1210 /* 0x7e */ { NULL, NULL, 0 },
1211 /* 0x7f */ { NULL, NULL, 0 },
1212 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1213 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1214 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1215 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1216 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1217 /* 0x85 */ { NULL, NULL, 0 },
1218 /* 0x86 */ { NULL, NULL, 0 },
1219 /* 0x87 */ { NULL, NULL, 0 },
1220 /* 0x88 */ { NULL, NULL, 0 },
1221 /* 0x89 */ { NULL, NULL, 0 },
1222 /* 0x8a */ { NULL, NULL, 0 },
1223 /* 0x8b */ { NULL, NULL, 0 },
1224 /* 0x8c */ { NULL, NULL, 0 },
1225 /* 0x8d */ { NULL, NULL, 0 },
1226 /* 0x8e */ { NULL, NULL, 0 },
1227 /* 0x8f */ { NULL, NULL, 0 },
1228 /* 0x90 */ { NULL, NULL, 0 },
1229 /* 0x91 */ { NULL, NULL, 0 },
1230 /* 0x92 */ { NULL, NULL, 0 },
1231 /* 0x93 */ { NULL, NULL, 0 },
1232 /* 0x94 */ { NULL, NULL, 0 },
1233 /* 0x95 */ { NULL, NULL, 0 },
1234 /* 0x96 */ { NULL, NULL, 0 },
1235 /* 0x97 */ { NULL, NULL, 0 },
1236 /* 0x98 */ { NULL, NULL, 0 },
1237 /* 0x99 */ { NULL, NULL, 0 },
1238 /* 0x9a */ { NULL, NULL, 0 },
1239 /* 0x9b */ { NULL, NULL, 0 },
1240 /* 0x9c */ { NULL, NULL, 0 },
1241 /* 0x9d */ { NULL, NULL, 0 },
1242 /* 0x9e */ { NULL, NULL, 0 },
1243 /* 0x9f */ { NULL, NULL, 0 },
1244 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1245 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1246 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1247 /* 0xa3 */ { NULL, NULL, 0 },
1248 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1249 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1250 /* 0xa6 */ { NULL, NULL, 0 },
1251 /* 0xa7 */ { NULL, NULL, 0 },
1252 /* 0xa8 */ { NULL, NULL, 0 },
1253 /* 0xa9 */ { NULL, NULL, 0 },
1254 /* 0xaa */ { NULL, NULL, 0 },
1255 /* 0xab */ { NULL, NULL, 0 },
1256 /* 0xac */ { NULL, NULL, 0 },
1257 /* 0xad */ { NULL, NULL, 0 },
1258 /* 0xae */ { NULL, NULL, 0 },
1259 /* 0xaf */ { NULL, NULL, 0 },
1260 /* 0xb0 */ { NULL, NULL, 0 },
1261 /* 0xb1 */ { NULL, NULL, 0 },
1262 /* 0xb2 */ { NULL, NULL, 0 },
1263 /* 0xb3 */ { NULL, NULL, 0 },
1264 /* 0xb4 */ { NULL, NULL, 0 },
1265 /* 0xb5 */ { NULL, NULL, 0 },
1266 /* 0xb6 */ { NULL, NULL, 0 },
1267 /* 0xb7 */ { NULL, NULL, 0 },
1268 /* 0xb8 */ { NULL, NULL, 0 },
1269 /* 0xb9 */ { NULL, NULL, 0 },
1270 /* 0xba */ { NULL, NULL, 0 },
1271 /* 0xbb */ { NULL, NULL, 0 },
1272 /* 0xbc */ { NULL, NULL, 0 },
1273 /* 0xbd */ { NULL, NULL, 0 },
1274 /* 0xbe */ { NULL, NULL, 0 },
1275 /* 0xbf */ { NULL, NULL, 0 },
1276 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1277 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1278 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1279 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1280 /* 0xc4 */ { NULL, NULL, 0 },
1281 /* 0xc5 */ { NULL, NULL, 0 },
1282 /* 0xc6 */ { NULL, NULL, 0 },
1283 /* 0xc7 */ { NULL, NULL, 0 },
1284 /* 0xc8 */ { NULL, NULL, 0 },
1285 /* 0xc9 */ { NULL, NULL, 0 },
1286 /* 0xca */ { NULL, NULL, 0 },
1287 /* 0xcb */ { NULL, NULL, 0 },
1288 /* 0xcc */ { NULL, NULL, 0 },
1289 /* 0xcd */ { NULL, NULL, 0 },
1290 /* 0xce */ { NULL, NULL, 0 },
1291 /* 0xcf */ { NULL, NULL, 0 },
1292 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1293 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1294 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1295 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1296 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1297 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1298 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1299 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1300 /* 0xd8 */ { NULL, NULL, 0 },
1301 /* 0xd9 */ { NULL, NULL, 0 },
1302 /* 0xda */ { NULL, NULL, 0 },
1303 /* 0xdb */ { NULL, NULL, 0 },
1304 /* 0xdc */ { NULL, NULL, 0 },
1305 /* 0xdd */ { NULL, NULL, 0 },
1306 /* 0xde */ { NULL, NULL, 0 },
1307 /* 0xdf */ { NULL, NULL, 0 },
1308 /* 0xe0 */ { NULL, NULL, 0 },
1309 /* 0xe1 */ { NULL, NULL, 0 },
1310 /* 0xe2 */ { NULL, NULL, 0 },
1311 /* 0xe3 */ { NULL, NULL, 0 },
1312 /* 0xe4 */ { NULL, NULL, 0 },
1313 /* 0xe5 */ { NULL, NULL, 0 },
1314 /* 0xe6 */ { NULL, NULL, 0 },
1315 /* 0xe7 */ { NULL, NULL, 0 },
1316 /* 0xe8 */ { NULL, NULL, 0 },
1317 /* 0xe9 */ { NULL, NULL, 0 },
1318 /* 0xea */ { NULL, NULL, 0 },
1319 /* 0xeb */ { NULL, NULL, 0 },
1320 /* 0xec */ { NULL, NULL, 0 },
1321 /* 0xed */ { NULL, NULL, 0 },
1322 /* 0xee */ { NULL, NULL, 0 },
1323 /* 0xef */ { NULL, NULL, 0 },
1324 /* 0xf0 */ { NULL, NULL, 0 },
1325 /* 0xf1 */ { NULL, NULL, 0 },
1326 /* 0xf2 */ { NULL, NULL, 0 },
1327 /* 0xf3 */ { NULL, NULL, 0 },
1328 /* 0xf4 */ { NULL, NULL, 0 },
1329 /* 0xf5 */ { NULL, NULL, 0 },
1330 /* 0xf6 */ { NULL, NULL, 0 },
1331 /* 0xf7 */ { NULL, NULL, 0 },
1332 /* 0xf8 */ { NULL, NULL, 0 },
1333 /* 0xf9 */ { NULL, NULL, 0 },
1334 /* 0xfa */ { NULL, NULL, 0 },
1335 /* 0xfb */ { NULL, NULL, 0 },
1336 /* 0xfc */ { NULL, NULL, 0 },
1337 /* 0xfd */ { NULL, NULL, 0 },
1338 /* 0xfe */ { NULL, NULL, 0 },
1339 /* 0xff */ { NULL, NULL, 0 }
1343 /*******************************************************************
1344 allocate and initialize a reply packet
1345 ********************************************************************/
1347 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1348 const uint8_t *inbuf, char **outbuf,
1349 uint8_t num_words, uint32_t num_bytes)
1351 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1354 * Protect against integer wrap.
1355 * The SMB layer reply can be up to 0xFFFFFF bytes.
1357 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1358 char *msg;
1359 if (asprintf(&msg, "num_bytes too large: %u",
1360 (unsigned)num_bytes) == -1) {
1361 msg = discard_const_p(char, "num_bytes too large");
1363 smb_panic(msg);
1367 * Here we include the NBT header for now.
1369 *outbuf = talloc_array(mem_ctx, char,
1370 NBT_HDR_SIZE + smb_len);
1371 if (*outbuf == NULL) {
1372 return false;
1375 construct_reply_common(req->cmd, inbuf, *outbuf);
1376 srv_set_message(*outbuf, num_words, num_bytes, false);
1378 * Zero out the word area, the caller has to take care of the bcc area
1379 * himself
1381 if (num_words != 0) {
1382 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1385 return true;
1388 void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1390 char *outbuf;
1391 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1392 num_bytes)) {
1393 smb_panic("could not allocate output buffer\n");
1395 req->outbuf = (uint8_t *)outbuf;
1399 /*******************************************************************
1400 Dump a packet to a file.
1401 ********************************************************************/
1403 static void smb_dump(const char *name, int type, const char *data)
1405 size_t len;
1406 int fd, i;
1407 char *fname = NULL;
1408 if (DEBUGLEVEL < 50) {
1409 return;
1412 len = smb_len_tcp(data)+4;
1413 for (i=1;i<100;i++) {
1414 fname = talloc_asprintf(talloc_tos(),
1415 "/tmp/%s.%d.%s",
1416 name,
1418 type ? "req" : "resp");
1419 if (fname == NULL) {
1420 return;
1422 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1423 if (fd != -1 || errno != EEXIST) break;
1424 TALLOC_FREE(fname);
1426 if (fd != -1) {
1427 ssize_t ret = write(fd, data, len);
1428 if (ret != len)
1429 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1430 close(fd);
1431 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1433 TALLOC_FREE(fname);
1436 static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
1437 struct smb_request *req,
1438 uint8_t type,
1439 bool *update_session_globalp,
1440 bool *update_tcon_globalp)
1442 connection_struct *conn = req->conn;
1443 struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
1444 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
1445 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1446 bool update_session = false;
1447 bool update_tcon = false;
1449 if (req->encrypted) {
1450 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
1453 if (srv_is_signing_active(req->xconn)) {
1454 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
1455 } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
1457 * echo can be unsigned. Sesssion setup except final
1458 * session setup response too
1460 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1463 update_session |= smbXsrv_set_crypto_flag(
1464 &session->global->encryption_flags, encrypt_flag);
1465 update_session |= smbXsrv_set_crypto_flag(
1466 &session->global->signing_flags, sign_flag);
1468 if (tcon) {
1469 update_tcon |= smbXsrv_set_crypto_flag(
1470 &tcon->global->encryption_flags, encrypt_flag);
1471 update_tcon |= smbXsrv_set_crypto_flag(
1472 &tcon->global->signing_flags, sign_flag);
1475 if (update_session) {
1476 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1479 *update_session_globalp = update_session;
1480 *update_tcon_globalp = update_tcon;
1481 return;
1484 /****************************************************************************
1485 Prepare everything for calling the actual request function, and potentially
1486 call the request function via the "new" interface.
1488 Return False if the "legacy" function needs to be called, everything is
1489 prepared.
1491 Return True if we're done.
1493 I know this API sucks, but it is the one with the least code change I could
1494 find.
1495 ****************************************************************************/
1497 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1499 int flags;
1500 uint64_t session_tag;
1501 connection_struct *conn = NULL;
1502 struct smbXsrv_connection *xconn = req->xconn;
1503 NTTIME now = timeval_to_nttime(&req->request_time);
1504 struct smbXsrv_session *session = NULL;
1505 NTSTATUS status;
1507 errno = 0;
1509 if (!xconn->smb1.negprot.done) {
1510 switch (type) {
1512 * Without a negprot the request must
1513 * either be a negprot, or one of the
1514 * evil old SMB mailslot messaging types.
1516 case SMBnegprot:
1517 case SMBsendstrt:
1518 case SMBsendend:
1519 case SMBsendtxt:
1520 break;
1521 default:
1522 exit_server_cleanly("The first request "
1523 "should be a negprot");
1527 if (smb_messages[type].fn == NULL) {
1528 DEBUG(0,("Unknown message type %d!\n",type));
1529 smb_dump("Unknown", 1, (const char *)req->inbuf);
1530 reply_unknown_new(req, type);
1531 return NULL;
1534 flags = smb_messages[type].flags;
1536 /* In share mode security we must ignore the vuid. */
1537 session_tag = req->vuid;
1538 conn = req->conn;
1540 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1541 (int)getpid(), (unsigned long)conn));
1543 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1545 /* Ensure this value is replaced in the incoming packet. */
1546 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1549 * Ensure the correct username is in current_user_info. This is a
1550 * really ugly bugfix for problems with multiple session_setup_and_X's
1551 * being done and allowing %U and %G substitutions to work correctly.
1552 * There is a reason this code is done here, don't move it unless you
1553 * know what you're doing... :-).
1554 * JRA.
1558 * lookup an existing session
1560 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1561 * here, the main check is still in change_to_user()
1563 status = smb1srv_session_lookup(xconn,
1564 session_tag,
1565 now,
1566 &session);
1567 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1568 switch (type) {
1569 case SMBsesssetupX:
1570 status = NT_STATUS_OK;
1571 break;
1572 default:
1573 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1574 (unsigned long long)session_tag,
1575 (unsigned long long)req->mid));
1576 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1577 return conn;
1581 if (session != NULL && !(flags & AS_USER)) {
1582 struct user_struct *vuser = session->compat;
1585 * change_to_user() implies set_current_user_info()
1586 * and chdir_connect_service().
1588 * So we only call set_current_user_info if
1589 * we don't have AS_USER specified.
1591 if (vuser) {
1592 set_current_user_info(
1593 vuser->session_info->unix_info->sanitized_username,
1594 vuser->session_info->unix_info->unix_name,
1595 vuser->session_info->info->domain_name);
1599 /* Does this call need to be run as the connected user? */
1600 if (flags & AS_USER) {
1602 /* Does this call need a valid tree connection? */
1603 if (!conn) {
1605 * Amazingly, the error code depends on the command
1606 * (from Samba4).
1608 if (type == SMBntcreateX) {
1609 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1610 } else {
1611 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1613 return NULL;
1616 set_current_case_sensitive(conn, SVAL(req->inbuf,smb_flg));
1619 * change_to_user() implies set_current_user_info()
1620 * and chdir_connect_service().
1622 if (!change_to_user(conn,session_tag)) {
1623 DEBUG(0, ("Error: Could not change to user. Removing "
1624 "deferred open, mid=%llu.\n",
1625 (unsigned long long)req->mid));
1626 reply_force_doserror(req, ERRSRV, ERRbaduid);
1627 return conn;
1630 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1632 /* Does it need write permission? */
1633 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1634 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1635 return conn;
1638 /* IPC services are limited */
1639 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1640 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1641 return conn;
1643 } else if (flags & AS_GUEST) {
1645 * Does this protocol need to be run as guest? (Only archane
1646 * messenger service requests have this...)
1648 if (!change_to_guest()) {
1649 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1650 return conn;
1652 } else {
1653 /* This call needs to be run as root */
1654 change_to_root_user();
1657 /* load service specific parameters */
1658 if (conn) {
1659 if (req->encrypted) {
1660 conn->encrypted_tid = true;
1661 /* encrypted required from now on. */
1662 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1663 } else if (ENCRYPTION_REQUIRED(conn)) {
1664 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1665 DEBUG(1,("service[%s] requires encryption"
1666 "%s ACCESS_DENIED. mid=%llu\n",
1667 lp_servicename(talloc_tos(), SNUM(conn)),
1668 smb_fn_name(type),
1669 (unsigned long long)req->mid));
1670 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1671 return conn;
1675 if (flags & DO_CHDIR) {
1676 bool ok;
1678 ok = chdir_current_service(conn);
1679 if (!ok) {
1680 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1681 return conn;
1684 conn->num_smb_operations++;
1688 * Update encryption and signing state tracking flags that are
1689 * used by smbstatus to display signing and encryption status.
1691 if (session != NULL) {
1692 bool update_session_global = false;
1693 bool update_tcon_global = false;
1695 smb1srv_update_crypto_flags(session, req, type,
1696 &update_session_global,
1697 &update_tcon_global);
1699 if (update_session_global) {
1700 status = smbXsrv_session_update(session);
1701 if (!NT_STATUS_IS_OK(status)) {
1702 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1703 return conn;
1707 if (update_tcon_global) {
1708 status = smbXsrv_tcon_update(req->conn->tcon);
1709 if (!NT_STATUS_IS_OK(status)) {
1710 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1711 return conn;
1716 smb_messages[type].fn(req);
1717 return req->conn;
1720 /****************************************************************************
1721 Construct a reply to the incoming packet.
1722 ****************************************************************************/
1724 static void construct_reply(struct smbXsrv_connection *xconn,
1725 char *inbuf, int size, size_t unread_bytes,
1726 uint32_t seqnum, bool encrypted,
1727 struct smb_perfcount_data *deferred_pcd)
1729 struct smbd_server_connection *sconn = xconn->client->sconn;
1730 struct smb_request *req;
1732 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1733 smb_panic("could not allocate smb_request");
1736 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1737 encrypted, seqnum)) {
1738 exit_server_cleanly("Invalid SMB request");
1741 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1743 /* we popped this message off the queue - keep original perf data */
1744 if (deferred_pcd)
1745 req->pcd = *deferred_pcd;
1746 else {
1747 SMB_PERFCOUNT_START(&req->pcd);
1748 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1749 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1752 req->conn = switch_message(req->cmd, req);
1754 if (req->outbuf == NULL) {
1756 * Request has suspended itself, will come
1757 * back here.
1759 return;
1761 if (CVAL(req->outbuf,0) == 0) {
1762 show_msg((char *)req->outbuf);
1764 smb_request_done(req);
1767 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1768 char *inbuf, int size, uint32_t seqnum,
1769 bool encrypted,
1770 struct smb_perfcount_data *deferred_pcd)
1772 struct smb_request **reqs = NULL;
1773 struct smb_request *req;
1774 unsigned num_reqs;
1775 bool ok;
1777 ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
1778 seqnum, &reqs, &num_reqs);
1779 if (!ok) {
1780 char errbuf[smb_size];
1781 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1782 __LINE__, __FILE__);
1783 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1784 NULL)) {
1785 exit_server_cleanly("construct_reply_chain: "
1786 "srv_send_smb failed.");
1788 return;
1791 req = reqs[0];
1792 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1794 req->conn = switch_message(req->cmd, req);
1796 if (req->outbuf == NULL) {
1798 * Request has suspended itself, will come
1799 * back here.
1801 return;
1803 smb_request_done(req);
1807 * To be called from an async SMB handler that is potentially chained
1808 * when it is finished for shipping.
1811 void smb_request_done(struct smb_request *req)
1813 struct smb_request **reqs = NULL;
1814 struct smb_request *first_req;
1815 size_t i, num_reqs, next_index;
1816 NTSTATUS status;
1818 if (req->chain == NULL) {
1819 first_req = req;
1820 goto shipit;
1823 reqs = req->chain;
1824 num_reqs = talloc_array_length(reqs);
1826 for (i=0; i<num_reqs; i++) {
1827 if (reqs[i] == req) {
1828 break;
1831 if (i == num_reqs) {
1833 * Invalid chain, should not happen
1835 status = NT_STATUS_INTERNAL_ERROR;
1836 goto error;
1838 next_index = i+1;
1840 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1841 struct smb_request *next = reqs[next_index];
1842 struct smbXsrv_tcon *tcon;
1843 NTTIME now = timeval_to_nttime(&req->request_time);
1845 next->vuid = SVAL(req->outbuf, smb_uid);
1846 next->tid = SVAL(req->outbuf, smb_tid);
1847 status = smb1srv_tcon_lookup(req->xconn, next->tid,
1848 now, &tcon);
1850 if (NT_STATUS_IS_OK(status)) {
1851 next->conn = tcon->compat;
1852 } else {
1853 next->conn = NULL;
1855 next->chain_fsp = req->chain_fsp;
1856 next->inbuf = req->inbuf;
1858 req = next;
1859 req->conn = switch_message(req->cmd, req);
1861 if (req->outbuf == NULL) {
1863 * Request has suspended itself, will come
1864 * back here.
1866 return;
1868 next_index += 1;
1871 first_req = reqs[0];
1873 for (i=1; i<next_index; i++) {
1874 bool ok;
1876 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1877 if (!ok) {
1878 status = NT_STATUS_INTERNAL_ERROR;
1879 goto error;
1883 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1884 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1887 * This scary statement intends to set the
1888 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1889 * to the value last_req->outbuf carries
1891 SSVAL(first_req->outbuf, smb_flg2,
1892 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1893 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1896 * Transfer the error codes from the subrequest to the main one
1898 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1899 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1901 _smb_setlen_large(
1902 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1904 shipit:
1905 if (!srv_send_smb(first_req->xconn,
1906 (char *)first_req->outbuf,
1907 true, first_req->seqnum+1,
1908 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1909 &first_req->pcd)) {
1910 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1911 "failed.");
1913 TALLOC_FREE(req); /* non-chained case */
1914 TALLOC_FREE(reqs); /* chained case */
1915 return;
1917 error:
1919 char errbuf[smb_size];
1920 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1921 if (!srv_send_smb(req->xconn, errbuf, true,
1922 req->seqnum+1, req->encrypted,
1923 NULL)) {
1924 exit_server_cleanly("construct_reply_chain: "
1925 "srv_send_smb failed.");
1928 TALLOC_FREE(req); /* non-chained case */
1929 TALLOC_FREE(reqs); /* chained case */
1932 /****************************************************************************
1933 Process an smb from the client
1934 ****************************************************************************/
1935 static void process_smb(struct smbXsrv_connection *xconn,
1936 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1937 uint32_t seqnum, bool encrypted,
1938 struct smb_perfcount_data *deferred_pcd)
1940 struct smbd_server_connection *sconn = xconn->client->sconn;
1941 int msg_type = CVAL(inbuf,0);
1943 DO_PROFILE_INC(request);
1945 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1946 smb_len(inbuf) ) );
1947 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1948 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1950 if (msg_type != NBSSmessage) {
1952 * NetBIOS session request, keepalive, etc.
1954 reply_special(xconn, (char *)inbuf, nread);
1955 goto done;
1958 if (sconn->using_smb2) {
1959 /* At this point we're not really using smb2,
1960 * we make the decision here.. */
1961 if (smbd_is_smb2_header(inbuf, nread)) {
1962 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1963 size_t pdulen = nread - NBT_HDR_SIZE;
1964 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1965 return;
1967 if (nread >= smb_size && valid_smb_header(inbuf)
1968 && CVAL(inbuf, smb_com) != 0x72) {
1969 /* This is a non-negprot SMB1 packet.
1970 Disable SMB2 from now on. */
1971 sconn->using_smb2 = false;
1975 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1976 * so subtract 4 from it. */
1977 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1978 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1979 smb_len(inbuf)));
1981 /* special magic for immediate exit */
1982 if ((nread == 9) &&
1983 (IVAL(inbuf, 4) == 0x74697865) &&
1984 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1985 uint8_t exitcode = CVAL(inbuf, 8);
1986 DEBUG(1, ("Exiting immediately with code %d\n",
1987 (int)exitcode));
1988 exit(exitcode);
1991 exit_server_cleanly("Non-SMB packet");
1994 show_msg((char *)inbuf);
1996 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1997 construct_reply_chain(xconn, (char *)inbuf, nread,
1998 seqnum, encrypted, deferred_pcd);
1999 } else {
2000 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
2001 seqnum, encrypted, deferred_pcd);
2004 sconn->trans_num++;
2006 done:
2007 sconn->num_requests++;
2009 /* The timeout_processing function isn't run nearly
2010 often enough to implement 'max log size' without
2011 overrunning the size of the file by many megabytes.
2012 This is especially true if we are running at debug
2013 level 10. Checking every 50 SMBs is a nice
2014 tradeoff of performance vs log file size overrun. */
2016 if ((sconn->num_requests % 50) == 0 &&
2017 need_to_check_log_size()) {
2018 change_to_root_user();
2019 check_log_size();
2023 /****************************************************************************
2024 Return a string containing the function name of a SMB command.
2025 ****************************************************************************/
2027 const char *smb_fn_name(int type)
2029 const char *unknown_name = "SMBunknown";
2031 if (smb_messages[type].name == NULL)
2032 return(unknown_name);
2034 return(smb_messages[type].name);
2037 /****************************************************************************
2038 Helper functions for contruct_reply.
2039 ****************************************************************************/
2041 void add_to_common_flags2(uint32_t v)
2043 common_flags2 |= v;
2046 void remove_from_common_flags2(uint32_t v)
2048 common_flags2 &= ~v;
2051 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
2052 char *outbuf)
2054 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
2055 uint16_t out_flags2 = common_flags2;
2057 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
2058 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
2059 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
2061 srv_set_message(outbuf,0,0,false);
2063 SCVAL(outbuf, smb_com, cmd);
2064 SIVAL(outbuf,smb_rcls,0);
2065 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
2066 SSVAL(outbuf,smb_flg2, out_flags2);
2067 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
2068 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2070 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2071 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2072 SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
2073 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2074 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2077 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2079 construct_reply_common(req->cmd, req->inbuf, outbuf);
2083 * @brief Find the smb_cmd offset of the last command pushed
2084 * @param[in] buf The buffer we're building up
2085 * @retval Where can we put our next andx cmd?
2087 * While chaining requests, the "next" request we're looking at needs to put
2088 * its SMB_Command before the data the previous request already built up added
2089 * to the chain. Find the offset to the place where we have to put our cmd.
2092 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2094 uint8_t cmd;
2095 size_t ofs;
2097 cmd = CVAL(buf, smb_com);
2099 if (!is_andx_req(cmd)) {
2100 return false;
2103 ofs = smb_vwv0;
2105 while (CVAL(buf, ofs) != 0xff) {
2107 if (!is_andx_req(CVAL(buf, ofs))) {
2108 return false;
2112 * ofs is from start of smb header, so add the 4 length
2113 * bytes. The next cmd is right after the wct field.
2115 ofs = SVAL(buf, ofs+2) + 4 + 1;
2117 if (ofs+4 >= talloc_get_size(buf)) {
2118 return false;
2122 *pofs = ofs;
2123 return true;
2127 * @brief Do the smb chaining at a buffer level
2128 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2129 * @param[in] andx_buf Buffer to be appended
2132 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2134 uint8_t smb_command = CVAL(andx_buf, smb_com);
2135 uint8_t wct = CVAL(andx_buf, smb_wct);
2136 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2137 uint32_t num_bytes = smb_buflen(andx_buf);
2138 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2140 uint8_t *outbuf;
2141 size_t old_size, new_size;
2142 size_t ofs;
2143 size_t chain_padding = 0;
2144 size_t andx_cmd_ofs;
2147 old_size = talloc_get_size(*poutbuf);
2149 if ((old_size % 4) != 0) {
2151 * Align the wct field of subsequent requests to a 4-byte
2152 * boundary
2154 chain_padding = 4 - (old_size % 4);
2158 * After the old request comes the new wct field (1 byte), the vwv's
2159 * and the num_bytes field.
2162 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2163 new_size += num_bytes;
2165 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2166 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2167 (unsigned)new_size));
2168 return false;
2171 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2172 if (outbuf == NULL) {
2173 DEBUG(0, ("talloc failed\n"));
2174 return false;
2176 *poutbuf = outbuf;
2178 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2179 DEBUG(1, ("invalid command chain\n"));
2180 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2181 return false;
2184 if (chain_padding != 0) {
2185 memset(outbuf + old_size, 0, chain_padding);
2186 old_size += chain_padding;
2189 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2190 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2192 ofs = old_size;
2195 * Push the chained request:
2197 * wct field
2200 SCVAL(outbuf, ofs, wct);
2201 ofs += 1;
2204 * vwv array
2207 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2210 * HACK ALERT
2212 * Read&X has an offset into its data buffer at
2213 * vwv[6]. reply_read_andx has no idea anymore that it's
2214 * running from within a chain, so we have to fix up the
2215 * offset here.
2217 * Although it looks disgusting at this place, I want to keep
2218 * it here. The alternative would be to push knowledge about
2219 * the andx chain down into read&x again.
2222 if (smb_command == SMBreadX) {
2223 uint8_t *bytes_addr;
2225 if (wct < 7) {
2227 * Invalid read&x response
2229 return false;
2232 bytes_addr = outbuf + ofs /* vwv start */
2233 + sizeof(uint16_t) * wct /* vwv array */
2234 + sizeof(uint16_t) /* bcc */
2235 + 1; /* padding byte */
2237 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2238 bytes_addr - outbuf - 4);
2241 ofs += sizeof(uint16_t) * wct;
2244 * bcc (byte count)
2247 SSVAL(outbuf, ofs, num_bytes);
2248 ofs += sizeof(uint16_t);
2251 * The bytes field
2254 memcpy(outbuf + ofs, bytes, num_bytes);
2256 return true;
2259 bool smb1_is_chain(const uint8_t *buf)
2261 uint8_t cmd, wct, andx_cmd;
2263 cmd = CVAL(buf, smb_com);
2264 if (!is_andx_req(cmd)) {
2265 return false;
2267 wct = CVAL(buf, smb_wct);
2268 if (wct < 2) {
2269 return false;
2271 andx_cmd = CVAL(buf, smb_vwv);
2272 return (andx_cmd != 0xFF);
2275 bool smb1_walk_chain(const uint8_t *buf,
2276 bool (*fn)(uint8_t cmd,
2277 uint8_t wct, const uint16_t *vwv,
2278 uint16_t num_bytes, const uint8_t *bytes,
2279 void *private_data),
2280 void *private_data)
2282 size_t smblen = smb_len(buf);
2283 const char *smb_buf = smb_base(buf);
2284 uint8_t cmd, chain_cmd;
2285 uint8_t wct;
2286 const uint16_t *vwv;
2287 uint16_t num_bytes;
2288 const uint8_t *bytes;
2290 cmd = CVAL(buf, smb_com);
2291 wct = CVAL(buf, smb_wct);
2292 vwv = (const uint16_t *)(buf + smb_vwv);
2293 num_bytes = smb_buflen(buf);
2294 bytes = (const uint8_t *)smb_buf_const(buf);
2296 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2297 return false;
2300 if (!is_andx_req(cmd)) {
2301 return true;
2303 if (wct < 2) {
2304 return false;
2307 chain_cmd = CVAL(vwv, 0);
2309 while (chain_cmd != 0xff) {
2310 uint32_t chain_offset; /* uint32_t to avoid overflow */
2311 size_t length_needed;
2312 ptrdiff_t vwv_offset;
2314 chain_offset = SVAL(vwv+1, 0);
2317 * Check if the client tries to fool us. The chain
2318 * offset needs to point beyond the current request in
2319 * the chain, it needs to strictly grow. Otherwise we
2320 * might be tricked into an endless loop always
2321 * processing the same request over and over again. We
2322 * used to assume that vwv and the byte buffer array
2323 * in a chain are always attached, but OS/2 the
2324 * Write&X/Read&X chain puts the Read&X vwv array
2325 * right behind the Write&X vwv chain. The Write&X bcc
2326 * array is put behind the Read&X vwv array. So now we
2327 * check whether the chain offset points strictly
2328 * behind the previous vwv array. req->buf points
2329 * right after the vwv array of the previous
2330 * request. See
2331 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2332 * more information.
2335 vwv_offset = ((const char *)vwv - smb_buf);
2336 if (chain_offset <= vwv_offset) {
2337 return false;
2341 * Next check: Make sure the chain offset does not
2342 * point beyond the overall smb request length.
2345 length_needed = chain_offset+1; /* wct */
2346 if (length_needed > smblen) {
2347 return false;
2351 * Now comes the pointer magic. Goal here is to set up
2352 * vwv and buf correctly again. The chain offset (the
2353 * former vwv[1]) points at the new wct field.
2356 wct = CVAL(smb_buf, chain_offset);
2358 if (is_andx_req(chain_cmd) && (wct < 2)) {
2359 return false;
2363 * Next consistency check: Make the new vwv array fits
2364 * in the overall smb request.
2367 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2368 if (length_needed > smblen) {
2369 return false;
2371 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2374 * Now grab the new byte buffer....
2377 num_bytes = SVAL(vwv+wct, 0);
2380 * .. and check that it fits.
2383 length_needed += num_bytes;
2384 if (length_needed > smblen) {
2385 return false;
2387 bytes = (const uint8_t *)(vwv+wct+1);
2389 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2390 return false;
2393 if (!is_andx_req(chain_cmd)) {
2394 return true;
2396 chain_cmd = CVAL(vwv, 0);
2398 return true;
2401 static bool smb1_chain_length_cb(uint8_t cmd,
2402 uint8_t wct, const uint16_t *vwv,
2403 uint16_t num_bytes, const uint8_t *bytes,
2404 void *private_data)
2406 unsigned *count = (unsigned *)private_data;
2407 *count += 1;
2408 return true;
2411 unsigned smb1_chain_length(const uint8_t *buf)
2413 unsigned count = 0;
2415 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2416 return 0;
2418 return count;
2421 struct smb1_parse_chain_state {
2422 TALLOC_CTX *mem_ctx;
2423 const uint8_t *buf;
2424 struct smbd_server_connection *sconn;
2425 struct smbXsrv_connection *xconn;
2426 bool encrypted;
2427 uint32_t seqnum;
2429 struct smb_request **reqs;
2430 unsigned num_reqs;
2433 static bool smb1_parse_chain_cb(uint8_t cmd,
2434 uint8_t wct, const uint16_t *vwv,
2435 uint16_t num_bytes, const uint8_t *bytes,
2436 void *private_data)
2438 struct smb1_parse_chain_state *state =
2439 (struct smb1_parse_chain_state *)private_data;
2440 struct smb_request **reqs;
2441 struct smb_request *req;
2442 bool ok;
2444 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2445 struct smb_request *, state->num_reqs+1);
2446 if (reqs == NULL) {
2447 return false;
2449 state->reqs = reqs;
2451 req = talloc(reqs, struct smb_request);
2452 if (req == NULL) {
2453 return false;
2456 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2457 state->encrypted, state->seqnum);
2458 if (!ok) {
2459 return false;
2461 req->cmd = cmd;
2462 req->wct = wct;
2463 req->vwv = vwv;
2464 req->buflen = num_bytes;
2465 req->buf = bytes;
2467 reqs[state->num_reqs] = req;
2468 state->num_reqs += 1;
2469 return true;
2472 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2473 struct smbXsrv_connection *xconn,
2474 bool encrypted, uint32_t seqnum,
2475 struct smb_request ***reqs, unsigned *num_reqs)
2477 struct smbd_server_connection *sconn = NULL;
2478 struct smb1_parse_chain_state state;
2479 unsigned i;
2481 if (xconn != NULL) {
2482 sconn = xconn->client->sconn;
2485 state.mem_ctx = mem_ctx;
2486 state.buf = buf;
2487 state.sconn = sconn;
2488 state.xconn = xconn;
2489 state.encrypted = encrypted;
2490 state.seqnum = seqnum;
2491 state.reqs = NULL;
2492 state.num_reqs = 0;
2494 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2495 TALLOC_FREE(state.reqs);
2496 return false;
2498 for (i=0; i<state.num_reqs; i++) {
2499 state.reqs[i]->chain = state.reqs;
2501 *reqs = state.reqs;
2502 *num_reqs = state.num_reqs;
2503 return true;
2506 /****************************************************************************
2507 Check if services need reloading.
2508 ****************************************************************************/
2510 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2513 if (last_smb_conf_reload_time == 0) {
2514 last_smb_conf_reload_time = t;
2517 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2518 reload_services(sconn, conn_snum_used, true);
2519 last_smb_conf_reload_time = t;
2523 static bool fd_is_readable(int fd)
2525 int ret, revents;
2527 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2529 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2533 static void smbd_server_connection_write_handler(
2534 struct smbXsrv_connection *xconn)
2536 /* TODO: make write nonblocking */
2539 static void smbd_server_connection_read_handler(
2540 struct smbXsrv_connection *xconn, int fd)
2542 uint8_t *inbuf = NULL;
2543 size_t inbuf_len = 0;
2544 size_t unread_bytes = 0;
2545 bool encrypted = false;
2546 TALLOC_CTX *mem_ctx = talloc_tos();
2547 NTSTATUS status;
2548 uint32_t seqnum;
2550 bool async_echo = lp_async_smb_echo_handler();
2551 bool from_client = false;
2553 if (async_echo) {
2554 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2556 * This is the super-ugly hack to prefer the packets
2557 * forwarded by the echo handler over the ones by the
2558 * client directly
2560 fd = xconn->smb1.echo_handler.trusted_fd;
2564 from_client = (xconn->transport.sock == fd);
2566 if (async_echo && from_client) {
2567 smbd_lock_socket(xconn);
2569 if (!fd_is_readable(fd)) {
2570 DEBUG(10,("the echo listener was faster\n"));
2571 smbd_unlock_socket(xconn);
2572 return;
2576 /* TODO: make this completely nonblocking */
2577 status = receive_smb_talloc(mem_ctx, xconn, fd,
2578 (char **)(void *)&inbuf,
2579 0, /* timeout */
2580 &unread_bytes,
2581 &encrypted,
2582 &inbuf_len, &seqnum,
2583 !from_client /* trusted channel */);
2585 if (async_echo && from_client) {
2586 smbd_unlock_socket(xconn);
2589 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2590 goto process;
2592 if (NT_STATUS_IS_ERR(status)) {
2593 exit_server_cleanly("failed to receive smb request");
2595 if (!NT_STATUS_IS_OK(status)) {
2596 return;
2599 process:
2600 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2601 seqnum, encrypted, NULL);
2604 static void smbd_server_connection_handler(struct tevent_context *ev,
2605 struct tevent_fd *fde,
2606 uint16_t flags,
2607 void *private_data)
2609 struct smbXsrv_connection *xconn =
2610 talloc_get_type_abort(private_data,
2611 struct smbXsrv_connection);
2613 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2615 * we're not supposed to do any io
2617 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2618 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2619 return;
2622 if (flags & TEVENT_FD_WRITE) {
2623 smbd_server_connection_write_handler(xconn);
2624 return;
2626 if (flags & TEVENT_FD_READ) {
2627 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2628 return;
2632 static void smbd_server_echo_handler(struct tevent_context *ev,
2633 struct tevent_fd *fde,
2634 uint16_t flags,
2635 void *private_data)
2637 struct smbXsrv_connection *xconn =
2638 talloc_get_type_abort(private_data,
2639 struct smbXsrv_connection);
2641 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2643 * we're not supposed to do any io
2645 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2646 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2647 return;
2650 if (flags & TEVENT_FD_WRITE) {
2651 smbd_server_connection_write_handler(xconn);
2652 return;
2654 if (flags & TEVENT_FD_READ) {
2655 smbd_server_connection_read_handler(
2656 xconn, xconn->smb1.echo_handler.trusted_fd);
2657 return;
2661 struct smbd_release_ip_state {
2662 struct smbXsrv_connection *xconn;
2663 struct tevent_immediate *im;
2664 char addr[INET6_ADDRSTRLEN];
2667 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2668 struct tevent_immediate *im,
2669 void *private_data)
2671 struct smbd_release_ip_state *state =
2672 talloc_get_type_abort(private_data,
2673 struct smbd_release_ip_state);
2674 struct smbXsrv_connection *xconn = state->xconn;
2676 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2678 * smbd_server_connection_terminate() already triggered ?
2680 return;
2683 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2686 /****************************************************************************
2687 received when we should release a specific IP
2688 ****************************************************************************/
2689 static int release_ip(struct tevent_context *ev,
2690 uint32_t src_vnn, uint32_t dst_vnn,
2691 uint64_t dst_srvid,
2692 const uint8_t *msg, size_t msglen,
2693 void *private_data)
2695 struct smbd_release_ip_state *state =
2696 talloc_get_type_abort(private_data,
2697 struct smbd_release_ip_state);
2698 struct smbXsrv_connection *xconn = state->xconn;
2699 const char *ip;
2700 const char *addr = state->addr;
2701 const char *p = addr;
2703 if (msglen == 0) {
2704 return 0;
2706 if (msg[msglen-1] != '\0') {
2707 return 0;
2710 ip = (const char *)msg;
2712 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2713 /* avoid recursion */
2714 return 0;
2717 if (strncmp("::ffff:", addr, 7) == 0) {
2718 p = addr + 7;
2721 DEBUG(10, ("Got release IP message for %s, "
2722 "our address is %s\n", ip, p));
2724 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2725 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2726 ip));
2728 * With SMB2 we should do a clean disconnect,
2729 * the previous_session_id in the session setup
2730 * will cleanup the old session, tcons and opens.
2732 * A clean disconnect is needed in order to support
2733 * durable handles.
2735 * Note: typically this is never triggered
2736 * as we got a TCP RST (triggered by ctdb event scripts)
2737 * before we get CTDB_SRVID_RELEASE_IP.
2739 * We used to call _exit(1) here, but as this was mostly never
2740 * triggered and has implication on our process model,
2741 * we can just use smbd_server_connection_terminate()
2742 * (also for SMB1).
2744 * We don't call smbd_server_connection_terminate() directly
2745 * as we might be called from within ctdbd_migrate(),
2746 * we need to defer our action to the next event loop
2748 tevent_schedule_immediate(state->im,
2749 xconn->client->raw_ev_ctx,
2750 smbd_release_ip_immediate,
2751 state);
2754 * Make sure we don't get any io on the connection.
2756 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2757 return EADDRNOTAVAIL;
2760 return 0;
2763 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2764 struct sockaddr_storage *srv,
2765 struct sockaddr_storage *clnt)
2767 struct smbd_release_ip_state *state;
2768 struct ctdbd_connection *cconn;
2769 int ret;
2771 cconn = messaging_ctdb_connection();
2772 if (cconn == NULL) {
2773 return NT_STATUS_NO_MEMORY;
2776 state = talloc_zero(xconn, struct smbd_release_ip_state);
2777 if (state == NULL) {
2778 return NT_STATUS_NO_MEMORY;
2780 state->xconn = xconn;
2781 state->im = tevent_create_immediate(state);
2782 if (state->im == NULL) {
2783 return NT_STATUS_NO_MEMORY;
2785 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2786 return NT_STATUS_NO_MEMORY;
2789 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2790 if (ret != 0) {
2791 return map_nt_error_from_unix(ret);
2793 return NT_STATUS_OK;
2796 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2797 void *private_data, uint32_t msg_type,
2798 struct server_id server_id, DATA_BLOB *data)
2800 struct smbd_server_connection *sconn = talloc_get_type_abort(
2801 private_data, struct smbd_server_connection);
2802 const char *ip = (char *) data->data;
2803 char *client_ip;
2805 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2807 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2808 talloc_tos());
2809 if (client_ip == NULL) {
2810 return;
2813 if (strequal(ip, client_ip)) {
2814 DBG_WARNING("Got kill client message for %s - "
2815 "exiting immediately\n", ip);
2816 exit_server_cleanly("Forced disconnect for client");
2819 TALLOC_FREE(client_ip);
2823 * Send keepalive packets to our client
2825 static bool keepalive_fn(const struct timeval *now, void *private_data)
2827 struct smbd_server_connection *sconn = talloc_get_type_abort(
2828 private_data, struct smbd_server_connection);
2829 struct smbXsrv_connection *xconn = NULL;
2830 bool ret;
2832 if (sconn->using_smb2) {
2833 /* Don't do keepalives on an SMB2 connection. */
2834 return false;
2838 * With SMB1 we only have 1 connection
2840 xconn = sconn->client->connections;
2841 smbd_lock_socket(xconn);
2842 ret = send_keepalive(xconn->transport.sock);
2843 smbd_unlock_socket(xconn);
2845 if (!ret) {
2846 int saved_errno = errno;
2848 * Try and give an error message saying what
2849 * client failed.
2851 DEBUG(0, ("send_keepalive failed for client %s. "
2852 "Error %s - exiting\n",
2853 smbXsrv_connection_dbg(xconn),
2854 strerror(saved_errno)));
2855 errno = saved_errno;
2856 return False;
2858 return True;
2862 * Do the recurring check if we're idle
2864 static bool deadtime_fn(const struct timeval *now, void *private_data)
2866 struct smbd_server_connection *sconn =
2867 (struct smbd_server_connection *)private_data;
2869 if ((conn_num_open(sconn) == 0)
2870 || (conn_idle_all(sconn, now->tv_sec))) {
2871 DEBUG( 2, ( "Closing idle connection\n" ) );
2872 messaging_send(sconn->msg_ctx,
2873 messaging_server_id(sconn->msg_ctx),
2874 MSG_SHUTDOWN, &data_blob_null);
2875 return False;
2878 return True;
2882 * Do the recurring log file and smb.conf reload checks.
2885 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2887 struct smbd_server_connection *sconn = talloc_get_type_abort(
2888 private_data, struct smbd_server_connection);
2890 DEBUG(5, ("housekeeping\n"));
2892 change_to_root_user();
2894 /* update printer queue caches if necessary */
2895 update_monitored_printq_cache(sconn->msg_ctx);
2897 /* check if we need to reload services */
2898 check_reload(sconn, time_mono(NULL));
2901 * Force a log file check.
2903 force_check_log_size();
2904 check_log_size();
2905 return true;
2909 * Read an smb packet in the echo handler child, giving the parent
2910 * smbd one second to react once the socket becomes readable.
2913 struct smbd_echo_read_state {
2914 struct tevent_context *ev;
2915 struct smbXsrv_connection *xconn;
2917 char *buf;
2918 size_t buflen;
2919 uint32_t seqnum;
2922 static void smbd_echo_read_readable(struct tevent_req *subreq);
2923 static void smbd_echo_read_waited(struct tevent_req *subreq);
2925 static struct tevent_req *smbd_echo_read_send(
2926 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2927 struct smbXsrv_connection *xconn)
2929 struct tevent_req *req, *subreq;
2930 struct smbd_echo_read_state *state;
2932 req = tevent_req_create(mem_ctx, &state,
2933 struct smbd_echo_read_state);
2934 if (req == NULL) {
2935 return NULL;
2937 state->ev = ev;
2938 state->xconn = xconn;
2940 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2941 if (tevent_req_nomem(subreq, req)) {
2942 return tevent_req_post(req, ev);
2944 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2945 return req;
2948 static void smbd_echo_read_readable(struct tevent_req *subreq)
2950 struct tevent_req *req = tevent_req_callback_data(
2951 subreq, struct tevent_req);
2952 struct smbd_echo_read_state *state = tevent_req_data(
2953 req, struct smbd_echo_read_state);
2954 bool ok;
2955 int err;
2957 ok = wait_for_read_recv(subreq, &err);
2958 TALLOC_FREE(subreq);
2959 if (!ok) {
2960 tevent_req_nterror(req, map_nt_error_from_unix(err));
2961 return;
2965 * Give the parent smbd one second to step in
2968 subreq = tevent_wakeup_send(
2969 state, state->ev, timeval_current_ofs(1, 0));
2970 if (tevent_req_nomem(subreq, req)) {
2971 return;
2973 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2976 static void smbd_echo_read_waited(struct tevent_req *subreq)
2978 struct tevent_req *req = tevent_req_callback_data(
2979 subreq, struct tevent_req);
2980 struct smbd_echo_read_state *state = tevent_req_data(
2981 req, struct smbd_echo_read_state);
2982 struct smbXsrv_connection *xconn = state->xconn;
2983 bool ok;
2984 NTSTATUS status;
2985 size_t unread = 0;
2986 bool encrypted;
2988 ok = tevent_wakeup_recv(subreq);
2989 TALLOC_FREE(subreq);
2990 if (!ok) {
2991 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2992 return;
2995 ok = smbd_lock_socket_internal(xconn);
2996 if (!ok) {
2997 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2998 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2999 return;
3002 if (!fd_is_readable(xconn->transport.sock)) {
3003 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3004 (int)getpid()));
3006 ok = smbd_unlock_socket_internal(xconn);
3007 if (!ok) {
3008 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3009 DEBUG(1, ("%s: failed to unlock socket\n",
3010 __location__));
3011 return;
3014 subreq = wait_for_read_send(state, state->ev,
3015 xconn->transport.sock, false);
3016 if (tevent_req_nomem(subreq, req)) {
3017 return;
3019 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
3020 return;
3023 status = receive_smb_talloc(state, xconn,
3024 xconn->transport.sock,
3025 &state->buf,
3026 0 /* timeout */,
3027 &unread,
3028 &encrypted,
3029 &state->buflen,
3030 &state->seqnum,
3031 false /* trusted_channel*/);
3033 if (tevent_req_nterror(req, status)) {
3034 tevent_req_nterror(req, status);
3035 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3036 (int)getpid(), nt_errstr(status)));
3037 return;
3040 ok = smbd_unlock_socket_internal(xconn);
3041 if (!ok) {
3042 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3043 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
3044 return;
3046 tevent_req_done(req);
3049 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3050 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
3052 struct smbd_echo_read_state *state = tevent_req_data(
3053 req, struct smbd_echo_read_state);
3054 NTSTATUS status;
3056 if (tevent_req_is_nterror(req, &status)) {
3057 return status;
3059 *pbuf = talloc_move(mem_ctx, &state->buf);
3060 *pbuflen = state->buflen;
3061 *pseqnum = state->seqnum;
3062 return NT_STATUS_OK;
3065 struct smbd_echo_state {
3066 struct tevent_context *ev;
3067 struct iovec *pending;
3068 struct smbd_server_connection *sconn;
3069 struct smbXsrv_connection *xconn;
3070 int parent_pipe;
3072 struct tevent_fd *parent_fde;
3074 struct tevent_req *write_req;
3077 static void smbd_echo_writer_done(struct tevent_req *req);
3079 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3081 int num_pending;
3083 if (state->write_req != NULL) {
3084 return;
3087 num_pending = talloc_array_length(state->pending);
3088 if (num_pending == 0) {
3089 return;
3092 state->write_req = writev_send(state, state->ev, NULL,
3093 state->parent_pipe, false,
3094 state->pending, num_pending);
3095 if (state->write_req == NULL) {
3096 DEBUG(1, ("writev_send failed\n"));
3097 exit(1);
3100 talloc_steal(state->write_req, state->pending);
3101 state->pending = NULL;
3103 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3104 state);
3107 static void smbd_echo_writer_done(struct tevent_req *req)
3109 struct smbd_echo_state *state = tevent_req_callback_data(
3110 req, struct smbd_echo_state);
3111 ssize_t written;
3112 int err;
3114 written = writev_recv(req, &err);
3115 TALLOC_FREE(req);
3116 state->write_req = NULL;
3117 if (written == -1) {
3118 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3119 exit(1);
3121 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3122 smbd_echo_activate_writer(state);
3125 static bool smbd_echo_reply(struct smbd_echo_state *state,
3126 uint8_t *inbuf, size_t inbuf_len,
3127 uint32_t seqnum)
3129 struct smb_request req;
3130 uint16_t num_replies;
3131 char *outbuf;
3132 bool ok;
3134 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3135 DEBUG(10, ("Got netbios keepalive\n"));
3137 * Just swallow it
3139 return true;
3142 if (inbuf_len < smb_size) {
3143 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3144 return false;
3146 if (!valid_smb_header(inbuf)) {
3147 DEBUG(10, ("Got invalid SMB header\n"));
3148 return false;
3151 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3152 seqnum)) {
3153 return false;
3155 req.inbuf = inbuf;
3157 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3158 smb_messages[req.cmd].name
3159 ? smb_messages[req.cmd].name : "unknown"));
3161 if (req.cmd != SMBecho) {
3162 return false;
3164 if (req.wct < 1) {
3165 return false;
3168 num_replies = SVAL(req.vwv+0, 0);
3169 if (num_replies != 1) {
3170 /* Not a Windows "Hey, you're still there?" request */
3171 return false;
3174 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3175 1, req.buflen)) {
3176 DEBUG(10, ("create_outbuf failed\n"));
3177 return false;
3179 req.outbuf = (uint8_t *)outbuf;
3181 SSVAL(req.outbuf, smb_vwv0, num_replies);
3183 if (req.buflen > 0) {
3184 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3187 ok = srv_send_smb(req.xconn,
3188 (char *)outbuf,
3189 true, seqnum+1,
3190 false, &req.pcd);
3191 TALLOC_FREE(outbuf);
3192 if (!ok) {
3193 exit(1);
3196 return true;
3199 static void smbd_echo_exit(struct tevent_context *ev,
3200 struct tevent_fd *fde, uint16_t flags,
3201 void *private_data)
3203 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3204 exit(0);
3207 static void smbd_echo_got_packet(struct tevent_req *req);
3209 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3210 int parent_pipe)
3212 struct smbd_echo_state *state;
3213 struct tevent_req *read_req;
3215 state = talloc_zero(xconn, struct smbd_echo_state);
3216 if (state == NULL) {
3217 DEBUG(1, ("talloc failed\n"));
3218 return;
3220 state->xconn = xconn;
3221 state->parent_pipe = parent_pipe;
3222 state->ev = samba_tevent_context_init(state);
3223 if (state->ev == NULL) {
3224 DEBUG(1, ("samba_tevent_context_init failed\n"));
3225 TALLOC_FREE(state);
3226 return;
3228 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3229 TEVENT_FD_READ, smbd_echo_exit,
3230 state);
3231 if (state->parent_fde == NULL) {
3232 DEBUG(1, ("tevent_add_fd failed\n"));
3233 TALLOC_FREE(state);
3234 return;
3237 read_req = smbd_echo_read_send(state, state->ev, xconn);
3238 if (read_req == NULL) {
3239 DEBUG(1, ("smbd_echo_read_send failed\n"));
3240 TALLOC_FREE(state);
3241 return;
3243 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3245 while (true) {
3246 if (tevent_loop_once(state->ev) == -1) {
3247 DEBUG(1, ("tevent_loop_once failed: %s\n",
3248 strerror(errno)));
3249 break;
3252 TALLOC_FREE(state);
3255 static void smbd_echo_got_packet(struct tevent_req *req)
3257 struct smbd_echo_state *state = tevent_req_callback_data(
3258 req, struct smbd_echo_state);
3259 NTSTATUS status;
3260 char *buf = NULL;
3261 size_t buflen = 0;
3262 uint32_t seqnum = 0;
3263 bool reply;
3265 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3266 TALLOC_FREE(req);
3267 if (!NT_STATUS_IS_OK(status)) {
3268 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3269 nt_errstr(status)));
3270 exit(1);
3273 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3274 if (!reply) {
3275 size_t num_pending;
3276 struct iovec *tmp;
3277 struct iovec *iov;
3279 num_pending = talloc_array_length(state->pending);
3280 tmp = talloc_realloc(state, state->pending, struct iovec,
3281 num_pending+1);
3282 if (tmp == NULL) {
3283 DEBUG(1, ("talloc_realloc failed\n"));
3284 exit(1);
3286 state->pending = tmp;
3288 if (buflen >= smb_size) {
3290 * place the seqnum in the packet so that the main process
3291 * can reply with signing
3293 SIVAL(buf, smb_ss_field, seqnum);
3294 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3297 iov = &state->pending[num_pending];
3298 iov->iov_base = talloc_move(state->pending, &buf);
3299 iov->iov_len = buflen;
3301 DEBUG(10,("echo_handler[%d]: forward to main\n",
3302 (int)getpid()));
3303 smbd_echo_activate_writer(state);
3306 req = smbd_echo_read_send(state, state->ev, state->xconn);
3307 if (req == NULL) {
3308 DEBUG(1, ("smbd_echo_read_send failed\n"));
3309 exit(1);
3311 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3316 * Handle SMBecho requests in a forked child process
3318 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3320 int listener_pipe[2];
3321 int res;
3322 pid_t child;
3323 bool use_mutex = false;
3325 res = pipe(listener_pipe);
3326 if (res == -1) {
3327 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3328 return false;
3331 #ifdef HAVE_ROBUST_MUTEXES
3332 use_mutex = tdb_runtime_check_for_robust_mutexes();
3334 if (use_mutex) {
3335 pthread_mutexattr_t a;
3337 xconn->smb1.echo_handler.socket_mutex =
3338 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3339 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3340 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3341 strerror(errno)));
3342 goto fail;
3345 res = pthread_mutexattr_init(&a);
3346 if (res != 0) {
3347 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3348 strerror(res)));
3349 goto fail;
3351 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3352 if (res != 0) {
3353 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3354 strerror(res)));
3355 pthread_mutexattr_destroy(&a);
3356 goto fail;
3358 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3359 if (res != 0) {
3360 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3361 strerror(res)));
3362 pthread_mutexattr_destroy(&a);
3363 goto fail;
3365 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3366 if (res != 0) {
3367 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3368 "%s\n", strerror(res)));
3369 pthread_mutexattr_destroy(&a);
3370 goto fail;
3372 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3373 &a);
3374 pthread_mutexattr_destroy(&a);
3375 if (res != 0) {
3376 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3377 strerror(res)));
3378 goto fail;
3381 #endif
3383 if (!use_mutex) {
3384 xconn->smb1.echo_handler.socket_lock_fd =
3385 create_unlink_tmp(lp_lock_directory());
3386 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3387 DEBUG(1, ("Could not create lock fd: %s\n",
3388 strerror(errno)));
3389 goto fail;
3393 child = fork();
3394 if (child == 0) {
3395 NTSTATUS status;
3397 close(listener_pipe[0]);
3398 set_blocking(listener_pipe[1], false);
3400 status = smbd_reinit_after_fork(xconn->client->msg_ctx,
3401 xconn->client->raw_ev_ctx,
3402 true,
3403 "smbd-echo");
3404 if (!NT_STATUS_IS_OK(status)) {
3405 DEBUG(1, ("reinit_after_fork failed: %s\n",
3406 nt_errstr(status)));
3407 exit(1);
3409 initialize_password_db(true, xconn->client->raw_ev_ctx);
3410 smbd_echo_loop(xconn, listener_pipe[1]);
3411 exit(0);
3413 close(listener_pipe[1]);
3414 listener_pipe[1] = -1;
3415 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3417 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3420 * Without smb signing this is the same as the normal smbd
3421 * listener. This needs to change once signing comes in.
3423 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(
3424 xconn->client->raw_ev_ctx,
3425 xconn,
3426 xconn->smb1.echo_handler.trusted_fd,
3427 TEVENT_FD_READ,
3428 smbd_server_echo_handler,
3429 xconn);
3430 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3431 DEBUG(1, ("event_add_fd failed\n"));
3432 goto fail;
3435 return true;
3437 fail:
3438 if (listener_pipe[0] != -1) {
3439 close(listener_pipe[0]);
3441 if (listener_pipe[1] != -1) {
3442 close(listener_pipe[1]);
3444 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3445 close(xconn->smb1.echo_handler.socket_lock_fd);
3447 #ifdef HAVE_ROBUST_MUTEXES
3448 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3449 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3450 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3452 #endif
3453 smbd_echo_init(xconn);
3455 return false;
3458 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3460 while (user) {
3461 if (user->session_info &&
3462 (user->session_info->unix_token->uid == uid)) {
3463 return true;
3465 user = user->next;
3467 return false;
3470 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3472 while (user) {
3473 if (user->session_info != NULL) {
3474 int i;
3475 struct security_unix_token *utok;
3477 utok = user->session_info->unix_token;
3478 if (utok->gid == gid) {
3479 return true;
3481 for(i=0; i<utok->ngroups; i++) {
3482 if (utok->groups[i] == gid) {
3483 return true;
3487 user = user->next;
3489 return false;
3492 static bool sid_in_use(const struct user_struct *user,
3493 const struct dom_sid *psid)
3495 while (user) {
3496 struct security_token *tok;
3498 if (user->session_info == NULL) {
3499 continue;
3501 tok = user->session_info->security_token;
3502 if (tok == NULL) {
3504 * Not sure session_info->security_token can
3505 * ever be NULL. This check might be not
3506 * necessary.
3508 continue;
3510 if (security_token_has_sid(tok, psid)) {
3511 return true;
3513 user = user->next;
3515 return false;
3518 static bool id_in_use(const struct user_struct *user,
3519 const struct id_cache_ref *id)
3521 switch(id->type) {
3522 case UID:
3523 return uid_in_use(user, id->id.uid);
3524 case GID:
3525 return gid_in_use(user, id->id.gid);
3526 case SID:
3527 return sid_in_use(user, &id->id.sid);
3528 default:
3529 break;
3531 return false;
3534 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3535 void *private_data,
3536 uint32_t msg_type,
3537 struct server_id server_id,
3538 DATA_BLOB* data)
3540 const char *msg = (data && data->data)
3541 ? (const char *)data->data : "<NULL>";
3542 struct id_cache_ref id;
3543 struct smbd_server_connection *sconn =
3544 talloc_get_type_abort(private_data,
3545 struct smbd_server_connection);
3547 if (!id_cache_ref_parse(msg, &id)) {
3548 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3549 return;
3552 if (id_in_use(sconn->users, &id)) {
3553 exit_server_cleanly(msg);
3555 id_cache_delete_from_cache(&id);
3558 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3559 enum protocol_types protocol)
3561 NTSTATUS status;
3563 conn->protocol = protocol;
3565 if (conn->client->session_table != NULL) {
3566 return NT_STATUS_OK;
3569 if (protocol >= PROTOCOL_SMB2_02) {
3570 status = smb2srv_session_table_init(conn);
3571 if (!NT_STATUS_IS_OK(status)) {
3572 conn->protocol = PROTOCOL_NONE;
3573 return status;
3576 status = smb2srv_open_table_init(conn);
3577 if (!NT_STATUS_IS_OK(status)) {
3578 conn->protocol = PROTOCOL_NONE;
3579 return status;
3581 } else {
3582 status = smb1srv_session_table_init(conn);
3583 if (!NT_STATUS_IS_OK(status)) {
3584 conn->protocol = PROTOCOL_NONE;
3585 return status;
3588 status = smb1srv_tcon_table_init(conn);
3589 if (!NT_STATUS_IS_OK(status)) {
3590 conn->protocol = PROTOCOL_NONE;
3591 return status;
3594 status = smb1srv_open_table_init(conn);
3595 if (!NT_STATUS_IS_OK(status)) {
3596 conn->protocol = PROTOCOL_NONE;
3597 return status;
3601 set_Protocol(protocol);
3602 return NT_STATUS_OK;
3605 struct smbd_tevent_trace_state {
3606 struct tevent_context *ev;
3607 TALLOC_CTX *frame;
3608 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3611 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3612 void *private_data)
3614 struct smbd_tevent_trace_state *state =
3615 (struct smbd_tevent_trace_state *)private_data;
3617 switch (point) {
3618 case TEVENT_TRACE_BEFORE_WAIT:
3619 if (!smbprofile_dump_pending()) {
3621 * If there's no dump pending
3622 * we don't want to schedule a new 1 sec timer.
3624 * Instead we want to sleep as long as nothing happens.
3626 smbprofile_dump_setup(NULL);
3628 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3629 break;
3630 case TEVENT_TRACE_AFTER_WAIT:
3631 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3632 if (!smbprofile_dump_pending()) {
3634 * We need to flush our state after sleeping
3635 * (hopefully a long time).
3637 smbprofile_dump();
3639 * future profiling events should trigger timers
3640 * on our main event context.
3642 smbprofile_dump_setup(state->ev);
3644 break;
3645 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3646 TALLOC_FREE(state->frame);
3647 state->frame = talloc_stackframe_pool(8192);
3648 break;
3649 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3650 TALLOC_FREE(state->frame);
3651 break;
3654 errno = 0;
3658 * Create a debug string for the connection
3660 * This is allocated to talloc_tos() or a string constant
3661 * in certain corner cases. The returned string should
3662 * hence not be free'd directly but only via the talloc stack.
3664 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3666 const char *ret;
3669 * TODO: this can be improved later
3670 * maybe including the client guid or more
3672 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3673 if (ret == NULL) {
3674 return "<tsocket_address_string() failed>";
3677 return ret;
3680 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3681 struct smbXsrv_connection **_xconn)
3683 TALLOC_CTX *frame = talloc_stackframe();
3684 struct smbXsrv_connection *xconn;
3685 struct sockaddr_storage ss_srv;
3686 void *sp_srv = (void *)&ss_srv;
3687 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3688 struct sockaddr_storage ss_clnt;
3689 void *sp_clnt = (void *)&ss_clnt;
3690 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3691 socklen_t sa_socklen;
3692 struct tsocket_address *local_address = NULL;
3693 struct tsocket_address *remote_address = NULL;
3694 const char *remaddr = NULL;
3695 char *p;
3696 const char *rhost = NULL;
3697 int ret;
3698 int tmp;
3700 *_xconn = NULL;
3702 DO_PROFILE_INC(connect);
3704 xconn = talloc_zero(client, struct smbXsrv_connection);
3705 if (xconn == NULL) {
3706 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3707 TALLOC_FREE(frame);
3708 return NT_STATUS_NO_MEMORY;
3710 talloc_steal(frame, xconn);
3712 xconn->transport.sock = sock_fd;
3713 smbd_echo_init(xconn);
3714 xconn->protocol = PROTOCOL_NONE;
3716 /* Ensure child is set to blocking mode */
3717 set_blocking(sock_fd,True);
3719 set_socket_options(sock_fd, "SO_KEEPALIVE");
3720 set_socket_options(sock_fd, lp_socket_options());
3722 sa_socklen = sizeof(ss_clnt);
3723 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3724 if (ret != 0) {
3725 int saved_errno = errno;
3726 int level = (errno == ENOTCONN)?2:0;
3727 DEBUG(level,("getpeername() failed - %s\n",
3728 strerror(saved_errno)));
3729 TALLOC_FREE(frame);
3730 return map_nt_error_from_unix_common(saved_errno);
3732 ret = tsocket_address_bsd_from_sockaddr(xconn,
3733 sa_clnt, sa_socklen,
3734 &remote_address);
3735 if (ret != 0) {
3736 int saved_errno = errno;
3737 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3738 __location__, strerror(saved_errno)));
3739 TALLOC_FREE(frame);
3740 return map_nt_error_from_unix_common(saved_errno);
3743 sa_socklen = sizeof(ss_srv);
3744 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3745 if (ret != 0) {
3746 int saved_errno = errno;
3747 int level = (errno == ENOTCONN)?2:0;
3748 DEBUG(level,("getsockname() failed - %s\n",
3749 strerror(saved_errno)));
3750 TALLOC_FREE(frame);
3751 return map_nt_error_from_unix_common(saved_errno);
3753 ret = tsocket_address_bsd_from_sockaddr(xconn,
3754 sa_srv, sa_socklen,
3755 &local_address);
3756 if (ret != 0) {
3757 int saved_errno = errno;
3758 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3759 __location__, strerror(saved_errno)));
3760 TALLOC_FREE(frame);
3761 return map_nt_error_from_unix_common(saved_errno);
3764 if (tsocket_address_is_inet(remote_address, "ip")) {
3765 remaddr = tsocket_address_inet_addr_string(remote_address,
3766 talloc_tos());
3767 if (remaddr == NULL) {
3768 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3769 __location__, strerror(errno)));
3770 TALLOC_FREE(frame);
3771 return NT_STATUS_NO_MEMORY;
3773 } else {
3774 remaddr = "0.0.0.0";
3778 * Before the first packet, check the global hosts allow/ hosts deny
3779 * parameters before doing any parsing of packets passed to us by the
3780 * client. This prevents attacks on our parsing code from hosts not in
3781 * the hosts allow list.
3784 ret = get_remote_hostname(remote_address,
3785 &p, talloc_tos());
3786 if (ret < 0) {
3787 int saved_errno = errno;
3788 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3789 __location__, strerror(saved_errno)));
3790 TALLOC_FREE(frame);
3791 return map_nt_error_from_unix_common(saved_errno);
3793 rhost = p;
3794 if (strequal(rhost, "UNKNOWN")) {
3795 rhost = remaddr;
3798 xconn->local_address = local_address;
3799 xconn->remote_address = remote_address;
3800 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3801 if (xconn->remote_hostname == NULL) {
3802 return NT_STATUS_NO_MEMORY;
3805 if (!srv_init_signing(xconn)) {
3806 DEBUG(0, ("Failed to init smb_signing\n"));
3807 TALLOC_FREE(frame);
3808 return NT_STATUS_INTERNAL_ERROR;
3811 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3812 xconn->remote_hostname,
3813 remaddr)) {
3814 DEBUG( 1, ("Connection denied from %s to %s\n",
3815 tsocket_address_string(remote_address, talloc_tos()),
3816 tsocket_address_string(local_address, talloc_tos())));
3819 * We return a valid xconn
3820 * so that the caller can return an error message
3821 * to the client
3823 client->connections = xconn;
3824 xconn->client = client;
3825 talloc_steal(client, xconn);
3827 *_xconn = xconn;
3828 TALLOC_FREE(frame);
3829 return NT_STATUS_NETWORK_ACCESS_DENIED;
3832 DEBUG(10, ("Connection allowed from %s to %s\n",
3833 tsocket_address_string(remote_address, talloc_tos()),
3834 tsocket_address_string(local_address, talloc_tos())));
3836 if (lp_clustering()) {
3838 * We need to tell ctdb about our client's TCP
3839 * connection, so that for failover ctdbd can send
3840 * tickle acks, triggering a reconnection by the
3841 * client.
3843 NTSTATUS status;
3845 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3846 if (!NT_STATUS_IS_OK(status)) {
3847 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3848 nt_errstr(status)));
3852 tmp = lp_max_xmit();
3853 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3854 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3856 xconn->smb1.negprot.max_recv = tmp;
3858 xconn->smb1.sessions.done_sesssetup = false;
3859 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3861 xconn->transport.fde = tevent_add_fd(client->raw_ev_ctx,
3862 xconn,
3863 sock_fd,
3864 TEVENT_FD_READ,
3865 smbd_server_connection_handler,
3866 xconn);
3867 if (!xconn->transport.fde) {
3868 TALLOC_FREE(frame);
3869 return NT_STATUS_NO_MEMORY;
3872 /* for now we only have one connection */
3873 DLIST_ADD_END(client->connections, xconn);
3874 xconn->client = client;
3875 talloc_steal(client, xconn);
3877 *_xconn = xconn;
3878 TALLOC_FREE(frame);
3879 return NT_STATUS_OK;
3882 /****************************************************************************
3883 Process commands from the client
3884 ****************************************************************************/
3886 void smbd_process(struct tevent_context *ev_ctx,
3887 struct messaging_context *msg_ctx,
3888 int sock_fd,
3889 bool interactive)
3891 struct smbd_tevent_trace_state trace_state = {
3892 .ev = ev_ctx,
3893 .frame = talloc_stackframe(),
3895 struct smbXsrv_client *client = NULL;
3896 struct smbd_server_connection *sconn = NULL;
3897 struct smbXsrv_connection *xconn = NULL;
3898 const char *locaddr = NULL;
3899 const char *remaddr = NULL;
3900 int ret;
3901 NTSTATUS status;
3902 struct timeval tv = timeval_current();
3903 NTTIME now = timeval_to_nttime(&tv);
3904 char *chroot_dir = NULL;
3905 int rc;
3907 status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
3908 if (!NT_STATUS_IS_OK(status)) {
3909 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
3910 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3914 * TODO: remove this...:-)
3916 global_smbXsrv_client = client;
3918 sconn = talloc_zero(client, struct smbd_server_connection);
3919 if (sconn == NULL) {
3920 exit_server("failed to create smbd_server_connection");
3923 client->sconn = sconn;
3924 sconn->client = client;
3926 sconn->ev_ctx = ev_ctx;
3927 sconn->msg_ctx = msg_ctx;
3929 ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
3930 &sconn->pool);
3931 if (ret != 0) {
3932 exit_server("pthreadpool_tevent_init() failed.");
3935 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3937 * We're not making the decision here,
3938 * we're just allowing the client
3939 * to decide between SMB1 and SMB2
3940 * with the first negprot
3941 * packet.
3943 sconn->using_smb2 = true;
3946 if (!interactive) {
3947 smbd_setup_sig_term_handler(sconn);
3948 smbd_setup_sig_hup_handler(sconn);
3951 status = smbd_add_connection(client, sock_fd, &xconn);
3952 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3954 * send a negative session response "not listening on calling
3955 * name"
3957 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3958 (void)srv_send_smb(xconn,(char *)buf, false,
3959 0, false, NULL);
3960 exit_server_cleanly("connection denied");
3961 } else if (!NT_STATUS_IS_OK(status)) {
3962 exit_server_cleanly(nt_errstr(status));
3965 sconn->local_address =
3966 tsocket_address_copy(xconn->local_address, sconn);
3967 if (sconn->local_address == NULL) {
3968 exit_server_cleanly("tsocket_address_copy() failed");
3970 sconn->remote_address =
3971 tsocket_address_copy(xconn->remote_address, sconn);
3972 if (sconn->remote_address == NULL) {
3973 exit_server_cleanly("tsocket_address_copy() failed");
3975 sconn->remote_hostname =
3976 talloc_strdup(sconn, xconn->remote_hostname);
3977 if (sconn->remote_hostname == NULL) {
3978 exit_server_cleanly("tsocket_strdup() failed");
3981 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3982 locaddr = tsocket_address_inet_addr_string(
3983 sconn->local_address,
3984 talloc_tos());
3985 if (locaddr == NULL) {
3986 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3987 __location__, strerror(errno)));
3988 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3990 } else {
3991 locaddr = "0.0.0.0";
3994 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
3995 remaddr = tsocket_address_inet_addr_string(
3996 sconn->remote_address,
3997 talloc_tos());
3998 if (remaddr == NULL) {
3999 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4000 __location__, strerror(errno)));
4001 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4003 } else {
4004 remaddr = "0.0.0.0";
4007 /* this is needed so that we get decent entries
4008 in smbstatus for port 445 connects */
4009 set_remote_machine_name(remaddr, false);
4010 reload_services(sconn, conn_snum_used, true);
4011 sub_set_socket_ids(remaddr,
4012 sconn->remote_hostname,
4013 locaddr);
4015 if (lp_preload_modules()) {
4016 smb_load_all_modules_absoute_path(lp_preload_modules());
4019 smb_perfcount_init();
4021 if (!init_account_policy()) {
4022 exit_server("Could not open account policy tdb.\n");
4025 chroot_dir = lp_root_directory(talloc_tos());
4026 if (chroot_dir[0] != '\0') {
4027 rc = chdir(chroot_dir);
4028 if (rc != 0) {
4029 DBG_ERR("Failed to chdir to %s\n", chroot_dir);
4030 exit_server("Failed to chdir()");
4033 rc = chroot(chroot_dir);
4034 if (rc != 0) {
4035 DBG_ERR("Failed to change root to %s\n", chroot_dir);
4036 exit_server("Failed to chroot()");
4038 DBG_WARNING("Changed root to %s\n", chroot_dir);
4040 TALLOC_FREE(chroot_dir);
4043 if (!file_init(sconn)) {
4044 exit_server("file_init() failed");
4047 /* Setup oplocks */
4048 if (!init_oplocks(sconn))
4049 exit_server("Failed to init oplocks");
4051 /* register our message handlers */
4052 messaging_register(sconn->msg_ctx, sconn,
4053 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4054 messaging_register(sconn->msg_ctx, sconn,
4055 MSG_SMB_CLOSE_FILE, msg_close_file);
4056 messaging_register(sconn->msg_ctx, sconn,
4057 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
4059 id_cache_register_msgs(sconn->msg_ctx);
4060 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
4061 messaging_register(sconn->msg_ctx, sconn,
4062 ID_CACHE_KILL, smbd_id_cache_kill);
4064 messaging_deregister(sconn->msg_ctx,
4065 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
4066 messaging_register(sconn->msg_ctx, sconn,
4067 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
4069 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
4070 NULL);
4071 messaging_register(sconn->msg_ctx, sconn,
4072 MSG_SMB_KILL_CLIENT_IP,
4073 msg_kill_client_ip);
4075 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
4078 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4079 * MSGs to all child processes
4081 messaging_deregister(sconn->msg_ctx,
4082 MSG_DEBUG, NULL);
4083 messaging_register(sconn->msg_ctx, NULL,
4084 MSG_DEBUG, debug_message);
4086 if ((lp_keepalive() != 0)
4087 && !(event_add_idle(ev_ctx, NULL,
4088 timeval_set(lp_keepalive(), 0),
4089 "keepalive", keepalive_fn,
4090 sconn))) {
4091 DEBUG(0, ("Could not add keepalive event\n"));
4092 exit(1);
4095 if (!(event_add_idle(ev_ctx, NULL,
4096 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4097 "deadtime", deadtime_fn, sconn))) {
4098 DEBUG(0, ("Could not add deadtime event\n"));
4099 exit(1);
4102 if (!(event_add_idle(ev_ctx, NULL,
4103 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4104 "housekeeping", housekeeping_fn, sconn))) {
4105 DEBUG(0, ("Could not add housekeeping event\n"));
4106 exit(1);
4109 smbprofile_dump_setup(ev_ctx);
4111 if (!init_dptrs(sconn)) {
4112 exit_server("init_dptrs() failed");
4115 TALLOC_FREE(trace_state.frame);
4117 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4118 &trace_state);
4120 ret = tevent_loop_wait(ev_ctx);
4121 if (ret != 0) {
4122 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4123 " exiting\n", ret, strerror(errno)));
4126 TALLOC_FREE(trace_state.frame);
4128 exit_server_cleanly(NULL);
4131 bool req_is_in_chain(const struct smb_request *req)
4133 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4135 * We're right now handling a subsequent request, so we must
4136 * be in a chain
4138 return true;
4141 if (!is_andx_req(req->cmd)) {
4142 return false;
4145 if (req->wct < 2) {
4147 * Okay, an illegal request, but definitely not chained :-)
4149 return false;
4152 return (CVAL(req->vwv+0, 0) != 0xFF);