lib: #include "util_event.h" only where needed
[Samba.git] / source3 / smbd / process.c
blob6a3395ceabf503e842e242f042e2195cf8ba54d1
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 int srv_set_message(char *buf,
278 int num_words,
279 int 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 ));
825 te = tevent_add_timer(pml->sconn->ev_ctx,
826 pml,
827 timeval_zero(),
828 smbd_deferred_open_timer,
829 pml);
830 if (!te) {
831 DEBUG(10,("schedule_deferred_open_message_smb: "
832 "event_add_timed() failed, "
833 "skipping mid %llu\n",
834 (unsigned long long)msg_mid ));
837 TALLOC_FREE(pml->te);
838 pml->te = te;
839 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
840 return true;
844 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
845 "find message mid %llu\n",
846 (unsigned long long)mid ));
848 return false;
851 /****************************************************************************
852 Return true if this mid is on the deferred queue and was not yet processed.
853 ****************************************************************************/
855 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
857 struct smbd_server_connection *sconn = xconn->client->sconn;
858 struct pending_message_list *pml;
860 if (sconn->using_smb2) {
861 return open_was_deferred_smb2(xconn, mid);
864 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
865 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
866 return True;
869 return False;
872 /****************************************************************************
873 Return the message queued by this mid.
874 ****************************************************************************/
876 static struct pending_message_list *get_deferred_open_message_smb(
877 struct smbd_server_connection *sconn, uint64_t mid)
879 struct pending_message_list *pml;
881 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
882 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
883 return pml;
886 return NULL;
889 /****************************************************************************
890 Get the state data queued by this mid.
891 ****************************************************************************/
893 bool get_deferred_open_message_state(struct smb_request *smbreq,
894 struct timeval *p_request_time,
895 struct deferred_open_record **open_rec)
897 struct pending_message_list *pml;
899 if (smbreq->sconn->using_smb2) {
900 return get_deferred_open_message_state_smb2(smbreq->smb2req,
901 p_request_time,
902 open_rec);
905 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
906 if (!pml) {
907 return false;
909 if (p_request_time) {
910 *p_request_time = pml->request_time;
912 if (open_rec != NULL) {
913 *open_rec = pml->open_rec;
915 return true;
918 /****************************************************************************
919 Function to push a deferred open smb message onto a linked list of local smb
920 messages ready for processing.
921 ****************************************************************************/
923 bool push_deferred_open_message_smb(struct smb_request *req,
924 struct timeval request_time,
925 struct timeval timeout,
926 struct file_id id,
927 struct deferred_open_record *open_rec)
929 struct timeval end_time;
931 if (req->smb2req) {
932 return push_deferred_open_message_smb2(req->smb2req,
933 request_time,
934 timeout,
936 open_rec);
939 if (req->unread_bytes) {
940 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
941 "unread_bytes = %u\n",
942 (unsigned int)req->unread_bytes ));
943 smb_panic("push_deferred_open_message_smb: "
944 "logic error unread_bytes != 0" );
947 end_time = timeval_sum(&request_time, &timeout);
949 DEBUG(10,("push_deferred_open_message_smb: pushing message "
950 "len %u mid %llu timeout time [%u.%06u]\n",
951 (unsigned int) smb_len(req->inbuf)+4,
952 (unsigned long long)req->mid,
953 (unsigned int)end_time.tv_sec,
954 (unsigned int)end_time.tv_usec));
956 return push_queued_message(req, request_time, end_time, open_rec);
959 static void smbd_sig_term_handler(struct tevent_context *ev,
960 struct tevent_signal *se,
961 int signum,
962 int count,
963 void *siginfo,
964 void *private_data)
966 exit_server_cleanly("termination signal");
969 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
971 struct tevent_signal *se;
973 se = tevent_add_signal(sconn->ev_ctx,
974 sconn,
975 SIGTERM, 0,
976 smbd_sig_term_handler,
977 sconn);
978 if (!se) {
979 exit_server("failed to setup SIGTERM handler");
983 static void smbd_sig_hup_handler(struct tevent_context *ev,
984 struct tevent_signal *se,
985 int signum,
986 int count,
987 void *siginfo,
988 void *private_data)
990 struct smbd_server_connection *sconn =
991 talloc_get_type_abort(private_data,
992 struct smbd_server_connection);
994 change_to_root_user();
995 DEBUG(1,("Reloading services after SIGHUP\n"));
996 reload_services(sconn, conn_snum_used, false);
999 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1001 struct tevent_signal *se;
1003 se = tevent_add_signal(sconn->ev_ctx,
1004 sconn,
1005 SIGHUP, 0,
1006 smbd_sig_hup_handler,
1007 sconn);
1008 if (!se) {
1009 exit_server("failed to setup SIGHUP handler");
1013 static void smbd_conf_updated(struct messaging_context *msg,
1014 void *private_data,
1015 uint32_t msg_type,
1016 struct server_id server_id,
1017 DATA_BLOB *data)
1019 struct smbd_server_connection *sconn =
1020 talloc_get_type_abort(private_data,
1021 struct smbd_server_connection);
1023 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1024 "updated. Reloading.\n"));
1025 change_to_root_user();
1026 reload_services(sconn, conn_snum_used, false);
1030 * Only allow 5 outstanding trans requests. We're allocating memory, so
1031 * prevent a DoS.
1034 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1036 int count = 0;
1037 for (; list != NULL; list = list->next) {
1039 if (list->mid == mid) {
1040 return NT_STATUS_INVALID_PARAMETER;
1043 count += 1;
1045 if (count > 5) {
1046 return NT_STATUS_INSUFFICIENT_RESOURCES;
1049 return NT_STATUS_OK;
1053 These flags determine some of the permissions required to do an operation
1055 Note that I don't set NEED_WRITE on some write operations because they
1056 are used by some brain-dead clients when printing, and I don't want to
1057 force write permissions on print services.
1059 #define AS_USER (1<<0)
1060 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1061 #define TIME_INIT (1<<2)
1062 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1063 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1064 #define DO_CHDIR (1<<6)
1067 define a list of possible SMB messages and their corresponding
1068 functions. Any message that has a NULL function is unimplemented -
1069 please feel free to contribute implementations!
1071 static const struct smb_message_struct {
1072 const char *name;
1073 void (*fn)(struct smb_request *req);
1074 int flags;
1075 } smb_messages[256] = {
1077 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1078 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1079 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1080 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1081 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1082 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1083 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1084 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1085 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1086 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1087 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1088 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1089 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1090 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1091 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1092 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1093 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1094 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1095 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1096 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1097 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1098 /* 0x15 */ { NULL, NULL, 0 },
1099 /* 0x16 */ { NULL, NULL, 0 },
1100 /* 0x17 */ { NULL, NULL, 0 },
1101 /* 0x18 */ { NULL, NULL, 0 },
1102 /* 0x19 */ { NULL, NULL, 0 },
1103 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1104 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1105 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1106 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1107 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1108 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1109 /* 0x20 */ { "SMBwritec", NULL,0},
1110 /* 0x21 */ { NULL, NULL, 0 },
1111 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1112 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1113 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1114 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1115 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1116 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1117 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1118 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1119 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1120 /* 0x2b */ { "SMBecho",reply_echo,0},
1121 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1122 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1123 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1124 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1125 /* 0x30 */ { NULL, NULL, 0 },
1126 /* 0x31 */ { NULL, NULL, 0 },
1127 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1128 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1129 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1130 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1131 /* 0x36 */ { NULL, NULL, 0 },
1132 /* 0x37 */ { NULL, NULL, 0 },
1133 /* 0x38 */ { NULL, NULL, 0 },
1134 /* 0x39 */ { NULL, NULL, 0 },
1135 /* 0x3a */ { NULL, NULL, 0 },
1136 /* 0x3b */ { NULL, NULL, 0 },
1137 /* 0x3c */ { NULL, NULL, 0 },
1138 /* 0x3d */ { NULL, NULL, 0 },
1139 /* 0x3e */ { NULL, NULL, 0 },
1140 /* 0x3f */ { NULL, NULL, 0 },
1141 /* 0x40 */ { NULL, NULL, 0 },
1142 /* 0x41 */ { NULL, NULL, 0 },
1143 /* 0x42 */ { NULL, NULL, 0 },
1144 /* 0x43 */ { NULL, NULL, 0 },
1145 /* 0x44 */ { NULL, NULL, 0 },
1146 /* 0x45 */ { NULL, NULL, 0 },
1147 /* 0x46 */ { NULL, NULL, 0 },
1148 /* 0x47 */ { NULL, NULL, 0 },
1149 /* 0x48 */ { NULL, NULL, 0 },
1150 /* 0x49 */ { NULL, NULL, 0 },
1151 /* 0x4a */ { NULL, NULL, 0 },
1152 /* 0x4b */ { NULL, NULL, 0 },
1153 /* 0x4c */ { NULL, NULL, 0 },
1154 /* 0x4d */ { NULL, NULL, 0 },
1155 /* 0x4e */ { NULL, NULL, 0 },
1156 /* 0x4f */ { NULL, NULL, 0 },
1157 /* 0x50 */ { NULL, NULL, 0 },
1158 /* 0x51 */ { NULL, NULL, 0 },
1159 /* 0x52 */ { NULL, NULL, 0 },
1160 /* 0x53 */ { NULL, NULL, 0 },
1161 /* 0x54 */ { NULL, NULL, 0 },
1162 /* 0x55 */ { NULL, NULL, 0 },
1163 /* 0x56 */ { NULL, NULL, 0 },
1164 /* 0x57 */ { NULL, NULL, 0 },
1165 /* 0x58 */ { NULL, NULL, 0 },
1166 /* 0x59 */ { NULL, NULL, 0 },
1167 /* 0x5a */ { NULL, NULL, 0 },
1168 /* 0x5b */ { NULL, NULL, 0 },
1169 /* 0x5c */ { NULL, NULL, 0 },
1170 /* 0x5d */ { NULL, NULL, 0 },
1171 /* 0x5e */ { NULL, NULL, 0 },
1172 /* 0x5f */ { NULL, NULL, 0 },
1173 /* 0x60 */ { NULL, NULL, 0 },
1174 /* 0x61 */ { NULL, NULL, 0 },
1175 /* 0x62 */ { NULL, NULL, 0 },
1176 /* 0x63 */ { NULL, NULL, 0 },
1177 /* 0x64 */ { NULL, NULL, 0 },
1178 /* 0x65 */ { NULL, NULL, 0 },
1179 /* 0x66 */ { NULL, NULL, 0 },
1180 /* 0x67 */ { NULL, NULL, 0 },
1181 /* 0x68 */ { NULL, NULL, 0 },
1182 /* 0x69 */ { NULL, NULL, 0 },
1183 /* 0x6a */ { NULL, NULL, 0 },
1184 /* 0x6b */ { NULL, NULL, 0 },
1185 /* 0x6c */ { NULL, NULL, 0 },
1186 /* 0x6d */ { NULL, NULL, 0 },
1187 /* 0x6e */ { NULL, NULL, 0 },
1188 /* 0x6f */ { NULL, NULL, 0 },
1189 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1190 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1191 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1192 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1193 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1194 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1195 /* 0x76 */ { NULL, NULL, 0 },
1196 /* 0x77 */ { NULL, NULL, 0 },
1197 /* 0x78 */ { NULL, NULL, 0 },
1198 /* 0x79 */ { NULL, NULL, 0 },
1199 /* 0x7a */ { NULL, NULL, 0 },
1200 /* 0x7b */ { NULL, NULL, 0 },
1201 /* 0x7c */ { NULL, NULL, 0 },
1202 /* 0x7d */ { NULL, NULL, 0 },
1203 /* 0x7e */ { NULL, NULL, 0 },
1204 /* 0x7f */ { NULL, NULL, 0 },
1205 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1206 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1207 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1208 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1209 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1210 /* 0x85 */ { NULL, NULL, 0 },
1211 /* 0x86 */ { NULL, NULL, 0 },
1212 /* 0x87 */ { NULL, NULL, 0 },
1213 /* 0x88 */ { NULL, NULL, 0 },
1214 /* 0x89 */ { NULL, NULL, 0 },
1215 /* 0x8a */ { NULL, NULL, 0 },
1216 /* 0x8b */ { NULL, NULL, 0 },
1217 /* 0x8c */ { NULL, NULL, 0 },
1218 /* 0x8d */ { NULL, NULL, 0 },
1219 /* 0x8e */ { NULL, NULL, 0 },
1220 /* 0x8f */ { NULL, NULL, 0 },
1221 /* 0x90 */ { NULL, NULL, 0 },
1222 /* 0x91 */ { NULL, NULL, 0 },
1223 /* 0x92 */ { NULL, NULL, 0 },
1224 /* 0x93 */ { NULL, NULL, 0 },
1225 /* 0x94 */ { NULL, NULL, 0 },
1226 /* 0x95 */ { NULL, NULL, 0 },
1227 /* 0x96 */ { NULL, NULL, 0 },
1228 /* 0x97 */ { NULL, NULL, 0 },
1229 /* 0x98 */ { NULL, NULL, 0 },
1230 /* 0x99 */ { NULL, NULL, 0 },
1231 /* 0x9a */ { NULL, NULL, 0 },
1232 /* 0x9b */ { NULL, NULL, 0 },
1233 /* 0x9c */ { NULL, NULL, 0 },
1234 /* 0x9d */ { NULL, NULL, 0 },
1235 /* 0x9e */ { NULL, NULL, 0 },
1236 /* 0x9f */ { NULL, NULL, 0 },
1237 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1238 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1239 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1240 /* 0xa3 */ { NULL, NULL, 0 },
1241 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1242 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1243 /* 0xa6 */ { NULL, NULL, 0 },
1244 /* 0xa7 */ { NULL, NULL, 0 },
1245 /* 0xa8 */ { NULL, NULL, 0 },
1246 /* 0xa9 */ { NULL, NULL, 0 },
1247 /* 0xaa */ { NULL, NULL, 0 },
1248 /* 0xab */ { NULL, NULL, 0 },
1249 /* 0xac */ { NULL, NULL, 0 },
1250 /* 0xad */ { NULL, NULL, 0 },
1251 /* 0xae */ { NULL, NULL, 0 },
1252 /* 0xaf */ { NULL, NULL, 0 },
1253 /* 0xb0 */ { NULL, NULL, 0 },
1254 /* 0xb1 */ { NULL, NULL, 0 },
1255 /* 0xb2 */ { NULL, NULL, 0 },
1256 /* 0xb3 */ { NULL, NULL, 0 },
1257 /* 0xb4 */ { NULL, NULL, 0 },
1258 /* 0xb5 */ { NULL, NULL, 0 },
1259 /* 0xb6 */ { NULL, NULL, 0 },
1260 /* 0xb7 */ { NULL, NULL, 0 },
1261 /* 0xb8 */ { NULL, NULL, 0 },
1262 /* 0xb9 */ { NULL, NULL, 0 },
1263 /* 0xba */ { NULL, NULL, 0 },
1264 /* 0xbb */ { NULL, NULL, 0 },
1265 /* 0xbc */ { NULL, NULL, 0 },
1266 /* 0xbd */ { NULL, NULL, 0 },
1267 /* 0xbe */ { NULL, NULL, 0 },
1268 /* 0xbf */ { NULL, NULL, 0 },
1269 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1270 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1271 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1272 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1273 /* 0xc4 */ { NULL, NULL, 0 },
1274 /* 0xc5 */ { NULL, NULL, 0 },
1275 /* 0xc6 */ { NULL, NULL, 0 },
1276 /* 0xc7 */ { NULL, NULL, 0 },
1277 /* 0xc8 */ { NULL, NULL, 0 },
1278 /* 0xc9 */ { NULL, NULL, 0 },
1279 /* 0xca */ { NULL, NULL, 0 },
1280 /* 0xcb */ { NULL, NULL, 0 },
1281 /* 0xcc */ { NULL, NULL, 0 },
1282 /* 0xcd */ { NULL, NULL, 0 },
1283 /* 0xce */ { NULL, NULL, 0 },
1284 /* 0xcf */ { NULL, NULL, 0 },
1285 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1286 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1287 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1288 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1289 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1290 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1291 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1292 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1293 /* 0xd8 */ { NULL, NULL, 0 },
1294 /* 0xd9 */ { NULL, NULL, 0 },
1295 /* 0xda */ { NULL, NULL, 0 },
1296 /* 0xdb */ { NULL, NULL, 0 },
1297 /* 0xdc */ { NULL, NULL, 0 },
1298 /* 0xdd */ { NULL, NULL, 0 },
1299 /* 0xde */ { NULL, NULL, 0 },
1300 /* 0xdf */ { NULL, NULL, 0 },
1301 /* 0xe0 */ { NULL, NULL, 0 },
1302 /* 0xe1 */ { NULL, NULL, 0 },
1303 /* 0xe2 */ { NULL, NULL, 0 },
1304 /* 0xe3 */ { NULL, NULL, 0 },
1305 /* 0xe4 */ { NULL, NULL, 0 },
1306 /* 0xe5 */ { NULL, NULL, 0 },
1307 /* 0xe6 */ { NULL, NULL, 0 },
1308 /* 0xe7 */ { NULL, NULL, 0 },
1309 /* 0xe8 */ { NULL, NULL, 0 },
1310 /* 0xe9 */ { NULL, NULL, 0 },
1311 /* 0xea */ { NULL, NULL, 0 },
1312 /* 0xeb */ { NULL, NULL, 0 },
1313 /* 0xec */ { NULL, NULL, 0 },
1314 /* 0xed */ { NULL, NULL, 0 },
1315 /* 0xee */ { NULL, NULL, 0 },
1316 /* 0xef */ { NULL, NULL, 0 },
1317 /* 0xf0 */ { NULL, NULL, 0 },
1318 /* 0xf1 */ { NULL, NULL, 0 },
1319 /* 0xf2 */ { NULL, NULL, 0 },
1320 /* 0xf3 */ { NULL, NULL, 0 },
1321 /* 0xf4 */ { NULL, NULL, 0 },
1322 /* 0xf5 */ { NULL, NULL, 0 },
1323 /* 0xf6 */ { NULL, NULL, 0 },
1324 /* 0xf7 */ { NULL, NULL, 0 },
1325 /* 0xf8 */ { NULL, NULL, 0 },
1326 /* 0xf9 */ { NULL, NULL, 0 },
1327 /* 0xfa */ { NULL, NULL, 0 },
1328 /* 0xfb */ { NULL, NULL, 0 },
1329 /* 0xfc */ { NULL, NULL, 0 },
1330 /* 0xfd */ { NULL, NULL, 0 },
1331 /* 0xfe */ { NULL, NULL, 0 },
1332 /* 0xff */ { NULL, NULL, 0 }
1336 /*******************************************************************
1337 allocate and initialize a reply packet
1338 ********************************************************************/
1340 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1341 const uint8_t *inbuf, char **outbuf,
1342 uint8_t num_words, uint32_t num_bytes)
1344 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1347 * Protect against integer wrap.
1348 * The SMB layer reply can be up to 0xFFFFFF bytes.
1350 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1351 char *msg;
1352 if (asprintf(&msg, "num_bytes too large: %u",
1353 (unsigned)num_bytes) == -1) {
1354 msg = discard_const_p(char, "num_bytes too large");
1356 smb_panic(msg);
1360 * Here we include the NBT header for now.
1362 *outbuf = talloc_array(mem_ctx, char,
1363 NBT_HDR_SIZE + smb_len);
1364 if (*outbuf == NULL) {
1365 return false;
1368 construct_reply_common(req->cmd, inbuf, *outbuf);
1369 srv_set_message(*outbuf, num_words, num_bytes, false);
1371 * Zero out the word area, the caller has to take care of the bcc area
1372 * himself
1374 if (num_words != 0) {
1375 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1378 return true;
1381 void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1383 char *outbuf;
1384 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1385 num_bytes)) {
1386 smb_panic("could not allocate output buffer\n");
1388 req->outbuf = (uint8_t *)outbuf;
1392 /*******************************************************************
1393 Dump a packet to a file.
1394 ********************************************************************/
1396 static void smb_dump(const char *name, int type, const char *data)
1398 size_t len;
1399 int fd, i;
1400 char *fname = NULL;
1401 if (DEBUGLEVEL < 50) {
1402 return;
1405 len = smb_len_tcp(data)+4;
1406 for (i=1;i<100;i++) {
1407 fname = talloc_asprintf(talloc_tos(),
1408 "/tmp/%s.%d.%s",
1409 name,
1411 type ? "req" : "resp");
1412 if (fname == NULL) {
1413 return;
1415 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1416 if (fd != -1 || errno != EEXIST) break;
1417 TALLOC_FREE(fname);
1419 if (fd != -1) {
1420 ssize_t ret = write(fd, data, len);
1421 if (ret != len)
1422 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1423 close(fd);
1424 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1426 TALLOC_FREE(fname);
1429 static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
1430 struct smb_request *req,
1431 uint8_t type,
1432 bool *update_session_globalp,
1433 bool *update_tcon_globalp)
1435 connection_struct *conn = req->conn;
1436 struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
1437 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
1438 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1439 bool update_session = false;
1440 bool update_tcon = false;
1442 if (req->encrypted) {
1443 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
1446 if (srv_is_signing_active(req->xconn)) {
1447 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
1448 } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
1450 * echo can be unsigned. Sesssion setup except final
1451 * session setup response too
1453 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1456 update_session |= smbXsrv_set_crypto_flag(
1457 &session->global->encryption_flags, encrypt_flag);
1458 update_session |= smbXsrv_set_crypto_flag(
1459 &session->global->signing_flags, sign_flag);
1461 if (tcon) {
1462 update_tcon |= smbXsrv_set_crypto_flag(
1463 &tcon->global->encryption_flags, encrypt_flag);
1464 update_tcon |= smbXsrv_set_crypto_flag(
1465 &tcon->global->signing_flags, sign_flag);
1468 if (update_session) {
1469 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1472 *update_session_globalp = update_session;
1473 *update_tcon_globalp = update_tcon;
1474 return;
1477 /****************************************************************************
1478 Prepare everything for calling the actual request function, and potentially
1479 call the request function via the "new" interface.
1481 Return False if the "legacy" function needs to be called, everything is
1482 prepared.
1484 Return True if we're done.
1486 I know this API sucks, but it is the one with the least code change I could
1487 find.
1488 ****************************************************************************/
1490 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1492 int flags;
1493 uint64_t session_tag;
1494 connection_struct *conn = NULL;
1495 struct smbXsrv_connection *xconn = req->xconn;
1496 NTTIME now = timeval_to_nttime(&req->request_time);
1497 struct smbXsrv_session *session = NULL;
1498 NTSTATUS status;
1500 errno = 0;
1502 if (!xconn->smb1.negprot.done) {
1503 switch (type) {
1505 * Without a negprot the request must
1506 * either be a negprot, or one of the
1507 * evil old SMB mailslot messaging types.
1509 case SMBnegprot:
1510 case SMBsendstrt:
1511 case SMBsendend:
1512 case SMBsendtxt:
1513 break;
1514 default:
1515 exit_server_cleanly("The first request "
1516 "should be a negprot");
1520 if (smb_messages[type].fn == NULL) {
1521 DEBUG(0,("Unknown message type %d!\n",type));
1522 smb_dump("Unknown", 1, (const char *)req->inbuf);
1523 reply_unknown_new(req, type);
1524 return NULL;
1527 flags = smb_messages[type].flags;
1529 /* In share mode security we must ignore the vuid. */
1530 session_tag = req->vuid;
1531 conn = req->conn;
1533 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1534 (int)getpid(), (unsigned long)conn));
1536 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1538 /* Ensure this value is replaced in the incoming packet. */
1539 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1542 * Ensure the correct username is in current_user_info. This is a
1543 * really ugly bugfix for problems with multiple session_setup_and_X's
1544 * being done and allowing %U and %G substitutions to work correctly.
1545 * There is a reason this code is done here, don't move it unless you
1546 * know what you're doing... :-).
1547 * JRA.
1551 * lookup an existing session
1553 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1554 * here, the main check is still in change_to_user()
1556 status = smb1srv_session_lookup(xconn,
1557 session_tag,
1558 now,
1559 &session);
1560 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1561 switch (type) {
1562 case SMBsesssetupX:
1563 status = NT_STATUS_OK;
1564 break;
1565 default:
1566 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1567 (unsigned long long)session_tag,
1568 (unsigned long long)req->mid));
1569 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1570 return conn;
1574 if (session_tag != xconn->client->last_session_id) {
1575 struct user_struct *vuser = NULL;
1577 xconn->client->last_session_id = session_tag;
1578 if (session) {
1579 vuser = session->compat;
1581 if (vuser) {
1582 set_current_user_info(
1583 vuser->session_info->unix_info->sanitized_username,
1584 vuser->session_info->unix_info->unix_name,
1585 vuser->session_info->info->domain_name);
1589 /* Does this call need to be run as the connected user? */
1590 if (flags & AS_USER) {
1592 /* Does this call need a valid tree connection? */
1593 if (!conn) {
1595 * Amazingly, the error code depends on the command
1596 * (from Samba4).
1598 if (type == SMBntcreateX) {
1599 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1600 } else {
1601 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1603 return NULL;
1606 if (!change_to_user(conn,session_tag)) {
1607 DEBUG(0, ("Error: Could not change to user. Removing "
1608 "deferred open, mid=%llu.\n",
1609 (unsigned long long)req->mid));
1610 reply_force_doserror(req, ERRSRV, ERRbaduid);
1611 return conn;
1614 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1616 /* Does it need write permission? */
1617 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1618 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1619 return conn;
1622 /* IPC services are limited */
1623 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1624 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1625 return conn;
1627 } else {
1628 /* This call needs to be run as root */
1629 change_to_root_user();
1632 /* load service specific parameters */
1633 if (conn) {
1634 if (req->encrypted) {
1635 conn->encrypted_tid = true;
1636 /* encrypted required from now on. */
1637 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1638 } else if (ENCRYPTION_REQUIRED(conn)) {
1639 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1640 DEBUG(1,("service[%s] requires encryption"
1641 "%s ACCESS_DENIED. mid=%llu\n",
1642 lp_servicename(talloc_tos(), SNUM(conn)),
1643 smb_fn_name(type),
1644 (unsigned long long)req->mid));
1645 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1646 return conn;
1650 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1651 (flags & (AS_USER|DO_CHDIR)
1652 ?True:False))) {
1653 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1654 return conn;
1656 conn->num_smb_operations++;
1660 * Does this protocol need to be run as guest? (Only archane
1661 * messenger service requests have this...)
1663 if (flags & AS_GUEST) {
1664 char *raddr;
1665 bool ok;
1667 if (!change_to_guest()) {
1668 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1669 return conn;
1672 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1673 talloc_tos());
1674 if (raddr == NULL) {
1675 reply_nterror(req, NT_STATUS_NO_MEMORY);
1676 return conn;
1680 * Haven't we checked this in smbd_process already???
1683 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1684 xconn->remote_hostname, raddr);
1685 TALLOC_FREE(raddr);
1687 if (!ok) {
1688 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1689 return conn;
1694 * Update encryption and signing state tracking flags that are
1695 * used by smbstatus to display signing and encryption status.
1697 if (session != NULL) {
1698 bool update_session_global = false;
1699 bool update_tcon_global = false;
1701 smb1srv_update_crypto_flags(session, req, type,
1702 &update_session_global,
1703 &update_tcon_global);
1705 if (update_session_global) {
1706 status = smbXsrv_session_update(session);
1707 if (!NT_STATUS_IS_OK(status)) {
1708 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1709 return conn;
1713 if (update_tcon_global) {
1714 status = smbXsrv_tcon_update(req->conn->tcon);
1715 if (!NT_STATUS_IS_OK(status)) {
1716 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1717 return conn;
1722 smb_messages[type].fn(req);
1723 return req->conn;
1726 /****************************************************************************
1727 Construct a reply to the incoming packet.
1728 ****************************************************************************/
1730 static void construct_reply(struct smbXsrv_connection *xconn,
1731 char *inbuf, int size, size_t unread_bytes,
1732 uint32_t seqnum, bool encrypted,
1733 struct smb_perfcount_data *deferred_pcd)
1735 struct smbd_server_connection *sconn = xconn->client->sconn;
1736 struct smb_request *req;
1738 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1739 smb_panic("could not allocate smb_request");
1742 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1743 encrypted, seqnum)) {
1744 exit_server_cleanly("Invalid SMB request");
1747 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1749 /* we popped this message off the queue - keep original perf data */
1750 if (deferred_pcd)
1751 req->pcd = *deferred_pcd;
1752 else {
1753 SMB_PERFCOUNT_START(&req->pcd);
1754 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1755 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1758 req->conn = switch_message(req->cmd, req);
1760 if (req->outbuf == NULL) {
1762 * Request has suspended itself, will come
1763 * back here.
1765 return;
1767 if (CVAL(req->outbuf,0) == 0) {
1768 show_msg((char *)req->outbuf);
1770 smb_request_done(req);
1773 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1774 char *inbuf, int size, uint32_t seqnum,
1775 bool encrypted,
1776 struct smb_perfcount_data *deferred_pcd)
1778 struct smb_request **reqs = NULL;
1779 struct smb_request *req;
1780 unsigned num_reqs;
1781 bool ok;
1783 ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
1784 seqnum, &reqs, &num_reqs);
1785 if (!ok) {
1786 char errbuf[smb_size];
1787 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1788 __LINE__, __FILE__);
1789 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1790 NULL)) {
1791 exit_server_cleanly("construct_reply_chain: "
1792 "srv_send_smb failed.");
1794 return;
1797 req = reqs[0];
1798 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1800 req->conn = switch_message(req->cmd, req);
1802 if (req->outbuf == NULL) {
1804 * Request has suspended itself, will come
1805 * back here.
1807 return;
1809 smb_request_done(req);
1813 * To be called from an async SMB handler that is potentially chained
1814 * when it is finished for shipping.
1817 void smb_request_done(struct smb_request *req)
1819 struct smb_request **reqs = NULL;
1820 struct smb_request *first_req;
1821 size_t i, num_reqs, next_index;
1822 NTSTATUS status;
1824 if (req->chain == NULL) {
1825 first_req = req;
1826 goto shipit;
1829 reqs = req->chain;
1830 num_reqs = talloc_array_length(reqs);
1832 for (i=0; i<num_reqs; i++) {
1833 if (reqs[i] == req) {
1834 break;
1837 if (i == num_reqs) {
1839 * Invalid chain, should not happen
1841 status = NT_STATUS_INTERNAL_ERROR;
1842 goto error;
1844 next_index = i+1;
1846 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1847 struct smb_request *next = reqs[next_index];
1848 struct smbXsrv_tcon *tcon;
1849 NTTIME now = timeval_to_nttime(&req->request_time);
1851 next->vuid = SVAL(req->outbuf, smb_uid);
1852 next->tid = SVAL(req->outbuf, smb_tid);
1853 status = smb1srv_tcon_lookup(req->xconn, next->tid,
1854 now, &tcon);
1856 if (NT_STATUS_IS_OK(status)) {
1857 next->conn = tcon->compat;
1858 } else {
1859 next->conn = NULL;
1861 next->chain_fsp = req->chain_fsp;
1862 next->inbuf = req->inbuf;
1864 req = next;
1865 req->conn = switch_message(req->cmd, req);
1867 if (req->outbuf == NULL) {
1869 * Request has suspended itself, will come
1870 * back here.
1872 return;
1874 next_index += 1;
1877 first_req = reqs[0];
1879 for (i=1; i<next_index; i++) {
1880 bool ok;
1882 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1883 if (!ok) {
1884 status = NT_STATUS_INTERNAL_ERROR;
1885 goto error;
1889 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1890 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1893 * This scary statement intends to set the
1894 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1895 * to the value last_req->outbuf carries
1897 SSVAL(first_req->outbuf, smb_flg2,
1898 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1899 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1902 * Transfer the error codes from the subrequest to the main one
1904 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1905 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1907 _smb_setlen_large(
1908 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1910 shipit:
1911 if (!srv_send_smb(first_req->xconn,
1912 (char *)first_req->outbuf,
1913 true, first_req->seqnum+1,
1914 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1915 &first_req->pcd)) {
1916 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1917 "failed.");
1919 TALLOC_FREE(req); /* non-chained case */
1920 TALLOC_FREE(reqs); /* chained case */
1921 return;
1923 error:
1925 char errbuf[smb_size];
1926 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1927 if (!srv_send_smb(req->xconn, errbuf, true,
1928 req->seqnum+1, req->encrypted,
1929 NULL)) {
1930 exit_server_cleanly("construct_reply_chain: "
1931 "srv_send_smb failed.");
1934 TALLOC_FREE(req); /* non-chained case */
1935 TALLOC_FREE(reqs); /* chained case */
1938 /****************************************************************************
1939 Process an smb from the client
1940 ****************************************************************************/
1941 static void process_smb(struct smbXsrv_connection *xconn,
1942 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1943 uint32_t seqnum, bool encrypted,
1944 struct smb_perfcount_data *deferred_pcd)
1946 struct smbd_server_connection *sconn = xconn->client->sconn;
1947 int msg_type = CVAL(inbuf,0);
1949 DO_PROFILE_INC(request);
1951 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1952 smb_len(inbuf) ) );
1953 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1954 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1956 if (msg_type != NBSSmessage) {
1958 * NetBIOS session request, keepalive, etc.
1960 reply_special(xconn, (char *)inbuf, nread);
1961 goto done;
1964 if (sconn->using_smb2) {
1965 /* At this point we're not really using smb2,
1966 * we make the decision here.. */
1967 if (smbd_is_smb2_header(inbuf, nread)) {
1968 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1969 size_t pdulen = nread - NBT_HDR_SIZE;
1970 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1971 return;
1973 if (nread >= smb_size && valid_smb_header(inbuf)
1974 && CVAL(inbuf, smb_com) != 0x72) {
1975 /* This is a non-negprot SMB1 packet.
1976 Disable SMB2 from now on. */
1977 sconn->using_smb2 = false;
1981 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1982 * so subtract 4 from it. */
1983 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1984 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1985 smb_len(inbuf)));
1987 /* special magic for immediate exit */
1988 if ((nread == 9) &&
1989 (IVAL(inbuf, 4) == 0x74697865) &&
1990 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1991 uint8_t exitcode = CVAL(inbuf, 8);
1992 DEBUG(1, ("Exiting immediately with code %d\n",
1993 (int)exitcode));
1994 exit(exitcode);
1997 exit_server_cleanly("Non-SMB packet");
2000 show_msg((char *)inbuf);
2002 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
2003 construct_reply_chain(xconn, (char *)inbuf, nread,
2004 seqnum, encrypted, deferred_pcd);
2005 } else {
2006 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
2007 seqnum, encrypted, deferred_pcd);
2010 sconn->trans_num++;
2012 done:
2013 sconn->num_requests++;
2015 /* The timeout_processing function isn't run nearly
2016 often enough to implement 'max log size' without
2017 overrunning the size of the file by many megabytes.
2018 This is especially true if we are running at debug
2019 level 10. Checking every 50 SMBs is a nice
2020 tradeoff of performance vs log file size overrun. */
2022 if ((sconn->num_requests % 50) == 0 &&
2023 need_to_check_log_size()) {
2024 change_to_root_user();
2025 check_log_size();
2029 /****************************************************************************
2030 Return a string containing the function name of a SMB command.
2031 ****************************************************************************/
2033 const char *smb_fn_name(int type)
2035 const char *unknown_name = "SMBunknown";
2037 if (smb_messages[type].name == NULL)
2038 return(unknown_name);
2040 return(smb_messages[type].name);
2043 /****************************************************************************
2044 Helper functions for contruct_reply.
2045 ****************************************************************************/
2047 void add_to_common_flags2(uint32_t v)
2049 common_flags2 |= v;
2052 void remove_from_common_flags2(uint32_t v)
2054 common_flags2 &= ~v;
2057 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
2058 char *outbuf)
2060 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
2061 uint16_t out_flags2 = common_flags2;
2063 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
2064 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
2065 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
2067 srv_set_message(outbuf,0,0,false);
2069 SCVAL(outbuf, smb_com, cmd);
2070 SIVAL(outbuf,smb_rcls,0);
2071 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
2072 SSVAL(outbuf,smb_flg2, out_flags2);
2073 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
2074 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2076 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2077 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2078 SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
2079 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2080 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2083 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2085 construct_reply_common(req->cmd, req->inbuf, outbuf);
2089 * @brief Find the smb_cmd offset of the last command pushed
2090 * @param[in] buf The buffer we're building up
2091 * @retval Where can we put our next andx cmd?
2093 * While chaining requests, the "next" request we're looking at needs to put
2094 * its SMB_Command before the data the previous request already built up added
2095 * to the chain. Find the offset to the place where we have to put our cmd.
2098 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2100 uint8_t cmd;
2101 size_t ofs;
2103 cmd = CVAL(buf, smb_com);
2105 if (!is_andx_req(cmd)) {
2106 return false;
2109 ofs = smb_vwv0;
2111 while (CVAL(buf, ofs) != 0xff) {
2113 if (!is_andx_req(CVAL(buf, ofs))) {
2114 return false;
2118 * ofs is from start of smb header, so add the 4 length
2119 * bytes. The next cmd is right after the wct field.
2121 ofs = SVAL(buf, ofs+2) + 4 + 1;
2123 if (ofs+4 >= talloc_get_size(buf)) {
2124 return false;
2128 *pofs = ofs;
2129 return true;
2133 * @brief Do the smb chaining at a buffer level
2134 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2135 * @param[in] andx_buf Buffer to be appended
2138 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2140 uint8_t smb_command = CVAL(andx_buf, smb_com);
2141 uint8_t wct = CVAL(andx_buf, smb_wct);
2142 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2143 uint32_t num_bytes = smb_buflen(andx_buf);
2144 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2146 uint8_t *outbuf;
2147 size_t old_size, new_size;
2148 size_t ofs;
2149 size_t chain_padding = 0;
2150 size_t andx_cmd_ofs;
2153 old_size = talloc_get_size(*poutbuf);
2155 if ((old_size % 4) != 0) {
2157 * Align the wct field of subsequent requests to a 4-byte
2158 * boundary
2160 chain_padding = 4 - (old_size % 4);
2164 * After the old request comes the new wct field (1 byte), the vwv's
2165 * and the num_bytes field.
2168 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2169 new_size += num_bytes;
2171 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2172 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2173 (unsigned)new_size));
2174 return false;
2177 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2178 if (outbuf == NULL) {
2179 DEBUG(0, ("talloc failed\n"));
2180 return false;
2182 *poutbuf = outbuf;
2184 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2185 DEBUG(1, ("invalid command chain\n"));
2186 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2187 return false;
2190 if (chain_padding != 0) {
2191 memset(outbuf + old_size, 0, chain_padding);
2192 old_size += chain_padding;
2195 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2196 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2198 ofs = old_size;
2201 * Push the chained request:
2203 * wct field
2206 SCVAL(outbuf, ofs, wct);
2207 ofs += 1;
2210 * vwv array
2213 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2216 * HACK ALERT
2218 * Read&X has an offset into its data buffer at
2219 * vwv[6]. reply_read_andx has no idea anymore that it's
2220 * running from within a chain, so we have to fix up the
2221 * offset here.
2223 * Although it looks disgusting at this place, I want to keep
2224 * it here. The alternative would be to push knowledge about
2225 * the andx chain down into read&x again.
2228 if (smb_command == SMBreadX) {
2229 uint8_t *bytes_addr;
2231 if (wct < 7) {
2233 * Invalid read&x response
2235 return false;
2238 bytes_addr = outbuf + ofs /* vwv start */
2239 + sizeof(uint16_t) * wct /* vwv array */
2240 + sizeof(uint16_t) /* bcc */
2241 + 1; /* padding byte */
2243 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2244 bytes_addr - outbuf - 4);
2247 ofs += sizeof(uint16_t) * wct;
2250 * bcc (byte count)
2253 SSVAL(outbuf, ofs, num_bytes);
2254 ofs += sizeof(uint16_t);
2257 * The bytes field
2260 memcpy(outbuf + ofs, bytes, num_bytes);
2262 return true;
2265 bool smb1_is_chain(const uint8_t *buf)
2267 uint8_t cmd, wct, andx_cmd;
2269 cmd = CVAL(buf, smb_com);
2270 if (!is_andx_req(cmd)) {
2271 return false;
2273 wct = CVAL(buf, smb_wct);
2274 if (wct < 2) {
2275 return false;
2277 andx_cmd = CVAL(buf, smb_vwv);
2278 return (andx_cmd != 0xFF);
2281 bool smb1_walk_chain(const uint8_t *buf,
2282 bool (*fn)(uint8_t cmd,
2283 uint8_t wct, const uint16_t *vwv,
2284 uint16_t num_bytes, const uint8_t *bytes,
2285 void *private_data),
2286 void *private_data)
2288 size_t smblen = smb_len(buf);
2289 const char *smb_buf = smb_base(buf);
2290 uint8_t cmd, chain_cmd;
2291 uint8_t wct;
2292 const uint16_t *vwv;
2293 uint16_t num_bytes;
2294 const uint8_t *bytes;
2296 cmd = CVAL(buf, smb_com);
2297 wct = CVAL(buf, smb_wct);
2298 vwv = (const uint16_t *)(buf + smb_vwv);
2299 num_bytes = smb_buflen(buf);
2300 bytes = (const uint8_t *)smb_buf_const(buf);
2302 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2303 return false;
2306 if (!is_andx_req(cmd)) {
2307 return true;
2309 if (wct < 2) {
2310 return false;
2313 chain_cmd = CVAL(vwv, 0);
2315 while (chain_cmd != 0xff) {
2316 uint32_t chain_offset; /* uint32_t to avoid overflow */
2317 size_t length_needed;
2318 ptrdiff_t vwv_offset;
2320 chain_offset = SVAL(vwv+1, 0);
2323 * Check if the client tries to fool us. The chain
2324 * offset needs to point beyond the current request in
2325 * the chain, it needs to strictly grow. Otherwise we
2326 * might be tricked into an endless loop always
2327 * processing the same request over and over again. We
2328 * used to assume that vwv and the byte buffer array
2329 * in a chain are always attached, but OS/2 the
2330 * Write&X/Read&X chain puts the Read&X vwv array
2331 * right behind the Write&X vwv chain. The Write&X bcc
2332 * array is put behind the Read&X vwv array. So now we
2333 * check whether the chain offset points strictly
2334 * behind the previous vwv array. req->buf points
2335 * right after the vwv array of the previous
2336 * request. See
2337 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2338 * more information.
2341 vwv_offset = ((const char *)vwv - smb_buf);
2342 if (chain_offset <= vwv_offset) {
2343 return false;
2347 * Next check: Make sure the chain offset does not
2348 * point beyond the overall smb request length.
2351 length_needed = chain_offset+1; /* wct */
2352 if (length_needed > smblen) {
2353 return false;
2357 * Now comes the pointer magic. Goal here is to set up
2358 * vwv and buf correctly again. The chain offset (the
2359 * former vwv[1]) points at the new wct field.
2362 wct = CVAL(smb_buf, chain_offset);
2364 if (is_andx_req(chain_cmd) && (wct < 2)) {
2365 return false;
2369 * Next consistency check: Make the new vwv array fits
2370 * in the overall smb request.
2373 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2374 if (length_needed > smblen) {
2375 return false;
2377 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2380 * Now grab the new byte buffer....
2383 num_bytes = SVAL(vwv+wct, 0);
2386 * .. and check that it fits.
2389 length_needed += num_bytes;
2390 if (length_needed > smblen) {
2391 return false;
2393 bytes = (const uint8_t *)(vwv+wct+1);
2395 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2396 return false;
2399 if (!is_andx_req(chain_cmd)) {
2400 return true;
2402 chain_cmd = CVAL(vwv, 0);
2404 return true;
2407 static bool smb1_chain_length_cb(uint8_t cmd,
2408 uint8_t wct, const uint16_t *vwv,
2409 uint16_t num_bytes, const uint8_t *bytes,
2410 void *private_data)
2412 unsigned *count = (unsigned *)private_data;
2413 *count += 1;
2414 return true;
2417 unsigned smb1_chain_length(const uint8_t *buf)
2419 unsigned count = 0;
2421 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2422 return 0;
2424 return count;
2427 struct smb1_parse_chain_state {
2428 TALLOC_CTX *mem_ctx;
2429 const uint8_t *buf;
2430 struct smbd_server_connection *sconn;
2431 struct smbXsrv_connection *xconn;
2432 bool encrypted;
2433 uint32_t seqnum;
2435 struct smb_request **reqs;
2436 unsigned num_reqs;
2439 static bool smb1_parse_chain_cb(uint8_t cmd,
2440 uint8_t wct, const uint16_t *vwv,
2441 uint16_t num_bytes, const uint8_t *bytes,
2442 void *private_data)
2444 struct smb1_parse_chain_state *state =
2445 (struct smb1_parse_chain_state *)private_data;
2446 struct smb_request **reqs;
2447 struct smb_request *req;
2448 bool ok;
2450 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2451 struct smb_request *, state->num_reqs+1);
2452 if (reqs == NULL) {
2453 return false;
2455 state->reqs = reqs;
2457 req = talloc(reqs, struct smb_request);
2458 if (req == NULL) {
2459 return false;
2462 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2463 state->encrypted, state->seqnum);
2464 if (!ok) {
2465 return false;
2467 req->cmd = cmd;
2468 req->wct = wct;
2469 req->vwv = vwv;
2470 req->buflen = num_bytes;
2471 req->buf = bytes;
2473 reqs[state->num_reqs] = req;
2474 state->num_reqs += 1;
2475 return true;
2478 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2479 struct smbXsrv_connection *xconn,
2480 bool encrypted, uint32_t seqnum,
2481 struct smb_request ***reqs, unsigned *num_reqs)
2483 struct smbd_server_connection *sconn = NULL;
2484 struct smb1_parse_chain_state state;
2485 unsigned i;
2487 if (xconn != NULL) {
2488 sconn = xconn->client->sconn;
2491 state.mem_ctx = mem_ctx;
2492 state.buf = buf;
2493 state.sconn = sconn;
2494 state.xconn = xconn;
2495 state.encrypted = encrypted;
2496 state.seqnum = seqnum;
2497 state.reqs = NULL;
2498 state.num_reqs = 0;
2500 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2501 TALLOC_FREE(state.reqs);
2502 return false;
2504 for (i=0; i<state.num_reqs; i++) {
2505 state.reqs[i]->chain = state.reqs;
2507 *reqs = state.reqs;
2508 *num_reqs = state.num_reqs;
2509 return true;
2512 /****************************************************************************
2513 Check if services need reloading.
2514 ****************************************************************************/
2516 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2519 if (last_smb_conf_reload_time == 0) {
2520 last_smb_conf_reload_time = t;
2523 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2524 reload_services(sconn, conn_snum_used, true);
2525 last_smb_conf_reload_time = t;
2529 static bool fd_is_readable(int fd)
2531 int ret, revents;
2533 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2535 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2539 static void smbd_server_connection_write_handler(
2540 struct smbXsrv_connection *xconn)
2542 /* TODO: make write nonblocking */
2545 static void smbd_server_connection_read_handler(
2546 struct smbXsrv_connection *xconn, int fd)
2548 uint8_t *inbuf = NULL;
2549 size_t inbuf_len = 0;
2550 size_t unread_bytes = 0;
2551 bool encrypted = false;
2552 TALLOC_CTX *mem_ctx = talloc_tos();
2553 NTSTATUS status;
2554 uint32_t seqnum;
2556 bool async_echo = lp_async_smb_echo_handler();
2557 bool from_client = false;
2559 if (async_echo) {
2560 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2562 * This is the super-ugly hack to prefer the packets
2563 * forwarded by the echo handler over the ones by the
2564 * client directly
2566 fd = xconn->smb1.echo_handler.trusted_fd;
2570 from_client = (xconn->transport.sock == fd);
2572 if (async_echo && from_client) {
2573 smbd_lock_socket(xconn);
2575 if (!fd_is_readable(fd)) {
2576 DEBUG(10,("the echo listener was faster\n"));
2577 smbd_unlock_socket(xconn);
2578 return;
2582 /* TODO: make this completely nonblocking */
2583 status = receive_smb_talloc(mem_ctx, xconn, fd,
2584 (char **)(void *)&inbuf,
2585 0, /* timeout */
2586 &unread_bytes,
2587 &encrypted,
2588 &inbuf_len, &seqnum,
2589 !from_client /* trusted channel */);
2591 if (async_echo && from_client) {
2592 smbd_unlock_socket(xconn);
2595 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2596 goto process;
2598 if (NT_STATUS_IS_ERR(status)) {
2599 exit_server_cleanly("failed to receive smb request");
2601 if (!NT_STATUS_IS_OK(status)) {
2602 return;
2605 process:
2606 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2607 seqnum, encrypted, NULL);
2610 static void smbd_server_connection_handler(struct tevent_context *ev,
2611 struct tevent_fd *fde,
2612 uint16_t flags,
2613 void *private_data)
2615 struct smbXsrv_connection *xconn =
2616 talloc_get_type_abort(private_data,
2617 struct smbXsrv_connection);
2619 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2621 * we're not supposed to do any io
2623 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2624 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2625 return;
2628 if (flags & TEVENT_FD_WRITE) {
2629 smbd_server_connection_write_handler(xconn);
2630 return;
2632 if (flags & TEVENT_FD_READ) {
2633 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2634 return;
2638 static void smbd_server_echo_handler(struct tevent_context *ev,
2639 struct tevent_fd *fde,
2640 uint16_t flags,
2641 void *private_data)
2643 struct smbXsrv_connection *xconn =
2644 talloc_get_type_abort(private_data,
2645 struct smbXsrv_connection);
2647 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2649 * we're not supposed to do any io
2651 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2652 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2653 return;
2656 if (flags & TEVENT_FD_WRITE) {
2657 smbd_server_connection_write_handler(xconn);
2658 return;
2660 if (flags & TEVENT_FD_READ) {
2661 smbd_server_connection_read_handler(
2662 xconn, xconn->smb1.echo_handler.trusted_fd);
2663 return;
2667 struct smbd_release_ip_state {
2668 struct smbXsrv_connection *xconn;
2669 struct tevent_immediate *im;
2670 char addr[INET6_ADDRSTRLEN];
2673 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2674 struct tevent_immediate *im,
2675 void *private_data)
2677 struct smbd_release_ip_state *state =
2678 talloc_get_type_abort(private_data,
2679 struct smbd_release_ip_state);
2680 struct smbXsrv_connection *xconn = state->xconn;
2682 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2684 * smbd_server_connection_terminate() already triggered ?
2686 return;
2689 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2692 /****************************************************************************
2693 received when we should release a specific IP
2694 ****************************************************************************/
2695 static int release_ip(struct tevent_context *ev,
2696 uint32_t src_vnn, uint32_t dst_vnn,
2697 uint64_t dst_srvid,
2698 const uint8_t *msg, size_t msglen,
2699 void *private_data)
2701 struct smbd_release_ip_state *state =
2702 talloc_get_type_abort(private_data,
2703 struct smbd_release_ip_state);
2704 struct smbXsrv_connection *xconn = state->xconn;
2705 const char *ip;
2706 const char *addr = state->addr;
2707 const char *p = addr;
2709 if (msglen == 0) {
2710 return 0;
2712 if (msg[msglen-1] != '\0') {
2713 return 0;
2716 ip = (const char *)msg;
2718 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2719 /* avoid recursion */
2720 return 0;
2723 if (strncmp("::ffff:", addr, 7) == 0) {
2724 p = addr + 7;
2727 DEBUG(10, ("Got release IP message for %s, "
2728 "our address is %s\n", ip, p));
2730 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2731 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2732 ip));
2734 * With SMB2 we should do a clean disconnect,
2735 * the previous_session_id in the session setup
2736 * will cleanup the old session, tcons and opens.
2738 * A clean disconnect is needed in order to support
2739 * durable handles.
2741 * Note: typically this is never triggered
2742 * as we got a TCP RST (triggered by ctdb event scripts)
2743 * before we get CTDB_SRVID_RELEASE_IP.
2745 * We used to call _exit(1) here, but as this was mostly never
2746 * triggered and has implication on our process model,
2747 * we can just use smbd_server_connection_terminate()
2748 * (also for SMB1).
2750 * We don't call smbd_server_connection_terminate() directly
2751 * as we might be called from within ctdbd_migrate(),
2752 * we need to defer our action to the next event loop
2754 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2755 smbd_release_ip_immediate, state);
2758 * Make sure we don't get any io on the connection.
2760 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2761 return EADDRNOTAVAIL;
2764 return 0;
2767 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2768 struct sockaddr_storage *srv,
2769 struct sockaddr_storage *clnt)
2771 struct smbd_release_ip_state *state;
2772 struct ctdbd_connection *cconn;
2773 int ret;
2775 cconn = messaging_ctdb_connection();
2776 if (cconn == NULL) {
2777 return NT_STATUS_NO_MEMORY;
2780 state = talloc_zero(xconn, struct smbd_release_ip_state);
2781 if (state == NULL) {
2782 return NT_STATUS_NO_MEMORY;
2784 state->xconn = xconn;
2785 state->im = tevent_create_immediate(state);
2786 if (state->im == NULL) {
2787 return NT_STATUS_NO_MEMORY;
2789 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2790 return NT_STATUS_NO_MEMORY;
2793 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2794 if (ret != 0) {
2795 return map_nt_error_from_unix(ret);
2797 return NT_STATUS_OK;
2800 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2801 void *private_data, uint32_t msg_type,
2802 struct server_id server_id, DATA_BLOB *data)
2804 struct smbd_server_connection *sconn = talloc_get_type_abort(
2805 private_data, struct smbd_server_connection);
2806 const char *ip = (char *) data->data;
2807 char *client_ip;
2809 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2811 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2812 talloc_tos());
2813 if (client_ip == NULL) {
2814 return;
2817 if (strequal(ip, client_ip)) {
2818 DBG_WARNING("Got kill client message for %s - "
2819 "exiting immediately\n", ip);
2820 exit_server_cleanly("Forced disconnect for client");
2823 TALLOC_FREE(client_ip);
2827 * Send keepalive packets to our client
2829 static bool keepalive_fn(const struct timeval *now, void *private_data)
2831 struct smbd_server_connection *sconn = talloc_get_type_abort(
2832 private_data, struct smbd_server_connection);
2833 struct smbXsrv_connection *xconn = NULL;
2834 bool ret;
2836 if (sconn->using_smb2) {
2837 /* Don't do keepalives on an SMB2 connection. */
2838 return false;
2842 * With SMB1 we only have 1 connection
2844 xconn = sconn->client->connections;
2845 smbd_lock_socket(xconn);
2846 ret = send_keepalive(xconn->transport.sock);
2847 smbd_unlock_socket(xconn);
2849 if (!ret) {
2850 int saved_errno = errno;
2852 * Try and give an error message saying what
2853 * client failed.
2855 DEBUG(0, ("send_keepalive failed for client %s. "
2856 "Error %s - exiting\n",
2857 smbXsrv_connection_dbg(xconn),
2858 strerror(saved_errno)));
2859 errno = saved_errno;
2860 return False;
2862 return True;
2866 * Do the recurring check if we're idle
2868 static bool deadtime_fn(const struct timeval *now, void *private_data)
2870 struct smbd_server_connection *sconn =
2871 (struct smbd_server_connection *)private_data;
2873 if ((conn_num_open(sconn) == 0)
2874 || (conn_idle_all(sconn, now->tv_sec))) {
2875 DEBUG( 2, ( "Closing idle connection\n" ) );
2876 messaging_send(sconn->msg_ctx,
2877 messaging_server_id(sconn->msg_ctx),
2878 MSG_SHUTDOWN, &data_blob_null);
2879 return False;
2882 return True;
2886 * Do the recurring log file and smb.conf reload checks.
2889 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2891 struct smbd_server_connection *sconn = talloc_get_type_abort(
2892 private_data, struct smbd_server_connection);
2894 DEBUG(5, ("housekeeping\n"));
2896 change_to_root_user();
2898 /* update printer queue caches if necessary */
2899 update_monitored_printq_cache(sconn->msg_ctx);
2901 /* check if we need to reload services */
2902 check_reload(sconn, time_mono(NULL));
2905 * Force a log file check.
2907 force_check_log_size();
2908 check_log_size();
2909 return true;
2913 * Read an smb packet in the echo handler child, giving the parent
2914 * smbd one second to react once the socket becomes readable.
2917 struct smbd_echo_read_state {
2918 struct tevent_context *ev;
2919 struct smbXsrv_connection *xconn;
2921 char *buf;
2922 size_t buflen;
2923 uint32_t seqnum;
2926 static void smbd_echo_read_readable(struct tevent_req *subreq);
2927 static void smbd_echo_read_waited(struct tevent_req *subreq);
2929 static struct tevent_req *smbd_echo_read_send(
2930 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2931 struct smbXsrv_connection *xconn)
2933 struct tevent_req *req, *subreq;
2934 struct smbd_echo_read_state *state;
2936 req = tevent_req_create(mem_ctx, &state,
2937 struct smbd_echo_read_state);
2938 if (req == NULL) {
2939 return NULL;
2941 state->ev = ev;
2942 state->xconn = xconn;
2944 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2945 if (tevent_req_nomem(subreq, req)) {
2946 return tevent_req_post(req, ev);
2948 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2949 return req;
2952 static void smbd_echo_read_readable(struct tevent_req *subreq)
2954 struct tevent_req *req = tevent_req_callback_data(
2955 subreq, struct tevent_req);
2956 struct smbd_echo_read_state *state = tevent_req_data(
2957 req, struct smbd_echo_read_state);
2958 bool ok;
2959 int err;
2961 ok = wait_for_read_recv(subreq, &err);
2962 TALLOC_FREE(subreq);
2963 if (!ok) {
2964 tevent_req_nterror(req, map_nt_error_from_unix(err));
2965 return;
2969 * Give the parent smbd one second to step in
2972 subreq = tevent_wakeup_send(
2973 state, state->ev, timeval_current_ofs(1, 0));
2974 if (tevent_req_nomem(subreq, req)) {
2975 return;
2977 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2980 static void smbd_echo_read_waited(struct tevent_req *subreq)
2982 struct tevent_req *req = tevent_req_callback_data(
2983 subreq, struct tevent_req);
2984 struct smbd_echo_read_state *state = tevent_req_data(
2985 req, struct smbd_echo_read_state);
2986 struct smbXsrv_connection *xconn = state->xconn;
2987 bool ok;
2988 NTSTATUS status;
2989 size_t unread = 0;
2990 bool encrypted;
2992 ok = tevent_wakeup_recv(subreq);
2993 TALLOC_FREE(subreq);
2994 if (!ok) {
2995 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2996 return;
2999 ok = smbd_lock_socket_internal(xconn);
3000 if (!ok) {
3001 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3002 DEBUG(0, ("%s: failed to lock socket\n", __location__));
3003 return;
3006 if (!fd_is_readable(xconn->transport.sock)) {
3007 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3008 (int)getpid()));
3010 ok = smbd_unlock_socket_internal(xconn);
3011 if (!ok) {
3012 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3013 DEBUG(1, ("%s: failed to unlock socket\n",
3014 __location__));
3015 return;
3018 subreq = wait_for_read_send(state, state->ev,
3019 xconn->transport.sock, false);
3020 if (tevent_req_nomem(subreq, req)) {
3021 return;
3023 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
3024 return;
3027 status = receive_smb_talloc(state, xconn,
3028 xconn->transport.sock,
3029 &state->buf,
3030 0 /* timeout */,
3031 &unread,
3032 &encrypted,
3033 &state->buflen,
3034 &state->seqnum,
3035 false /* trusted_channel*/);
3037 if (tevent_req_nterror(req, status)) {
3038 tevent_req_nterror(req, status);
3039 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3040 (int)getpid(), nt_errstr(status)));
3041 return;
3044 ok = smbd_unlock_socket_internal(xconn);
3045 if (!ok) {
3046 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3047 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
3048 return;
3050 tevent_req_done(req);
3053 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3054 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
3056 struct smbd_echo_read_state *state = tevent_req_data(
3057 req, struct smbd_echo_read_state);
3058 NTSTATUS status;
3060 if (tevent_req_is_nterror(req, &status)) {
3061 return status;
3063 *pbuf = talloc_move(mem_ctx, &state->buf);
3064 *pbuflen = state->buflen;
3065 *pseqnum = state->seqnum;
3066 return NT_STATUS_OK;
3069 struct smbd_echo_state {
3070 struct tevent_context *ev;
3071 struct iovec *pending;
3072 struct smbd_server_connection *sconn;
3073 struct smbXsrv_connection *xconn;
3074 int parent_pipe;
3076 struct tevent_fd *parent_fde;
3078 struct tevent_req *write_req;
3081 static void smbd_echo_writer_done(struct tevent_req *req);
3083 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3085 int num_pending;
3087 if (state->write_req != NULL) {
3088 return;
3091 num_pending = talloc_array_length(state->pending);
3092 if (num_pending == 0) {
3093 return;
3096 state->write_req = writev_send(state, state->ev, NULL,
3097 state->parent_pipe, false,
3098 state->pending, num_pending);
3099 if (state->write_req == NULL) {
3100 DEBUG(1, ("writev_send failed\n"));
3101 exit(1);
3104 talloc_steal(state->write_req, state->pending);
3105 state->pending = NULL;
3107 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3108 state);
3111 static void smbd_echo_writer_done(struct tevent_req *req)
3113 struct smbd_echo_state *state = tevent_req_callback_data(
3114 req, struct smbd_echo_state);
3115 ssize_t written;
3116 int err;
3118 written = writev_recv(req, &err);
3119 TALLOC_FREE(req);
3120 state->write_req = NULL;
3121 if (written == -1) {
3122 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3123 exit(1);
3125 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3126 smbd_echo_activate_writer(state);
3129 static bool smbd_echo_reply(struct smbd_echo_state *state,
3130 uint8_t *inbuf, size_t inbuf_len,
3131 uint32_t seqnum)
3133 struct smb_request req;
3134 uint16_t num_replies;
3135 char *outbuf;
3136 bool ok;
3138 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3139 DEBUG(10, ("Got netbios keepalive\n"));
3141 * Just swallow it
3143 return true;
3146 if (inbuf_len < smb_size) {
3147 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3148 return false;
3150 if (!valid_smb_header(inbuf)) {
3151 DEBUG(10, ("Got invalid SMB header\n"));
3152 return false;
3155 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3156 seqnum)) {
3157 return false;
3159 req.inbuf = inbuf;
3161 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3162 smb_messages[req.cmd].name
3163 ? smb_messages[req.cmd].name : "unknown"));
3165 if (req.cmd != SMBecho) {
3166 return false;
3168 if (req.wct < 1) {
3169 return false;
3172 num_replies = SVAL(req.vwv+0, 0);
3173 if (num_replies != 1) {
3174 /* Not a Windows "Hey, you're still there?" request */
3175 return false;
3178 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3179 1, req.buflen)) {
3180 DEBUG(10, ("create_outbuf failed\n"));
3181 return false;
3183 req.outbuf = (uint8_t *)outbuf;
3185 SSVAL(req.outbuf, smb_vwv0, num_replies);
3187 if (req.buflen > 0) {
3188 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3191 ok = srv_send_smb(req.xconn,
3192 (char *)outbuf,
3193 true, seqnum+1,
3194 false, &req.pcd);
3195 TALLOC_FREE(outbuf);
3196 if (!ok) {
3197 exit(1);
3200 return true;
3203 static void smbd_echo_exit(struct tevent_context *ev,
3204 struct tevent_fd *fde, uint16_t flags,
3205 void *private_data)
3207 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3208 exit(0);
3211 static void smbd_echo_got_packet(struct tevent_req *req);
3213 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3214 int parent_pipe)
3216 struct smbd_echo_state *state;
3217 struct tevent_req *read_req;
3219 state = talloc_zero(xconn, struct smbd_echo_state);
3220 if (state == NULL) {
3221 DEBUG(1, ("talloc failed\n"));
3222 return;
3224 state->xconn = xconn;
3225 state->parent_pipe = parent_pipe;
3226 state->ev = samba_tevent_context_init(state);
3227 if (state->ev == NULL) {
3228 DEBUG(1, ("samba_tevent_context_init failed\n"));
3229 TALLOC_FREE(state);
3230 return;
3232 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3233 TEVENT_FD_READ, smbd_echo_exit,
3234 state);
3235 if (state->parent_fde == NULL) {
3236 DEBUG(1, ("tevent_add_fd failed\n"));
3237 TALLOC_FREE(state);
3238 return;
3241 read_req = smbd_echo_read_send(state, state->ev, xconn);
3242 if (read_req == NULL) {
3243 DEBUG(1, ("smbd_echo_read_send failed\n"));
3244 TALLOC_FREE(state);
3245 return;
3247 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3249 while (true) {
3250 if (tevent_loop_once(state->ev) == -1) {
3251 DEBUG(1, ("tevent_loop_once failed: %s\n",
3252 strerror(errno)));
3253 break;
3256 TALLOC_FREE(state);
3259 static void smbd_echo_got_packet(struct tevent_req *req)
3261 struct smbd_echo_state *state = tevent_req_callback_data(
3262 req, struct smbd_echo_state);
3263 NTSTATUS status;
3264 char *buf = NULL;
3265 size_t buflen = 0;
3266 uint32_t seqnum = 0;
3267 bool reply;
3269 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3270 TALLOC_FREE(req);
3271 if (!NT_STATUS_IS_OK(status)) {
3272 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3273 nt_errstr(status)));
3274 exit(1);
3277 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3278 if (!reply) {
3279 size_t num_pending;
3280 struct iovec *tmp;
3281 struct iovec *iov;
3283 num_pending = talloc_array_length(state->pending);
3284 tmp = talloc_realloc(state, state->pending, struct iovec,
3285 num_pending+1);
3286 if (tmp == NULL) {
3287 DEBUG(1, ("talloc_realloc failed\n"));
3288 exit(1);
3290 state->pending = tmp;
3292 if (buflen >= smb_size) {
3294 * place the seqnum in the packet so that the main process
3295 * can reply with signing
3297 SIVAL(buf, smb_ss_field, seqnum);
3298 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3301 iov = &state->pending[num_pending];
3302 iov->iov_base = talloc_move(state->pending, &buf);
3303 iov->iov_len = buflen;
3305 DEBUG(10,("echo_handler[%d]: forward to main\n",
3306 (int)getpid()));
3307 smbd_echo_activate_writer(state);
3310 req = smbd_echo_read_send(state, state->ev, state->xconn);
3311 if (req == NULL) {
3312 DEBUG(1, ("smbd_echo_read_send failed\n"));
3313 exit(1);
3315 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3320 * Handle SMBecho requests in a forked child process
3322 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3324 int listener_pipe[2];
3325 int res;
3326 pid_t child;
3327 bool use_mutex = false;
3329 res = pipe(listener_pipe);
3330 if (res == -1) {
3331 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3332 return false;
3335 #ifdef HAVE_ROBUST_MUTEXES
3336 use_mutex = tdb_runtime_check_for_robust_mutexes();
3338 if (use_mutex) {
3339 pthread_mutexattr_t a;
3341 xconn->smb1.echo_handler.socket_mutex =
3342 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3343 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3344 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3345 strerror(errno)));
3346 goto fail;
3349 res = pthread_mutexattr_init(&a);
3350 if (res != 0) {
3351 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3352 strerror(res)));
3353 goto fail;
3355 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3356 if (res != 0) {
3357 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3358 strerror(res)));
3359 pthread_mutexattr_destroy(&a);
3360 goto fail;
3362 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3363 if (res != 0) {
3364 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3365 strerror(res)));
3366 pthread_mutexattr_destroy(&a);
3367 goto fail;
3369 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3370 if (res != 0) {
3371 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3372 "%s\n", strerror(res)));
3373 pthread_mutexattr_destroy(&a);
3374 goto fail;
3376 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3377 &a);
3378 pthread_mutexattr_destroy(&a);
3379 if (res != 0) {
3380 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3381 strerror(res)));
3382 goto fail;
3385 #endif
3387 if (!use_mutex) {
3388 xconn->smb1.echo_handler.socket_lock_fd =
3389 create_unlink_tmp(lp_lock_directory());
3390 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3391 DEBUG(1, ("Could not create lock fd: %s\n",
3392 strerror(errno)));
3393 goto fail;
3397 child = fork();
3398 if (child == 0) {
3399 NTSTATUS status;
3401 close(listener_pipe[0]);
3402 set_blocking(listener_pipe[1], false);
3404 status = smbd_reinit_after_fork(xconn->msg_ctx, xconn->ev_ctx,
3405 true, "smbd-echo");
3406 if (!NT_STATUS_IS_OK(status)) {
3407 DEBUG(1, ("reinit_after_fork failed: %s\n",
3408 nt_errstr(status)));
3409 exit(1);
3411 initialize_password_db(true, xconn->ev_ctx);
3412 smbd_echo_loop(xconn, listener_pipe[1]);
3413 exit(0);
3415 close(listener_pipe[1]);
3416 listener_pipe[1] = -1;
3417 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3419 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3422 * Without smb signing this is the same as the normal smbd
3423 * listener. This needs to change once signing comes in.
3425 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3426 xconn,
3427 xconn->smb1.echo_handler.trusted_fd,
3428 TEVENT_FD_READ,
3429 smbd_server_echo_handler,
3430 xconn);
3431 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3432 DEBUG(1, ("event_add_fd failed\n"));
3433 goto fail;
3436 return true;
3438 fail:
3439 if (listener_pipe[0] != -1) {
3440 close(listener_pipe[0]);
3442 if (listener_pipe[1] != -1) {
3443 close(listener_pipe[1]);
3445 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3446 close(xconn->smb1.echo_handler.socket_lock_fd);
3448 #ifdef HAVE_ROBUST_MUTEXES
3449 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3450 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3451 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3453 #endif
3454 smbd_echo_init(xconn);
3456 return false;
3459 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3461 while (user) {
3462 if (user->session_info &&
3463 (user->session_info->unix_token->uid == uid)) {
3464 return true;
3466 user = user->next;
3468 return false;
3471 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3473 while (user) {
3474 if (user->session_info != NULL) {
3475 int i;
3476 struct security_unix_token *utok;
3478 utok = user->session_info->unix_token;
3479 if (utok->gid == gid) {
3480 return true;
3482 for(i=0; i<utok->ngroups; i++) {
3483 if (utok->groups[i] == gid) {
3484 return true;
3488 user = user->next;
3490 return false;
3493 static bool sid_in_use(const struct user_struct *user,
3494 const struct dom_sid *psid)
3496 while (user) {
3497 struct security_token *tok;
3499 if (user->session_info == NULL) {
3500 continue;
3502 tok = user->session_info->security_token;
3503 if (tok == NULL) {
3505 * Not sure session_info->security_token can
3506 * ever be NULL. This check might be not
3507 * necessary.
3509 continue;
3511 if (security_token_has_sid(tok, psid)) {
3512 return true;
3514 user = user->next;
3516 return false;
3519 static bool id_in_use(const struct user_struct *user,
3520 const struct id_cache_ref *id)
3522 switch(id->type) {
3523 case UID:
3524 return uid_in_use(user, id->id.uid);
3525 case GID:
3526 return gid_in_use(user, id->id.gid);
3527 case SID:
3528 return sid_in_use(user, &id->id.sid);
3529 default:
3530 break;
3532 return false;
3535 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3536 void *private_data,
3537 uint32_t msg_type,
3538 struct server_id server_id,
3539 DATA_BLOB* data)
3541 const char *msg = (data && data->data)
3542 ? (const char *)data->data : "<NULL>";
3543 struct id_cache_ref id;
3544 struct smbd_server_connection *sconn =
3545 talloc_get_type_abort(private_data,
3546 struct smbd_server_connection);
3548 if (!id_cache_ref_parse(msg, &id)) {
3549 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3550 return;
3553 if (id_in_use(sconn->users, &id)) {
3554 exit_server_cleanly(msg);
3556 id_cache_delete_from_cache(&id);
3559 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3560 enum protocol_types protocol)
3562 NTSTATUS status;
3564 conn->protocol = protocol;
3566 if (conn->client->session_table != NULL) {
3567 return NT_STATUS_OK;
3570 if (protocol >= PROTOCOL_SMB2_02) {
3571 status = smb2srv_session_table_init(conn);
3572 if (!NT_STATUS_IS_OK(status)) {
3573 conn->protocol = PROTOCOL_NONE;
3574 return status;
3577 status = smb2srv_open_table_init(conn);
3578 if (!NT_STATUS_IS_OK(status)) {
3579 conn->protocol = PROTOCOL_NONE;
3580 return status;
3582 } else {
3583 status = smb1srv_session_table_init(conn);
3584 if (!NT_STATUS_IS_OK(status)) {
3585 conn->protocol = PROTOCOL_NONE;
3586 return status;
3589 status = smb1srv_tcon_table_init(conn);
3590 if (!NT_STATUS_IS_OK(status)) {
3591 conn->protocol = PROTOCOL_NONE;
3592 return status;
3595 status = smb1srv_open_table_init(conn);
3596 if (!NT_STATUS_IS_OK(status)) {
3597 conn->protocol = PROTOCOL_NONE;
3598 return status;
3602 set_Protocol(protocol);
3603 return NT_STATUS_OK;
3606 struct smbd_tevent_trace_state {
3607 struct tevent_context *ev;
3608 TALLOC_CTX *frame;
3609 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3612 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3613 void *private_data)
3615 struct smbd_tevent_trace_state *state =
3616 (struct smbd_tevent_trace_state *)private_data;
3618 switch (point) {
3619 case TEVENT_TRACE_BEFORE_WAIT:
3620 if (!smbprofile_dump_pending()) {
3622 * If there's no dump pending
3623 * we don't want to schedule a new 1 sec timer.
3625 * Instead we want to sleep as long as nothing happens.
3627 smbprofile_dump_setup(NULL);
3629 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3630 break;
3631 case TEVENT_TRACE_AFTER_WAIT:
3632 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3633 if (!smbprofile_dump_pending()) {
3635 * We need to flush our state after sleeping
3636 * (hopefully a long time).
3638 smbprofile_dump();
3640 * future profiling events should trigger timers
3641 * on our main event context.
3643 smbprofile_dump_setup(state->ev);
3645 break;
3646 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3647 TALLOC_FREE(state->frame);
3648 state->frame = talloc_stackframe_pool(8192);
3649 break;
3650 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3651 TALLOC_FREE(state->frame);
3652 break;
3655 errno = 0;
3659 * Create a debug string for the connection
3661 * This is allocated to talloc_tos() or a string constant
3662 * in certain corner cases. The returned string should
3663 * hence not be free'd directly but only via the talloc stack.
3665 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3667 const char *ret;
3670 * TODO: this can be improved later
3671 * maybe including the client guid or more
3673 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3674 if (ret == NULL) {
3675 return "<tsocket_address_string() failed>";
3678 return ret;
3681 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3682 struct smbXsrv_connection **_xconn)
3684 TALLOC_CTX *frame = talloc_stackframe();
3685 struct smbXsrv_connection *xconn;
3686 struct sockaddr_storage ss_srv;
3687 void *sp_srv = (void *)&ss_srv;
3688 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3689 struct sockaddr_storage ss_clnt;
3690 void *sp_clnt = (void *)&ss_clnt;
3691 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3692 socklen_t sa_socklen;
3693 struct tsocket_address *local_address = NULL;
3694 struct tsocket_address *remote_address = NULL;
3695 const char *remaddr = NULL;
3696 char *p;
3697 const char *rhost = NULL;
3698 int ret;
3699 int tmp;
3701 *_xconn = NULL;
3703 DO_PROFILE_INC(connect);
3705 xconn = talloc_zero(client, struct smbXsrv_connection);
3706 if (xconn == NULL) {
3707 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3708 TALLOC_FREE(frame);
3709 return NT_STATUS_NO_MEMORY;
3711 talloc_steal(frame, xconn);
3713 xconn->ev_ctx = client->ev_ctx;
3714 xconn->msg_ctx = client->msg_ctx;
3715 xconn->transport.sock = sock_fd;
3716 smbd_echo_init(xconn);
3717 xconn->protocol = PROTOCOL_NONE;
3719 /* Ensure child is set to blocking mode */
3720 set_blocking(sock_fd,True);
3722 set_socket_options(sock_fd, "SO_KEEPALIVE");
3723 set_socket_options(sock_fd, lp_socket_options());
3725 sa_socklen = sizeof(ss_clnt);
3726 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3727 if (ret != 0) {
3728 int saved_errno = errno;
3729 int level = (errno == ENOTCONN)?2:0;
3730 DEBUG(level,("getpeername() failed - %s\n",
3731 strerror(saved_errno)));
3732 TALLOC_FREE(frame);
3733 return map_nt_error_from_unix_common(saved_errno);
3735 ret = tsocket_address_bsd_from_sockaddr(xconn,
3736 sa_clnt, sa_socklen,
3737 &remote_address);
3738 if (ret != 0) {
3739 int saved_errno = errno;
3740 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3741 __location__, strerror(saved_errno)));
3742 TALLOC_FREE(frame);
3743 return map_nt_error_from_unix_common(saved_errno);
3746 sa_socklen = sizeof(ss_srv);
3747 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3748 if (ret != 0) {
3749 int saved_errno = errno;
3750 int level = (errno == ENOTCONN)?2:0;
3751 DEBUG(level,("getsockname() failed - %s\n",
3752 strerror(saved_errno)));
3753 TALLOC_FREE(frame);
3754 return map_nt_error_from_unix_common(saved_errno);
3756 ret = tsocket_address_bsd_from_sockaddr(xconn,
3757 sa_srv, sa_socklen,
3758 &local_address);
3759 if (ret != 0) {
3760 int saved_errno = errno;
3761 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3762 __location__, strerror(saved_errno)));
3763 TALLOC_FREE(frame);
3764 return map_nt_error_from_unix_common(saved_errno);
3767 if (tsocket_address_is_inet(remote_address, "ip")) {
3768 remaddr = tsocket_address_inet_addr_string(remote_address,
3769 talloc_tos());
3770 if (remaddr == NULL) {
3771 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3772 __location__, strerror(errno)));
3773 TALLOC_FREE(frame);
3774 return NT_STATUS_NO_MEMORY;
3776 } else {
3777 remaddr = "0.0.0.0";
3781 * Before the first packet, check the global hosts allow/ hosts deny
3782 * parameters before doing any parsing of packets passed to us by the
3783 * client. This prevents attacks on our parsing code from hosts not in
3784 * the hosts allow list.
3787 ret = get_remote_hostname(remote_address,
3788 &p, talloc_tos());
3789 if (ret < 0) {
3790 int saved_errno = errno;
3791 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3792 __location__, strerror(saved_errno)));
3793 TALLOC_FREE(frame);
3794 return map_nt_error_from_unix_common(saved_errno);
3796 rhost = p;
3797 if (strequal(rhost, "UNKNOWN")) {
3798 rhost = remaddr;
3801 xconn->local_address = local_address;
3802 xconn->remote_address = remote_address;
3803 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3804 if (xconn->remote_hostname == NULL) {
3805 return NT_STATUS_NO_MEMORY;
3808 if (!srv_init_signing(xconn)) {
3809 DEBUG(0, ("Failed to init smb_signing\n"));
3810 TALLOC_FREE(frame);
3811 return NT_STATUS_INTERNAL_ERROR;
3814 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3815 xconn->remote_hostname,
3816 remaddr)) {
3817 DEBUG( 1, ("Connection denied from %s to %s\n",
3818 tsocket_address_string(remote_address, talloc_tos()),
3819 tsocket_address_string(local_address, talloc_tos())));
3822 * We return a valid xconn
3823 * so that the caller can return an error message
3824 * to the client
3826 client->connections = xconn;
3827 xconn->client = client;
3828 talloc_steal(client, xconn);
3830 *_xconn = xconn;
3831 TALLOC_FREE(frame);
3832 return NT_STATUS_NETWORK_ACCESS_DENIED;
3835 DEBUG(10, ("Connection allowed from %s to %s\n",
3836 tsocket_address_string(remote_address, talloc_tos()),
3837 tsocket_address_string(local_address, talloc_tos())));
3839 if (lp_clustering()) {
3841 * We need to tell ctdb about our client's TCP
3842 * connection, so that for failover ctdbd can send
3843 * tickle acks, triggering a reconnection by the
3844 * client.
3846 NTSTATUS status;
3848 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3849 if (!NT_STATUS_IS_OK(status)) {
3850 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3851 nt_errstr(status)));
3855 tmp = lp_max_xmit();
3856 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3857 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3859 xconn->smb1.negprot.max_recv = tmp;
3861 xconn->smb1.sessions.done_sesssetup = false;
3862 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3864 xconn->transport.fde = tevent_add_fd(client->ev_ctx,
3865 xconn,
3866 sock_fd,
3867 TEVENT_FD_READ,
3868 smbd_server_connection_handler,
3869 xconn);
3870 if (!xconn->transport.fde) {
3871 TALLOC_FREE(frame);
3872 return NT_STATUS_NO_MEMORY;
3875 /* for now we only have one connection */
3876 DLIST_ADD_END(client->connections, xconn);
3877 xconn->client = client;
3878 talloc_steal(client, xconn);
3880 *_xconn = xconn;
3881 TALLOC_FREE(frame);
3882 return NT_STATUS_OK;
3885 /****************************************************************************
3886 Process commands from the client
3887 ****************************************************************************/
3889 void smbd_process(struct tevent_context *ev_ctx,
3890 struct messaging_context *msg_ctx,
3891 int sock_fd,
3892 bool interactive)
3894 struct smbd_tevent_trace_state trace_state = {
3895 .ev = ev_ctx,
3896 .frame = talloc_stackframe(),
3898 struct smbXsrv_client *client = NULL;
3899 struct smbd_server_connection *sconn = NULL;
3900 struct smbXsrv_connection *xconn = NULL;
3901 const char *locaddr = NULL;
3902 const char *remaddr = NULL;
3903 int ret;
3904 NTSTATUS status;
3905 struct timeval tv = timeval_current();
3906 NTTIME now = timeval_to_nttime(&tv);
3907 char *chroot_dir = NULL;
3908 int rc;
3910 status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
3911 if (!NT_STATUS_IS_OK(status)) {
3912 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
3913 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3917 * TODO: remove this...:-)
3919 global_smbXsrv_client = client;
3921 sconn = talloc_zero(client, struct smbd_server_connection);
3922 if (sconn == NULL) {
3923 exit_server("failed to create smbd_server_connection");
3926 client->sconn = sconn;
3927 sconn->client = client;
3929 sconn->ev_ctx = ev_ctx;
3930 sconn->msg_ctx = msg_ctx;
3932 ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
3933 &sconn->pool);
3934 if (ret != 0) {
3935 exit_server("pthreadpool_tevent_init() failed.");
3938 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3940 * We're not making the decision here,
3941 * we're just allowing the client
3942 * to decide between SMB1 and SMB2
3943 * with the first negprot
3944 * packet.
3946 sconn->using_smb2 = true;
3949 if (!interactive) {
3950 smbd_setup_sig_term_handler(sconn);
3951 smbd_setup_sig_hup_handler(sconn);
3954 status = smbd_add_connection(client, sock_fd, &xconn);
3955 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3957 * send a negative session response "not listening on calling
3958 * name"
3960 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3961 (void)srv_send_smb(xconn,(char *)buf, false,
3962 0, false, NULL);
3963 exit_server_cleanly("connection denied");
3964 } else if (!NT_STATUS_IS_OK(status)) {
3965 exit_server_cleanly(nt_errstr(status));
3968 sconn->local_address =
3969 tsocket_address_copy(xconn->local_address, sconn);
3970 if (sconn->local_address == NULL) {
3971 exit_server_cleanly("tsocket_address_copy() failed");
3973 sconn->remote_address =
3974 tsocket_address_copy(xconn->remote_address, sconn);
3975 if (sconn->remote_address == NULL) {
3976 exit_server_cleanly("tsocket_address_copy() failed");
3978 sconn->remote_hostname =
3979 talloc_strdup(sconn, xconn->remote_hostname);
3980 if (sconn->remote_hostname == NULL) {
3981 exit_server_cleanly("tsocket_strdup() failed");
3984 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3985 locaddr = tsocket_address_inet_addr_string(
3986 sconn->local_address,
3987 talloc_tos());
3988 if (locaddr == NULL) {
3989 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3990 __location__, strerror(errno)));
3991 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3993 } else {
3994 locaddr = "0.0.0.0";
3997 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
3998 remaddr = tsocket_address_inet_addr_string(
3999 sconn->remote_address,
4000 talloc_tos());
4001 if (remaddr == NULL) {
4002 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4003 __location__, strerror(errno)));
4004 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4006 } else {
4007 remaddr = "0.0.0.0";
4010 /* this is needed so that we get decent entries
4011 in smbstatus for port 445 connects */
4012 set_remote_machine_name(remaddr, false);
4013 reload_services(sconn, conn_snum_used, true);
4014 sub_set_socket_ids(remaddr,
4015 sconn->remote_hostname,
4016 locaddr);
4018 if (lp_preload_modules()) {
4019 smb_load_all_modules_absoute_path(lp_preload_modules());
4022 smb_perfcount_init();
4024 if (!init_account_policy()) {
4025 exit_server("Could not open account policy tdb.\n");
4028 chroot_dir = lp_root_directory(talloc_tos());
4029 if (chroot_dir[0] != '\0') {
4030 rc = chdir(chroot_dir);
4031 if (rc != 0) {
4032 DBG_ERR("Failed to chdir to %s\n", chroot_dir);
4033 exit_server("Failed to chdir()");
4036 rc = chroot(chroot_dir);
4037 if (rc != 0) {
4038 DBG_ERR("Failed to change root to %s\n", chroot_dir);
4039 exit_server("Failed to chroot()");
4041 DBG_WARNING("Changed root to %s\n", chroot_dir);
4043 TALLOC_FREE(chroot_dir);
4046 if (!file_init(sconn)) {
4047 exit_server("file_init() failed");
4050 /* Setup oplocks */
4051 if (!init_oplocks(sconn))
4052 exit_server("Failed to init oplocks");
4054 /* register our message handlers */
4055 messaging_register(sconn->msg_ctx, sconn,
4056 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4057 messaging_register(sconn->msg_ctx, sconn,
4058 MSG_SMB_CLOSE_FILE, msg_close_file);
4059 messaging_register(sconn->msg_ctx, sconn,
4060 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
4062 id_cache_register_msgs(sconn->msg_ctx);
4063 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
4064 messaging_register(sconn->msg_ctx, sconn,
4065 ID_CACHE_KILL, smbd_id_cache_kill);
4067 messaging_deregister(sconn->msg_ctx,
4068 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
4069 messaging_register(sconn->msg_ctx, sconn,
4070 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
4072 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
4073 NULL);
4074 messaging_register(sconn->msg_ctx, sconn,
4075 MSG_SMB_KILL_CLIENT_IP,
4076 msg_kill_client_ip);
4078 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
4081 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4082 * MSGs to all child processes
4084 messaging_deregister(sconn->msg_ctx,
4085 MSG_DEBUG, NULL);
4086 messaging_register(sconn->msg_ctx, NULL,
4087 MSG_DEBUG, debug_message);
4089 if ((lp_keepalive() != 0)
4090 && !(event_add_idle(ev_ctx, NULL,
4091 timeval_set(lp_keepalive(), 0),
4092 "keepalive", keepalive_fn,
4093 sconn))) {
4094 DEBUG(0, ("Could not add keepalive event\n"));
4095 exit(1);
4098 if (!(event_add_idle(ev_ctx, NULL,
4099 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4100 "deadtime", deadtime_fn, sconn))) {
4101 DEBUG(0, ("Could not add deadtime event\n"));
4102 exit(1);
4105 if (!(event_add_idle(ev_ctx, NULL,
4106 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4107 "housekeeping", housekeeping_fn, sconn))) {
4108 DEBUG(0, ("Could not add housekeeping event\n"));
4109 exit(1);
4112 smbprofile_dump_setup(ev_ctx);
4114 if (!init_dptrs(sconn)) {
4115 exit_server("init_dptrs() failed");
4118 TALLOC_FREE(trace_state.frame);
4120 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4121 &trace_state);
4123 ret = tevent_loop_wait(ev_ctx);
4124 if (ret != 0) {
4125 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4126 " exiting\n", ret, strerror(errno)));
4129 TALLOC_FREE(trace_state.frame);
4131 exit_server_cleanly(NULL);
4134 bool req_is_in_chain(const struct smb_request *req)
4136 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4138 * We're right now handling a subsequent request, so we must
4139 * be in a chain
4141 return true;
4144 if (!is_andx_req(req->cmd)) {
4145 return false;
4148 if (req->wct < 2) {
4150 * Okay, an illegal request, but definitely not chained :-)
4152 return false;
4155 return (CVAL(req->vwv+0, 0) != 0xFF);