negoex.idl: use DATA_BLOB for negoex_BYTE_VECTOR
[Samba.git] / source3 / smbd / process.c
blobc99c75ebe871b8b5b13033ccc98f2905cfd2150c
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 smb_init_perfcount_data(&req->pcd);
634 /* Ensure we have at least wct words and 2 bytes of bcc. */
635 if (smb_size + req->wct*2 > req_size) {
636 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
637 (unsigned int)req->wct,
638 (unsigned int)req_size));
639 return false;
641 /* Ensure bcc is correct. */
642 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
643 DEBUG(0,("init_smb_request: invalid bcc number %u "
644 "(wct = %u, size %u)\n",
645 (unsigned int)req->buflen,
646 (unsigned int)req->wct,
647 (unsigned int)req_size));
648 return false;
651 req->outbuf = NULL;
652 return true;
655 static void process_smb(struct smbXsrv_connection *xconn,
656 uint8_t *inbuf, size_t nread, size_t unread_bytes,
657 uint32_t seqnum, bool encrypted,
658 struct smb_perfcount_data *deferred_pcd);
660 static void smbd_deferred_open_timer(struct tevent_context *ev,
661 struct tevent_timer *te,
662 struct timeval _tval,
663 void *private_data)
665 struct pending_message_list *msg = talloc_get_type(private_data,
666 struct pending_message_list);
667 struct smbd_server_connection *sconn = msg->sconn;
668 struct smbXsrv_connection *xconn = msg->xconn;
669 TALLOC_CTX *mem_ctx = talloc_tos();
670 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
671 uint8_t *inbuf;
673 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
674 msg->buf.length);
675 if (inbuf == NULL) {
676 exit_server("smbd_deferred_open_timer: talloc failed\n");
677 return;
680 /* We leave this message on the queue so the open code can
681 know this is a retry. */
682 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
683 (unsigned long long)mid ));
685 /* Mark the message as processed so this is not
686 * re-processed in error. */
687 msg->processed = true;
689 process_smb(xconn, inbuf,
690 msg->buf.length, 0,
691 msg->seqnum, msg->encrypted, &msg->pcd);
693 /* If it's still there and was processed, remove it. */
694 msg = get_deferred_open_message_smb(sconn, mid);
695 if (msg && msg->processed) {
696 remove_deferred_open_message_smb(xconn, mid);
700 /****************************************************************************
701 Function to push a message onto the tail of a linked list of smb messages ready
702 for processing.
703 ****************************************************************************/
705 static bool push_queued_message(struct smb_request *req,
706 struct timeval request_time,
707 struct timeval end_time,
708 struct deferred_open_record *open_rec)
710 int msg_len = smb_len(req->inbuf) + 4;
711 struct pending_message_list *msg;
713 msg = talloc_zero(NULL, struct pending_message_list);
715 if(msg == NULL) {
716 DEBUG(0,("push_message: malloc fail (1)\n"));
717 return False;
719 msg->sconn = req->sconn;
720 msg->xconn = req->xconn;
722 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
723 if(msg->buf.data == NULL) {
724 DEBUG(0,("push_message: malloc fail (2)\n"));
725 TALLOC_FREE(msg);
726 return False;
729 msg->request_time = request_time;
730 msg->seqnum = req->seqnum;
731 msg->encrypted = req->encrypted;
732 msg->processed = false;
733 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
735 if (open_rec) {
736 msg->open_rec = talloc_move(msg, &open_rec);
739 #if 0
740 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
741 msg,
742 end_time,
743 smbd_deferred_open_timer,
744 msg);
745 if (!msg->te) {
746 DEBUG(0,("push_message: event_add_timed failed\n"));
747 TALLOC_FREE(msg);
748 return false;
750 #endif
752 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
753 struct pending_message_list *);
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 /****************************************************************************
1434 Prepare everything for calling the actual request function, and potentially
1435 call the request function via the "new" interface.
1437 Return False if the "legacy" function needs to be called, everything is
1438 prepared.
1440 Return True if we're done.
1442 I know this API sucks, but it is the one with the least code change I could
1443 find.
1444 ****************************************************************************/
1446 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1448 int flags;
1449 uint64_t session_tag;
1450 connection_struct *conn = NULL;
1451 struct smbXsrv_connection *xconn = req->xconn;
1452 NTTIME now = timeval_to_nttime(&req->request_time);
1453 struct smbXsrv_session *session = NULL;
1454 NTSTATUS status;
1456 errno = 0;
1458 if (!xconn->smb1.negprot.done) {
1459 switch (type) {
1461 * Without a negprot the request must
1462 * either be a negprot, or one of the
1463 * evil old SMB mailslot messaging types.
1465 case SMBnegprot:
1466 case SMBsendstrt:
1467 case SMBsendend:
1468 case SMBsendtxt:
1469 break;
1470 default:
1471 exit_server_cleanly("The first request "
1472 "should be a negprot");
1476 if (smb_messages[type].fn == NULL) {
1477 DEBUG(0,("Unknown message type %d!\n",type));
1478 smb_dump("Unknown", 1, (const char *)req->inbuf);
1479 reply_unknown_new(req, type);
1480 return NULL;
1483 flags = smb_messages[type].flags;
1485 /* In share mode security we must ignore the vuid. */
1486 session_tag = req->vuid;
1487 conn = req->conn;
1489 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1490 (int)getpid(), (unsigned long)conn));
1492 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1494 /* Ensure this value is replaced in the incoming packet. */
1495 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1498 * Ensure the correct username is in current_user_info. This is a
1499 * really ugly bugfix for problems with multiple session_setup_and_X's
1500 * being done and allowing %U and %G substitutions to work correctly.
1501 * There is a reason this code is done here, don't move it unless you
1502 * know what you're doing... :-).
1503 * JRA.
1507 * lookup an existing session
1509 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1510 * here, the main check is still in change_to_user()
1512 status = smb1srv_session_lookup(xconn,
1513 session_tag,
1514 now,
1515 &session);
1516 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1517 switch (type) {
1518 case SMBsesssetupX:
1519 status = NT_STATUS_OK;
1520 break;
1521 default:
1522 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1523 (unsigned long long)session_tag,
1524 (unsigned long long)req->mid));
1525 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1526 return conn;
1530 if (session_tag != xconn->client->last_session_id) {
1531 struct user_struct *vuser = NULL;
1533 xconn->client->last_session_id = session_tag;
1534 if (session) {
1535 vuser = session->compat;
1537 if (vuser) {
1538 set_current_user_info(
1539 vuser->session_info->unix_info->sanitized_username,
1540 vuser->session_info->unix_info->unix_name,
1541 vuser->session_info->info->domain_name);
1545 /* Does this call need to be run as the connected user? */
1546 if (flags & AS_USER) {
1548 /* Does this call need a valid tree connection? */
1549 if (!conn) {
1551 * Amazingly, the error code depends on the command
1552 * (from Samba4).
1554 if (type == SMBntcreateX) {
1555 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1556 } else {
1557 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1559 return NULL;
1562 if (!change_to_user(conn,session_tag)) {
1563 DEBUG(0, ("Error: Could not change to user. Removing "
1564 "deferred open, mid=%llu.\n",
1565 (unsigned long long)req->mid));
1566 reply_force_doserror(req, ERRSRV, ERRbaduid);
1567 return conn;
1570 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1572 /* Does it need write permission? */
1573 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1574 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1575 return conn;
1578 /* IPC services are limited */
1579 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1580 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1581 return conn;
1583 } else {
1584 /* This call needs to be run as root */
1585 change_to_root_user();
1588 /* load service specific parameters */
1589 if (conn) {
1590 if (req->encrypted) {
1591 conn->encrypted_tid = true;
1592 /* encrypted required from now on. */
1593 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1594 } else if (ENCRYPTION_REQUIRED(conn)) {
1595 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1596 DEBUG(1,("service[%s] requires encryption"
1597 "%s ACCESS_DENIED. mid=%llu\n",
1598 lp_servicename(talloc_tos(), SNUM(conn)),
1599 smb_fn_name(type),
1600 (unsigned long long)req->mid));
1601 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1602 return conn;
1606 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1607 (flags & (AS_USER|DO_CHDIR)
1608 ?True:False))) {
1609 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1610 return conn;
1612 conn->num_smb_operations++;
1616 * Does this protocol need to be run as guest? (Only archane
1617 * messenger service requests have this...)
1619 if (flags & AS_GUEST) {
1620 char *raddr;
1621 bool ok;
1623 if (!change_to_guest()) {
1624 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1625 return conn;
1628 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1629 talloc_tos());
1630 if (raddr == NULL) {
1631 reply_nterror(req, NT_STATUS_NO_MEMORY);
1632 return conn;
1636 * Haven't we checked this in smbd_process already???
1639 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1640 xconn->remote_hostname, raddr);
1641 TALLOC_FREE(raddr);
1643 if (!ok) {
1644 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1645 return conn;
1649 smb_messages[type].fn(req);
1650 return req->conn;
1653 /****************************************************************************
1654 Construct a reply to the incoming packet.
1655 ****************************************************************************/
1657 static void construct_reply(struct smbXsrv_connection *xconn,
1658 char *inbuf, int size, size_t unread_bytes,
1659 uint32_t seqnum, bool encrypted,
1660 struct smb_perfcount_data *deferred_pcd)
1662 struct smbd_server_connection *sconn = xconn->client->sconn;
1663 struct smb_request *req;
1665 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1666 smb_panic("could not allocate smb_request");
1669 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1670 encrypted, seqnum)) {
1671 exit_server_cleanly("Invalid SMB request");
1674 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1676 /* we popped this message off the queue - keep original perf data */
1677 if (deferred_pcd)
1678 req->pcd = *deferred_pcd;
1679 else {
1680 SMB_PERFCOUNT_START(&req->pcd);
1681 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1682 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1685 req->conn = switch_message(req->cmd, req);
1687 if (req->outbuf == NULL) {
1689 * Request has suspended itself, will come
1690 * back here.
1692 return;
1694 if (CVAL(req->outbuf,0) == 0) {
1695 show_msg((char *)req->outbuf);
1697 smb_request_done(req);
1700 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1701 char *inbuf, int size, uint32_t seqnum,
1702 bool encrypted,
1703 struct smb_perfcount_data *deferred_pcd)
1705 struct smb_request **reqs = NULL;
1706 struct smb_request *req;
1707 unsigned num_reqs;
1708 bool ok;
1710 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, xconn, encrypted,
1711 seqnum, &reqs, &num_reqs);
1712 if (!ok) {
1713 char errbuf[smb_size];
1714 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1715 __LINE__, __FILE__);
1716 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1717 NULL)) {
1718 exit_server_cleanly("construct_reply_chain: "
1719 "srv_send_smb failed.");
1721 return;
1724 req = reqs[0];
1725 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1727 req->conn = switch_message(req->cmd, req);
1729 if (req->outbuf == NULL) {
1731 * Request has suspended itself, will come
1732 * back here.
1734 return;
1736 smb_request_done(req);
1740 * To be called from an async SMB handler that is potentially chained
1741 * when it is finished for shipping.
1744 void smb_request_done(struct smb_request *req)
1746 struct smb_request **reqs = NULL;
1747 struct smb_request *first_req;
1748 size_t i, num_reqs, next_index;
1749 NTSTATUS status;
1751 if (req->chain == NULL) {
1752 first_req = req;
1753 goto shipit;
1756 reqs = req->chain;
1757 num_reqs = talloc_array_length(reqs);
1759 for (i=0; i<num_reqs; i++) {
1760 if (reqs[i] == req) {
1761 break;
1764 if (i == num_reqs) {
1766 * Invalid chain, should not happen
1768 status = NT_STATUS_INTERNAL_ERROR;
1769 goto error;
1771 next_index = i+1;
1773 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1774 struct smb_request *next = reqs[next_index];
1775 struct smbXsrv_tcon *tcon;
1776 NTTIME now = timeval_to_nttime(&req->request_time);
1778 next->vuid = SVAL(req->outbuf, smb_uid);
1779 next->tid = SVAL(req->outbuf, smb_tid);
1780 status = smb1srv_tcon_lookup(req->xconn, req->tid,
1781 now, &tcon);
1782 if (NT_STATUS_IS_OK(status)) {
1783 req->conn = tcon->compat;
1784 } else {
1785 req->conn = NULL;
1787 next->chain_fsp = req->chain_fsp;
1788 next->inbuf = req->inbuf;
1790 req = next;
1791 req->conn = switch_message(req->cmd, req);
1793 if (req->outbuf == NULL) {
1795 * Request has suspended itself, will come
1796 * back here.
1798 return;
1800 next_index += 1;
1803 first_req = reqs[0];
1805 for (i=1; i<next_index; i++) {
1806 bool ok;
1808 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1809 if (!ok) {
1810 status = NT_STATUS_INTERNAL_ERROR;
1811 goto error;
1815 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1816 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1819 * This scary statement intends to set the
1820 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1821 * to the value last_req->outbuf carries
1823 SSVAL(first_req->outbuf, smb_flg2,
1824 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1825 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1828 * Transfer the error codes from the subrequest to the main one
1830 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1831 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1833 _smb_setlen_large(
1834 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1836 shipit:
1837 if (!srv_send_smb(first_req->xconn,
1838 (char *)first_req->outbuf,
1839 true, first_req->seqnum+1,
1840 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1841 &first_req->pcd)) {
1842 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1843 "failed.");
1845 TALLOC_FREE(req); /* non-chained case */
1846 TALLOC_FREE(reqs); /* chained case */
1847 return;
1849 error:
1851 char errbuf[smb_size];
1852 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1853 if (!srv_send_smb(req->xconn, errbuf, true,
1854 req->seqnum+1, req->encrypted,
1855 NULL)) {
1856 exit_server_cleanly("construct_reply_chain: "
1857 "srv_send_smb failed.");
1860 TALLOC_FREE(req); /* non-chained case */
1861 TALLOC_FREE(reqs); /* chained case */
1864 /****************************************************************************
1865 Process an smb from the client
1866 ****************************************************************************/
1867 static void process_smb(struct smbXsrv_connection *xconn,
1868 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1869 uint32_t seqnum, bool encrypted,
1870 struct smb_perfcount_data *deferred_pcd)
1872 struct smbd_server_connection *sconn = xconn->client->sconn;
1873 int msg_type = CVAL(inbuf,0);
1875 DO_PROFILE_INC(request);
1877 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1878 smb_len(inbuf) ) );
1879 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1880 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1882 if (msg_type != NBSSmessage) {
1884 * NetBIOS session request, keepalive, etc.
1886 reply_special(xconn, (char *)inbuf, nread);
1887 goto done;
1890 if (sconn->using_smb2) {
1891 /* At this point we're not really using smb2,
1892 * we make the decision here.. */
1893 if (smbd_is_smb2_header(inbuf, nread)) {
1894 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1895 size_t pdulen = nread - NBT_HDR_SIZE;
1896 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1897 return;
1898 } else if (nread >= smb_size && valid_smb_header(inbuf)
1899 && CVAL(inbuf, smb_com) != 0x72) {
1900 /* This is a non-negprot SMB1 packet.
1901 Disable SMB2 from now on. */
1902 sconn->using_smb2 = false;
1906 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1907 * so subtract 4 from it. */
1908 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1909 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1910 smb_len(inbuf)));
1912 /* special magic for immediate exit */
1913 if ((nread == 9) &&
1914 (IVAL(inbuf, 4) == 0x74697865) &&
1915 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1916 uint8_t exitcode = CVAL(inbuf, 8);
1917 DEBUG(1, ("Exiting immediately with code %d\n",
1918 (int)exitcode));
1919 exit(exitcode);
1922 exit_server_cleanly("Non-SMB packet");
1925 show_msg((char *)inbuf);
1927 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1928 construct_reply_chain(xconn, (char *)inbuf, nread,
1929 seqnum, encrypted, deferred_pcd);
1930 } else {
1931 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
1932 seqnum, encrypted, deferred_pcd);
1935 sconn->trans_num++;
1937 done:
1938 sconn->num_requests++;
1940 /* The timeout_processing function isn't run nearly
1941 often enough to implement 'max log size' without
1942 overrunning the size of the file by many megabytes.
1943 This is especially true if we are running at debug
1944 level 10. Checking every 50 SMBs is a nice
1945 tradeoff of performance vs log file size overrun. */
1947 if ((sconn->num_requests % 50) == 0 &&
1948 need_to_check_log_size()) {
1949 change_to_root_user();
1950 check_log_size();
1954 /****************************************************************************
1955 Return a string containing the function name of a SMB command.
1956 ****************************************************************************/
1958 const char *smb_fn_name(int type)
1960 const char *unknown_name = "SMBunknown";
1962 if (smb_messages[type].name == NULL)
1963 return(unknown_name);
1965 return(smb_messages[type].name);
1968 /****************************************************************************
1969 Helper functions for contruct_reply.
1970 ****************************************************************************/
1972 void add_to_common_flags2(uint32_t v)
1974 common_flags2 |= v;
1977 void remove_from_common_flags2(uint32_t v)
1979 common_flags2 &= ~v;
1982 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
1983 char *outbuf)
1985 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1986 uint16_t out_flags2 = common_flags2;
1988 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1989 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1990 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1992 srv_set_message(outbuf,0,0,false);
1994 SCVAL(outbuf, smb_com, cmd);
1995 SIVAL(outbuf,smb_rcls,0);
1996 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1997 SSVAL(outbuf,smb_flg2, out_flags2);
1998 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1999 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2001 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2002 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2003 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2004 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2007 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2009 construct_reply_common(req->cmd, req->inbuf, outbuf);
2013 * @brief Find the smb_cmd offset of the last command pushed
2014 * @param[in] buf The buffer we're building up
2015 * @retval Where can we put our next andx cmd?
2017 * While chaining requests, the "next" request we're looking at needs to put
2018 * its SMB_Command before the data the previous request already built up added
2019 * to the chain. Find the offset to the place where we have to put our cmd.
2022 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2024 uint8_t cmd;
2025 size_t ofs;
2027 cmd = CVAL(buf, smb_com);
2029 if (!is_andx_req(cmd)) {
2030 return false;
2033 ofs = smb_vwv0;
2035 while (CVAL(buf, ofs) != 0xff) {
2037 if (!is_andx_req(CVAL(buf, ofs))) {
2038 return false;
2042 * ofs is from start of smb header, so add the 4 length
2043 * bytes. The next cmd is right after the wct field.
2045 ofs = SVAL(buf, ofs+2) + 4 + 1;
2047 if (ofs+4 >= talloc_get_size(buf)) {
2048 return false;
2052 *pofs = ofs;
2053 return true;
2057 * @brief Do the smb chaining at a buffer level
2058 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2059 * @param[in] andx_buf Buffer to be appended
2062 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2064 uint8_t smb_command = CVAL(andx_buf, smb_com);
2065 uint8_t wct = CVAL(andx_buf, smb_wct);
2066 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2067 uint32_t num_bytes = smb_buflen(andx_buf);
2068 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2070 uint8_t *outbuf;
2071 size_t old_size, new_size;
2072 size_t ofs;
2073 size_t chain_padding = 0;
2074 size_t andx_cmd_ofs;
2077 old_size = talloc_get_size(*poutbuf);
2079 if ((old_size % 4) != 0) {
2081 * Align the wct field of subsequent requests to a 4-byte
2082 * boundary
2084 chain_padding = 4 - (old_size % 4);
2088 * After the old request comes the new wct field (1 byte), the vwv's
2089 * and the num_bytes field.
2092 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2093 new_size += num_bytes;
2095 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2096 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2097 (unsigned)new_size));
2098 return false;
2101 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2102 if (outbuf == NULL) {
2103 DEBUG(0, ("talloc failed\n"));
2104 return false;
2106 *poutbuf = outbuf;
2108 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2109 DEBUG(1, ("invalid command chain\n"));
2110 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2111 return false;
2114 if (chain_padding != 0) {
2115 memset(outbuf + old_size, 0, chain_padding);
2116 old_size += chain_padding;
2119 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2120 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2122 ofs = old_size;
2125 * Push the chained request:
2127 * wct field
2130 SCVAL(outbuf, ofs, wct);
2131 ofs += 1;
2134 * vwv array
2137 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2140 * HACK ALERT
2142 * Read&X has an offset into its data buffer at
2143 * vwv[6]. reply_read_andx has no idea anymore that it's
2144 * running from within a chain, so we have to fix up the
2145 * offset here.
2147 * Although it looks disgusting at this place, I want to keep
2148 * it here. The alternative would be to push knowledge about
2149 * the andx chain down into read&x again.
2152 if (smb_command == SMBreadX) {
2153 uint8_t *bytes_addr;
2155 if (wct < 7) {
2157 * Invalid read&x response
2159 return false;
2162 bytes_addr = outbuf + ofs /* vwv start */
2163 + sizeof(uint16_t) * wct /* vwv array */
2164 + sizeof(uint16_t) /* bcc */
2165 + 1; /* padding byte */
2167 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2168 bytes_addr - outbuf - 4);
2171 ofs += sizeof(uint16_t) * wct;
2174 * bcc (byte count)
2177 SSVAL(outbuf, ofs, num_bytes);
2178 ofs += sizeof(uint16_t);
2181 * The bytes field
2184 memcpy(outbuf + ofs, bytes, num_bytes);
2186 return true;
2189 bool smb1_is_chain(const uint8_t *buf)
2191 uint8_t cmd, wct, andx_cmd;
2193 cmd = CVAL(buf, smb_com);
2194 if (!is_andx_req(cmd)) {
2195 return false;
2197 wct = CVAL(buf, smb_wct);
2198 if (wct < 2) {
2199 return false;
2201 andx_cmd = CVAL(buf, smb_vwv);
2202 return (andx_cmd != 0xFF);
2205 bool smb1_walk_chain(const uint8_t *buf,
2206 bool (*fn)(uint8_t cmd,
2207 uint8_t wct, const uint16_t *vwv,
2208 uint16_t num_bytes, const uint8_t *bytes,
2209 void *private_data),
2210 void *private_data)
2212 size_t smblen = smb_len(buf);
2213 const char *smb_buf = smb_base(buf);
2214 uint8_t cmd, chain_cmd;
2215 uint8_t wct;
2216 const uint16_t *vwv;
2217 uint16_t num_bytes;
2218 const uint8_t *bytes;
2220 cmd = CVAL(buf, smb_com);
2221 wct = CVAL(buf, smb_wct);
2222 vwv = (const uint16_t *)(buf + smb_vwv);
2223 num_bytes = smb_buflen(buf);
2224 bytes = (const uint8_t *)smb_buf_const(buf);
2226 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2227 return false;
2230 if (!is_andx_req(cmd)) {
2231 return true;
2233 if (wct < 2) {
2234 return false;
2237 chain_cmd = CVAL(vwv, 0);
2239 while (chain_cmd != 0xff) {
2240 uint32_t chain_offset; /* uint32_t to avoid overflow */
2241 size_t length_needed;
2242 ptrdiff_t vwv_offset;
2244 chain_offset = SVAL(vwv+1, 0);
2247 * Check if the client tries to fool us. The chain
2248 * offset needs to point beyond the current request in
2249 * the chain, it needs to strictly grow. Otherwise we
2250 * might be tricked into an endless loop always
2251 * processing the same request over and over again. We
2252 * used to assume that vwv and the byte buffer array
2253 * in a chain are always attached, but OS/2 the
2254 * Write&X/Read&X chain puts the Read&X vwv array
2255 * right behind the Write&X vwv chain. The Write&X bcc
2256 * array is put behind the Read&X vwv array. So now we
2257 * check whether the chain offset points strictly
2258 * behind the previous vwv array. req->buf points
2259 * right after the vwv array of the previous
2260 * request. See
2261 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2262 * more information.
2265 vwv_offset = ((const char *)vwv - smb_buf);
2266 if (chain_offset <= vwv_offset) {
2267 return false;
2271 * Next check: Make sure the chain offset does not
2272 * point beyond the overall smb request length.
2275 length_needed = chain_offset+1; /* wct */
2276 if (length_needed > smblen) {
2277 return false;
2281 * Now comes the pointer magic. Goal here is to set up
2282 * vwv and buf correctly again. The chain offset (the
2283 * former vwv[1]) points at the new wct field.
2286 wct = CVAL(smb_buf, chain_offset);
2288 if (is_andx_req(chain_cmd) && (wct < 2)) {
2289 return false;
2293 * Next consistency check: Make the new vwv array fits
2294 * in the overall smb request.
2297 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2298 if (length_needed > smblen) {
2299 return false;
2301 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2304 * Now grab the new byte buffer....
2307 num_bytes = SVAL(vwv+wct, 0);
2310 * .. and check that it fits.
2313 length_needed += num_bytes;
2314 if (length_needed > smblen) {
2315 return false;
2317 bytes = (const uint8_t *)(vwv+wct+1);
2319 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2320 return false;
2323 if (!is_andx_req(chain_cmd)) {
2324 return true;
2326 chain_cmd = CVAL(vwv, 0);
2328 return true;
2331 static bool smb1_chain_length_cb(uint8_t cmd,
2332 uint8_t wct, const uint16_t *vwv,
2333 uint16_t num_bytes, const uint8_t *bytes,
2334 void *private_data)
2336 unsigned *count = (unsigned *)private_data;
2337 *count += 1;
2338 return true;
2341 unsigned smb1_chain_length(const uint8_t *buf)
2343 unsigned count = 0;
2345 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2346 return 0;
2348 return count;
2351 struct smb1_parse_chain_state {
2352 TALLOC_CTX *mem_ctx;
2353 const uint8_t *buf;
2354 struct smbd_server_connection *sconn;
2355 struct smbXsrv_connection *xconn;
2356 bool encrypted;
2357 uint32_t seqnum;
2359 struct smb_request **reqs;
2360 unsigned num_reqs;
2363 static bool smb1_parse_chain_cb(uint8_t cmd,
2364 uint8_t wct, const uint16_t *vwv,
2365 uint16_t num_bytes, const uint8_t *bytes,
2366 void *private_data)
2368 struct smb1_parse_chain_state *state =
2369 (struct smb1_parse_chain_state *)private_data;
2370 struct smb_request **reqs;
2371 struct smb_request *req;
2372 bool ok;
2374 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2375 struct smb_request *, state->num_reqs+1);
2376 if (reqs == NULL) {
2377 return false;
2379 state->reqs = reqs;
2381 req = talloc(reqs, struct smb_request);
2382 if (req == NULL) {
2383 return false;
2386 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2387 state->encrypted, state->seqnum);
2388 if (!ok) {
2389 return false;
2391 req->cmd = cmd;
2392 req->wct = wct;
2393 req->vwv = vwv;
2394 req->buflen = num_bytes;
2395 req->buf = bytes;
2397 reqs[state->num_reqs] = req;
2398 state->num_reqs += 1;
2399 return true;
2402 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2403 struct smbXsrv_connection *xconn,
2404 bool encrypted, uint32_t seqnum,
2405 struct smb_request ***reqs, unsigned *num_reqs)
2407 struct smbd_server_connection *sconn = NULL;
2408 struct smb1_parse_chain_state state;
2409 unsigned i;
2411 if (xconn != NULL) {
2412 sconn = xconn->client->sconn;
2415 state.mem_ctx = mem_ctx;
2416 state.buf = buf;
2417 state.sconn = sconn;
2418 state.xconn = xconn;
2419 state.encrypted = encrypted;
2420 state.seqnum = seqnum;
2421 state.reqs = NULL;
2422 state.num_reqs = 0;
2424 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2425 TALLOC_FREE(state.reqs);
2426 return false;
2428 for (i=0; i<state.num_reqs; i++) {
2429 state.reqs[i]->chain = state.reqs;
2431 *reqs = state.reqs;
2432 *num_reqs = state.num_reqs;
2433 return true;
2436 /****************************************************************************
2437 Check if services need reloading.
2438 ****************************************************************************/
2440 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2443 if (last_smb_conf_reload_time == 0) {
2444 last_smb_conf_reload_time = t;
2447 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2448 reload_services(sconn, conn_snum_used, true);
2449 last_smb_conf_reload_time = t;
2453 static bool fd_is_readable(int fd)
2455 int ret, revents;
2457 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2459 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2463 static void smbd_server_connection_write_handler(
2464 struct smbXsrv_connection *xconn)
2466 /* TODO: make write nonblocking */
2469 static void smbd_server_connection_read_handler(
2470 struct smbXsrv_connection *xconn, int fd)
2472 uint8_t *inbuf = NULL;
2473 size_t inbuf_len = 0;
2474 size_t unread_bytes = 0;
2475 bool encrypted = false;
2476 TALLOC_CTX *mem_ctx = talloc_tos();
2477 NTSTATUS status;
2478 uint32_t seqnum;
2480 bool async_echo = lp_async_smb_echo_handler();
2481 bool from_client = false;
2483 if (async_echo) {
2484 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2486 * This is the super-ugly hack to prefer the packets
2487 * forwarded by the echo handler over the ones by the
2488 * client directly
2490 fd = xconn->smb1.echo_handler.trusted_fd;
2494 from_client = (xconn->transport.sock == fd);
2496 if (async_echo && from_client) {
2497 smbd_lock_socket(xconn);
2499 if (!fd_is_readable(fd)) {
2500 DEBUG(10,("the echo listener was faster\n"));
2501 smbd_unlock_socket(xconn);
2502 return;
2506 /* TODO: make this completely nonblocking */
2507 status = receive_smb_talloc(mem_ctx, xconn, fd,
2508 (char **)(void *)&inbuf,
2509 0, /* timeout */
2510 &unread_bytes,
2511 &encrypted,
2512 &inbuf_len, &seqnum,
2513 !from_client /* trusted channel */);
2515 if (async_echo && from_client) {
2516 smbd_unlock_socket(xconn);
2519 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2520 goto process;
2522 if (NT_STATUS_IS_ERR(status)) {
2523 exit_server_cleanly("failed to receive smb request");
2525 if (!NT_STATUS_IS_OK(status)) {
2526 return;
2529 process:
2530 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2531 seqnum, encrypted, NULL);
2534 static void smbd_server_connection_handler(struct tevent_context *ev,
2535 struct tevent_fd *fde,
2536 uint16_t flags,
2537 void *private_data)
2539 struct smbXsrv_connection *xconn =
2540 talloc_get_type_abort(private_data,
2541 struct smbXsrv_connection);
2543 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2545 * we're not supposed to do any io
2547 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2548 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2549 return;
2552 if (flags & TEVENT_FD_WRITE) {
2553 smbd_server_connection_write_handler(xconn);
2554 return;
2556 if (flags & TEVENT_FD_READ) {
2557 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2558 return;
2562 static void smbd_server_echo_handler(struct tevent_context *ev,
2563 struct tevent_fd *fde,
2564 uint16_t flags,
2565 void *private_data)
2567 struct smbXsrv_connection *xconn =
2568 talloc_get_type_abort(private_data,
2569 struct smbXsrv_connection);
2571 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2573 * we're not supposed to do any io
2575 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2576 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2577 return;
2580 if (flags & TEVENT_FD_WRITE) {
2581 smbd_server_connection_write_handler(xconn);
2582 return;
2584 if (flags & TEVENT_FD_READ) {
2585 smbd_server_connection_read_handler(
2586 xconn, xconn->smb1.echo_handler.trusted_fd);
2587 return;
2591 struct smbd_release_ip_state {
2592 struct smbXsrv_connection *xconn;
2593 struct tevent_immediate *im;
2594 char addr[INET6_ADDRSTRLEN];
2597 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2598 struct tevent_immediate *im,
2599 void *private_data)
2601 struct smbd_release_ip_state *state =
2602 talloc_get_type_abort(private_data,
2603 struct smbd_release_ip_state);
2604 struct smbXsrv_connection *xconn = state->xconn;
2606 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2608 * smbd_server_connection_terminate() already triggered ?
2610 return;
2613 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2616 /****************************************************************************
2617 received when we should release a specific IP
2618 ****************************************************************************/
2619 static int release_ip(uint32_t src_vnn, uint32_t dst_vnn,
2620 uint64_t dst_srvid,
2621 const uint8_t *msg, size_t msglen,
2622 void *private_data)
2624 struct smbd_release_ip_state *state =
2625 talloc_get_type_abort(private_data,
2626 struct smbd_release_ip_state);
2627 struct smbXsrv_connection *xconn = state->xconn;
2628 const char *ip;
2629 const char *addr = state->addr;
2630 const char *p = addr;
2632 if (msglen == 0) {
2633 return 0;
2635 if (msg[msglen-1] != '\0') {
2636 return 0;
2639 ip = (const char *)msg;
2641 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2642 /* avoid recursion */
2643 return 0;
2646 if (strncmp("::ffff:", addr, 7) == 0) {
2647 p = addr + 7;
2650 DEBUG(10, ("Got release IP message for %s, "
2651 "our address is %s\n", ip, p));
2653 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2654 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2655 ip));
2657 * With SMB2 we should do a clean disconnect,
2658 * the previous_session_id in the session setup
2659 * will cleanup the old session, tcons and opens.
2661 * A clean disconnect is needed in order to support
2662 * durable handles.
2664 * Note: typically this is never triggered
2665 * as we got a TCP RST (triggered by ctdb event scripts)
2666 * before we get CTDB_SRVID_RELEASE_IP.
2668 * We used to call _exit(1) here, but as this was mostly never
2669 * triggered and has implication on our process model,
2670 * we can just use smbd_server_connection_terminate()
2671 * (also for SMB1).
2673 * We don't call smbd_server_connection_terminate() directly
2674 * as we might be called from within ctdbd_migrate(),
2675 * we need to defer our action to the next event loop
2677 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2678 smbd_release_ip_immediate, state);
2681 * Make sure we don't get any io on the connection.
2683 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2684 return EADDRNOTAVAIL;
2687 return 0;
2690 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2691 struct sockaddr_storage *srv,
2692 struct sockaddr_storage *clnt)
2694 struct smbd_release_ip_state *state;
2695 struct ctdbd_connection *cconn;
2696 int ret;
2698 cconn = messaging_ctdbd_connection();
2699 if (cconn == NULL) {
2700 return NT_STATUS_NO_MEMORY;
2703 state = talloc_zero(xconn, struct smbd_release_ip_state);
2704 if (state == NULL) {
2705 return NT_STATUS_NO_MEMORY;
2707 state->xconn = xconn;
2708 state->im = tevent_create_immediate(state);
2709 if (state->im == NULL) {
2710 return NT_STATUS_NO_MEMORY;
2712 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2713 return NT_STATUS_NO_MEMORY;
2716 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2717 if (ret != 0) {
2718 return map_nt_error_from_unix(ret);
2720 return NT_STATUS_OK;
2723 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2724 void *private_data, uint32_t msg_type,
2725 struct server_id server_id, DATA_BLOB *data)
2727 struct smbd_server_connection *sconn = talloc_get_type_abort(
2728 private_data, struct smbd_server_connection);
2729 const char *ip = (char *) data->data;
2730 char *client_ip;
2732 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2734 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2735 talloc_tos());
2736 if (client_ip == NULL) {
2737 return;
2740 if (strequal(ip, client_ip)) {
2741 DBG_WARNING("Got kill client message for %s - "
2742 "exiting immediately\n", ip);
2743 exit_server_cleanly("Forced disconnect for client");
2746 TALLOC_FREE(client_ip);
2750 * Send keepalive packets to our client
2752 static bool keepalive_fn(const struct timeval *now, void *private_data)
2754 struct smbd_server_connection *sconn = talloc_get_type_abort(
2755 private_data, struct smbd_server_connection);
2756 struct smbXsrv_connection *xconn = NULL;
2757 bool ret;
2759 if (sconn->using_smb2) {
2760 /* Don't do keepalives on an SMB2 connection. */
2761 return false;
2765 * With SMB1 we only have 1 connection
2767 xconn = sconn->client->connections;
2768 smbd_lock_socket(xconn);
2769 ret = send_keepalive(xconn->transport.sock);
2770 smbd_unlock_socket(xconn);
2772 if (!ret) {
2773 int saved_errno = errno;
2775 * Try and give an error message saying what
2776 * client failed.
2778 DEBUG(0, ("send_keepalive failed for client %s. "
2779 "Error %s - exiting\n",
2780 smbXsrv_connection_dbg(xconn),
2781 strerror(saved_errno)));
2782 errno = saved_errno;
2783 return False;
2785 return True;
2789 * Do the recurring check if we're idle
2791 static bool deadtime_fn(const struct timeval *now, void *private_data)
2793 struct smbd_server_connection *sconn =
2794 (struct smbd_server_connection *)private_data;
2796 if ((conn_num_open(sconn) == 0)
2797 || (conn_idle_all(sconn, now->tv_sec))) {
2798 DEBUG( 2, ( "Closing idle connection\n" ) );
2799 messaging_send(sconn->msg_ctx,
2800 messaging_server_id(sconn->msg_ctx),
2801 MSG_SHUTDOWN, &data_blob_null);
2802 return False;
2805 return True;
2809 * Do the recurring log file and smb.conf reload checks.
2812 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2814 struct smbd_server_connection *sconn = talloc_get_type_abort(
2815 private_data, struct smbd_server_connection);
2817 DEBUG(5, ("housekeeping\n"));
2819 change_to_root_user();
2821 /* update printer queue caches if necessary */
2822 update_monitored_printq_cache(sconn->msg_ctx);
2824 /* check if we need to reload services */
2825 check_reload(sconn, time_mono(NULL));
2828 * Force a log file check.
2830 force_check_log_size();
2831 check_log_size();
2832 return true;
2836 * Read an smb packet in the echo handler child, giving the parent
2837 * smbd one second to react once the socket becomes readable.
2840 struct smbd_echo_read_state {
2841 struct tevent_context *ev;
2842 struct smbXsrv_connection *xconn;
2844 char *buf;
2845 size_t buflen;
2846 uint32_t seqnum;
2849 static void smbd_echo_read_readable(struct tevent_req *subreq);
2850 static void smbd_echo_read_waited(struct tevent_req *subreq);
2852 static struct tevent_req *smbd_echo_read_send(
2853 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2854 struct smbXsrv_connection *xconn)
2856 struct tevent_req *req, *subreq;
2857 struct smbd_echo_read_state *state;
2859 req = tevent_req_create(mem_ctx, &state,
2860 struct smbd_echo_read_state);
2861 if (req == NULL) {
2862 return NULL;
2864 state->ev = ev;
2865 state->xconn = xconn;
2867 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2868 if (tevent_req_nomem(subreq, req)) {
2869 return tevent_req_post(req, ev);
2871 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2872 return req;
2875 static void smbd_echo_read_readable(struct tevent_req *subreq)
2877 struct tevent_req *req = tevent_req_callback_data(
2878 subreq, struct tevent_req);
2879 struct smbd_echo_read_state *state = tevent_req_data(
2880 req, struct smbd_echo_read_state);
2881 bool ok;
2882 int err;
2884 ok = wait_for_read_recv(subreq, &err);
2885 TALLOC_FREE(subreq);
2886 if (!ok) {
2887 tevent_req_nterror(req, map_nt_error_from_unix(err));
2888 return;
2892 * Give the parent smbd one second to step in
2895 subreq = tevent_wakeup_send(
2896 state, state->ev, timeval_current_ofs(1, 0));
2897 if (tevent_req_nomem(subreq, req)) {
2898 return;
2900 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2903 static void smbd_echo_read_waited(struct tevent_req *subreq)
2905 struct tevent_req *req = tevent_req_callback_data(
2906 subreq, struct tevent_req);
2907 struct smbd_echo_read_state *state = tevent_req_data(
2908 req, struct smbd_echo_read_state);
2909 struct smbXsrv_connection *xconn = state->xconn;
2910 bool ok;
2911 NTSTATUS status;
2912 size_t unread = 0;
2913 bool encrypted;
2915 ok = tevent_wakeup_recv(subreq);
2916 TALLOC_FREE(subreq);
2917 if (!ok) {
2918 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2919 return;
2922 ok = smbd_lock_socket_internal(xconn);
2923 if (!ok) {
2924 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2925 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2926 return;
2929 if (!fd_is_readable(xconn->transport.sock)) {
2930 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2931 (int)getpid()));
2933 ok = smbd_unlock_socket_internal(xconn);
2934 if (!ok) {
2935 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2936 DEBUG(1, ("%s: failed to unlock socket\n",
2937 __location__));
2938 return;
2941 subreq = wait_for_read_send(state, state->ev,
2942 xconn->transport.sock, false);
2943 if (tevent_req_nomem(subreq, req)) {
2944 return;
2946 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2947 return;
2950 status = receive_smb_talloc(state, xconn,
2951 xconn->transport.sock,
2952 &state->buf,
2953 0 /* timeout */,
2954 &unread,
2955 &encrypted,
2956 &state->buflen,
2957 &state->seqnum,
2958 false /* trusted_channel*/);
2960 if (tevent_req_nterror(req, status)) {
2961 tevent_req_nterror(req, status);
2962 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2963 (int)getpid(), nt_errstr(status)));
2964 return;
2967 ok = smbd_unlock_socket_internal(xconn);
2968 if (!ok) {
2969 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2970 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2971 return;
2973 tevent_req_done(req);
2976 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2977 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2979 struct smbd_echo_read_state *state = tevent_req_data(
2980 req, struct smbd_echo_read_state);
2981 NTSTATUS status;
2983 if (tevent_req_is_nterror(req, &status)) {
2984 return status;
2986 *pbuf = talloc_move(mem_ctx, &state->buf);
2987 *pbuflen = state->buflen;
2988 *pseqnum = state->seqnum;
2989 return NT_STATUS_OK;
2992 struct smbd_echo_state {
2993 struct tevent_context *ev;
2994 struct iovec *pending;
2995 struct smbd_server_connection *sconn;
2996 struct smbXsrv_connection *xconn;
2997 int parent_pipe;
2999 struct tevent_fd *parent_fde;
3001 struct tevent_req *write_req;
3004 static void smbd_echo_writer_done(struct tevent_req *req);
3006 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3008 int num_pending;
3010 if (state->write_req != NULL) {
3011 return;
3014 num_pending = talloc_array_length(state->pending);
3015 if (num_pending == 0) {
3016 return;
3019 state->write_req = writev_send(state, state->ev, NULL,
3020 state->parent_pipe, false,
3021 state->pending, num_pending);
3022 if (state->write_req == NULL) {
3023 DEBUG(1, ("writev_send failed\n"));
3024 exit(1);
3027 talloc_steal(state->write_req, state->pending);
3028 state->pending = NULL;
3030 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3031 state);
3034 static void smbd_echo_writer_done(struct tevent_req *req)
3036 struct smbd_echo_state *state = tevent_req_callback_data(
3037 req, struct smbd_echo_state);
3038 ssize_t written;
3039 int err;
3041 written = writev_recv(req, &err);
3042 TALLOC_FREE(req);
3043 state->write_req = NULL;
3044 if (written == -1) {
3045 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3046 exit(1);
3048 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3049 smbd_echo_activate_writer(state);
3052 static bool smbd_echo_reply(struct smbd_echo_state *state,
3053 uint8_t *inbuf, size_t inbuf_len,
3054 uint32_t seqnum)
3056 struct smb_request req;
3057 uint16_t num_replies;
3058 char *outbuf;
3059 bool ok;
3061 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3062 DEBUG(10, ("Got netbios keepalive\n"));
3064 * Just swallow it
3066 return true;
3069 if (inbuf_len < smb_size) {
3070 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3071 return false;
3073 if (!valid_smb_header(inbuf)) {
3074 DEBUG(10, ("Got invalid SMB header\n"));
3075 return false;
3078 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3079 seqnum)) {
3080 return false;
3082 req.inbuf = inbuf;
3084 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3085 smb_messages[req.cmd].name
3086 ? smb_messages[req.cmd].name : "unknown"));
3088 if (req.cmd != SMBecho) {
3089 return false;
3091 if (req.wct < 1) {
3092 return false;
3095 num_replies = SVAL(req.vwv+0, 0);
3096 if (num_replies != 1) {
3097 /* Not a Windows "Hey, you're still there?" request */
3098 return false;
3101 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3102 1, req.buflen)) {
3103 DEBUG(10, ("create_outbuf failed\n"));
3104 return false;
3106 req.outbuf = (uint8_t *)outbuf;
3108 SSVAL(req.outbuf, smb_vwv0, num_replies);
3110 if (req.buflen > 0) {
3111 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3114 ok = srv_send_smb(req.xconn,
3115 (char *)outbuf,
3116 true, seqnum+1,
3117 false, &req.pcd);
3118 TALLOC_FREE(outbuf);
3119 if (!ok) {
3120 exit(1);
3123 return true;
3126 static void smbd_echo_exit(struct tevent_context *ev,
3127 struct tevent_fd *fde, uint16_t flags,
3128 void *private_data)
3130 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3131 exit(0);
3134 static void smbd_echo_got_packet(struct tevent_req *req);
3136 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3137 int parent_pipe)
3139 struct smbd_echo_state *state;
3140 struct tevent_req *read_req;
3142 state = talloc_zero(xconn, struct smbd_echo_state);
3143 if (state == NULL) {
3144 DEBUG(1, ("talloc failed\n"));
3145 return;
3147 state->xconn = xconn;
3148 state->parent_pipe = parent_pipe;
3149 state->ev = s3_tevent_context_init(state);
3150 if (state->ev == NULL) {
3151 DEBUG(1, ("tevent_context_init failed\n"));
3152 TALLOC_FREE(state);
3153 return;
3155 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3156 TEVENT_FD_READ, smbd_echo_exit,
3157 state);
3158 if (state->parent_fde == NULL) {
3159 DEBUG(1, ("tevent_add_fd failed\n"));
3160 TALLOC_FREE(state);
3161 return;
3164 read_req = smbd_echo_read_send(state, state->ev, xconn);
3165 if (read_req == NULL) {
3166 DEBUG(1, ("smbd_echo_read_send failed\n"));
3167 TALLOC_FREE(state);
3168 return;
3170 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3172 while (true) {
3173 if (tevent_loop_once(state->ev) == -1) {
3174 DEBUG(1, ("tevent_loop_once failed: %s\n",
3175 strerror(errno)));
3176 break;
3179 TALLOC_FREE(state);
3182 static void smbd_echo_got_packet(struct tevent_req *req)
3184 struct smbd_echo_state *state = tevent_req_callback_data(
3185 req, struct smbd_echo_state);
3186 NTSTATUS status;
3187 char *buf = NULL;
3188 size_t buflen = 0;
3189 uint32_t seqnum = 0;
3190 bool reply;
3192 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3193 TALLOC_FREE(req);
3194 if (!NT_STATUS_IS_OK(status)) {
3195 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3196 nt_errstr(status)));
3197 exit(1);
3200 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3201 if (!reply) {
3202 size_t num_pending;
3203 struct iovec *tmp;
3204 struct iovec *iov;
3206 num_pending = talloc_array_length(state->pending);
3207 tmp = talloc_realloc(state, state->pending, struct iovec,
3208 num_pending+1);
3209 if (tmp == NULL) {
3210 DEBUG(1, ("talloc_realloc failed\n"));
3211 exit(1);
3213 state->pending = tmp;
3215 if (buflen >= smb_size) {
3217 * place the seqnum in the packet so that the main process
3218 * can reply with signing
3220 SIVAL(buf, smb_ss_field, seqnum);
3221 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3224 iov = &state->pending[num_pending];
3225 iov->iov_base = talloc_move(state->pending, &buf);
3226 iov->iov_len = buflen;
3228 DEBUG(10,("echo_handler[%d]: forward to main\n",
3229 (int)getpid()));
3230 smbd_echo_activate_writer(state);
3233 req = smbd_echo_read_send(state, state->ev, state->xconn);
3234 if (req == NULL) {
3235 DEBUG(1, ("smbd_echo_read_send failed\n"));
3236 exit(1);
3238 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3243 * Handle SMBecho requests in a forked child process
3245 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3247 int listener_pipe[2];
3248 int res;
3249 pid_t child;
3250 bool use_mutex = false;
3252 res = pipe(listener_pipe);
3253 if (res == -1) {
3254 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3255 return false;
3258 #ifdef HAVE_ROBUST_MUTEXES
3259 use_mutex = tdb_runtime_check_for_robust_mutexes();
3261 if (use_mutex) {
3262 pthread_mutexattr_t a;
3264 xconn->smb1.echo_handler.socket_mutex =
3265 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3266 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3267 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3268 strerror(errno)));
3269 goto fail;
3272 res = pthread_mutexattr_init(&a);
3273 if (res != 0) {
3274 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3275 strerror(res)));
3276 goto fail;
3278 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3279 if (res != 0) {
3280 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3281 strerror(res)));
3282 pthread_mutexattr_destroy(&a);
3283 goto fail;
3285 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3286 if (res != 0) {
3287 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3288 strerror(res)));
3289 pthread_mutexattr_destroy(&a);
3290 goto fail;
3292 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3293 if (res != 0) {
3294 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3295 "%s\n", strerror(res)));
3296 pthread_mutexattr_destroy(&a);
3297 goto fail;
3299 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3300 &a);
3301 pthread_mutexattr_destroy(&a);
3302 if (res != 0) {
3303 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3304 strerror(res)));
3305 goto fail;
3308 #endif
3310 if (!use_mutex) {
3311 xconn->smb1.echo_handler.socket_lock_fd =
3312 create_unlink_tmp(lp_lock_directory());
3313 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3314 DEBUG(1, ("Could not create lock fd: %s\n",
3315 strerror(errno)));
3316 goto fail;
3320 child = fork();
3321 if (child == 0) {
3322 NTSTATUS status;
3324 close(listener_pipe[0]);
3325 set_blocking(listener_pipe[1], false);
3327 status = smbd_reinit_after_fork(xconn->msg_ctx, xconn->ev_ctx,
3328 true, "smbd-echo");
3329 if (!NT_STATUS_IS_OK(status)) {
3330 DEBUG(1, ("reinit_after_fork failed: %s\n",
3331 nt_errstr(status)));
3332 exit(1);
3334 smbd_echo_loop(xconn, listener_pipe[1]);
3335 exit(0);
3337 close(listener_pipe[1]);
3338 listener_pipe[1] = -1;
3339 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3341 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3344 * Without smb signing this is the same as the normal smbd
3345 * listener. This needs to change once signing comes in.
3347 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3348 xconn,
3349 xconn->smb1.echo_handler.trusted_fd,
3350 TEVENT_FD_READ,
3351 smbd_server_echo_handler,
3352 xconn);
3353 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3354 DEBUG(1, ("event_add_fd failed\n"));
3355 goto fail;
3358 return true;
3360 fail:
3361 if (listener_pipe[0] != -1) {
3362 close(listener_pipe[0]);
3364 if (listener_pipe[1] != -1) {
3365 close(listener_pipe[1]);
3367 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3368 close(xconn->smb1.echo_handler.socket_lock_fd);
3370 #ifdef HAVE_ROBUST_MUTEXES
3371 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3372 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3373 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3375 #endif
3376 smbd_echo_init(xconn);
3378 return false;
3381 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3383 while (user) {
3384 if (user->session_info &&
3385 (user->session_info->unix_token->uid == uid)) {
3386 return true;
3388 user = user->next;
3390 return false;
3393 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3395 while (user) {
3396 if (user->session_info != NULL) {
3397 int i;
3398 struct security_unix_token *utok;
3400 utok = user->session_info->unix_token;
3401 if (utok->gid == gid) {
3402 return true;
3404 for(i=0; i<utok->ngroups; i++) {
3405 if (utok->groups[i] == gid) {
3406 return true;
3410 user = user->next;
3412 return false;
3415 static bool sid_in_use(const struct user_struct *user,
3416 const struct dom_sid *psid)
3418 while (user) {
3419 struct security_token *tok;
3421 if (user->session_info == NULL) {
3422 continue;
3424 tok = user->session_info->security_token;
3425 if (tok == NULL) {
3427 * Not sure session_info->security_token can
3428 * ever be NULL. This check might be not
3429 * necessary.
3431 continue;
3433 if (security_token_has_sid(tok, psid)) {
3434 return true;
3436 user = user->next;
3438 return false;
3441 static bool id_in_use(const struct user_struct *user,
3442 const struct id_cache_ref *id)
3444 switch(id->type) {
3445 case UID:
3446 return uid_in_use(user, id->id.uid);
3447 case GID:
3448 return gid_in_use(user, id->id.gid);
3449 case SID:
3450 return sid_in_use(user, &id->id.sid);
3451 default:
3452 break;
3454 return false;
3457 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3458 void *private_data,
3459 uint32_t msg_type,
3460 struct server_id server_id,
3461 DATA_BLOB* data)
3463 const char *msg = (data && data->data)
3464 ? (const char *)data->data : "<NULL>";
3465 struct id_cache_ref id;
3466 struct smbd_server_connection *sconn =
3467 talloc_get_type_abort(private_data,
3468 struct smbd_server_connection);
3470 if (!id_cache_ref_parse(msg, &id)) {
3471 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3472 return;
3475 if (id_in_use(sconn->users, &id)) {
3476 exit_server_cleanly(msg);
3478 id_cache_delete_from_cache(&id);
3481 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3482 enum protocol_types protocol)
3484 NTSTATUS status;
3486 conn->protocol = protocol;
3488 if (protocol >= PROTOCOL_SMB2_02) {
3489 status = smb2srv_session_table_init(conn);
3490 if (!NT_STATUS_IS_OK(status)) {
3491 conn->protocol = PROTOCOL_NONE;
3492 return status;
3495 status = smb2srv_open_table_init(conn);
3496 if (!NT_STATUS_IS_OK(status)) {
3497 conn->protocol = PROTOCOL_NONE;
3498 return status;
3500 } else {
3501 status = smb1srv_session_table_init(conn);
3502 if (!NT_STATUS_IS_OK(status)) {
3503 conn->protocol = PROTOCOL_NONE;
3504 return status;
3507 status = smb1srv_tcon_table_init(conn);
3508 if (!NT_STATUS_IS_OK(status)) {
3509 conn->protocol = PROTOCOL_NONE;
3510 return status;
3513 status = smb1srv_open_table_init(conn);
3514 if (!NT_STATUS_IS_OK(status)) {
3515 conn->protocol = PROTOCOL_NONE;
3516 return status;
3520 set_Protocol(protocol);
3521 return NT_STATUS_OK;
3524 struct smbd_tevent_trace_state {
3525 struct tevent_context *ev;
3526 TALLOC_CTX *frame;
3527 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3530 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3531 void *private_data)
3533 struct smbd_tevent_trace_state *state =
3534 (struct smbd_tevent_trace_state *)private_data;
3536 switch (point) {
3537 case TEVENT_TRACE_BEFORE_WAIT:
3538 if (!smbprofile_dump_pending()) {
3540 * If there's no dump pending
3541 * we don't want to schedule a new 1 sec timer.
3543 * Instead we want to sleep as long as nothing happens.
3545 smbprofile_dump_setup(NULL);
3547 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3548 break;
3549 case TEVENT_TRACE_AFTER_WAIT:
3550 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3551 if (!smbprofile_dump_pending()) {
3553 * We need to flush our state after sleeping
3554 * (hopefully a long time).
3556 smbprofile_dump();
3558 * future profiling events should trigger timers
3559 * on our main event context.
3561 smbprofile_dump_setup(state->ev);
3563 break;
3564 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3565 TALLOC_FREE(state->frame);
3566 state->frame = talloc_stackframe_pool(8192);
3567 break;
3568 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3569 TALLOC_FREE(state->frame);
3570 break;
3573 errno = 0;
3577 * Create a debug string for the connection
3579 * This is allocated to talloc_tos() or a string constant
3580 * in certain corner cases. The returned string should
3581 * hence not be free'd directly but only via the talloc stack.
3583 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3585 const char *ret;
3588 * TODO: this can be improved later
3589 * maybe including the client guid or more
3591 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3592 if (ret == NULL) {
3593 return "<tsocket_address_string() failed>";
3596 return ret;
3599 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3600 struct smbXsrv_connection **_xconn)
3602 TALLOC_CTX *frame = talloc_stackframe();
3603 struct smbXsrv_connection *xconn;
3604 struct sockaddr_storage ss_srv;
3605 void *sp_srv = (void *)&ss_srv;
3606 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3607 struct sockaddr_storage ss_clnt;
3608 void *sp_clnt = (void *)&ss_clnt;
3609 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3610 socklen_t sa_socklen;
3611 struct tsocket_address *local_address = NULL;
3612 struct tsocket_address *remote_address = NULL;
3613 const char *remaddr = NULL;
3614 char *p;
3615 const char *rhost = NULL;
3616 int ret;
3617 int tmp;
3619 *_xconn = NULL;
3621 DO_PROFILE_INC(connect);
3623 xconn = talloc_zero(client, struct smbXsrv_connection);
3624 if (xconn == NULL) {
3625 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3626 TALLOC_FREE(frame);
3627 return NT_STATUS_NO_MEMORY;
3629 talloc_steal(frame, xconn);
3631 xconn->ev_ctx = client->ev_ctx;
3632 xconn->msg_ctx = client->msg_ctx;
3633 xconn->transport.sock = sock_fd;
3634 smbd_echo_init(xconn);
3635 xconn->protocol = PROTOCOL_NONE;
3637 /* Ensure child is set to blocking mode */
3638 set_blocking(sock_fd,True);
3640 set_socket_options(sock_fd, "SO_KEEPALIVE");
3641 set_socket_options(sock_fd, lp_socket_options());
3643 sa_socklen = sizeof(ss_clnt);
3644 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3645 if (ret != 0) {
3646 int saved_errno = errno;
3647 int level = (errno == ENOTCONN)?2:0;
3648 DEBUG(level,("getpeername() failed - %s\n",
3649 strerror(saved_errno)));
3650 TALLOC_FREE(frame);
3651 return map_nt_error_from_unix_common(saved_errno);
3653 ret = tsocket_address_bsd_from_sockaddr(xconn,
3654 sa_clnt, sa_socklen,
3655 &remote_address);
3656 if (ret != 0) {
3657 int saved_errno = errno;
3658 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3659 __location__, strerror(saved_errno)));
3660 TALLOC_FREE(frame);
3661 return map_nt_error_from_unix_common(saved_errno);
3664 sa_socklen = sizeof(ss_srv);
3665 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3666 if (ret != 0) {
3667 int saved_errno = errno;
3668 int level = (errno == ENOTCONN)?2:0;
3669 DEBUG(level,("getsockname() failed - %s\n",
3670 strerror(saved_errno)));
3671 TALLOC_FREE(frame);
3672 return map_nt_error_from_unix_common(saved_errno);
3674 ret = tsocket_address_bsd_from_sockaddr(xconn,
3675 sa_srv, sa_socklen,
3676 &local_address);
3677 if (ret != 0) {
3678 int saved_errno = errno;
3679 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3680 __location__, strerror(saved_errno)));
3681 TALLOC_FREE(frame);
3682 return map_nt_error_from_unix_common(saved_errno);
3685 if (tsocket_address_is_inet(remote_address, "ip")) {
3686 remaddr = tsocket_address_inet_addr_string(remote_address,
3687 talloc_tos());
3688 if (remaddr == NULL) {
3689 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3690 __location__, strerror(errno)));
3691 TALLOC_FREE(frame);
3692 return NT_STATUS_NO_MEMORY;
3694 } else {
3695 remaddr = "0.0.0.0";
3699 * Before the first packet, check the global hosts allow/ hosts deny
3700 * parameters before doing any parsing of packets passed to us by the
3701 * client. This prevents attacks on our parsing code from hosts not in
3702 * the hosts allow list.
3705 ret = get_remote_hostname(remote_address,
3706 &p, talloc_tos());
3707 if (ret < 0) {
3708 int saved_errno = errno;
3709 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3710 __location__, strerror(saved_errno)));
3711 TALLOC_FREE(frame);
3712 return map_nt_error_from_unix_common(saved_errno);
3714 rhost = p;
3715 if (strequal(rhost, "UNKNOWN")) {
3716 rhost = remaddr;
3719 xconn->local_address = local_address;
3720 xconn->remote_address = remote_address;
3721 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3722 if (xconn->remote_hostname == NULL) {
3723 return NT_STATUS_NO_MEMORY;
3726 if (!srv_init_signing(xconn)) {
3727 DEBUG(0, ("Failed to init smb_signing\n"));
3728 TALLOC_FREE(frame);
3729 return NT_STATUS_INTERNAL_ERROR;
3732 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3733 xconn->remote_hostname,
3734 remaddr)) {
3735 DEBUG( 1, ("Connection denied from %s to %s\n",
3736 tsocket_address_string(remote_address, talloc_tos()),
3737 tsocket_address_string(local_address, talloc_tos())));
3740 * We return a valid xconn
3741 * so that the caller can return an error message
3742 * to the client
3744 client->connections = xconn;
3745 xconn->client = client;
3746 talloc_steal(client, xconn);
3748 *_xconn = xconn;
3749 TALLOC_FREE(frame);
3750 return NT_STATUS_NETWORK_ACCESS_DENIED;
3753 DEBUG(10, ("Connection allowed from %s to %s\n",
3754 tsocket_address_string(remote_address, talloc_tos()),
3755 tsocket_address_string(local_address, talloc_tos())));
3757 if (lp_clustering()) {
3759 * We need to tell ctdb about our client's TCP
3760 * connection, so that for failover ctdbd can send
3761 * tickle acks, triggering a reconnection by the
3762 * client.
3764 NTSTATUS status;
3766 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3767 if (!NT_STATUS_IS_OK(status)) {
3768 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3769 nt_errstr(status)));
3773 tmp = lp_max_xmit();
3774 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3775 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3777 xconn->smb1.negprot.max_recv = tmp;
3779 xconn->smb1.sessions.done_sesssetup = false;
3780 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3782 xconn->transport.fde = tevent_add_fd(client->ev_ctx,
3783 xconn,
3784 sock_fd,
3785 TEVENT_FD_READ,
3786 smbd_server_connection_handler,
3787 xconn);
3788 if (!xconn->transport.fde) {
3789 TALLOC_FREE(frame);
3790 return NT_STATUS_NO_MEMORY;
3793 /* for now we only have one connection */
3794 DLIST_ADD_END(client->connections, xconn, NULL);
3795 xconn->client = client;
3796 talloc_steal(client, xconn);
3798 *_xconn = xconn;
3799 TALLOC_FREE(frame);
3800 return NT_STATUS_OK;
3803 /****************************************************************************
3804 Process commands from the client
3805 ****************************************************************************/
3807 void smbd_process(struct tevent_context *ev_ctx,
3808 struct messaging_context *msg_ctx,
3809 int sock_fd,
3810 bool interactive)
3812 struct smbd_tevent_trace_state trace_state = {
3813 .ev = ev_ctx,
3814 .frame = talloc_stackframe(),
3816 struct smbXsrv_client *client = NULL;
3817 struct smbd_server_connection *sconn = NULL;
3818 struct smbXsrv_connection *xconn = NULL;
3819 const char *locaddr = NULL;
3820 const char *remaddr = NULL;
3821 int ret;
3822 NTSTATUS status;
3824 client = talloc_zero(ev_ctx, struct smbXsrv_client);
3825 if (client == NULL) {
3826 DEBUG(0,("talloc_zero(struct smbXsrv_client)\n"));
3827 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3831 * TODO: remove this...:-)
3833 global_smbXsrv_client = client;
3835 client->ev_ctx = ev_ctx;
3836 client->msg_ctx = msg_ctx;
3838 sconn = talloc_zero(client, struct smbd_server_connection);
3839 if (sconn == NULL) {
3840 exit_server("failed to create smbd_server_connection");
3843 client->sconn = sconn;
3844 sconn->client = client;
3846 sconn->ev_ctx = ev_ctx;
3847 sconn->msg_ctx = msg_ctx;
3849 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3851 * We're not making the decision here,
3852 * we're just allowing the client
3853 * to decide between SMB1 and SMB2
3854 * with the first negprot
3855 * packet.
3857 sconn->using_smb2 = true;
3860 if (!interactive) {
3861 smbd_setup_sig_term_handler(sconn);
3862 smbd_setup_sig_hup_handler(sconn);
3864 if (!serverid_register(messaging_server_id(msg_ctx),
3865 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3866 |FLAG_MSG_DBWRAP
3867 |FLAG_MSG_PRINT_GENERAL)) {
3868 exit_server_cleanly("Could not register myself in "
3869 "serverid.tdb");
3873 status = smbd_add_connection(client, sock_fd, &xconn);
3874 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3876 * send a negative session response "not listening on calling
3877 * name"
3879 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3880 (void)srv_send_smb(xconn,(char *)buf, false,
3881 0, false, NULL);
3882 exit_server_cleanly("connection denied");
3883 } else if (!NT_STATUS_IS_OK(status)) {
3884 exit_server_cleanly(nt_errstr(status));
3887 sconn->local_address =
3888 tsocket_address_copy(xconn->local_address, sconn);
3889 if (sconn->local_address == NULL) {
3890 exit_server_cleanly("tsocket_address_copy() failed");
3892 sconn->remote_address =
3893 tsocket_address_copy(xconn->remote_address, sconn);
3894 if (sconn->remote_address == NULL) {
3895 exit_server_cleanly("tsocket_address_copy() failed");
3897 sconn->remote_hostname =
3898 talloc_strdup(sconn, xconn->remote_hostname);
3899 if (sconn->remote_hostname == NULL) {
3900 exit_server_cleanly("tsocket_strdup() failed");
3903 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3904 locaddr = tsocket_address_inet_addr_string(
3905 sconn->local_address,
3906 talloc_tos());
3907 if (locaddr == NULL) {
3908 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3909 __location__, strerror(errno)));
3910 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3912 } else {
3913 locaddr = "0.0.0.0";
3916 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
3917 remaddr = tsocket_address_inet_addr_string(
3918 sconn->remote_address,
3919 talloc_tos());
3920 if (remaddr == NULL) {
3921 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3922 __location__, strerror(errno)));
3923 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3925 } else {
3926 remaddr = "0.0.0.0";
3929 /* this is needed so that we get decent entries
3930 in smbstatus for port 445 connects */
3931 set_remote_machine_name(remaddr, false);
3932 reload_services(sconn, conn_snum_used, true);
3933 sub_set_socket_ids(remaddr,
3934 sconn->remote_hostname,
3935 locaddr);
3937 if (lp_preload_modules()) {
3938 smb_load_modules(lp_preload_modules());
3941 smb_perfcount_init();
3943 if (!init_account_policy()) {
3944 exit_server("Could not open account policy tdb.\n");
3947 if (*lp_root_directory(talloc_tos())) {
3948 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3949 DEBUG(0,("Failed to change root to %s\n",
3950 lp_root_directory(talloc_tos())));
3951 exit_server("Failed to chroot()");
3953 if (chdir("/") == -1) {
3954 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3955 exit_server("Failed to chroot()");
3957 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3960 if (!file_init(sconn)) {
3961 exit_server("file_init() failed");
3964 /* Setup oplocks */
3965 if (!init_oplocks(sconn))
3966 exit_server("Failed to init oplocks");
3968 /* register our message handlers */
3969 messaging_register(sconn->msg_ctx, sconn,
3970 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3971 messaging_register(sconn->msg_ctx, sconn,
3972 MSG_SMB_CLOSE_FILE, msg_close_file);
3973 messaging_register(sconn->msg_ctx, sconn,
3974 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3976 id_cache_register_msgs(sconn->msg_ctx);
3977 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3978 messaging_register(sconn->msg_ctx, sconn,
3979 ID_CACHE_KILL, smbd_id_cache_kill);
3981 messaging_deregister(sconn->msg_ctx,
3982 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3983 messaging_register(sconn->msg_ctx, sconn,
3984 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3986 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3987 NULL);
3988 messaging_register(sconn->msg_ctx, sconn,
3989 MSG_SMB_KILL_CLIENT_IP,
3990 msg_kill_client_ip);
3992 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3995 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3996 * MSGs to all child processes
3998 messaging_deregister(sconn->msg_ctx,
3999 MSG_DEBUG, NULL);
4000 messaging_register(sconn->msg_ctx, NULL,
4001 MSG_DEBUG, debug_message);
4003 if ((lp_keepalive() != 0)
4004 && !(event_add_idle(ev_ctx, NULL,
4005 timeval_set(lp_keepalive(), 0),
4006 "keepalive", keepalive_fn,
4007 sconn))) {
4008 DEBUG(0, ("Could not add keepalive event\n"));
4009 exit(1);
4012 if (!(event_add_idle(ev_ctx, NULL,
4013 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4014 "deadtime", deadtime_fn, sconn))) {
4015 DEBUG(0, ("Could not add deadtime event\n"));
4016 exit(1);
4019 if (!(event_add_idle(ev_ctx, NULL,
4020 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4021 "housekeeping", housekeeping_fn, sconn))) {
4022 DEBUG(0, ("Could not add housekeeping event\n"));
4023 exit(1);
4026 smbprofile_dump_setup(ev_ctx);
4028 if (!init_dptrs(sconn)) {
4029 exit_server("init_dptrs() failed");
4032 TALLOC_FREE(trace_state.frame);
4034 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4035 &trace_state);
4037 ret = tevent_loop_wait(ev_ctx);
4038 if (ret != 0) {
4039 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4040 " exiting\n", ret, strerror(errno)));
4043 TALLOC_FREE(trace_state.frame);
4045 exit_server_cleanly(NULL);
4048 bool req_is_in_chain(const struct smb_request *req)
4050 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4052 * We're right now handling a subsequent request, so we must
4053 * be in a chain
4055 return true;
4058 if (!is_andx_req(req->cmd)) {
4059 return false;
4062 if (req->wct < 2) {
4064 * Okay, an illegal request, but definitely not chained :-)
4066 return false;
4069 return (CVAL(req->vwv+0, 0) != 0xFF);