docs: Fix typo in man smb.conf.
[Samba.git] / source3 / smbd / process.c
blob8f097ecbc00a87d450336252b9afa31362f3e8c9
1 /*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
42 #include "lib/util/sys_rw_data.h"
43 #include "serverid.h"
44 #include "system/threads.h"
46 /* Internal message queue for deferred opens. */
47 struct pending_message_list {
48 struct pending_message_list *next, *prev;
49 struct timeval request_time; /* When was this first issued? */
50 struct smbd_server_connection *sconn;
51 struct smbXsrv_connection *xconn;
52 struct tevent_timer *te;
53 struct smb_perfcount_data pcd;
54 uint32_t seqnum;
55 bool encrypted;
56 bool processed;
57 DATA_BLOB buf;
58 struct deferred_open_record *open_rec;
61 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
62 char *outbuf);
63 static struct pending_message_list *get_deferred_open_message_smb(
64 struct smbd_server_connection *sconn, uint64_t mid);
65 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
67 static void smbd_echo_init(struct smbXsrv_connection *xconn)
69 xconn->smb1.echo_handler.trusted_fd = -1;
70 xconn->smb1.echo_handler.socket_lock_fd = -1;
71 #ifdef HAVE_ROBUST_MUTEXES
72 xconn->smb1.echo_handler.socket_mutex = NULL;
73 #endif
76 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
78 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
79 return true;
82 #ifdef HAVE_ROBUST_MUTEXES
83 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
84 return true;
86 #endif
88 return false;
91 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
93 if (!smbd_echo_active(xconn)) {
94 return true;
97 xconn->smb1.echo_handler.ref_count++;
99 if (xconn->smb1.echo_handler.ref_count > 1) {
100 return true;
103 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
105 #ifdef HAVE_ROBUST_MUTEXES
106 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
107 int ret = EINTR;
109 while (ret == EINTR) {
110 ret = pthread_mutex_lock(
111 xconn->smb1.echo_handler.socket_mutex);
112 if (ret == 0) {
113 break;
116 if (ret != 0) {
117 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
118 strerror(ret)));
119 return false;
122 #endif
124 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
125 bool ok;
127 do {
128 ok = fcntl_lock(
129 xconn->smb1.echo_handler.socket_lock_fd,
130 F_SETLKW, 0, 0, F_WRLCK);
131 } while (!ok && (errno == EINTR));
133 if (!ok) {
134 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
135 return false;
139 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
141 return true;
144 void smbd_lock_socket(struct smbXsrv_connection *xconn)
146 if (!smbd_lock_socket_internal(xconn)) {
147 exit_server_cleanly("failed to lock socket");
151 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
153 if (!smbd_echo_active(xconn)) {
154 return true;
157 xconn->smb1.echo_handler.ref_count--;
159 if (xconn->smb1.echo_handler.ref_count > 0) {
160 return true;
163 #ifdef HAVE_ROBUST_MUTEXES
164 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
165 int ret = EINTR;
167 while (ret == EINTR) {
168 ret = pthread_mutex_unlock(
169 xconn->smb1.echo_handler.socket_mutex);
170 if (ret == 0) {
171 break;
174 if (ret != 0) {
175 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
176 strerror(ret)));
177 return false;
180 #endif
182 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
183 bool ok;
185 do {
186 ok = fcntl_lock(
187 xconn->smb1.echo_handler.socket_lock_fd,
188 F_SETLKW, 0, 0, F_UNLCK);
189 } while (!ok && (errno == EINTR));
191 if (!ok) {
192 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
193 return false;
197 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
199 return true;
202 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
204 if (!smbd_unlock_socket_internal(xconn)) {
205 exit_server_cleanly("failed to unlock socket");
209 /* Accessor function for smb_read_error for smbd functions. */
211 /****************************************************************************
212 Send an smb to a fd.
213 ****************************************************************************/
215 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
216 bool do_signing, uint32_t seqnum,
217 bool do_encrypt,
218 struct smb_perfcount_data *pcd)
220 size_t len = 0;
221 ssize_t ret;
222 char *buf_out = buffer;
224 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
226 * we're not supposed to do any io
228 return true;
231 smbd_lock_socket(xconn);
233 if (do_signing) {
234 /* Sign the outgoing packet if required. */
235 srv_calculate_sign_mac(xconn, buf_out, seqnum);
238 if (do_encrypt) {
239 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
240 if (!NT_STATUS_IS_OK(status)) {
241 DEBUG(0, ("send_smb: SMB encryption failed "
242 "on outgoing packet! Error %s\n",
243 nt_errstr(status) ));
244 ret = -1;
245 goto out;
249 len = smb_len_large(buf_out) + 4;
251 ret = write_data(xconn->transport.sock, buf_out, len);
252 if (ret <= 0) {
253 int saved_errno = errno;
255 * Try and give an error message saying what
256 * client failed.
258 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
259 (int)getpid(), (int)len,
260 smbXsrv_connection_dbg(xconn),
261 (int)ret, strerror(saved_errno)));
262 errno = saved_errno;
264 srv_free_enc_buffer(xconn, buf_out);
265 goto out;
268 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
269 srv_free_enc_buffer(xconn, buf_out);
270 out:
271 SMB_PERFCOUNT_END(pcd);
273 smbd_unlock_socket(xconn);
274 return (ret > 0);
277 /*******************************************************************
278 Setup the word count and byte count for a smb message.
279 ********************************************************************/
281 int srv_set_message(char *buf,
282 int num_words,
283 int num_bytes,
284 bool zero)
286 if (zero && (num_words || num_bytes)) {
287 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
289 SCVAL(buf,smb_wct,num_words);
290 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
291 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
292 return (smb_size + num_words*2 + num_bytes);
295 static bool valid_smb_header(const uint8_t *inbuf)
297 if (is_encrypted_packet(inbuf)) {
298 return true;
301 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
302 * but it just looks weird to call strncmp for this one.
304 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
307 /* Socket functions for smbd packet processing. */
309 static bool valid_packet_size(size_t len)
312 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
313 * of header. Don't print the error if this fits.... JRA.
316 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
317 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
318 (unsigned long)len));
319 return false;
321 return true;
324 static NTSTATUS read_packet_remainder(int fd, char *buffer,
325 unsigned int timeout, ssize_t len)
327 NTSTATUS status;
329 if (len <= 0) {
330 return NT_STATUS_OK;
333 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
334 if (!NT_STATUS_IS_OK(status)) {
335 char addr[INET6_ADDRSTRLEN];
336 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
337 "error = %s.\n",
338 get_peer_addr(fd, addr, sizeof(addr)),
339 nt_errstr(status)));
341 return status;
344 /****************************************************************************
345 Attempt a zerocopy writeX read. We know here that len > smb_size-4
346 ****************************************************************************/
349 * Unfortunately, earlier versions of smbclient/libsmbclient
350 * don't send this "standard" writeX header. I've fixed this
351 * for 3.2 but we'll use the old method with earlier versions.
352 * Windows and CIFSFS at least use this standard size. Not
353 * sure about MacOSX.
356 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
357 (2*14) + /* word count (including bcc) */ \
358 1 /* pad byte */)
360 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
361 const char lenbuf[4],
362 struct smbXsrv_connection *xconn,
363 int sock,
364 char **buffer,
365 unsigned int timeout,
366 size_t *p_unread,
367 size_t *len_ret)
369 /* Size of a WRITEX call (+4 byte len). */
370 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
371 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
372 ssize_t toread;
373 NTSTATUS status;
375 memcpy(writeX_header, lenbuf, 4);
377 status = read_fd_with_timeout(
378 sock, writeX_header + 4,
379 STANDARD_WRITE_AND_X_HEADER_SIZE,
380 STANDARD_WRITE_AND_X_HEADER_SIZE,
381 timeout, NULL);
383 if (!NT_STATUS_IS_OK(status)) {
384 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
385 "error = %s.\n",
386 smbXsrv_connection_dbg(xconn),
387 nt_errstr(status)));
388 return status;
392 * Ok - now try and see if this is a possible
393 * valid writeX call.
396 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
398 * If the data offset is beyond what
399 * we've read, drain the extra bytes.
401 uint16_t doff = SVAL(writeX_header,smb_vwv11);
402 ssize_t newlen;
404 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
405 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
406 if (drain_socket(sock, drain) != drain) {
407 smb_panic("receive_smb_raw_talloc_partial_read:"
408 " failed to drain pending bytes");
410 } else {
411 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
414 /* Spoof down the length and null out the bcc. */
415 set_message_bcc(writeX_header, 0);
416 newlen = smb_len(writeX_header);
418 /* Copy the header we've written. */
420 *buffer = (char *)talloc_memdup(mem_ctx,
421 writeX_header,
422 sizeof(writeX_header));
424 if (*buffer == NULL) {
425 DEBUG(0, ("Could not allocate inbuf of length %d\n",
426 (int)sizeof(writeX_header)));
427 return NT_STATUS_NO_MEMORY;
430 /* Work out the remaining bytes. */
431 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
432 *len_ret = newlen + 4;
433 return NT_STATUS_OK;
436 if (!valid_packet_size(len)) {
437 return NT_STATUS_INVALID_PARAMETER;
441 * Not a valid writeX call. Just do the standard
442 * talloc and return.
445 *buffer = talloc_array(mem_ctx, char, len+4);
447 if (*buffer == NULL) {
448 DEBUG(0, ("Could not allocate inbuf of length %d\n",
449 (int)len+4));
450 return NT_STATUS_NO_MEMORY;
453 /* Copy in what we already read. */
454 memcpy(*buffer,
455 writeX_header,
456 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
457 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
459 if(toread > 0) {
460 status = read_packet_remainder(
461 sock,
462 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
463 timeout, toread);
465 if (!NT_STATUS_IS_OK(status)) {
466 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
467 nt_errstr(status)));
468 return status;
472 *len_ret = len + 4;
473 return NT_STATUS_OK;
476 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
477 struct smbXsrv_connection *xconn,
478 int sock,
479 char **buffer, unsigned int timeout,
480 size_t *p_unread, size_t *plen)
482 char lenbuf[4];
483 size_t len;
484 int min_recv_size = lp_min_receive_file_size();
485 NTSTATUS status;
487 *p_unread = 0;
489 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
490 &len);
491 if (!NT_STATUS_IS_OK(status)) {
492 return status;
495 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
496 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
497 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
498 !srv_is_signing_active(xconn) &&
499 xconn->smb1.echo_handler.trusted_fde == NULL) {
501 return receive_smb_raw_talloc_partial_read(
502 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
503 p_unread, plen);
506 if (!valid_packet_size(len)) {
507 return NT_STATUS_INVALID_PARAMETER;
511 * The +4 here can't wrap, we've checked the length above already.
514 *buffer = talloc_array(mem_ctx, char, len+4);
516 if (*buffer == NULL) {
517 DEBUG(0, ("Could not allocate inbuf of length %d\n",
518 (int)len+4));
519 return NT_STATUS_NO_MEMORY;
522 memcpy(*buffer, lenbuf, sizeof(lenbuf));
524 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
525 if (!NT_STATUS_IS_OK(status)) {
526 return status;
529 *plen = len + 4;
530 return NT_STATUS_OK;
533 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
534 struct smbXsrv_connection *xconn,
535 int sock,
536 char **buffer, unsigned int timeout,
537 size_t *p_unread, bool *p_encrypted,
538 size_t *p_len,
539 uint32_t *seqnum,
540 bool trusted_channel)
542 size_t len = 0;
543 NTSTATUS status;
545 *p_encrypted = false;
547 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
548 p_unread, &len);
549 if (!NT_STATUS_IS_OK(status)) {
550 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
551 ("receive_smb_raw_talloc failed for client %s "
552 "read error = %s.\n",
553 smbXsrv_connection_dbg(xconn),
554 nt_errstr(status)) );
555 return status;
558 if (is_encrypted_packet((uint8_t *)*buffer)) {
559 status = srv_decrypt_buffer(xconn, *buffer);
560 if (!NT_STATUS_IS_OK(status)) {
561 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
562 "incoming packet! Error %s\n",
563 nt_errstr(status) ));
564 return status;
566 *p_encrypted = true;
569 /* Check the incoming SMB signature. */
570 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
571 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
572 "incoming packet!\n"));
573 return NT_STATUS_INVALID_NETWORK_RESPONSE;
576 *p_len = len;
577 return NT_STATUS_OK;
581 * Initialize a struct smb_request from an inbuf
584 static bool init_smb_request(struct smb_request *req,
585 struct smbd_server_connection *sconn,
586 struct smbXsrv_connection *xconn,
587 const uint8_t *inbuf,
588 size_t unread_bytes, bool encrypted,
589 uint32_t seqnum)
591 struct smbXsrv_tcon *tcon;
592 NTSTATUS status;
593 NTTIME now;
594 size_t req_size = smb_len(inbuf) + 4;
596 /* Ensure we have at least smb_size bytes. */
597 if (req_size < smb_size) {
598 DEBUG(0,("init_smb_request: invalid request size %u\n",
599 (unsigned int)req_size ));
600 return false;
603 req->request_time = timeval_current();
604 now = timeval_to_nttime(&req->request_time);
606 req->cmd = CVAL(inbuf, smb_com);
607 req->flags2 = SVAL(inbuf, smb_flg2);
608 req->smbpid = SVAL(inbuf, smb_pid);
609 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
610 req->seqnum = seqnum;
611 req->vuid = SVAL(inbuf, smb_uid);
612 req->tid = SVAL(inbuf, smb_tid);
613 req->wct = CVAL(inbuf, smb_wct);
614 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
615 req->buflen = smb_buflen(inbuf);
616 req->buf = (const uint8_t *)smb_buf_const(inbuf);
617 req->unread_bytes = unread_bytes;
618 req->encrypted = encrypted;
619 req->sconn = sconn;
620 req->xconn = xconn;
621 req->conn = NULL;
622 if (xconn != NULL) {
623 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
624 if (NT_STATUS_IS_OK(status)) {
625 req->conn = tcon->compat;
628 req->chain_fsp = NULL;
629 req->smb2req = NULL;
630 req->priv_paths = NULL;
631 req->chain = NULL;
632 req->posix_pathnames = lp_posix_pathnames();
633 smb_init_perfcount_data(&req->pcd);
635 /* Ensure we have at least wct words and 2 bytes of bcc. */
636 if (smb_size + req->wct*2 > req_size) {
637 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
638 (unsigned int)req->wct,
639 (unsigned int)req_size));
640 return false;
642 /* Ensure bcc is correct. */
643 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
644 DEBUG(0,("init_smb_request: invalid bcc number %u "
645 "(wct = %u, size %u)\n",
646 (unsigned int)req->buflen,
647 (unsigned int)req->wct,
648 (unsigned int)req_size));
649 return false;
652 req->outbuf = NULL;
653 return true;
656 static void process_smb(struct smbXsrv_connection *xconn,
657 uint8_t *inbuf, size_t nread, size_t unread_bytes,
658 uint32_t seqnum, bool encrypted,
659 struct smb_perfcount_data *deferred_pcd);
661 static void smbd_deferred_open_timer(struct tevent_context *ev,
662 struct tevent_timer *te,
663 struct timeval _tval,
664 void *private_data)
666 struct pending_message_list *msg = talloc_get_type(private_data,
667 struct pending_message_list);
668 struct smbd_server_connection *sconn = msg->sconn;
669 struct smbXsrv_connection *xconn = msg->xconn;
670 TALLOC_CTX *mem_ctx = talloc_tos();
671 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
672 uint8_t *inbuf;
674 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
675 msg->buf.length);
676 if (inbuf == NULL) {
677 exit_server("smbd_deferred_open_timer: talloc failed\n");
678 return;
681 /* We leave this message on the queue so the open code can
682 know this is a retry. */
683 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
684 (unsigned long long)mid ));
686 /* Mark the message as processed so this is not
687 * re-processed in error. */
688 msg->processed = true;
690 process_smb(xconn, inbuf,
691 msg->buf.length, 0,
692 msg->seqnum, msg->encrypted, &msg->pcd);
694 /* If it's still there and was processed, remove it. */
695 msg = get_deferred_open_message_smb(sconn, mid);
696 if (msg && msg->processed) {
697 remove_deferred_open_message_smb(xconn, mid);
701 /****************************************************************************
702 Function to push a message onto the tail of a linked list of smb messages ready
703 for processing.
704 ****************************************************************************/
706 static bool push_queued_message(struct smb_request *req,
707 struct timeval request_time,
708 struct timeval end_time,
709 struct deferred_open_record *open_rec)
711 int msg_len = smb_len(req->inbuf) + 4;
712 struct pending_message_list *msg;
714 msg = talloc_zero(NULL, struct pending_message_list);
716 if(msg == NULL) {
717 DEBUG(0,("push_message: malloc fail (1)\n"));
718 return False;
720 msg->sconn = req->sconn;
721 msg->xconn = req->xconn;
723 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
724 if(msg->buf.data == NULL) {
725 DEBUG(0,("push_message: malloc fail (2)\n"));
726 TALLOC_FREE(msg);
727 return False;
730 msg->request_time = request_time;
731 msg->seqnum = req->seqnum;
732 msg->encrypted = req->encrypted;
733 msg->processed = false;
734 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
736 if (open_rec) {
737 msg->open_rec = talloc_move(msg, &open_rec);
740 #if 0
741 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
742 msg,
743 end_time,
744 smbd_deferred_open_timer,
745 msg);
746 if (!msg->te) {
747 DEBUG(0,("push_message: event_add_timed failed\n"));
748 TALLOC_FREE(msg);
749 return false;
751 #endif
753 DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
755 DEBUG(10,("push_message: pushed message length %u on "
756 "deferred_open_queue\n", (unsigned int)msg_len));
758 return True;
761 /****************************************************************************
762 Function to delete a sharing violation open message by mid.
763 ****************************************************************************/
765 void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
766 uint64_t mid)
768 struct smbd_server_connection *sconn = xconn->client->sconn;
769 struct pending_message_list *pml;
771 if (sconn->using_smb2) {
772 remove_deferred_open_message_smb2(xconn, mid);
773 return;
776 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
777 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
778 DEBUG(10,("remove_deferred_open_message_smb: "
779 "deleting mid %llu len %u\n",
780 (unsigned long long)mid,
781 (unsigned int)pml->buf.length ));
782 DLIST_REMOVE(sconn->deferred_open_queue, pml);
783 TALLOC_FREE(pml);
784 return;
789 /****************************************************************************
790 Move a sharing violation open retry message to the front of the list and
791 schedule it for immediate processing.
792 ****************************************************************************/
794 bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
795 uint64_t mid)
797 struct smbd_server_connection *sconn = xconn->client->sconn;
798 struct pending_message_list *pml;
799 int i = 0;
801 if (sconn->using_smb2) {
802 return schedule_deferred_open_message_smb2(xconn, mid);
805 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
806 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
808 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
809 "msg_mid = %llu\n",
810 i++,
811 (unsigned long long)msg_mid ));
813 if (mid == msg_mid) {
814 struct tevent_timer *te;
816 if (pml->processed) {
817 /* A processed message should not be
818 * rescheduled. */
819 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
820 "message mid %llu was already processed\n",
821 (unsigned long long)msg_mid ));
822 continue;
825 DEBUG(10,("schedule_deferred_open_message_smb: "
826 "scheduling mid %llu\n",
827 (unsigned long long)mid ));
829 te = tevent_add_timer(pml->sconn->ev_ctx,
830 pml,
831 timeval_zero(),
832 smbd_deferred_open_timer,
833 pml);
834 if (!te) {
835 DEBUG(10,("schedule_deferred_open_message_smb: "
836 "event_add_timed() failed, "
837 "skipping mid %llu\n",
838 (unsigned long long)msg_mid ));
841 TALLOC_FREE(pml->te);
842 pml->te = te;
843 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
844 return true;
848 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
849 "find message mid %llu\n",
850 (unsigned long long)mid ));
852 return false;
855 /****************************************************************************
856 Return true if this mid is on the deferred queue and was not yet processed.
857 ****************************************************************************/
859 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
861 struct smbd_server_connection *sconn = xconn->client->sconn;
862 struct pending_message_list *pml;
864 if (sconn->using_smb2) {
865 return open_was_deferred_smb2(xconn, mid);
868 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
869 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
870 return True;
873 return False;
876 /****************************************************************************
877 Return the message queued by this mid.
878 ****************************************************************************/
880 static struct pending_message_list *get_deferred_open_message_smb(
881 struct smbd_server_connection *sconn, uint64_t mid)
883 struct pending_message_list *pml;
885 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
886 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
887 return pml;
890 return NULL;
893 /****************************************************************************
894 Get the state data queued by this mid.
895 ****************************************************************************/
897 bool get_deferred_open_message_state(struct smb_request *smbreq,
898 struct timeval *p_request_time,
899 struct deferred_open_record **open_rec)
901 struct pending_message_list *pml;
903 if (smbreq->sconn->using_smb2) {
904 return get_deferred_open_message_state_smb2(smbreq->smb2req,
905 p_request_time,
906 open_rec);
909 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
910 if (!pml) {
911 return false;
913 if (p_request_time) {
914 *p_request_time = pml->request_time;
916 if (open_rec != NULL) {
917 *open_rec = pml->open_rec;
919 return true;
922 /****************************************************************************
923 Function to push a deferred open smb message onto a linked list of local smb
924 messages ready for processing.
925 ****************************************************************************/
927 bool push_deferred_open_message_smb(struct smb_request *req,
928 struct timeval request_time,
929 struct timeval timeout,
930 struct file_id id,
931 struct deferred_open_record *open_rec)
933 struct timeval end_time;
935 if (req->smb2req) {
936 return push_deferred_open_message_smb2(req->smb2req,
937 request_time,
938 timeout,
940 open_rec);
943 if (req->unread_bytes) {
944 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
945 "unread_bytes = %u\n",
946 (unsigned int)req->unread_bytes ));
947 smb_panic("push_deferred_open_message_smb: "
948 "logic error unread_bytes != 0" );
951 end_time = timeval_sum(&request_time, &timeout);
953 DEBUG(10,("push_deferred_open_message_smb: pushing message "
954 "len %u mid %llu timeout time [%u.%06u]\n",
955 (unsigned int) smb_len(req->inbuf)+4,
956 (unsigned long long)req->mid,
957 (unsigned int)end_time.tv_sec,
958 (unsigned int)end_time.tv_usec));
960 return push_queued_message(req, request_time, end_time, open_rec);
963 static void smbd_sig_term_handler(struct tevent_context *ev,
964 struct tevent_signal *se,
965 int signum,
966 int count,
967 void *siginfo,
968 void *private_data)
970 exit_server_cleanly("termination signal");
973 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
975 struct tevent_signal *se;
977 se = tevent_add_signal(sconn->ev_ctx,
978 sconn,
979 SIGTERM, 0,
980 smbd_sig_term_handler,
981 sconn);
982 if (!se) {
983 exit_server("failed to setup SIGTERM handler");
987 static void smbd_sig_hup_handler(struct tevent_context *ev,
988 struct tevent_signal *se,
989 int signum,
990 int count,
991 void *siginfo,
992 void *private_data)
994 struct smbd_server_connection *sconn =
995 talloc_get_type_abort(private_data,
996 struct smbd_server_connection);
998 change_to_root_user();
999 DEBUG(1,("Reloading services after SIGHUP\n"));
1000 reload_services(sconn, conn_snum_used, false);
1003 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1005 struct tevent_signal *se;
1007 se = tevent_add_signal(sconn->ev_ctx,
1008 sconn,
1009 SIGHUP, 0,
1010 smbd_sig_hup_handler,
1011 sconn);
1012 if (!se) {
1013 exit_server("failed to setup SIGHUP handler");
1017 static void smbd_conf_updated(struct messaging_context *msg,
1018 void *private_data,
1019 uint32_t msg_type,
1020 struct server_id server_id,
1021 DATA_BLOB *data)
1023 struct smbd_server_connection *sconn =
1024 talloc_get_type_abort(private_data,
1025 struct smbd_server_connection);
1027 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1028 "updated. Reloading.\n"));
1029 change_to_root_user();
1030 reload_services(sconn, conn_snum_used, false);
1034 * Only allow 5 outstanding trans requests. We're allocating memory, so
1035 * prevent a DoS.
1038 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1040 int count = 0;
1041 for (; list != NULL; list = list->next) {
1043 if (list->mid == mid) {
1044 return NT_STATUS_INVALID_PARAMETER;
1047 count += 1;
1049 if (count > 5) {
1050 return NT_STATUS_INSUFFICIENT_RESOURCES;
1053 return NT_STATUS_OK;
1057 These flags determine some of the permissions required to do an operation
1059 Note that I don't set NEED_WRITE on some write operations because they
1060 are used by some brain-dead clients when printing, and I don't want to
1061 force write permissions on print services.
1063 #define AS_USER (1<<0)
1064 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1065 #define TIME_INIT (1<<2)
1066 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1067 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1068 #define DO_CHDIR (1<<6)
1071 define a list of possible SMB messages and their corresponding
1072 functions. Any message that has a NULL function is unimplemented -
1073 please feel free to contribute implementations!
1075 static const struct smb_message_struct {
1076 const char *name;
1077 void (*fn)(struct smb_request *req);
1078 int flags;
1079 } smb_messages[256] = {
1081 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1082 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1083 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1084 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1085 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1086 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1087 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1088 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1089 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1090 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1091 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1092 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1093 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1094 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1095 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1096 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1097 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1098 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1099 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1100 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1101 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1102 /* 0x15 */ { NULL, NULL, 0 },
1103 /* 0x16 */ { NULL, NULL, 0 },
1104 /* 0x17 */ { NULL, NULL, 0 },
1105 /* 0x18 */ { NULL, NULL, 0 },
1106 /* 0x19 */ { NULL, NULL, 0 },
1107 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1108 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1109 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1110 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1111 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1112 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1113 /* 0x20 */ { "SMBwritec", NULL,0},
1114 /* 0x21 */ { NULL, NULL, 0 },
1115 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1116 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1117 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1118 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1119 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1120 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1121 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1122 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1123 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1124 /* 0x2b */ { "SMBecho",reply_echo,0},
1125 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1126 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1127 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1128 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1129 /* 0x30 */ { NULL, NULL, 0 },
1130 /* 0x31 */ { NULL, NULL, 0 },
1131 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1132 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1133 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1134 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1135 /* 0x36 */ { NULL, NULL, 0 },
1136 /* 0x37 */ { NULL, NULL, 0 },
1137 /* 0x38 */ { NULL, NULL, 0 },
1138 /* 0x39 */ { NULL, NULL, 0 },
1139 /* 0x3a */ { NULL, NULL, 0 },
1140 /* 0x3b */ { NULL, NULL, 0 },
1141 /* 0x3c */ { NULL, NULL, 0 },
1142 /* 0x3d */ { NULL, NULL, 0 },
1143 /* 0x3e */ { NULL, NULL, 0 },
1144 /* 0x3f */ { NULL, NULL, 0 },
1145 /* 0x40 */ { NULL, NULL, 0 },
1146 /* 0x41 */ { NULL, NULL, 0 },
1147 /* 0x42 */ { NULL, NULL, 0 },
1148 /* 0x43 */ { NULL, NULL, 0 },
1149 /* 0x44 */ { NULL, NULL, 0 },
1150 /* 0x45 */ { NULL, NULL, 0 },
1151 /* 0x46 */ { NULL, NULL, 0 },
1152 /* 0x47 */ { NULL, NULL, 0 },
1153 /* 0x48 */ { NULL, NULL, 0 },
1154 /* 0x49 */ { NULL, NULL, 0 },
1155 /* 0x4a */ { NULL, NULL, 0 },
1156 /* 0x4b */ { NULL, NULL, 0 },
1157 /* 0x4c */ { NULL, NULL, 0 },
1158 /* 0x4d */ { NULL, NULL, 0 },
1159 /* 0x4e */ { NULL, NULL, 0 },
1160 /* 0x4f */ { NULL, NULL, 0 },
1161 /* 0x50 */ { NULL, NULL, 0 },
1162 /* 0x51 */ { NULL, NULL, 0 },
1163 /* 0x52 */ { NULL, NULL, 0 },
1164 /* 0x53 */ { NULL, NULL, 0 },
1165 /* 0x54 */ { NULL, NULL, 0 },
1166 /* 0x55 */ { NULL, NULL, 0 },
1167 /* 0x56 */ { NULL, NULL, 0 },
1168 /* 0x57 */ { NULL, NULL, 0 },
1169 /* 0x58 */ { NULL, NULL, 0 },
1170 /* 0x59 */ { NULL, NULL, 0 },
1171 /* 0x5a */ { NULL, NULL, 0 },
1172 /* 0x5b */ { NULL, NULL, 0 },
1173 /* 0x5c */ { NULL, NULL, 0 },
1174 /* 0x5d */ { NULL, NULL, 0 },
1175 /* 0x5e */ { NULL, NULL, 0 },
1176 /* 0x5f */ { NULL, NULL, 0 },
1177 /* 0x60 */ { NULL, NULL, 0 },
1178 /* 0x61 */ { NULL, NULL, 0 },
1179 /* 0x62 */ { NULL, NULL, 0 },
1180 /* 0x63 */ { NULL, NULL, 0 },
1181 /* 0x64 */ { NULL, NULL, 0 },
1182 /* 0x65 */ { NULL, NULL, 0 },
1183 /* 0x66 */ { NULL, NULL, 0 },
1184 /* 0x67 */ { NULL, NULL, 0 },
1185 /* 0x68 */ { NULL, NULL, 0 },
1186 /* 0x69 */ { NULL, NULL, 0 },
1187 /* 0x6a */ { NULL, NULL, 0 },
1188 /* 0x6b */ { NULL, NULL, 0 },
1189 /* 0x6c */ { NULL, NULL, 0 },
1190 /* 0x6d */ { NULL, NULL, 0 },
1191 /* 0x6e */ { NULL, NULL, 0 },
1192 /* 0x6f */ { NULL, NULL, 0 },
1193 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1194 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1195 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1196 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1197 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1198 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1199 /* 0x76 */ { NULL, NULL, 0 },
1200 /* 0x77 */ { NULL, NULL, 0 },
1201 /* 0x78 */ { NULL, NULL, 0 },
1202 /* 0x79 */ { NULL, NULL, 0 },
1203 /* 0x7a */ { NULL, NULL, 0 },
1204 /* 0x7b */ { NULL, NULL, 0 },
1205 /* 0x7c */ { NULL, NULL, 0 },
1206 /* 0x7d */ { NULL, NULL, 0 },
1207 /* 0x7e */ { NULL, NULL, 0 },
1208 /* 0x7f */ { NULL, NULL, 0 },
1209 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1210 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1211 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1212 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1213 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1214 /* 0x85 */ { NULL, NULL, 0 },
1215 /* 0x86 */ { NULL, NULL, 0 },
1216 /* 0x87 */ { NULL, NULL, 0 },
1217 /* 0x88 */ { NULL, NULL, 0 },
1218 /* 0x89 */ { NULL, NULL, 0 },
1219 /* 0x8a */ { NULL, NULL, 0 },
1220 /* 0x8b */ { NULL, NULL, 0 },
1221 /* 0x8c */ { NULL, NULL, 0 },
1222 /* 0x8d */ { NULL, NULL, 0 },
1223 /* 0x8e */ { NULL, NULL, 0 },
1224 /* 0x8f */ { NULL, NULL, 0 },
1225 /* 0x90 */ { NULL, NULL, 0 },
1226 /* 0x91 */ { NULL, NULL, 0 },
1227 /* 0x92 */ { NULL, NULL, 0 },
1228 /* 0x93 */ { NULL, NULL, 0 },
1229 /* 0x94 */ { NULL, NULL, 0 },
1230 /* 0x95 */ { NULL, NULL, 0 },
1231 /* 0x96 */ { NULL, NULL, 0 },
1232 /* 0x97 */ { NULL, NULL, 0 },
1233 /* 0x98 */ { NULL, NULL, 0 },
1234 /* 0x99 */ { NULL, NULL, 0 },
1235 /* 0x9a */ { NULL, NULL, 0 },
1236 /* 0x9b */ { NULL, NULL, 0 },
1237 /* 0x9c */ { NULL, NULL, 0 },
1238 /* 0x9d */ { NULL, NULL, 0 },
1239 /* 0x9e */ { NULL, NULL, 0 },
1240 /* 0x9f */ { NULL, NULL, 0 },
1241 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1242 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1243 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1244 /* 0xa3 */ { NULL, NULL, 0 },
1245 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1246 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1247 /* 0xa6 */ { NULL, NULL, 0 },
1248 /* 0xa7 */ { NULL, NULL, 0 },
1249 /* 0xa8 */ { NULL, NULL, 0 },
1250 /* 0xa9 */ { NULL, NULL, 0 },
1251 /* 0xaa */ { NULL, NULL, 0 },
1252 /* 0xab */ { NULL, NULL, 0 },
1253 /* 0xac */ { NULL, NULL, 0 },
1254 /* 0xad */ { NULL, NULL, 0 },
1255 /* 0xae */ { NULL, NULL, 0 },
1256 /* 0xaf */ { NULL, NULL, 0 },
1257 /* 0xb0 */ { NULL, NULL, 0 },
1258 /* 0xb1 */ { NULL, NULL, 0 },
1259 /* 0xb2 */ { NULL, NULL, 0 },
1260 /* 0xb3 */ { NULL, NULL, 0 },
1261 /* 0xb4 */ { NULL, NULL, 0 },
1262 /* 0xb5 */ { NULL, NULL, 0 },
1263 /* 0xb6 */ { NULL, NULL, 0 },
1264 /* 0xb7 */ { NULL, NULL, 0 },
1265 /* 0xb8 */ { NULL, NULL, 0 },
1266 /* 0xb9 */ { NULL, NULL, 0 },
1267 /* 0xba */ { NULL, NULL, 0 },
1268 /* 0xbb */ { NULL, NULL, 0 },
1269 /* 0xbc */ { NULL, NULL, 0 },
1270 /* 0xbd */ { NULL, NULL, 0 },
1271 /* 0xbe */ { NULL, NULL, 0 },
1272 /* 0xbf */ { NULL, NULL, 0 },
1273 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1274 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1275 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1276 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1277 /* 0xc4 */ { NULL, NULL, 0 },
1278 /* 0xc5 */ { NULL, NULL, 0 },
1279 /* 0xc6 */ { NULL, NULL, 0 },
1280 /* 0xc7 */ { NULL, NULL, 0 },
1281 /* 0xc8 */ { NULL, NULL, 0 },
1282 /* 0xc9 */ { NULL, NULL, 0 },
1283 /* 0xca */ { NULL, NULL, 0 },
1284 /* 0xcb */ { NULL, NULL, 0 },
1285 /* 0xcc */ { NULL, NULL, 0 },
1286 /* 0xcd */ { NULL, NULL, 0 },
1287 /* 0xce */ { NULL, NULL, 0 },
1288 /* 0xcf */ { NULL, NULL, 0 },
1289 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1290 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1291 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1292 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1293 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1294 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1295 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1296 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1297 /* 0xd8 */ { NULL, NULL, 0 },
1298 /* 0xd9 */ { NULL, NULL, 0 },
1299 /* 0xda */ { NULL, NULL, 0 },
1300 /* 0xdb */ { NULL, NULL, 0 },
1301 /* 0xdc */ { NULL, NULL, 0 },
1302 /* 0xdd */ { NULL, NULL, 0 },
1303 /* 0xde */ { NULL, NULL, 0 },
1304 /* 0xdf */ { NULL, NULL, 0 },
1305 /* 0xe0 */ { NULL, NULL, 0 },
1306 /* 0xe1 */ { NULL, NULL, 0 },
1307 /* 0xe2 */ { NULL, NULL, 0 },
1308 /* 0xe3 */ { NULL, NULL, 0 },
1309 /* 0xe4 */ { NULL, NULL, 0 },
1310 /* 0xe5 */ { NULL, NULL, 0 },
1311 /* 0xe6 */ { NULL, NULL, 0 },
1312 /* 0xe7 */ { NULL, NULL, 0 },
1313 /* 0xe8 */ { NULL, NULL, 0 },
1314 /* 0xe9 */ { NULL, NULL, 0 },
1315 /* 0xea */ { NULL, NULL, 0 },
1316 /* 0xeb */ { NULL, NULL, 0 },
1317 /* 0xec */ { NULL, NULL, 0 },
1318 /* 0xed */ { NULL, NULL, 0 },
1319 /* 0xee */ { NULL, NULL, 0 },
1320 /* 0xef */ { NULL, NULL, 0 },
1321 /* 0xf0 */ { NULL, NULL, 0 },
1322 /* 0xf1 */ { NULL, NULL, 0 },
1323 /* 0xf2 */ { NULL, NULL, 0 },
1324 /* 0xf3 */ { NULL, NULL, 0 },
1325 /* 0xf4 */ { NULL, NULL, 0 },
1326 /* 0xf5 */ { NULL, NULL, 0 },
1327 /* 0xf6 */ { NULL, NULL, 0 },
1328 /* 0xf7 */ { NULL, NULL, 0 },
1329 /* 0xf8 */ { NULL, NULL, 0 },
1330 /* 0xf9 */ { NULL, NULL, 0 },
1331 /* 0xfa */ { NULL, NULL, 0 },
1332 /* 0xfb */ { NULL, NULL, 0 },
1333 /* 0xfc */ { NULL, NULL, 0 },
1334 /* 0xfd */ { NULL, NULL, 0 },
1335 /* 0xfe */ { NULL, NULL, 0 },
1336 /* 0xff */ { NULL, NULL, 0 }
1340 /*******************************************************************
1341 allocate and initialize a reply packet
1342 ********************************************************************/
1344 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1345 const uint8_t *inbuf, char **outbuf,
1346 uint8_t num_words, uint32_t num_bytes)
1348 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1351 * Protect against integer wrap.
1352 * The SMB layer reply can be up to 0xFFFFFF bytes.
1354 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1355 char *msg;
1356 if (asprintf(&msg, "num_bytes too large: %u",
1357 (unsigned)num_bytes) == -1) {
1358 msg = discard_const_p(char, "num_bytes too large");
1360 smb_panic(msg);
1364 * Here we include the NBT header for now.
1366 *outbuf = talloc_array(mem_ctx, char,
1367 NBT_HDR_SIZE + smb_len);
1368 if (*outbuf == NULL) {
1369 return false;
1372 construct_reply_common(req->cmd, inbuf, *outbuf);
1373 srv_set_message(*outbuf, num_words, num_bytes, false);
1375 * Zero out the word area, the caller has to take care of the bcc area
1376 * himself
1378 if (num_words != 0) {
1379 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1382 return true;
1385 void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1387 char *outbuf;
1388 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1389 num_bytes)) {
1390 smb_panic("could not allocate output buffer\n");
1392 req->outbuf = (uint8_t *)outbuf;
1396 /*******************************************************************
1397 Dump a packet to a file.
1398 ********************************************************************/
1400 static void smb_dump(const char *name, int type, const char *data)
1402 size_t len;
1403 int fd, i;
1404 char *fname = NULL;
1405 if (DEBUGLEVEL < 50) {
1406 return;
1409 len = smb_len_tcp(data)+4;
1410 for (i=1;i<100;i++) {
1411 fname = talloc_asprintf(talloc_tos(),
1412 "/tmp/%s.%d.%s",
1413 name,
1415 type ? "req" : "resp");
1416 if (fname == NULL) {
1417 return;
1419 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1420 if (fd != -1 || errno != EEXIST) break;
1421 TALLOC_FREE(fname);
1423 if (fd != -1) {
1424 ssize_t ret = write(fd, data, len);
1425 if (ret != len)
1426 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1427 close(fd);
1428 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1430 TALLOC_FREE(fname);
1433 static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
1434 struct smb_request *req,
1435 uint8_t type,
1436 bool *update_session_globalp,
1437 bool *update_tcon_globalp)
1439 connection_struct *conn = req->conn;
1440 struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
1441 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
1442 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1443 bool update_session = false;
1444 bool update_tcon = false;
1446 if (req->encrypted) {
1447 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
1450 if (srv_is_signing_active(req->xconn)) {
1451 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
1452 } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
1454 * echo can be unsigned. Sesssion setup except final
1455 * session setup response too
1457 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1460 update_session |= smbXsrv_set_crypto_flag(
1461 &session->global->encryption_flags, encrypt_flag);
1462 update_session |= smbXsrv_set_crypto_flag(
1463 &session->global->signing_flags, sign_flag);
1465 if (tcon) {
1466 update_tcon |= smbXsrv_set_crypto_flag(
1467 &tcon->global->encryption_flags, encrypt_flag);
1468 update_tcon |= smbXsrv_set_crypto_flag(
1469 &tcon->global->signing_flags, sign_flag);
1472 if (update_session) {
1473 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1476 *update_session_globalp = update_session;
1477 *update_tcon_globalp = update_tcon;
1478 return;
1481 /****************************************************************************
1482 Prepare everything for calling the actual request function, and potentially
1483 call the request function via the "new" interface.
1485 Return False if the "legacy" function needs to be called, everything is
1486 prepared.
1488 Return True if we're done.
1490 I know this API sucks, but it is the one with the least code change I could
1491 find.
1492 ****************************************************************************/
1494 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1496 int flags;
1497 uint64_t session_tag;
1498 connection_struct *conn = NULL;
1499 struct smbXsrv_connection *xconn = req->xconn;
1500 NTTIME now = timeval_to_nttime(&req->request_time);
1501 struct smbXsrv_session *session = NULL;
1502 NTSTATUS status;
1504 errno = 0;
1506 if (!xconn->smb1.negprot.done) {
1507 switch (type) {
1509 * Without a negprot the request must
1510 * either be a negprot, or one of the
1511 * evil old SMB mailslot messaging types.
1513 case SMBnegprot:
1514 case SMBsendstrt:
1515 case SMBsendend:
1516 case SMBsendtxt:
1517 break;
1518 default:
1519 exit_server_cleanly("The first request "
1520 "should be a negprot");
1524 if (smb_messages[type].fn == NULL) {
1525 DEBUG(0,("Unknown message type %d!\n",type));
1526 smb_dump("Unknown", 1, (const char *)req->inbuf);
1527 reply_unknown_new(req, type);
1528 return NULL;
1531 flags = smb_messages[type].flags;
1533 /* In share mode security we must ignore the vuid. */
1534 session_tag = req->vuid;
1535 conn = req->conn;
1537 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1538 (int)getpid(), (unsigned long)conn));
1540 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1542 /* Ensure this value is replaced in the incoming packet. */
1543 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1546 * Ensure the correct username is in current_user_info. This is a
1547 * really ugly bugfix for problems with multiple session_setup_and_X's
1548 * being done and allowing %U and %G substitutions to work correctly.
1549 * There is a reason this code is done here, don't move it unless you
1550 * know what you're doing... :-).
1551 * JRA.
1555 * lookup an existing session
1557 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1558 * here, the main check is still in change_to_user()
1560 status = smb1srv_session_lookup(xconn,
1561 session_tag,
1562 now,
1563 &session);
1564 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1565 switch (type) {
1566 case SMBsesssetupX:
1567 status = NT_STATUS_OK;
1568 break;
1569 default:
1570 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1571 (unsigned long long)session_tag,
1572 (unsigned long long)req->mid));
1573 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1574 return conn;
1578 if (session_tag != xconn->client->last_session_id) {
1579 struct user_struct *vuser = NULL;
1581 xconn->client->last_session_id = session_tag;
1582 if (session) {
1583 vuser = session->compat;
1585 if (vuser) {
1586 set_current_user_info(
1587 vuser->session_info->unix_info->sanitized_username,
1588 vuser->session_info->unix_info->unix_name,
1589 vuser->session_info->info->domain_name);
1593 /* Does this call need to be run as the connected user? */
1594 if (flags & AS_USER) {
1596 /* Does this call need a valid tree connection? */
1597 if (!conn) {
1599 * Amazingly, the error code depends on the command
1600 * (from Samba4).
1602 if (type == SMBntcreateX) {
1603 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1604 } else {
1605 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1607 return NULL;
1610 if (!change_to_user(conn,session_tag)) {
1611 DEBUG(0, ("Error: Could not change to user. Removing "
1612 "deferred open, mid=%llu.\n",
1613 (unsigned long long)req->mid));
1614 reply_force_doserror(req, ERRSRV, ERRbaduid);
1615 return conn;
1618 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1620 /* Does it need write permission? */
1621 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1622 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1623 return conn;
1626 /* IPC services are limited */
1627 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1628 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1629 return conn;
1631 } else {
1632 /* This call needs to be run as root */
1633 change_to_root_user();
1636 /* load service specific parameters */
1637 if (conn) {
1638 if (req->encrypted) {
1639 conn->encrypted_tid = true;
1640 /* encrypted required from now on. */
1641 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1642 } else if (ENCRYPTION_REQUIRED(conn)) {
1643 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1644 DEBUG(1,("service[%s] requires encryption"
1645 "%s ACCESS_DENIED. mid=%llu\n",
1646 lp_servicename(talloc_tos(), SNUM(conn)),
1647 smb_fn_name(type),
1648 (unsigned long long)req->mid));
1649 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1650 return conn;
1654 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1655 (flags & (AS_USER|DO_CHDIR)
1656 ?True:False))) {
1657 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1658 return conn;
1660 conn->num_smb_operations++;
1664 * Does this protocol need to be run as guest? (Only archane
1665 * messenger service requests have this...)
1667 if (flags & AS_GUEST) {
1668 char *raddr;
1669 bool ok;
1671 if (!change_to_guest()) {
1672 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1673 return conn;
1676 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1677 talloc_tos());
1678 if (raddr == NULL) {
1679 reply_nterror(req, NT_STATUS_NO_MEMORY);
1680 return conn;
1684 * Haven't we checked this in smbd_process already???
1687 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1688 xconn->remote_hostname, raddr);
1689 TALLOC_FREE(raddr);
1691 if (!ok) {
1692 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1693 return conn;
1698 * Update encryption and signing state tracking flags that are
1699 * used by smbstatus to display signing and encryption status.
1701 if (session != NULL) {
1702 bool update_session_global = false;
1703 bool update_tcon_global = false;
1705 smb1srv_update_crypto_flags(session, req, type,
1706 &update_session_global,
1707 &update_tcon_global);
1709 if (update_session_global) {
1710 status = smbXsrv_session_update(session);
1711 if (!NT_STATUS_IS_OK(status)) {
1712 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1713 return conn;
1717 if (update_tcon_global) {
1718 status = smbXsrv_tcon_update(req->conn->tcon);
1719 if (!NT_STATUS_IS_OK(status)) {
1720 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1721 return conn;
1726 smb_messages[type].fn(req);
1727 return req->conn;
1730 /****************************************************************************
1731 Construct a reply to the incoming packet.
1732 ****************************************************************************/
1734 static void construct_reply(struct smbXsrv_connection *xconn,
1735 char *inbuf, int size, size_t unread_bytes,
1736 uint32_t seqnum, bool encrypted,
1737 struct smb_perfcount_data *deferred_pcd)
1739 struct smbd_server_connection *sconn = xconn->client->sconn;
1740 struct smb_request *req;
1742 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1743 smb_panic("could not allocate smb_request");
1746 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1747 encrypted, seqnum)) {
1748 exit_server_cleanly("Invalid SMB request");
1751 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1753 /* we popped this message off the queue - keep original perf data */
1754 if (deferred_pcd)
1755 req->pcd = *deferred_pcd;
1756 else {
1757 SMB_PERFCOUNT_START(&req->pcd);
1758 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1759 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1762 req->conn = switch_message(req->cmd, req);
1764 if (req->outbuf == NULL) {
1766 * Request has suspended itself, will come
1767 * back here.
1769 return;
1771 if (CVAL(req->outbuf,0) == 0) {
1772 show_msg((char *)req->outbuf);
1774 smb_request_done(req);
1777 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1778 char *inbuf, int size, uint32_t seqnum,
1779 bool encrypted,
1780 struct smb_perfcount_data *deferred_pcd)
1782 struct smb_request **reqs = NULL;
1783 struct smb_request *req;
1784 unsigned num_reqs;
1785 bool ok;
1787 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, xconn, encrypted,
1788 seqnum, &reqs, &num_reqs);
1789 if (!ok) {
1790 char errbuf[smb_size];
1791 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1792 __LINE__, __FILE__);
1793 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1794 NULL)) {
1795 exit_server_cleanly("construct_reply_chain: "
1796 "srv_send_smb failed.");
1798 return;
1801 req = reqs[0];
1802 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1804 req->conn = switch_message(req->cmd, req);
1806 if (req->outbuf == NULL) {
1808 * Request has suspended itself, will come
1809 * back here.
1811 return;
1813 smb_request_done(req);
1817 * To be called from an async SMB handler that is potentially chained
1818 * when it is finished for shipping.
1821 void smb_request_done(struct smb_request *req)
1823 struct smb_request **reqs = NULL;
1824 struct smb_request *first_req;
1825 size_t i, num_reqs, next_index;
1826 NTSTATUS status;
1828 if (req->chain == NULL) {
1829 first_req = req;
1830 goto shipit;
1833 reqs = req->chain;
1834 num_reqs = talloc_array_length(reqs);
1836 for (i=0; i<num_reqs; i++) {
1837 if (reqs[i] == req) {
1838 break;
1841 if (i == num_reqs) {
1843 * Invalid chain, should not happen
1845 status = NT_STATUS_INTERNAL_ERROR;
1846 goto error;
1848 next_index = i+1;
1850 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1851 struct smb_request *next = reqs[next_index];
1852 struct smbXsrv_tcon *tcon;
1853 NTTIME now = timeval_to_nttime(&req->request_time);
1855 next->vuid = SVAL(req->outbuf, smb_uid);
1856 next->tid = SVAL(req->outbuf, smb_tid);
1857 status = smb1srv_tcon_lookup(req->xconn, req->tid,
1858 now, &tcon);
1859 if (NT_STATUS_IS_OK(status)) {
1860 req->conn = tcon->compat;
1861 } else {
1862 req->conn = NULL;
1864 next->chain_fsp = req->chain_fsp;
1865 next->inbuf = req->inbuf;
1867 req = next;
1868 req->conn = switch_message(req->cmd, req);
1870 if (req->outbuf == NULL) {
1872 * Request has suspended itself, will come
1873 * back here.
1875 return;
1877 next_index += 1;
1880 first_req = reqs[0];
1882 for (i=1; i<next_index; i++) {
1883 bool ok;
1885 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1886 if (!ok) {
1887 status = NT_STATUS_INTERNAL_ERROR;
1888 goto error;
1892 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1893 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1896 * This scary statement intends to set the
1897 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1898 * to the value last_req->outbuf carries
1900 SSVAL(first_req->outbuf, smb_flg2,
1901 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1902 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1905 * Transfer the error codes from the subrequest to the main one
1907 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1908 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1910 _smb_setlen_large(
1911 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1913 shipit:
1914 if (!srv_send_smb(first_req->xconn,
1915 (char *)first_req->outbuf,
1916 true, first_req->seqnum+1,
1917 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1918 &first_req->pcd)) {
1919 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1920 "failed.");
1922 TALLOC_FREE(req); /* non-chained case */
1923 TALLOC_FREE(reqs); /* chained case */
1924 return;
1926 error:
1928 char errbuf[smb_size];
1929 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1930 if (!srv_send_smb(req->xconn, errbuf, true,
1931 req->seqnum+1, req->encrypted,
1932 NULL)) {
1933 exit_server_cleanly("construct_reply_chain: "
1934 "srv_send_smb failed.");
1937 TALLOC_FREE(req); /* non-chained case */
1938 TALLOC_FREE(reqs); /* chained case */
1941 /****************************************************************************
1942 Process an smb from the client
1943 ****************************************************************************/
1944 static void process_smb(struct smbXsrv_connection *xconn,
1945 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1946 uint32_t seqnum, bool encrypted,
1947 struct smb_perfcount_data *deferred_pcd)
1949 struct smbd_server_connection *sconn = xconn->client->sconn;
1950 int msg_type = CVAL(inbuf,0);
1952 DO_PROFILE_INC(request);
1954 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1955 smb_len(inbuf) ) );
1956 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1957 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1959 if (msg_type != NBSSmessage) {
1961 * NetBIOS session request, keepalive, etc.
1963 reply_special(xconn, (char *)inbuf, nread);
1964 goto done;
1967 if (sconn->using_smb2) {
1968 /* At this point we're not really using smb2,
1969 * we make the decision here.. */
1970 if (smbd_is_smb2_header(inbuf, nread)) {
1971 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1972 size_t pdulen = nread - NBT_HDR_SIZE;
1973 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1974 return;
1975 } else if (nread >= smb_size && valid_smb_header(inbuf)
1976 && CVAL(inbuf, smb_com) != 0x72) {
1977 /* This is a non-negprot SMB1 packet.
1978 Disable SMB2 from now on. */
1979 sconn->using_smb2 = false;
1983 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1984 * so subtract 4 from it. */
1985 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1986 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1987 smb_len(inbuf)));
1989 /* special magic for immediate exit */
1990 if ((nread == 9) &&
1991 (IVAL(inbuf, 4) == 0x74697865) &&
1992 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1993 uint8_t exitcode = CVAL(inbuf, 8);
1994 DEBUG(1, ("Exiting immediately with code %d\n",
1995 (int)exitcode));
1996 exit(exitcode);
1999 exit_server_cleanly("Non-SMB packet");
2002 show_msg((char *)inbuf);
2004 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
2005 construct_reply_chain(xconn, (char *)inbuf, nread,
2006 seqnum, encrypted, deferred_pcd);
2007 } else {
2008 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
2009 seqnum, encrypted, deferred_pcd);
2012 sconn->trans_num++;
2014 done:
2015 sconn->num_requests++;
2017 /* The timeout_processing function isn't run nearly
2018 often enough to implement 'max log size' without
2019 overrunning the size of the file by many megabytes.
2020 This is especially true if we are running at debug
2021 level 10. Checking every 50 SMBs is a nice
2022 tradeoff of performance vs log file size overrun. */
2024 if ((sconn->num_requests % 50) == 0 &&
2025 need_to_check_log_size()) {
2026 change_to_root_user();
2027 check_log_size();
2031 /****************************************************************************
2032 Return a string containing the function name of a SMB command.
2033 ****************************************************************************/
2035 const char *smb_fn_name(int type)
2037 const char *unknown_name = "SMBunknown";
2039 if (smb_messages[type].name == NULL)
2040 return(unknown_name);
2042 return(smb_messages[type].name);
2045 /****************************************************************************
2046 Helper functions for contruct_reply.
2047 ****************************************************************************/
2049 void add_to_common_flags2(uint32_t v)
2051 common_flags2 |= v;
2054 void remove_from_common_flags2(uint32_t v)
2056 common_flags2 &= ~v;
2059 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
2060 char *outbuf)
2062 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
2063 uint16_t out_flags2 = common_flags2;
2065 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
2066 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
2067 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
2069 srv_set_message(outbuf,0,0,false);
2071 SCVAL(outbuf, smb_com, cmd);
2072 SIVAL(outbuf,smb_rcls,0);
2073 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
2074 SSVAL(outbuf,smb_flg2, out_flags2);
2075 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
2076 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2078 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2079 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2080 SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
2081 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2082 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2085 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2087 construct_reply_common(req->cmd, req->inbuf, outbuf);
2091 * @brief Find the smb_cmd offset of the last command pushed
2092 * @param[in] buf The buffer we're building up
2093 * @retval Where can we put our next andx cmd?
2095 * While chaining requests, the "next" request we're looking at needs to put
2096 * its SMB_Command before the data the previous request already built up added
2097 * to the chain. Find the offset to the place where we have to put our cmd.
2100 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2102 uint8_t cmd;
2103 size_t ofs;
2105 cmd = CVAL(buf, smb_com);
2107 if (!is_andx_req(cmd)) {
2108 return false;
2111 ofs = smb_vwv0;
2113 while (CVAL(buf, ofs) != 0xff) {
2115 if (!is_andx_req(CVAL(buf, ofs))) {
2116 return false;
2120 * ofs is from start of smb header, so add the 4 length
2121 * bytes. The next cmd is right after the wct field.
2123 ofs = SVAL(buf, ofs+2) + 4 + 1;
2125 if (ofs+4 >= talloc_get_size(buf)) {
2126 return false;
2130 *pofs = ofs;
2131 return true;
2135 * @brief Do the smb chaining at a buffer level
2136 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2137 * @param[in] andx_buf Buffer to be appended
2140 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2142 uint8_t smb_command = CVAL(andx_buf, smb_com);
2143 uint8_t wct = CVAL(andx_buf, smb_wct);
2144 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2145 uint32_t num_bytes = smb_buflen(andx_buf);
2146 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2148 uint8_t *outbuf;
2149 size_t old_size, new_size;
2150 size_t ofs;
2151 size_t chain_padding = 0;
2152 size_t andx_cmd_ofs;
2155 old_size = talloc_get_size(*poutbuf);
2157 if ((old_size % 4) != 0) {
2159 * Align the wct field of subsequent requests to a 4-byte
2160 * boundary
2162 chain_padding = 4 - (old_size % 4);
2166 * After the old request comes the new wct field (1 byte), the vwv's
2167 * and the num_bytes field.
2170 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2171 new_size += num_bytes;
2173 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2174 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2175 (unsigned)new_size));
2176 return false;
2179 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2180 if (outbuf == NULL) {
2181 DEBUG(0, ("talloc failed\n"));
2182 return false;
2184 *poutbuf = outbuf;
2186 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2187 DEBUG(1, ("invalid command chain\n"));
2188 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2189 return false;
2192 if (chain_padding != 0) {
2193 memset(outbuf + old_size, 0, chain_padding);
2194 old_size += chain_padding;
2197 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2198 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2200 ofs = old_size;
2203 * Push the chained request:
2205 * wct field
2208 SCVAL(outbuf, ofs, wct);
2209 ofs += 1;
2212 * vwv array
2215 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2218 * HACK ALERT
2220 * Read&X has an offset into its data buffer at
2221 * vwv[6]. reply_read_andx has no idea anymore that it's
2222 * running from within a chain, so we have to fix up the
2223 * offset here.
2225 * Although it looks disgusting at this place, I want to keep
2226 * it here. The alternative would be to push knowledge about
2227 * the andx chain down into read&x again.
2230 if (smb_command == SMBreadX) {
2231 uint8_t *bytes_addr;
2233 if (wct < 7) {
2235 * Invalid read&x response
2237 return false;
2240 bytes_addr = outbuf + ofs /* vwv start */
2241 + sizeof(uint16_t) * wct /* vwv array */
2242 + sizeof(uint16_t) /* bcc */
2243 + 1; /* padding byte */
2245 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2246 bytes_addr - outbuf - 4);
2249 ofs += sizeof(uint16_t) * wct;
2252 * bcc (byte count)
2255 SSVAL(outbuf, ofs, num_bytes);
2256 ofs += sizeof(uint16_t);
2259 * The bytes field
2262 memcpy(outbuf + ofs, bytes, num_bytes);
2264 return true;
2267 bool smb1_is_chain(const uint8_t *buf)
2269 uint8_t cmd, wct, andx_cmd;
2271 cmd = CVAL(buf, smb_com);
2272 if (!is_andx_req(cmd)) {
2273 return false;
2275 wct = CVAL(buf, smb_wct);
2276 if (wct < 2) {
2277 return false;
2279 andx_cmd = CVAL(buf, smb_vwv);
2280 return (andx_cmd != 0xFF);
2283 bool smb1_walk_chain(const uint8_t *buf,
2284 bool (*fn)(uint8_t cmd,
2285 uint8_t wct, const uint16_t *vwv,
2286 uint16_t num_bytes, const uint8_t *bytes,
2287 void *private_data),
2288 void *private_data)
2290 size_t smblen = smb_len(buf);
2291 const char *smb_buf = smb_base(buf);
2292 uint8_t cmd, chain_cmd;
2293 uint8_t wct;
2294 const uint16_t *vwv;
2295 uint16_t num_bytes;
2296 const uint8_t *bytes;
2298 cmd = CVAL(buf, smb_com);
2299 wct = CVAL(buf, smb_wct);
2300 vwv = (const uint16_t *)(buf + smb_vwv);
2301 num_bytes = smb_buflen(buf);
2302 bytes = (const uint8_t *)smb_buf_const(buf);
2304 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2305 return false;
2308 if (!is_andx_req(cmd)) {
2309 return true;
2311 if (wct < 2) {
2312 return false;
2315 chain_cmd = CVAL(vwv, 0);
2317 while (chain_cmd != 0xff) {
2318 uint32_t chain_offset; /* uint32_t to avoid overflow */
2319 size_t length_needed;
2320 ptrdiff_t vwv_offset;
2322 chain_offset = SVAL(vwv+1, 0);
2325 * Check if the client tries to fool us. The chain
2326 * offset needs to point beyond the current request in
2327 * the chain, it needs to strictly grow. Otherwise we
2328 * might be tricked into an endless loop always
2329 * processing the same request over and over again. We
2330 * used to assume that vwv and the byte buffer array
2331 * in a chain are always attached, but OS/2 the
2332 * Write&X/Read&X chain puts the Read&X vwv array
2333 * right behind the Write&X vwv chain. The Write&X bcc
2334 * array is put behind the Read&X vwv array. So now we
2335 * check whether the chain offset points strictly
2336 * behind the previous vwv array. req->buf points
2337 * right after the vwv array of the previous
2338 * request. See
2339 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2340 * more information.
2343 vwv_offset = ((const char *)vwv - smb_buf);
2344 if (chain_offset <= vwv_offset) {
2345 return false;
2349 * Next check: Make sure the chain offset does not
2350 * point beyond the overall smb request length.
2353 length_needed = chain_offset+1; /* wct */
2354 if (length_needed > smblen) {
2355 return false;
2359 * Now comes the pointer magic. Goal here is to set up
2360 * vwv and buf correctly again. The chain offset (the
2361 * former vwv[1]) points at the new wct field.
2364 wct = CVAL(smb_buf, chain_offset);
2366 if (is_andx_req(chain_cmd) && (wct < 2)) {
2367 return false;
2371 * Next consistency check: Make the new vwv array fits
2372 * in the overall smb request.
2375 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2376 if (length_needed > smblen) {
2377 return false;
2379 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2382 * Now grab the new byte buffer....
2385 num_bytes = SVAL(vwv+wct, 0);
2388 * .. and check that it fits.
2391 length_needed += num_bytes;
2392 if (length_needed > smblen) {
2393 return false;
2395 bytes = (const uint8_t *)(vwv+wct+1);
2397 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2398 return false;
2401 if (!is_andx_req(chain_cmd)) {
2402 return true;
2404 chain_cmd = CVAL(vwv, 0);
2406 return true;
2409 static bool smb1_chain_length_cb(uint8_t cmd,
2410 uint8_t wct, const uint16_t *vwv,
2411 uint16_t num_bytes, const uint8_t *bytes,
2412 void *private_data)
2414 unsigned *count = (unsigned *)private_data;
2415 *count += 1;
2416 return true;
2419 unsigned smb1_chain_length(const uint8_t *buf)
2421 unsigned count = 0;
2423 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2424 return 0;
2426 return count;
2429 struct smb1_parse_chain_state {
2430 TALLOC_CTX *mem_ctx;
2431 const uint8_t *buf;
2432 struct smbd_server_connection *sconn;
2433 struct smbXsrv_connection *xconn;
2434 bool encrypted;
2435 uint32_t seqnum;
2437 struct smb_request **reqs;
2438 unsigned num_reqs;
2441 static bool smb1_parse_chain_cb(uint8_t cmd,
2442 uint8_t wct, const uint16_t *vwv,
2443 uint16_t num_bytes, const uint8_t *bytes,
2444 void *private_data)
2446 struct smb1_parse_chain_state *state =
2447 (struct smb1_parse_chain_state *)private_data;
2448 struct smb_request **reqs;
2449 struct smb_request *req;
2450 bool ok;
2452 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2453 struct smb_request *, state->num_reqs+1);
2454 if (reqs == NULL) {
2455 return false;
2457 state->reqs = reqs;
2459 req = talloc(reqs, struct smb_request);
2460 if (req == NULL) {
2461 return false;
2464 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2465 state->encrypted, state->seqnum);
2466 if (!ok) {
2467 return false;
2469 req->cmd = cmd;
2470 req->wct = wct;
2471 req->vwv = vwv;
2472 req->buflen = num_bytes;
2473 req->buf = bytes;
2475 reqs[state->num_reqs] = req;
2476 state->num_reqs += 1;
2477 return true;
2480 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2481 struct smbXsrv_connection *xconn,
2482 bool encrypted, uint32_t seqnum,
2483 struct smb_request ***reqs, unsigned *num_reqs)
2485 struct smbd_server_connection *sconn = NULL;
2486 struct smb1_parse_chain_state state;
2487 unsigned i;
2489 if (xconn != NULL) {
2490 sconn = xconn->client->sconn;
2493 state.mem_ctx = mem_ctx;
2494 state.buf = buf;
2495 state.sconn = sconn;
2496 state.xconn = xconn;
2497 state.encrypted = encrypted;
2498 state.seqnum = seqnum;
2499 state.reqs = NULL;
2500 state.num_reqs = 0;
2502 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2503 TALLOC_FREE(state.reqs);
2504 return false;
2506 for (i=0; i<state.num_reqs; i++) {
2507 state.reqs[i]->chain = state.reqs;
2509 *reqs = state.reqs;
2510 *num_reqs = state.num_reqs;
2511 return true;
2514 /****************************************************************************
2515 Check if services need reloading.
2516 ****************************************************************************/
2518 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2521 if (last_smb_conf_reload_time == 0) {
2522 last_smb_conf_reload_time = t;
2525 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2526 reload_services(sconn, conn_snum_used, true);
2527 last_smb_conf_reload_time = t;
2531 static bool fd_is_readable(int fd)
2533 int ret, revents;
2535 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2537 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2541 static void smbd_server_connection_write_handler(
2542 struct smbXsrv_connection *xconn)
2544 /* TODO: make write nonblocking */
2547 static void smbd_server_connection_read_handler(
2548 struct smbXsrv_connection *xconn, int fd)
2550 uint8_t *inbuf = NULL;
2551 size_t inbuf_len = 0;
2552 size_t unread_bytes = 0;
2553 bool encrypted = false;
2554 TALLOC_CTX *mem_ctx = talloc_tos();
2555 NTSTATUS status;
2556 uint32_t seqnum;
2558 bool async_echo = lp_async_smb_echo_handler();
2559 bool from_client = false;
2561 if (async_echo) {
2562 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2564 * This is the super-ugly hack to prefer the packets
2565 * forwarded by the echo handler over the ones by the
2566 * client directly
2568 fd = xconn->smb1.echo_handler.trusted_fd;
2572 from_client = (xconn->transport.sock == fd);
2574 if (async_echo && from_client) {
2575 smbd_lock_socket(xconn);
2577 if (!fd_is_readable(fd)) {
2578 DEBUG(10,("the echo listener was faster\n"));
2579 smbd_unlock_socket(xconn);
2580 return;
2584 /* TODO: make this completely nonblocking */
2585 status = receive_smb_talloc(mem_ctx, xconn, fd,
2586 (char **)(void *)&inbuf,
2587 0, /* timeout */
2588 &unread_bytes,
2589 &encrypted,
2590 &inbuf_len, &seqnum,
2591 !from_client /* trusted channel */);
2593 if (async_echo && from_client) {
2594 smbd_unlock_socket(xconn);
2597 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2598 goto process;
2600 if (NT_STATUS_IS_ERR(status)) {
2601 exit_server_cleanly("failed to receive smb request");
2603 if (!NT_STATUS_IS_OK(status)) {
2604 return;
2607 process:
2608 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2609 seqnum, encrypted, NULL);
2612 static void smbd_server_connection_handler(struct tevent_context *ev,
2613 struct tevent_fd *fde,
2614 uint16_t flags,
2615 void *private_data)
2617 struct smbXsrv_connection *xconn =
2618 talloc_get_type_abort(private_data,
2619 struct smbXsrv_connection);
2621 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2623 * we're not supposed to do any io
2625 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2626 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2627 return;
2630 if (flags & TEVENT_FD_WRITE) {
2631 smbd_server_connection_write_handler(xconn);
2632 return;
2634 if (flags & TEVENT_FD_READ) {
2635 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2636 return;
2640 static void smbd_server_echo_handler(struct tevent_context *ev,
2641 struct tevent_fd *fde,
2642 uint16_t flags,
2643 void *private_data)
2645 struct smbXsrv_connection *xconn =
2646 talloc_get_type_abort(private_data,
2647 struct smbXsrv_connection);
2649 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2651 * we're not supposed to do any io
2653 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2654 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2655 return;
2658 if (flags & TEVENT_FD_WRITE) {
2659 smbd_server_connection_write_handler(xconn);
2660 return;
2662 if (flags & TEVENT_FD_READ) {
2663 smbd_server_connection_read_handler(
2664 xconn, xconn->smb1.echo_handler.trusted_fd);
2665 return;
2669 struct smbd_release_ip_state {
2670 struct smbXsrv_connection *xconn;
2671 struct tevent_immediate *im;
2672 char addr[INET6_ADDRSTRLEN];
2675 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2676 struct tevent_immediate *im,
2677 void *private_data)
2679 struct smbd_release_ip_state *state =
2680 talloc_get_type_abort(private_data,
2681 struct smbd_release_ip_state);
2682 struct smbXsrv_connection *xconn = state->xconn;
2684 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2686 * smbd_server_connection_terminate() already triggered ?
2688 return;
2691 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2694 /****************************************************************************
2695 received when we should release a specific IP
2696 ****************************************************************************/
2697 static int release_ip(uint32_t src_vnn, uint32_t dst_vnn,
2698 uint64_t dst_srvid,
2699 const uint8_t *msg, size_t msglen,
2700 void *private_data)
2702 struct smbd_release_ip_state *state =
2703 talloc_get_type_abort(private_data,
2704 struct smbd_release_ip_state);
2705 struct smbXsrv_connection *xconn = state->xconn;
2706 const char *ip;
2707 const char *addr = state->addr;
2708 const char *p = addr;
2710 if (msglen == 0) {
2711 return 0;
2713 if (msg[msglen-1] != '\0') {
2714 return 0;
2717 ip = (const char *)msg;
2719 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2720 /* avoid recursion */
2721 return 0;
2724 if (strncmp("::ffff:", addr, 7) == 0) {
2725 p = addr + 7;
2728 DEBUG(10, ("Got release IP message for %s, "
2729 "our address is %s\n", ip, p));
2731 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2732 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2733 ip));
2735 * With SMB2 we should do a clean disconnect,
2736 * the previous_session_id in the session setup
2737 * will cleanup the old session, tcons and opens.
2739 * A clean disconnect is needed in order to support
2740 * durable handles.
2742 * Note: typically this is never triggered
2743 * as we got a TCP RST (triggered by ctdb event scripts)
2744 * before we get CTDB_SRVID_RELEASE_IP.
2746 * We used to call _exit(1) here, but as this was mostly never
2747 * triggered and has implication on our process model,
2748 * we can just use smbd_server_connection_terminate()
2749 * (also for SMB1).
2751 * We don't call smbd_server_connection_terminate() directly
2752 * as we might be called from within ctdbd_migrate(),
2753 * we need to defer our action to the next event loop
2755 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2756 smbd_release_ip_immediate, state);
2759 * Make sure we don't get any io on the connection.
2761 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2762 return EADDRNOTAVAIL;
2765 return 0;
2768 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2769 struct sockaddr_storage *srv,
2770 struct sockaddr_storage *clnt)
2772 struct smbd_release_ip_state *state;
2773 struct ctdbd_connection *cconn;
2774 int ret;
2776 cconn = messaging_ctdbd_connection();
2777 if (cconn == NULL) {
2778 return NT_STATUS_NO_MEMORY;
2781 state = talloc_zero(xconn, struct smbd_release_ip_state);
2782 if (state == NULL) {
2783 return NT_STATUS_NO_MEMORY;
2785 state->xconn = xconn;
2786 state->im = tevent_create_immediate(state);
2787 if (state->im == NULL) {
2788 return NT_STATUS_NO_MEMORY;
2790 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2791 return NT_STATUS_NO_MEMORY;
2794 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2795 if (ret != 0) {
2796 return map_nt_error_from_unix(ret);
2798 return NT_STATUS_OK;
2801 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2802 void *private_data, uint32_t msg_type,
2803 struct server_id server_id, DATA_BLOB *data)
2805 struct smbd_server_connection *sconn = talloc_get_type_abort(
2806 private_data, struct smbd_server_connection);
2807 const char *ip = (char *) data->data;
2808 char *client_ip;
2810 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2812 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2813 talloc_tos());
2814 if (client_ip == NULL) {
2815 return;
2818 if (strequal(ip, client_ip)) {
2819 DBG_WARNING("Got kill client message for %s - "
2820 "exiting immediately\n", ip);
2821 exit_server_cleanly("Forced disconnect for client");
2824 TALLOC_FREE(client_ip);
2828 * Send keepalive packets to our client
2830 static bool keepalive_fn(const struct timeval *now, void *private_data)
2832 struct smbd_server_connection *sconn = talloc_get_type_abort(
2833 private_data, struct smbd_server_connection);
2834 struct smbXsrv_connection *xconn = NULL;
2835 bool ret;
2837 if (sconn->using_smb2) {
2838 /* Don't do keepalives on an SMB2 connection. */
2839 return false;
2843 * With SMB1 we only have 1 connection
2845 xconn = sconn->client->connections;
2846 smbd_lock_socket(xconn);
2847 ret = send_keepalive(xconn->transport.sock);
2848 smbd_unlock_socket(xconn);
2850 if (!ret) {
2851 int saved_errno = errno;
2853 * Try and give an error message saying what
2854 * client failed.
2856 DEBUG(0, ("send_keepalive failed for client %s. "
2857 "Error %s - exiting\n",
2858 smbXsrv_connection_dbg(xconn),
2859 strerror(saved_errno)));
2860 errno = saved_errno;
2861 return False;
2863 return True;
2867 * Do the recurring check if we're idle
2869 static bool deadtime_fn(const struct timeval *now, void *private_data)
2871 struct smbd_server_connection *sconn =
2872 (struct smbd_server_connection *)private_data;
2874 if ((conn_num_open(sconn) == 0)
2875 || (conn_idle_all(sconn, now->tv_sec))) {
2876 DEBUG( 2, ( "Closing idle connection\n" ) );
2877 messaging_send(sconn->msg_ctx,
2878 messaging_server_id(sconn->msg_ctx),
2879 MSG_SHUTDOWN, &data_blob_null);
2880 return False;
2883 return True;
2887 * Do the recurring log file and smb.conf reload checks.
2890 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2892 struct smbd_server_connection *sconn = talloc_get_type_abort(
2893 private_data, struct smbd_server_connection);
2895 DEBUG(5, ("housekeeping\n"));
2897 change_to_root_user();
2899 /* update printer queue caches if necessary */
2900 update_monitored_printq_cache(sconn->msg_ctx);
2902 /* check if we need to reload services */
2903 check_reload(sconn, time_mono(NULL));
2906 * Force a log file check.
2908 force_check_log_size();
2909 check_log_size();
2910 return true;
2914 * Read an smb packet in the echo handler child, giving the parent
2915 * smbd one second to react once the socket becomes readable.
2918 struct smbd_echo_read_state {
2919 struct tevent_context *ev;
2920 struct smbXsrv_connection *xconn;
2922 char *buf;
2923 size_t buflen;
2924 uint32_t seqnum;
2927 static void smbd_echo_read_readable(struct tevent_req *subreq);
2928 static void smbd_echo_read_waited(struct tevent_req *subreq);
2930 static struct tevent_req *smbd_echo_read_send(
2931 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2932 struct smbXsrv_connection *xconn)
2934 struct tevent_req *req, *subreq;
2935 struct smbd_echo_read_state *state;
2937 req = tevent_req_create(mem_ctx, &state,
2938 struct smbd_echo_read_state);
2939 if (req == NULL) {
2940 return NULL;
2942 state->ev = ev;
2943 state->xconn = xconn;
2945 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2946 if (tevent_req_nomem(subreq, req)) {
2947 return tevent_req_post(req, ev);
2949 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2950 return req;
2953 static void smbd_echo_read_readable(struct tevent_req *subreq)
2955 struct tevent_req *req = tevent_req_callback_data(
2956 subreq, struct tevent_req);
2957 struct smbd_echo_read_state *state = tevent_req_data(
2958 req, struct smbd_echo_read_state);
2959 bool ok;
2960 int err;
2962 ok = wait_for_read_recv(subreq, &err);
2963 TALLOC_FREE(subreq);
2964 if (!ok) {
2965 tevent_req_nterror(req, map_nt_error_from_unix(err));
2966 return;
2970 * Give the parent smbd one second to step in
2973 subreq = tevent_wakeup_send(
2974 state, state->ev, timeval_current_ofs(1, 0));
2975 if (tevent_req_nomem(subreq, req)) {
2976 return;
2978 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2981 static void smbd_echo_read_waited(struct tevent_req *subreq)
2983 struct tevent_req *req = tevent_req_callback_data(
2984 subreq, struct tevent_req);
2985 struct smbd_echo_read_state *state = tevent_req_data(
2986 req, struct smbd_echo_read_state);
2987 struct smbXsrv_connection *xconn = state->xconn;
2988 bool ok;
2989 NTSTATUS status;
2990 size_t unread = 0;
2991 bool encrypted;
2993 ok = tevent_wakeup_recv(subreq);
2994 TALLOC_FREE(subreq);
2995 if (!ok) {
2996 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2997 return;
3000 ok = smbd_lock_socket_internal(xconn);
3001 if (!ok) {
3002 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3003 DEBUG(0, ("%s: failed to lock socket\n", __location__));
3004 return;
3007 if (!fd_is_readable(xconn->transport.sock)) {
3008 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3009 (int)getpid()));
3011 ok = smbd_unlock_socket_internal(xconn);
3012 if (!ok) {
3013 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3014 DEBUG(1, ("%s: failed to unlock socket\n",
3015 __location__));
3016 return;
3019 subreq = wait_for_read_send(state, state->ev,
3020 xconn->transport.sock, false);
3021 if (tevent_req_nomem(subreq, req)) {
3022 return;
3024 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
3025 return;
3028 status = receive_smb_talloc(state, xconn,
3029 xconn->transport.sock,
3030 &state->buf,
3031 0 /* timeout */,
3032 &unread,
3033 &encrypted,
3034 &state->buflen,
3035 &state->seqnum,
3036 false /* trusted_channel*/);
3038 if (tevent_req_nterror(req, status)) {
3039 tevent_req_nterror(req, status);
3040 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3041 (int)getpid(), nt_errstr(status)));
3042 return;
3045 ok = smbd_unlock_socket_internal(xconn);
3046 if (!ok) {
3047 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3048 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
3049 return;
3051 tevent_req_done(req);
3054 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3055 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
3057 struct smbd_echo_read_state *state = tevent_req_data(
3058 req, struct smbd_echo_read_state);
3059 NTSTATUS status;
3061 if (tevent_req_is_nterror(req, &status)) {
3062 return status;
3064 *pbuf = talloc_move(mem_ctx, &state->buf);
3065 *pbuflen = state->buflen;
3066 *pseqnum = state->seqnum;
3067 return NT_STATUS_OK;
3070 struct smbd_echo_state {
3071 struct tevent_context *ev;
3072 struct iovec *pending;
3073 struct smbd_server_connection *sconn;
3074 struct smbXsrv_connection *xconn;
3075 int parent_pipe;
3077 struct tevent_fd *parent_fde;
3079 struct tevent_req *write_req;
3082 static void smbd_echo_writer_done(struct tevent_req *req);
3084 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3086 int num_pending;
3088 if (state->write_req != NULL) {
3089 return;
3092 num_pending = talloc_array_length(state->pending);
3093 if (num_pending == 0) {
3094 return;
3097 state->write_req = writev_send(state, state->ev, NULL,
3098 state->parent_pipe, false,
3099 state->pending, num_pending);
3100 if (state->write_req == NULL) {
3101 DEBUG(1, ("writev_send failed\n"));
3102 exit(1);
3105 talloc_steal(state->write_req, state->pending);
3106 state->pending = NULL;
3108 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3109 state);
3112 static void smbd_echo_writer_done(struct tevent_req *req)
3114 struct smbd_echo_state *state = tevent_req_callback_data(
3115 req, struct smbd_echo_state);
3116 ssize_t written;
3117 int err;
3119 written = writev_recv(req, &err);
3120 TALLOC_FREE(req);
3121 state->write_req = NULL;
3122 if (written == -1) {
3123 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3124 exit(1);
3126 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3127 smbd_echo_activate_writer(state);
3130 static bool smbd_echo_reply(struct smbd_echo_state *state,
3131 uint8_t *inbuf, size_t inbuf_len,
3132 uint32_t seqnum)
3134 struct smb_request req;
3135 uint16_t num_replies;
3136 char *outbuf;
3137 bool ok;
3139 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3140 DEBUG(10, ("Got netbios keepalive\n"));
3142 * Just swallow it
3144 return true;
3147 if (inbuf_len < smb_size) {
3148 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3149 return false;
3151 if (!valid_smb_header(inbuf)) {
3152 DEBUG(10, ("Got invalid SMB header\n"));
3153 return false;
3156 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3157 seqnum)) {
3158 return false;
3160 req.inbuf = inbuf;
3162 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3163 smb_messages[req.cmd].name
3164 ? smb_messages[req.cmd].name : "unknown"));
3166 if (req.cmd != SMBecho) {
3167 return false;
3169 if (req.wct < 1) {
3170 return false;
3173 num_replies = SVAL(req.vwv+0, 0);
3174 if (num_replies != 1) {
3175 /* Not a Windows "Hey, you're still there?" request */
3176 return false;
3179 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3180 1, req.buflen)) {
3181 DEBUG(10, ("create_outbuf failed\n"));
3182 return false;
3184 req.outbuf = (uint8_t *)outbuf;
3186 SSVAL(req.outbuf, smb_vwv0, num_replies);
3188 if (req.buflen > 0) {
3189 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3192 ok = srv_send_smb(req.xconn,
3193 (char *)outbuf,
3194 true, seqnum+1,
3195 false, &req.pcd);
3196 TALLOC_FREE(outbuf);
3197 if (!ok) {
3198 exit(1);
3201 return true;
3204 static void smbd_echo_exit(struct tevent_context *ev,
3205 struct tevent_fd *fde, uint16_t flags,
3206 void *private_data)
3208 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3209 exit(0);
3212 static void smbd_echo_got_packet(struct tevent_req *req);
3214 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3215 int parent_pipe)
3217 struct smbd_echo_state *state;
3218 struct tevent_req *read_req;
3220 state = talloc_zero(xconn, struct smbd_echo_state);
3221 if (state == NULL) {
3222 DEBUG(1, ("talloc failed\n"));
3223 return;
3225 state->xconn = xconn;
3226 state->parent_pipe = parent_pipe;
3227 state->ev = samba_tevent_context_init(state);
3228 if (state->ev == NULL) {
3229 DEBUG(1, ("samba_tevent_context_init failed\n"));
3230 TALLOC_FREE(state);
3231 return;
3233 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3234 TEVENT_FD_READ, smbd_echo_exit,
3235 state);
3236 if (state->parent_fde == NULL) {
3237 DEBUG(1, ("tevent_add_fd failed\n"));
3238 TALLOC_FREE(state);
3239 return;
3242 read_req = smbd_echo_read_send(state, state->ev, xconn);
3243 if (read_req == NULL) {
3244 DEBUG(1, ("smbd_echo_read_send failed\n"));
3245 TALLOC_FREE(state);
3246 return;
3248 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3250 while (true) {
3251 if (tevent_loop_once(state->ev) == -1) {
3252 DEBUG(1, ("tevent_loop_once failed: %s\n",
3253 strerror(errno)));
3254 break;
3257 TALLOC_FREE(state);
3260 static void smbd_echo_got_packet(struct tevent_req *req)
3262 struct smbd_echo_state *state = tevent_req_callback_data(
3263 req, struct smbd_echo_state);
3264 NTSTATUS status;
3265 char *buf = NULL;
3266 size_t buflen = 0;
3267 uint32_t seqnum = 0;
3268 bool reply;
3270 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3271 TALLOC_FREE(req);
3272 if (!NT_STATUS_IS_OK(status)) {
3273 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3274 nt_errstr(status)));
3275 exit(1);
3278 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3279 if (!reply) {
3280 size_t num_pending;
3281 struct iovec *tmp;
3282 struct iovec *iov;
3284 num_pending = talloc_array_length(state->pending);
3285 tmp = talloc_realloc(state, state->pending, struct iovec,
3286 num_pending+1);
3287 if (tmp == NULL) {
3288 DEBUG(1, ("talloc_realloc failed\n"));
3289 exit(1);
3291 state->pending = tmp;
3293 if (buflen >= smb_size) {
3295 * place the seqnum in the packet so that the main process
3296 * can reply with signing
3298 SIVAL(buf, smb_ss_field, seqnum);
3299 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3302 iov = &state->pending[num_pending];
3303 iov->iov_base = talloc_move(state->pending, &buf);
3304 iov->iov_len = buflen;
3306 DEBUG(10,("echo_handler[%d]: forward to main\n",
3307 (int)getpid()));
3308 smbd_echo_activate_writer(state);
3311 req = smbd_echo_read_send(state, state->ev, state->xconn);
3312 if (req == NULL) {
3313 DEBUG(1, ("smbd_echo_read_send failed\n"));
3314 exit(1);
3316 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3321 * Handle SMBecho requests in a forked child process
3323 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3325 int listener_pipe[2];
3326 int res;
3327 pid_t child;
3328 bool use_mutex = false;
3330 res = pipe(listener_pipe);
3331 if (res == -1) {
3332 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3333 return false;
3336 #ifdef HAVE_ROBUST_MUTEXES
3337 use_mutex = tdb_runtime_check_for_robust_mutexes();
3339 if (use_mutex) {
3340 pthread_mutexattr_t a;
3342 xconn->smb1.echo_handler.socket_mutex =
3343 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3344 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3345 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3346 strerror(errno)));
3347 goto fail;
3350 res = pthread_mutexattr_init(&a);
3351 if (res != 0) {
3352 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3353 strerror(res)));
3354 goto fail;
3356 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3357 if (res != 0) {
3358 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3359 strerror(res)));
3360 pthread_mutexattr_destroy(&a);
3361 goto fail;
3363 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3364 if (res != 0) {
3365 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3366 strerror(res)));
3367 pthread_mutexattr_destroy(&a);
3368 goto fail;
3370 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3371 if (res != 0) {
3372 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3373 "%s\n", strerror(res)));
3374 pthread_mutexattr_destroy(&a);
3375 goto fail;
3377 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3378 &a);
3379 pthread_mutexattr_destroy(&a);
3380 if (res != 0) {
3381 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3382 strerror(res)));
3383 goto fail;
3386 #endif
3388 if (!use_mutex) {
3389 xconn->smb1.echo_handler.socket_lock_fd =
3390 create_unlink_tmp(lp_lock_directory());
3391 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3392 DEBUG(1, ("Could not create lock fd: %s\n",
3393 strerror(errno)));
3394 goto fail;
3398 child = fork();
3399 if (child == 0) {
3400 NTSTATUS status;
3402 close(listener_pipe[0]);
3403 set_blocking(listener_pipe[1], false);
3405 status = smbd_reinit_after_fork(xconn->msg_ctx, xconn->ev_ctx,
3406 true, "smbd-echo");
3407 if (!NT_STATUS_IS_OK(status)) {
3408 DEBUG(1, ("reinit_after_fork failed: %s\n",
3409 nt_errstr(status)));
3410 exit(1);
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 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3934 * We're not making the decision here,
3935 * we're just allowing the client
3936 * to decide between SMB1 and SMB2
3937 * with the first negprot
3938 * packet.
3940 sconn->using_smb2 = true;
3943 if (!interactive) {
3944 smbd_setup_sig_term_handler(sconn);
3945 smbd_setup_sig_hup_handler(sconn);
3947 if (!serverid_register(messaging_server_id(msg_ctx),
3948 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3949 |FLAG_MSG_DBWRAP
3950 |FLAG_MSG_PRINT_GENERAL)) {
3951 exit_server_cleanly("Could not register myself in "
3952 "serverid.tdb");
3956 status = smbd_add_connection(client, sock_fd, &xconn);
3957 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3959 * send a negative session response "not listening on calling
3960 * name"
3962 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3963 (void)srv_send_smb(xconn,(char *)buf, false,
3964 0, false, NULL);
3965 exit_server_cleanly("connection denied");
3966 } else if (!NT_STATUS_IS_OK(status)) {
3967 exit_server_cleanly(nt_errstr(status));
3970 sconn->local_address =
3971 tsocket_address_copy(xconn->local_address, sconn);
3972 if (sconn->local_address == NULL) {
3973 exit_server_cleanly("tsocket_address_copy() failed");
3975 sconn->remote_address =
3976 tsocket_address_copy(xconn->remote_address, sconn);
3977 if (sconn->remote_address == NULL) {
3978 exit_server_cleanly("tsocket_address_copy() failed");
3980 sconn->remote_hostname =
3981 talloc_strdup(sconn, xconn->remote_hostname);
3982 if (sconn->remote_hostname == NULL) {
3983 exit_server_cleanly("tsocket_strdup() failed");
3986 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3987 locaddr = tsocket_address_inet_addr_string(
3988 sconn->local_address,
3989 talloc_tos());
3990 if (locaddr == NULL) {
3991 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3992 __location__, strerror(errno)));
3993 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3995 } else {
3996 locaddr = "0.0.0.0";
3999 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
4000 remaddr = tsocket_address_inet_addr_string(
4001 sconn->remote_address,
4002 talloc_tos());
4003 if (remaddr == NULL) {
4004 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4005 __location__, strerror(errno)));
4006 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4008 } else {
4009 remaddr = "0.0.0.0";
4012 /* this is needed so that we get decent entries
4013 in smbstatus for port 445 connects */
4014 set_remote_machine_name(remaddr, false);
4015 reload_services(sconn, conn_snum_used, true);
4016 sub_set_socket_ids(remaddr,
4017 sconn->remote_hostname,
4018 locaddr);
4020 if (lp_preload_modules()) {
4021 smb_load_modules(lp_preload_modules());
4024 smb_perfcount_init();
4026 if (!init_account_policy()) {
4027 exit_server("Could not open account policy tdb.\n");
4030 chroot_dir = lp_root_directory(talloc_tos());
4031 if (chroot_dir[0] != '\0') {
4032 rc = chdir(chroot_dir);
4033 if (rc != 0) {
4034 DBG_ERR("Failed to chdir to %s\n", chroot_dir);
4035 exit_server("Failed to chdir()");
4038 rc = chroot(chroot_dir);
4039 if (rc != 0) {
4040 DBG_ERR("Failed to change root to %s\n", chroot_dir);
4041 exit_server("Failed to chroot()");
4043 DBG_WARNING("Changed root to %s\n", chroot_dir);
4045 TALLOC_FREE(chroot_dir);
4048 if (!file_init(sconn)) {
4049 exit_server("file_init() failed");
4052 /* Setup oplocks */
4053 if (!init_oplocks(sconn))
4054 exit_server("Failed to init oplocks");
4056 /* register our message handlers */
4057 messaging_register(sconn->msg_ctx, sconn,
4058 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4059 messaging_register(sconn->msg_ctx, sconn,
4060 MSG_SMB_CLOSE_FILE, msg_close_file);
4061 messaging_register(sconn->msg_ctx, sconn,
4062 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
4064 id_cache_register_msgs(sconn->msg_ctx);
4065 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
4066 messaging_register(sconn->msg_ctx, sconn,
4067 ID_CACHE_KILL, smbd_id_cache_kill);
4069 messaging_deregister(sconn->msg_ctx,
4070 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
4071 messaging_register(sconn->msg_ctx, sconn,
4072 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
4074 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
4075 NULL);
4076 messaging_register(sconn->msg_ctx, sconn,
4077 MSG_SMB_KILL_CLIENT_IP,
4078 msg_kill_client_ip);
4080 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
4083 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4084 * MSGs to all child processes
4086 messaging_deregister(sconn->msg_ctx,
4087 MSG_DEBUG, NULL);
4088 messaging_register(sconn->msg_ctx, NULL,
4089 MSG_DEBUG, debug_message);
4091 if ((lp_keepalive() != 0)
4092 && !(event_add_idle(ev_ctx, NULL,
4093 timeval_set(lp_keepalive(), 0),
4094 "keepalive", keepalive_fn,
4095 sconn))) {
4096 DEBUG(0, ("Could not add keepalive event\n"));
4097 exit(1);
4100 if (!(event_add_idle(ev_ctx, NULL,
4101 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4102 "deadtime", deadtime_fn, sconn))) {
4103 DEBUG(0, ("Could not add deadtime event\n"));
4104 exit(1);
4107 if (!(event_add_idle(ev_ctx, NULL,
4108 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4109 "housekeeping", housekeeping_fn, sconn))) {
4110 DEBUG(0, ("Could not add housekeeping event\n"));
4111 exit(1);
4114 smbprofile_dump_setup(ev_ctx);
4116 if (!init_dptrs(sconn)) {
4117 exit_server("init_dptrs() failed");
4120 TALLOC_FREE(trace_state.frame);
4122 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4123 &trace_state);
4125 ret = tevent_loop_wait(ev_ctx);
4126 if (ret != 0) {
4127 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4128 " exiting\n", ret, strerror(errno)));
4131 TALLOC_FREE(trace_state.frame);
4133 exit_server_cleanly(NULL);
4136 bool req_is_in_chain(const struct smb_request *req)
4138 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4140 * We're right now handling a subsequent request, so we must
4141 * be in a chain
4143 return true;
4146 if (!is_andx_req(req->cmd)) {
4147 return false;
4150 if (req->wct < 2) {
4152 * Okay, an illegal request, but definitely not chained :-)
4154 return false;
4157 return (CVAL(req->vwv+0, 0) != 0xFF);