regedit: improvements for hexedit
[Samba.git] / source3 / smbd / process.c
blob74e7afced3b39fb0a1497d3ae407726d25a93f4f
1 /*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
42 #include "serverid.h"
43 #include "system/threads.h"
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list {
47 struct pending_message_list *next, *prev;
48 struct timeval request_time; /* When was this first issued? */
49 struct smbd_server_connection *sconn;
50 struct smbXsrv_connection *xconn;
51 struct tevent_timer *te;
52 struct smb_perfcount_data pcd;
53 uint32_t seqnum;
54 bool encrypted;
55 bool processed;
56 DATA_BLOB buf;
57 struct deferred_open_record *open_rec;
60 static void construct_reply_common(struct smb_request *req, const char *inbuf,
61 char *outbuf);
62 static struct pending_message_list *get_deferred_open_message_smb(
63 struct smbd_server_connection *sconn, uint64_t mid);
64 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
66 static void smbd_echo_init(struct smbXsrv_connection *xconn)
68 xconn->smb1.echo_handler.trusted_fd = -1;
69 xconn->smb1.echo_handler.socket_lock_fd = -1;
70 #ifdef HAVE_ROBUST_MUTEXES
71 xconn->smb1.echo_handler.socket_mutex = NULL;
72 #endif
75 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
77 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
78 return true;
81 #ifdef HAVE_ROBUST_MUTEXES
82 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
83 return true;
85 #endif
87 return false;
90 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
92 if (!smbd_echo_active(xconn)) {
93 return true;
96 xconn->smb1.echo_handler.ref_count++;
98 if (xconn->smb1.echo_handler.ref_count > 1) {
99 return true;
102 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
104 #ifdef HAVE_ROBUST_MUTEXES
105 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
106 int ret = EINTR;
108 while (ret == EINTR) {
109 ret = pthread_mutex_lock(
110 xconn->smb1.echo_handler.socket_mutex);
111 if (ret == 0) {
112 break;
115 if (ret != 0) {
116 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
117 strerror(ret)));
118 return false;
121 #endif
123 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
124 bool ok;
126 do {
127 ok = fcntl_lock(
128 xconn->smb1.echo_handler.socket_lock_fd,
129 F_SETLKW, 0, 0, F_WRLCK);
130 } while (!ok && (errno == EINTR));
132 if (!ok) {
133 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
134 return false;
138 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
140 return true;
143 void smbd_lock_socket(struct smbXsrv_connection *xconn)
145 if (!smbd_lock_socket_internal(xconn)) {
146 exit_server_cleanly("failed to lock socket");
150 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
152 if (!smbd_echo_active(xconn)) {
153 return true;
156 xconn->smb1.echo_handler.ref_count--;
158 if (xconn->smb1.echo_handler.ref_count > 0) {
159 return true;
162 #ifdef HAVE_ROBUST_MUTEXES
163 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
164 int ret = EINTR;
166 while (ret == EINTR) {
167 ret = pthread_mutex_unlock(
168 xconn->smb1.echo_handler.socket_mutex);
169 if (ret == 0) {
170 break;
173 if (ret != 0) {
174 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
175 strerror(ret)));
176 return false;
179 #endif
181 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
182 bool ok;
184 do {
185 ok = fcntl_lock(
186 xconn->smb1.echo_handler.socket_lock_fd,
187 F_SETLKW, 0, 0, F_UNLCK);
188 } while (!ok && (errno == EINTR));
190 if (!ok) {
191 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
192 return false;
196 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
198 return true;
201 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
203 if (!smbd_unlock_socket_internal(xconn)) {
204 exit_server_cleanly("failed to unlock socket");
208 /* Accessor function for smb_read_error for smbd functions. */
210 /****************************************************************************
211 Send an smb to a fd.
212 ****************************************************************************/
214 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
215 bool do_signing, uint32_t seqnum,
216 bool do_encrypt,
217 struct smb_perfcount_data *pcd)
219 size_t len = 0;
220 ssize_t ret;
221 char *buf_out = buffer;
223 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
225 * we're not supposed to do any io
227 return true;
230 smbd_lock_socket(xconn);
232 if (do_signing) {
233 /* Sign the outgoing packet if required. */
234 srv_calculate_sign_mac(xconn, buf_out, seqnum);
237 if (do_encrypt) {
238 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
239 if (!NT_STATUS_IS_OK(status)) {
240 DEBUG(0, ("send_smb: SMB encryption failed "
241 "on outgoing packet! Error %s\n",
242 nt_errstr(status) ));
243 ret = -1;
244 goto out;
248 len = smb_len_large(buf_out) + 4;
250 ret = write_data(xconn->transport.sock, buf_out, len);
251 if (ret <= 0) {
252 int saved_errno = errno;
254 * Try and give an error message saying what
255 * client failed.
257 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
258 (int)getpid(), (int)len,
259 smbXsrv_connection_dbg(xconn),
260 (int)ret, strerror(saved_errno)));
261 errno = saved_errno;
263 srv_free_enc_buffer(xconn, buf_out);
264 goto out;
267 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
268 srv_free_enc_buffer(xconn, buf_out);
269 out:
270 SMB_PERFCOUNT_END(pcd);
272 smbd_unlock_socket(xconn);
273 return (ret > 0);
276 /*******************************************************************
277 Setup the word count and byte count for a smb message.
278 ********************************************************************/
280 int srv_set_message(char *buf,
281 int num_words,
282 int num_bytes,
283 bool zero)
285 if (zero && (num_words || num_bytes)) {
286 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
288 SCVAL(buf,smb_wct,num_words);
289 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
290 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
291 return (smb_size + num_words*2 + num_bytes);
294 static bool valid_smb_header(const uint8_t *inbuf)
296 if (is_encrypted_packet(inbuf)) {
297 return true;
300 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
301 * but it just looks weird to call strncmp for this one.
303 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
306 /* Socket functions for smbd packet processing. */
308 static bool valid_packet_size(size_t len)
311 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
312 * of header. Don't print the error if this fits.... JRA.
315 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
316 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
317 (unsigned long)len));
318 return false;
320 return true;
323 static NTSTATUS read_packet_remainder(int fd, char *buffer,
324 unsigned int timeout, ssize_t len)
326 NTSTATUS status;
328 if (len <= 0) {
329 return NT_STATUS_OK;
332 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
333 if (!NT_STATUS_IS_OK(status)) {
334 char addr[INET6_ADDRSTRLEN];
335 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
336 "error = %s.\n",
337 get_peer_addr(fd, addr, sizeof(addr)),
338 nt_errstr(status)));
340 return status;
343 /****************************************************************************
344 Attempt a zerocopy writeX read. We know here that len > smb_size-4
345 ****************************************************************************/
348 * Unfortunately, earlier versions of smbclient/libsmbclient
349 * don't send this "standard" writeX header. I've fixed this
350 * for 3.2 but we'll use the old method with earlier versions.
351 * Windows and CIFSFS at least use this standard size. Not
352 * sure about MacOSX.
355 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
356 (2*14) + /* word count (including bcc) */ \
357 1 /* pad byte */)
359 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
360 const char lenbuf[4],
361 struct smbXsrv_connection *xconn,
362 int sock,
363 char **buffer,
364 unsigned int timeout,
365 size_t *p_unread,
366 size_t *len_ret)
368 /* Size of a WRITEX call (+4 byte len). */
369 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
370 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
371 ssize_t toread;
372 NTSTATUS status;
374 memcpy(writeX_header, lenbuf, 4);
376 status = read_fd_with_timeout(
377 sock, writeX_header + 4,
378 STANDARD_WRITE_AND_X_HEADER_SIZE,
379 STANDARD_WRITE_AND_X_HEADER_SIZE,
380 timeout, NULL);
382 if (!NT_STATUS_IS_OK(status)) {
383 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
384 "error = %s.\n",
385 smbXsrv_connection_dbg(xconn),
386 nt_errstr(status)));
387 return status;
391 * Ok - now try and see if this is a possible
392 * valid writeX call.
395 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
397 * If the data offset is beyond what
398 * we've read, drain the extra bytes.
400 uint16_t doff = SVAL(writeX_header,smb_vwv11);
401 ssize_t newlen;
403 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
404 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
405 if (drain_socket(sock, drain) != drain) {
406 smb_panic("receive_smb_raw_talloc_partial_read:"
407 " failed to drain pending bytes");
409 } else {
410 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
413 /* Spoof down the length and null out the bcc. */
414 set_message_bcc(writeX_header, 0);
415 newlen = smb_len(writeX_header);
417 /* Copy the header we've written. */
419 *buffer = (char *)talloc_memdup(mem_ctx,
420 writeX_header,
421 sizeof(writeX_header));
423 if (*buffer == NULL) {
424 DEBUG(0, ("Could not allocate inbuf of length %d\n",
425 (int)sizeof(writeX_header)));
426 return NT_STATUS_NO_MEMORY;
429 /* Work out the remaining bytes. */
430 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
431 *len_ret = newlen + 4;
432 return NT_STATUS_OK;
435 if (!valid_packet_size(len)) {
436 return NT_STATUS_INVALID_PARAMETER;
440 * Not a valid writeX call. Just do the standard
441 * talloc and return.
444 *buffer = talloc_array(mem_ctx, char, len+4);
446 if (*buffer == NULL) {
447 DEBUG(0, ("Could not allocate inbuf of length %d\n",
448 (int)len+4));
449 return NT_STATUS_NO_MEMORY;
452 /* Copy in what we already read. */
453 memcpy(*buffer,
454 writeX_header,
455 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
456 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
458 if(toread > 0) {
459 status = read_packet_remainder(
460 sock,
461 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
462 timeout, toread);
464 if (!NT_STATUS_IS_OK(status)) {
465 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
466 nt_errstr(status)));
467 return status;
471 *len_ret = len + 4;
472 return NT_STATUS_OK;
475 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
476 struct smbXsrv_connection *xconn,
477 int sock,
478 char **buffer, unsigned int timeout,
479 size_t *p_unread, size_t *plen)
481 char lenbuf[4];
482 size_t len;
483 int min_recv_size = lp_min_receive_file_size();
484 NTSTATUS status;
486 *p_unread = 0;
488 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
489 &len);
490 if (!NT_STATUS_IS_OK(status)) {
491 return status;
494 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
495 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
496 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
497 !srv_is_signing_active(xconn) &&
498 xconn->smb1.echo_handler.trusted_fde == NULL) {
500 return receive_smb_raw_talloc_partial_read(
501 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
502 p_unread, plen);
505 if (!valid_packet_size(len)) {
506 return NT_STATUS_INVALID_PARAMETER;
510 * The +4 here can't wrap, we've checked the length above already.
513 *buffer = talloc_array(mem_ctx, char, len+4);
515 if (*buffer == NULL) {
516 DEBUG(0, ("Could not allocate inbuf of length %d\n",
517 (int)len+4));
518 return NT_STATUS_NO_MEMORY;
521 memcpy(*buffer, lenbuf, sizeof(lenbuf));
523 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
524 if (!NT_STATUS_IS_OK(status)) {
525 return status;
528 *plen = len + 4;
529 return NT_STATUS_OK;
532 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
533 struct smbXsrv_connection *xconn,
534 int sock,
535 char **buffer, unsigned int timeout,
536 size_t *p_unread, bool *p_encrypted,
537 size_t *p_len,
538 uint32_t *seqnum,
539 bool trusted_channel)
541 size_t len = 0;
542 NTSTATUS status;
544 *p_encrypted = false;
546 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
547 p_unread, &len);
548 if (!NT_STATUS_IS_OK(status)) {
549 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
550 ("receive_smb_raw_talloc failed for client %s "
551 "read error = %s.\n",
552 smbXsrv_connection_dbg(xconn),
553 nt_errstr(status)) );
554 return status;
557 if (is_encrypted_packet((uint8_t *)*buffer)) {
558 status = srv_decrypt_buffer(xconn, *buffer);
559 if (!NT_STATUS_IS_OK(status)) {
560 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
561 "incoming packet! Error %s\n",
562 nt_errstr(status) ));
563 return status;
565 *p_encrypted = true;
568 /* Check the incoming SMB signature. */
569 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
570 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
571 "incoming packet!\n"));
572 return NT_STATUS_INVALID_NETWORK_RESPONSE;
575 *p_len = len;
576 return NT_STATUS_OK;
580 * Initialize a struct smb_request from an inbuf
583 static bool init_smb_request(struct smb_request *req,
584 struct smbd_server_connection *sconn,
585 struct smbXsrv_connection *xconn,
586 const uint8 *inbuf,
587 size_t unread_bytes, bool encrypted,
588 uint32_t seqnum)
590 struct smbXsrv_tcon *tcon;
591 NTSTATUS status;
592 NTTIME now;
593 size_t req_size = smb_len(inbuf) + 4;
595 /* Ensure we have at least smb_size bytes. */
596 if (req_size < smb_size) {
597 DEBUG(0,("init_smb_request: invalid request size %u\n",
598 (unsigned int)req_size ));
599 return false;
602 req->request_time = timeval_current();
603 now = timeval_to_nttime(&req->request_time);
605 req->cmd = CVAL(inbuf, smb_com);
606 req->flags2 = SVAL(inbuf, smb_flg2);
607 req->smbpid = SVAL(inbuf, smb_pid);
608 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
609 req->seqnum = seqnum;
610 req->vuid = SVAL(inbuf, smb_uid);
611 req->tid = SVAL(inbuf, smb_tid);
612 req->wct = CVAL(inbuf, smb_wct);
613 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
614 req->buflen = smb_buflen(inbuf);
615 req->buf = (const uint8_t *)smb_buf_const(inbuf);
616 req->unread_bytes = unread_bytes;
617 req->encrypted = encrypted;
618 req->sconn = sconn;
619 req->xconn = xconn;
620 req->conn = NULL;
621 if (xconn != NULL) {
622 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
623 if (NT_STATUS_IS_OK(status)) {
624 req->conn = tcon->compat;
627 req->chain_fsp = NULL;
628 req->smb2req = NULL;
629 req->priv_paths = NULL;
630 req->chain = NULL;
631 smb_init_perfcount_data(&req->pcd);
633 /* Ensure we have at least wct words and 2 bytes of bcc. */
634 if (smb_size + req->wct*2 > req_size) {
635 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
636 (unsigned int)req->wct,
637 (unsigned int)req_size));
638 return false;
640 /* Ensure bcc is correct. */
641 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
642 DEBUG(0,("init_smb_request: invalid bcc number %u "
643 "(wct = %u, size %u)\n",
644 (unsigned int)req->buflen,
645 (unsigned int)req->wct,
646 (unsigned int)req_size));
647 return false;
650 req->outbuf = NULL;
651 return true;
654 static void process_smb(struct smbXsrv_connection *xconn,
655 uint8_t *inbuf, size_t nread, size_t unread_bytes,
656 uint32_t seqnum, bool encrypted,
657 struct smb_perfcount_data *deferred_pcd);
659 static void smbd_deferred_open_timer(struct tevent_context *ev,
660 struct tevent_timer *te,
661 struct timeval _tval,
662 void *private_data)
664 struct pending_message_list *msg = talloc_get_type(private_data,
665 struct pending_message_list);
666 struct smbd_server_connection *sconn = msg->sconn;
667 struct smbXsrv_connection *xconn = msg->xconn;
668 TALLOC_CTX *mem_ctx = talloc_tos();
669 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
670 uint8_t *inbuf;
672 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
673 msg->buf.length);
674 if (inbuf == NULL) {
675 exit_server("smbd_deferred_open_timer: talloc failed\n");
676 return;
679 /* We leave this message on the queue so the open code can
680 know this is a retry. */
681 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
682 (unsigned long long)mid ));
684 /* Mark the message as processed so this is not
685 * re-processed in error. */
686 msg->processed = true;
688 process_smb(xconn, inbuf,
689 msg->buf.length, 0,
690 msg->seqnum, msg->encrypted, &msg->pcd);
692 /* If it's still there and was processed, remove it. */
693 msg = get_deferred_open_message_smb(sconn, mid);
694 if (msg && msg->processed) {
695 remove_deferred_open_message_smb(xconn, mid);
699 /****************************************************************************
700 Function to push a message onto the tail of a linked list of smb messages ready
701 for processing.
702 ****************************************************************************/
704 static bool push_queued_message(struct smb_request *req,
705 struct timeval request_time,
706 struct timeval end_time,
707 struct deferred_open_record *open_rec)
709 int msg_len = smb_len(req->inbuf) + 4;
710 struct pending_message_list *msg;
712 msg = talloc_zero(NULL, struct pending_message_list);
714 if(msg == NULL) {
715 DEBUG(0,("push_message: malloc fail (1)\n"));
716 return False;
718 msg->sconn = req->sconn;
719 msg->xconn = req->xconn;
721 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
722 if(msg->buf.data == NULL) {
723 DEBUG(0,("push_message: malloc fail (2)\n"));
724 TALLOC_FREE(msg);
725 return False;
728 msg->request_time = request_time;
729 msg->seqnum = req->seqnum;
730 msg->encrypted = req->encrypted;
731 msg->processed = false;
732 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
734 if (open_rec) {
735 msg->open_rec = talloc_move(msg, &open_rec);
738 #if 0
739 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
740 msg,
741 end_time,
742 smbd_deferred_open_timer,
743 msg);
744 if (!msg->te) {
745 DEBUG(0,("push_message: event_add_timed failed\n"));
746 TALLOC_FREE(msg);
747 return false;
749 #endif
751 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
752 struct pending_message_list *);
754 DEBUG(10,("push_message: pushed message length %u on "
755 "deferred_open_queue\n", (unsigned int)msg_len));
757 return True;
760 /****************************************************************************
761 Function to delete a sharing violation open message by mid.
762 ****************************************************************************/
764 void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
765 uint64_t mid)
767 struct smbd_server_connection *sconn = xconn->client->sconn;
768 struct pending_message_list *pml;
770 if (sconn->using_smb2) {
771 remove_deferred_open_message_smb2(xconn, mid);
772 return;
775 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
776 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
777 DEBUG(10,("remove_deferred_open_message_smb: "
778 "deleting mid %llu len %u\n",
779 (unsigned long long)mid,
780 (unsigned int)pml->buf.length ));
781 DLIST_REMOVE(sconn->deferred_open_queue, pml);
782 TALLOC_FREE(pml);
783 return;
788 /****************************************************************************
789 Move a sharing violation open retry message to the front of the list and
790 schedule it for immediate processing.
791 ****************************************************************************/
793 bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
794 uint64_t mid)
796 struct smbd_server_connection *sconn = xconn->client->sconn;
797 struct pending_message_list *pml;
798 int i = 0;
800 if (sconn->using_smb2) {
801 return schedule_deferred_open_message_smb2(xconn, mid);
804 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
805 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
807 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
808 "msg_mid = %llu\n",
809 i++,
810 (unsigned long long)msg_mid ));
812 if (mid == msg_mid) {
813 struct tevent_timer *te;
815 if (pml->processed) {
816 /* A processed message should not be
817 * rescheduled. */
818 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
819 "message mid %llu was already processed\n",
820 (unsigned long long)msg_mid ));
821 continue;
824 DEBUG(10,("schedule_deferred_open_message_smb: "
825 "scheduling mid %llu\n",
826 (unsigned long long)mid ));
828 te = tevent_add_timer(pml->sconn->ev_ctx,
829 pml,
830 timeval_zero(),
831 smbd_deferred_open_timer,
832 pml);
833 if (!te) {
834 DEBUG(10,("schedule_deferred_open_message_smb: "
835 "event_add_timed() failed, "
836 "skipping mid %llu\n",
837 (unsigned long long)msg_mid ));
840 TALLOC_FREE(pml->te);
841 pml->te = te;
842 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
843 return true;
847 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
848 "find message mid %llu\n",
849 (unsigned long long)mid ));
851 return false;
854 /****************************************************************************
855 Return true if this mid is on the deferred queue and was not yet processed.
856 ****************************************************************************/
858 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
860 struct smbd_server_connection *sconn = xconn->client->sconn;
861 struct pending_message_list *pml;
863 if (sconn->using_smb2) {
864 return open_was_deferred_smb2(xconn, mid);
867 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
868 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
869 return True;
872 return False;
875 /****************************************************************************
876 Return the message queued by this mid.
877 ****************************************************************************/
879 static struct pending_message_list *get_deferred_open_message_smb(
880 struct smbd_server_connection *sconn, uint64_t mid)
882 struct pending_message_list *pml;
884 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
885 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
886 return pml;
889 return NULL;
892 /****************************************************************************
893 Get the state data queued by this mid.
894 ****************************************************************************/
896 bool get_deferred_open_message_state(struct smb_request *smbreq,
897 struct timeval *p_request_time,
898 struct deferred_open_record **open_rec)
900 struct pending_message_list *pml;
902 if (smbreq->sconn->using_smb2) {
903 return get_deferred_open_message_state_smb2(smbreq->smb2req,
904 p_request_time,
905 open_rec);
908 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
909 if (!pml) {
910 return false;
912 if (p_request_time) {
913 *p_request_time = pml->request_time;
915 if (open_rec != NULL) {
916 *open_rec = pml->open_rec;
918 return true;
921 /****************************************************************************
922 Function to push a deferred open smb message onto a linked list of local smb
923 messages ready for processing.
924 ****************************************************************************/
926 bool push_deferred_open_message_smb(struct smb_request *req,
927 struct timeval request_time,
928 struct timeval timeout,
929 struct file_id id,
930 struct deferred_open_record *open_rec)
932 struct timeval end_time;
934 if (req->smb2req) {
935 return push_deferred_open_message_smb2(req->smb2req,
936 request_time,
937 timeout,
939 open_rec);
942 if (req->unread_bytes) {
943 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
944 "unread_bytes = %u\n",
945 (unsigned int)req->unread_bytes ));
946 smb_panic("push_deferred_open_message_smb: "
947 "logic error unread_bytes != 0" );
950 end_time = timeval_sum(&request_time, &timeout);
952 DEBUG(10,("push_deferred_open_message_smb: pushing message "
953 "len %u mid %llu timeout time [%u.%06u]\n",
954 (unsigned int) smb_len(req->inbuf)+4,
955 (unsigned long long)req->mid,
956 (unsigned int)end_time.tv_sec,
957 (unsigned int)end_time.tv_usec));
959 return push_queued_message(req, request_time, end_time, open_rec);
962 static void smbd_sig_term_handler(struct tevent_context *ev,
963 struct tevent_signal *se,
964 int signum,
965 int count,
966 void *siginfo,
967 void *private_data)
969 exit_server_cleanly("termination signal");
972 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
974 struct tevent_signal *se;
976 se = tevent_add_signal(sconn->ev_ctx,
977 sconn,
978 SIGTERM, 0,
979 smbd_sig_term_handler,
980 sconn);
981 if (!se) {
982 exit_server("failed to setup SIGTERM handler");
986 static void smbd_sig_hup_handler(struct tevent_context *ev,
987 struct tevent_signal *se,
988 int signum,
989 int count,
990 void *siginfo,
991 void *private_data)
993 struct smbd_server_connection *sconn =
994 talloc_get_type_abort(private_data,
995 struct smbd_server_connection);
997 change_to_root_user();
998 DEBUG(1,("Reloading services after SIGHUP\n"));
999 reload_services(sconn, conn_snum_used, false);
1002 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1004 struct tevent_signal *se;
1006 se = tevent_add_signal(sconn->ev_ctx,
1007 sconn,
1008 SIGHUP, 0,
1009 smbd_sig_hup_handler,
1010 sconn);
1011 if (!se) {
1012 exit_server("failed to setup SIGHUP handler");
1016 static void smbd_conf_updated(struct messaging_context *msg,
1017 void *private_data,
1018 uint32_t msg_type,
1019 struct server_id server_id,
1020 DATA_BLOB *data)
1022 struct smbd_server_connection *sconn =
1023 talloc_get_type_abort(private_data,
1024 struct smbd_server_connection);
1026 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1027 "updated. Reloading.\n"));
1028 change_to_root_user();
1029 reload_services(sconn, conn_snum_used, false);
1033 * Only allow 5 outstanding trans requests. We're allocating memory, so
1034 * prevent a DoS.
1037 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1039 int count = 0;
1040 for (; list != NULL; list = list->next) {
1042 if (list->mid == mid) {
1043 return NT_STATUS_INVALID_PARAMETER;
1046 count += 1;
1048 if (count > 5) {
1049 return NT_STATUS_INSUFFICIENT_RESOURCES;
1052 return NT_STATUS_OK;
1056 These flags determine some of the permissions required to do an operation
1058 Note that I don't set NEED_WRITE on some write operations because they
1059 are used by some brain-dead clients when printing, and I don't want to
1060 force write permissions on print services.
1062 #define AS_USER (1<<0)
1063 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1064 #define TIME_INIT (1<<2)
1065 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1066 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1067 #define DO_CHDIR (1<<6)
1070 define a list of possible SMB messages and their corresponding
1071 functions. Any message that has a NULL function is unimplemented -
1072 please feel free to contribute implementations!
1074 static const struct smb_message_struct {
1075 const char *name;
1076 void (*fn)(struct smb_request *req);
1077 int flags;
1078 } smb_messages[256] = {
1080 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1081 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1082 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1083 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1084 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1085 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1086 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1087 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1088 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1089 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1090 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1091 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1092 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1093 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1094 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1095 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1096 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1097 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1098 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1099 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1100 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1101 /* 0x15 */ { NULL, NULL, 0 },
1102 /* 0x16 */ { NULL, NULL, 0 },
1103 /* 0x17 */ { NULL, NULL, 0 },
1104 /* 0x18 */ { NULL, NULL, 0 },
1105 /* 0x19 */ { NULL, NULL, 0 },
1106 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1107 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1108 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1109 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1110 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1111 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1112 /* 0x20 */ { "SMBwritec", NULL,0},
1113 /* 0x21 */ { NULL, NULL, 0 },
1114 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1115 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1116 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1117 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1118 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1119 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1120 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1121 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1122 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1123 /* 0x2b */ { "SMBecho",reply_echo,0},
1124 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1125 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1126 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1127 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1128 /* 0x30 */ { NULL, NULL, 0 },
1129 /* 0x31 */ { NULL, NULL, 0 },
1130 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1131 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1132 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1133 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1134 /* 0x36 */ { NULL, NULL, 0 },
1135 /* 0x37 */ { NULL, NULL, 0 },
1136 /* 0x38 */ { NULL, NULL, 0 },
1137 /* 0x39 */ { NULL, NULL, 0 },
1138 /* 0x3a */ { NULL, NULL, 0 },
1139 /* 0x3b */ { NULL, NULL, 0 },
1140 /* 0x3c */ { NULL, NULL, 0 },
1141 /* 0x3d */ { NULL, NULL, 0 },
1142 /* 0x3e */ { NULL, NULL, 0 },
1143 /* 0x3f */ { NULL, NULL, 0 },
1144 /* 0x40 */ { NULL, NULL, 0 },
1145 /* 0x41 */ { NULL, NULL, 0 },
1146 /* 0x42 */ { NULL, NULL, 0 },
1147 /* 0x43 */ { NULL, NULL, 0 },
1148 /* 0x44 */ { NULL, NULL, 0 },
1149 /* 0x45 */ { NULL, NULL, 0 },
1150 /* 0x46 */ { NULL, NULL, 0 },
1151 /* 0x47 */ { NULL, NULL, 0 },
1152 /* 0x48 */ { NULL, NULL, 0 },
1153 /* 0x49 */ { NULL, NULL, 0 },
1154 /* 0x4a */ { NULL, NULL, 0 },
1155 /* 0x4b */ { NULL, NULL, 0 },
1156 /* 0x4c */ { NULL, NULL, 0 },
1157 /* 0x4d */ { NULL, NULL, 0 },
1158 /* 0x4e */ { NULL, NULL, 0 },
1159 /* 0x4f */ { NULL, NULL, 0 },
1160 /* 0x50 */ { NULL, NULL, 0 },
1161 /* 0x51 */ { NULL, NULL, 0 },
1162 /* 0x52 */ { NULL, NULL, 0 },
1163 /* 0x53 */ { NULL, NULL, 0 },
1164 /* 0x54 */ { NULL, NULL, 0 },
1165 /* 0x55 */ { NULL, NULL, 0 },
1166 /* 0x56 */ { NULL, NULL, 0 },
1167 /* 0x57 */ { NULL, NULL, 0 },
1168 /* 0x58 */ { NULL, NULL, 0 },
1169 /* 0x59 */ { NULL, NULL, 0 },
1170 /* 0x5a */ { NULL, NULL, 0 },
1171 /* 0x5b */ { NULL, NULL, 0 },
1172 /* 0x5c */ { NULL, NULL, 0 },
1173 /* 0x5d */ { NULL, NULL, 0 },
1174 /* 0x5e */ { NULL, NULL, 0 },
1175 /* 0x5f */ { NULL, NULL, 0 },
1176 /* 0x60 */ { NULL, NULL, 0 },
1177 /* 0x61 */ { NULL, NULL, 0 },
1178 /* 0x62 */ { NULL, NULL, 0 },
1179 /* 0x63 */ { NULL, NULL, 0 },
1180 /* 0x64 */ { NULL, NULL, 0 },
1181 /* 0x65 */ { NULL, NULL, 0 },
1182 /* 0x66 */ { NULL, NULL, 0 },
1183 /* 0x67 */ { NULL, NULL, 0 },
1184 /* 0x68 */ { NULL, NULL, 0 },
1185 /* 0x69 */ { NULL, NULL, 0 },
1186 /* 0x6a */ { NULL, NULL, 0 },
1187 /* 0x6b */ { NULL, NULL, 0 },
1188 /* 0x6c */ { NULL, NULL, 0 },
1189 /* 0x6d */ { NULL, NULL, 0 },
1190 /* 0x6e */ { NULL, NULL, 0 },
1191 /* 0x6f */ { NULL, NULL, 0 },
1192 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1193 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1194 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1195 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1196 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1197 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1198 /* 0x76 */ { NULL, NULL, 0 },
1199 /* 0x77 */ { NULL, NULL, 0 },
1200 /* 0x78 */ { NULL, NULL, 0 },
1201 /* 0x79 */ { NULL, NULL, 0 },
1202 /* 0x7a */ { NULL, NULL, 0 },
1203 /* 0x7b */ { NULL, NULL, 0 },
1204 /* 0x7c */ { NULL, NULL, 0 },
1205 /* 0x7d */ { NULL, NULL, 0 },
1206 /* 0x7e */ { NULL, NULL, 0 },
1207 /* 0x7f */ { NULL, NULL, 0 },
1208 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1209 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1210 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1211 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1212 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1213 /* 0x85 */ { NULL, NULL, 0 },
1214 /* 0x86 */ { NULL, NULL, 0 },
1215 /* 0x87 */ { NULL, NULL, 0 },
1216 /* 0x88 */ { NULL, NULL, 0 },
1217 /* 0x89 */ { NULL, NULL, 0 },
1218 /* 0x8a */ { NULL, NULL, 0 },
1219 /* 0x8b */ { NULL, NULL, 0 },
1220 /* 0x8c */ { NULL, NULL, 0 },
1221 /* 0x8d */ { NULL, NULL, 0 },
1222 /* 0x8e */ { NULL, NULL, 0 },
1223 /* 0x8f */ { NULL, NULL, 0 },
1224 /* 0x90 */ { NULL, NULL, 0 },
1225 /* 0x91 */ { NULL, NULL, 0 },
1226 /* 0x92 */ { NULL, NULL, 0 },
1227 /* 0x93 */ { NULL, NULL, 0 },
1228 /* 0x94 */ { NULL, NULL, 0 },
1229 /* 0x95 */ { NULL, NULL, 0 },
1230 /* 0x96 */ { NULL, NULL, 0 },
1231 /* 0x97 */ { NULL, NULL, 0 },
1232 /* 0x98 */ { NULL, NULL, 0 },
1233 /* 0x99 */ { NULL, NULL, 0 },
1234 /* 0x9a */ { NULL, NULL, 0 },
1235 /* 0x9b */ { NULL, NULL, 0 },
1236 /* 0x9c */ { NULL, NULL, 0 },
1237 /* 0x9d */ { NULL, NULL, 0 },
1238 /* 0x9e */ { NULL, NULL, 0 },
1239 /* 0x9f */ { NULL, NULL, 0 },
1240 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1241 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1242 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1243 /* 0xa3 */ { NULL, NULL, 0 },
1244 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1245 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1246 /* 0xa6 */ { NULL, NULL, 0 },
1247 /* 0xa7 */ { NULL, NULL, 0 },
1248 /* 0xa8 */ { NULL, NULL, 0 },
1249 /* 0xa9 */ { NULL, NULL, 0 },
1250 /* 0xaa */ { NULL, NULL, 0 },
1251 /* 0xab */ { NULL, NULL, 0 },
1252 /* 0xac */ { NULL, NULL, 0 },
1253 /* 0xad */ { NULL, NULL, 0 },
1254 /* 0xae */ { NULL, NULL, 0 },
1255 /* 0xaf */ { NULL, NULL, 0 },
1256 /* 0xb0 */ { NULL, NULL, 0 },
1257 /* 0xb1 */ { NULL, NULL, 0 },
1258 /* 0xb2 */ { NULL, NULL, 0 },
1259 /* 0xb3 */ { NULL, NULL, 0 },
1260 /* 0xb4 */ { NULL, NULL, 0 },
1261 /* 0xb5 */ { NULL, NULL, 0 },
1262 /* 0xb6 */ { NULL, NULL, 0 },
1263 /* 0xb7 */ { NULL, NULL, 0 },
1264 /* 0xb8 */ { NULL, NULL, 0 },
1265 /* 0xb9 */ { NULL, NULL, 0 },
1266 /* 0xba */ { NULL, NULL, 0 },
1267 /* 0xbb */ { NULL, NULL, 0 },
1268 /* 0xbc */ { NULL, NULL, 0 },
1269 /* 0xbd */ { NULL, NULL, 0 },
1270 /* 0xbe */ { NULL, NULL, 0 },
1271 /* 0xbf */ { NULL, NULL, 0 },
1272 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1273 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1274 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1275 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1276 /* 0xc4 */ { NULL, NULL, 0 },
1277 /* 0xc5 */ { NULL, NULL, 0 },
1278 /* 0xc6 */ { NULL, NULL, 0 },
1279 /* 0xc7 */ { NULL, NULL, 0 },
1280 /* 0xc8 */ { NULL, NULL, 0 },
1281 /* 0xc9 */ { NULL, NULL, 0 },
1282 /* 0xca */ { NULL, NULL, 0 },
1283 /* 0xcb */ { NULL, NULL, 0 },
1284 /* 0xcc */ { NULL, NULL, 0 },
1285 /* 0xcd */ { NULL, NULL, 0 },
1286 /* 0xce */ { NULL, NULL, 0 },
1287 /* 0xcf */ { NULL, NULL, 0 },
1288 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1289 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1290 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1291 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1292 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1293 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1294 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1295 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1296 /* 0xd8 */ { NULL, NULL, 0 },
1297 /* 0xd9 */ { NULL, NULL, 0 },
1298 /* 0xda */ { NULL, NULL, 0 },
1299 /* 0xdb */ { NULL, NULL, 0 },
1300 /* 0xdc */ { NULL, NULL, 0 },
1301 /* 0xdd */ { NULL, NULL, 0 },
1302 /* 0xde */ { NULL, NULL, 0 },
1303 /* 0xdf */ { NULL, NULL, 0 },
1304 /* 0xe0 */ { NULL, NULL, 0 },
1305 /* 0xe1 */ { NULL, NULL, 0 },
1306 /* 0xe2 */ { NULL, NULL, 0 },
1307 /* 0xe3 */ { NULL, NULL, 0 },
1308 /* 0xe4 */ { NULL, NULL, 0 },
1309 /* 0xe5 */ { NULL, NULL, 0 },
1310 /* 0xe6 */ { NULL, NULL, 0 },
1311 /* 0xe7 */ { NULL, NULL, 0 },
1312 /* 0xe8 */ { NULL, NULL, 0 },
1313 /* 0xe9 */ { NULL, NULL, 0 },
1314 /* 0xea */ { NULL, NULL, 0 },
1315 /* 0xeb */ { NULL, NULL, 0 },
1316 /* 0xec */ { NULL, NULL, 0 },
1317 /* 0xed */ { NULL, NULL, 0 },
1318 /* 0xee */ { NULL, NULL, 0 },
1319 /* 0xef */ { NULL, NULL, 0 },
1320 /* 0xf0 */ { NULL, NULL, 0 },
1321 /* 0xf1 */ { NULL, NULL, 0 },
1322 /* 0xf2 */ { NULL, NULL, 0 },
1323 /* 0xf3 */ { NULL, NULL, 0 },
1324 /* 0xf4 */ { NULL, NULL, 0 },
1325 /* 0xf5 */ { NULL, NULL, 0 },
1326 /* 0xf6 */ { NULL, NULL, 0 },
1327 /* 0xf7 */ { NULL, NULL, 0 },
1328 /* 0xf8 */ { NULL, NULL, 0 },
1329 /* 0xf9 */ { NULL, NULL, 0 },
1330 /* 0xfa */ { NULL, NULL, 0 },
1331 /* 0xfb */ { NULL, NULL, 0 },
1332 /* 0xfc */ { NULL, NULL, 0 },
1333 /* 0xfd */ { NULL, NULL, 0 },
1334 /* 0xfe */ { NULL, NULL, 0 },
1335 /* 0xff */ { NULL, NULL, 0 }
1339 /*******************************************************************
1340 allocate and initialize a reply packet
1341 ********************************************************************/
1343 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1344 const char *inbuf, char **outbuf, uint8_t num_words,
1345 uint32_t num_bytes)
1347 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1350 * Protect against integer wrap.
1351 * The SMB layer reply can be up to 0xFFFFFF bytes.
1353 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1354 char *msg;
1355 if (asprintf(&msg, "num_bytes too large: %u",
1356 (unsigned)num_bytes) == -1) {
1357 msg = discard_const_p(char, "num_bytes too large");
1359 smb_panic(msg);
1363 * Here we include the NBT header for now.
1365 *outbuf = talloc_array(mem_ctx, char,
1366 NBT_HDR_SIZE + smb_len);
1367 if (*outbuf == NULL) {
1368 return false;
1371 construct_reply_common(req, inbuf, *outbuf);
1372 srv_set_message(*outbuf, num_words, num_bytes, false);
1374 * Zero out the word area, the caller has to take care of the bcc area
1375 * himself
1377 if (num_words != 0) {
1378 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1381 return true;
1384 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1386 char *outbuf;
1387 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1388 num_bytes)) {
1389 smb_panic("could not allocate output buffer\n");
1391 req->outbuf = (uint8_t *)outbuf;
1395 /*******************************************************************
1396 Dump a packet to a file.
1397 ********************************************************************/
1399 static void smb_dump(const char *name, int type, const char *data)
1401 size_t len;
1402 int fd, i;
1403 char *fname = NULL;
1404 if (DEBUGLEVEL < 50) {
1405 return;
1408 len = smb_len_tcp(data)+4;
1409 for (i=1;i<100;i++) {
1410 fname = talloc_asprintf(talloc_tos(),
1411 "/tmp/%s.%d.%s",
1412 name,
1414 type ? "req" : "resp");
1415 if (fname == NULL) {
1416 return;
1418 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1419 if (fd != -1 || errno != EEXIST) break;
1420 TALLOC_FREE(fname);
1422 if (fd != -1) {
1423 ssize_t ret = write(fd, data, len);
1424 if (ret != len)
1425 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1426 close(fd);
1427 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1429 TALLOC_FREE(fname);
1432 /****************************************************************************
1433 Prepare everything for calling the actual request function, and potentially
1434 call the request function via the "new" interface.
1436 Return False if the "legacy" function needs to be called, everything is
1437 prepared.
1439 Return True if we're done.
1441 I know this API sucks, but it is the one with the least code change I could
1442 find.
1443 ****************************************************************************/
1445 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1447 int flags;
1448 uint64_t session_tag;
1449 connection_struct *conn = NULL;
1450 struct smbXsrv_connection *xconn = req->xconn;
1451 NTTIME now = timeval_to_nttime(&req->request_time);
1452 struct smbXsrv_session *session = NULL;
1453 NTSTATUS status;
1455 errno = 0;
1457 if (!xconn->smb1.negprot.done) {
1458 switch (type) {
1460 * Without a negprot the request must
1461 * either be a negprot, or one of the
1462 * evil old SMB mailslot messaging types.
1464 case SMBnegprot:
1465 case SMBsendstrt:
1466 case SMBsendend:
1467 case SMBsendtxt:
1468 break;
1469 default:
1470 exit_server_cleanly("The first request "
1471 "should be a negprot");
1475 if (smb_messages[type].fn == NULL) {
1476 DEBUG(0,("Unknown message type %d!\n",type));
1477 smb_dump("Unknown", 1, (const char *)req->inbuf);
1478 reply_unknown_new(req, type);
1479 return NULL;
1482 flags = smb_messages[type].flags;
1484 /* In share mode security we must ignore the vuid. */
1485 session_tag = req->vuid;
1486 conn = req->conn;
1488 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1489 (int)getpid(), (unsigned long)conn));
1491 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1493 /* Ensure this value is replaced in the incoming packet. */
1494 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1497 * Ensure the correct username is in current_user_info. This is a
1498 * really ugly bugfix for problems with multiple session_setup_and_X's
1499 * being done and allowing %U and %G substitutions to work correctly.
1500 * There is a reason this code is done here, don't move it unless you
1501 * know what you're doing... :-).
1502 * JRA.
1506 * lookup an existing session
1508 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1509 * here, the main check is still in change_to_user()
1511 status = smb1srv_session_lookup(xconn,
1512 session_tag,
1513 now,
1514 &session);
1515 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1516 switch (type) {
1517 case SMBsesssetupX:
1518 status = NT_STATUS_OK;
1519 break;
1520 default:
1521 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1522 (unsigned long long)session_tag,
1523 (unsigned long long)req->mid));
1524 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1525 return conn;
1529 if (session_tag != xconn->client->last_session_id) {
1530 struct user_struct *vuser = NULL;
1532 xconn->client->last_session_id = session_tag;
1533 if (session) {
1534 vuser = session->compat;
1536 if (vuser) {
1537 set_current_user_info(
1538 vuser->session_info->unix_info->sanitized_username,
1539 vuser->session_info->unix_info->unix_name,
1540 vuser->session_info->info->domain_name);
1544 /* Does this call need to be run as the connected user? */
1545 if (flags & AS_USER) {
1547 /* Does this call need a valid tree connection? */
1548 if (!conn) {
1550 * Amazingly, the error code depends on the command
1551 * (from Samba4).
1553 if (type == SMBntcreateX) {
1554 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1555 } else {
1556 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1558 return NULL;
1561 if (!change_to_user(conn,session_tag)) {
1562 DEBUG(0, ("Error: Could not change to user. Removing "
1563 "deferred open, mid=%llu.\n",
1564 (unsigned long long)req->mid));
1565 reply_force_doserror(req, ERRSRV, ERRbaduid);
1566 return conn;
1569 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1571 /* Does it need write permission? */
1572 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1573 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1574 return conn;
1577 /* IPC services are limited */
1578 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1579 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1580 return conn;
1582 } else {
1583 /* This call needs to be run as root */
1584 change_to_root_user();
1587 /* load service specific parameters */
1588 if (conn) {
1589 if (req->encrypted) {
1590 conn->encrypted_tid = true;
1591 /* encrypted required from now on. */
1592 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1593 } else if (ENCRYPTION_REQUIRED(conn)) {
1594 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1595 DEBUG(1,("service[%s] requires encryption"
1596 "%s ACCESS_DENIED. mid=%llu\n",
1597 lp_servicename(talloc_tos(), SNUM(conn)),
1598 smb_fn_name(type),
1599 (unsigned long long)req->mid));
1600 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1601 return conn;
1605 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1606 (flags & (AS_USER|DO_CHDIR)
1607 ?True:False))) {
1608 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1609 return conn;
1611 conn->num_smb_operations++;
1615 * Does this protocol need to be run as guest? (Only archane
1616 * messenger service requests have this...)
1618 if (flags & AS_GUEST) {
1619 char *raddr;
1620 bool ok;
1622 if (!change_to_guest()) {
1623 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1624 return conn;
1627 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1628 talloc_tos());
1629 if (raddr == NULL) {
1630 reply_nterror(req, NT_STATUS_NO_MEMORY);
1631 return conn;
1635 * Haven't we checked this in smbd_process already???
1638 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1639 xconn->remote_hostname, raddr);
1640 TALLOC_FREE(raddr);
1642 if (!ok) {
1643 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1644 return conn;
1648 smb_messages[type].fn(req);
1649 return req->conn;
1652 /****************************************************************************
1653 Construct a reply to the incoming packet.
1654 ****************************************************************************/
1656 static void construct_reply(struct smbXsrv_connection *xconn,
1657 char *inbuf, int size, size_t unread_bytes,
1658 uint32_t seqnum, bool encrypted,
1659 struct smb_perfcount_data *deferred_pcd)
1661 struct smbd_server_connection *sconn = xconn->client->sconn;
1662 struct smb_request *req;
1664 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1665 smb_panic("could not allocate smb_request");
1668 if (!init_smb_request(req, sconn, xconn, (uint8 *)inbuf, unread_bytes,
1669 encrypted, seqnum)) {
1670 exit_server_cleanly("Invalid SMB request");
1673 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1675 /* we popped this message off the queue - keep original perf data */
1676 if (deferred_pcd)
1677 req->pcd = *deferred_pcd;
1678 else {
1679 SMB_PERFCOUNT_START(&req->pcd);
1680 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1681 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1684 req->conn = switch_message(req->cmd, req);
1686 if (req->outbuf == NULL) {
1688 * Request has suspended itself, will come
1689 * back here.
1691 return;
1693 if (CVAL(req->outbuf,0) == 0) {
1694 show_msg((char *)req->outbuf);
1696 smb_request_done(req);
1699 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1700 char *inbuf, int size, uint32_t seqnum,
1701 bool encrypted,
1702 struct smb_perfcount_data *deferred_pcd)
1704 struct smb_request **reqs = NULL;
1705 struct smb_request *req;
1706 unsigned num_reqs;
1707 bool ok;
1709 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, xconn, encrypted,
1710 seqnum, &reqs, &num_reqs);
1711 if (!ok) {
1712 char errbuf[smb_size];
1713 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1714 __LINE__, __FILE__);
1715 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1716 NULL)) {
1717 exit_server_cleanly("construct_reply_chain: "
1718 "srv_send_smb failed.");
1720 return;
1723 req = reqs[0];
1724 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1726 req->conn = switch_message(req->cmd, req);
1728 if (req->outbuf == NULL) {
1730 * Request has suspended itself, will come
1731 * back here.
1733 return;
1735 smb_request_done(req);
1739 * To be called from an async SMB handler that is potentially chained
1740 * when it is finished for shipping.
1743 void smb_request_done(struct smb_request *req)
1745 struct smb_request **reqs = NULL;
1746 struct smb_request *first_req;
1747 size_t i, num_reqs, next_index;
1748 NTSTATUS status;
1750 if (req->chain == NULL) {
1751 first_req = req;
1752 goto shipit;
1755 reqs = req->chain;
1756 num_reqs = talloc_array_length(reqs);
1758 for (i=0; i<num_reqs; i++) {
1759 if (reqs[i] == req) {
1760 break;
1763 if (i == num_reqs) {
1765 * Invalid chain, should not happen
1767 status = NT_STATUS_INTERNAL_ERROR;
1768 goto error;
1770 next_index = i+1;
1772 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1773 struct smb_request *next = reqs[next_index];
1774 struct smbXsrv_tcon *tcon;
1775 NTTIME now = timeval_to_nttime(&req->request_time);
1777 next->vuid = SVAL(req->outbuf, smb_uid);
1778 next->tid = SVAL(req->outbuf, smb_tid);
1779 status = smb1srv_tcon_lookup(req->xconn, req->tid,
1780 now, &tcon);
1781 if (NT_STATUS_IS_OK(status)) {
1782 req->conn = tcon->compat;
1783 } else {
1784 req->conn = NULL;
1786 next->chain_fsp = req->chain_fsp;
1787 next->inbuf = req->inbuf;
1789 req = next;
1790 req->conn = switch_message(req->cmd, req);
1792 if (req->outbuf == NULL) {
1794 * Request has suspended itself, will come
1795 * back here.
1797 return;
1799 next_index += 1;
1802 first_req = reqs[0];
1804 for (i=1; i<next_index; i++) {
1805 bool ok;
1807 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1808 if (!ok) {
1809 status = NT_STATUS_INTERNAL_ERROR;
1810 goto error;
1814 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1815 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1818 * This scary statement intends to set the
1819 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1820 * to the value last_req->outbuf carries
1822 SSVAL(first_req->outbuf, smb_flg2,
1823 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1824 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1827 * Transfer the error codes from the subrequest to the main one
1829 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1830 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1832 _smb_setlen_large(
1833 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1835 shipit:
1836 if (!srv_send_smb(first_req->xconn,
1837 (char *)first_req->outbuf,
1838 true, first_req->seqnum+1,
1839 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1840 &first_req->pcd)) {
1841 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1842 "failed.");
1844 TALLOC_FREE(req); /* non-chained case */
1845 TALLOC_FREE(reqs); /* chained case */
1846 return;
1848 error:
1850 char errbuf[smb_size];
1851 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1852 if (!srv_send_smb(req->xconn, errbuf, true,
1853 req->seqnum+1, req->encrypted,
1854 NULL)) {
1855 exit_server_cleanly("construct_reply_chain: "
1856 "srv_send_smb failed.");
1859 TALLOC_FREE(req); /* non-chained case */
1860 TALLOC_FREE(reqs); /* chained case */
1863 /****************************************************************************
1864 Process an smb from the client
1865 ****************************************************************************/
1866 static void process_smb(struct smbXsrv_connection *xconn,
1867 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1868 uint32_t seqnum, bool encrypted,
1869 struct smb_perfcount_data *deferred_pcd)
1871 struct smbd_server_connection *sconn = xconn->client->sconn;
1872 int msg_type = CVAL(inbuf,0);
1874 DO_PROFILE_INC(smb_count);
1876 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1877 smb_len(inbuf) ) );
1878 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1879 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1881 if (msg_type != NBSSmessage) {
1883 * NetBIOS session request, keepalive, etc.
1885 reply_special(xconn, (char *)inbuf, nread);
1886 goto done;
1889 if (sconn->using_smb2) {
1890 /* At this point we're not really using smb2,
1891 * we make the decision here.. */
1892 if (smbd_is_smb2_header(inbuf, nread)) {
1893 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1894 size_t pdulen = nread - NBT_HDR_SIZE;
1895 smbd_smb2_first_negprot(xconn, inpdu, pdulen);
1896 return;
1897 } else if (nread >= smb_size && valid_smb_header(inbuf)
1898 && CVAL(inbuf, smb_com) != 0x72) {
1899 /* This is a non-negprot SMB1 packet.
1900 Disable SMB2 from now on. */
1901 sconn->using_smb2 = false;
1905 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1906 * so subtract 4 from it. */
1907 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1908 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1909 smb_len(inbuf)));
1911 /* special magic for immediate exit */
1912 if ((nread == 9) &&
1913 (IVAL(inbuf, 4) == 0x74697865) &&
1914 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1915 uint8_t exitcode = CVAL(inbuf, 8);
1916 DEBUG(1, ("Exiting immediately with code %d\n",
1917 (int)exitcode));
1918 exit(exitcode);
1921 exit_server_cleanly("Non-SMB packet");
1924 show_msg((char *)inbuf);
1926 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1927 construct_reply_chain(xconn, (char *)inbuf, nread,
1928 seqnum, encrypted, deferred_pcd);
1929 } else {
1930 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
1931 seqnum, encrypted, deferred_pcd);
1934 sconn->trans_num++;
1936 done:
1937 sconn->num_requests++;
1939 /* The timeout_processing function isn't run nearly
1940 often enough to implement 'max log size' without
1941 overrunning the size of the file by many megabytes.
1942 This is especially true if we are running at debug
1943 level 10. Checking every 50 SMBs is a nice
1944 tradeoff of performance vs log file size overrun. */
1946 if ((sconn->num_requests % 50) == 0 &&
1947 need_to_check_log_size()) {
1948 change_to_root_user();
1949 check_log_size();
1953 /****************************************************************************
1954 Return a string containing the function name of a SMB command.
1955 ****************************************************************************/
1957 const char *smb_fn_name(int type)
1959 const char *unknown_name = "SMBunknown";
1961 if (smb_messages[type].name == NULL)
1962 return(unknown_name);
1964 return(smb_messages[type].name);
1967 /****************************************************************************
1968 Helper functions for contruct_reply.
1969 ****************************************************************************/
1971 void add_to_common_flags2(uint32 v)
1973 common_flags2 |= v;
1976 void remove_from_common_flags2(uint32 v)
1978 common_flags2 &= ~v;
1981 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1982 char *outbuf)
1984 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1985 uint16_t out_flags2 = common_flags2;
1987 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1988 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1989 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1991 srv_set_message(outbuf,0,0,false);
1993 SCVAL(outbuf, smb_com, req->cmd);
1994 SIVAL(outbuf,smb_rcls,0);
1995 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1996 SSVAL(outbuf,smb_flg2, out_flags2);
1997 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1998 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2000 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2001 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2002 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2003 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2006 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2008 construct_reply_common(req, (const char *)req->inbuf, outbuf);
2012 * @brief Find the smb_cmd offset of the last command pushed
2013 * @param[in] buf The buffer we're building up
2014 * @retval Where can we put our next andx cmd?
2016 * While chaining requests, the "next" request we're looking at needs to put
2017 * its SMB_Command before the data the previous request already built up added
2018 * to the chain. Find the offset to the place where we have to put our cmd.
2021 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2023 uint8_t cmd;
2024 size_t ofs;
2026 cmd = CVAL(buf, smb_com);
2028 if (!is_andx_req(cmd)) {
2029 return false;
2032 ofs = smb_vwv0;
2034 while (CVAL(buf, ofs) != 0xff) {
2036 if (!is_andx_req(CVAL(buf, ofs))) {
2037 return false;
2041 * ofs is from start of smb header, so add the 4 length
2042 * bytes. The next cmd is right after the wct field.
2044 ofs = SVAL(buf, ofs+2) + 4 + 1;
2046 if (ofs+4 >= talloc_get_size(buf)) {
2047 return false;
2051 *pofs = ofs;
2052 return true;
2056 * @brief Do the smb chaining at a buffer level
2057 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2058 * @param[in] andx_buf Buffer to be appended
2061 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2063 uint8_t smb_command = CVAL(andx_buf, smb_com);
2064 uint8_t wct = CVAL(andx_buf, smb_wct);
2065 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2066 uint32_t num_bytes = smb_buflen(andx_buf);
2067 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2069 uint8_t *outbuf;
2070 size_t old_size, new_size;
2071 size_t ofs;
2072 size_t chain_padding = 0;
2073 size_t andx_cmd_ofs;
2076 old_size = talloc_get_size(*poutbuf);
2078 if ((old_size % 4) != 0) {
2080 * Align the wct field of subsequent requests to a 4-byte
2081 * boundary
2083 chain_padding = 4 - (old_size % 4);
2087 * After the old request comes the new wct field (1 byte), the vwv's
2088 * and the num_bytes field.
2091 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2092 new_size += num_bytes;
2094 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2095 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2096 (unsigned)new_size));
2097 return false;
2100 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2101 if (outbuf == NULL) {
2102 DEBUG(0, ("talloc failed\n"));
2103 return false;
2105 *poutbuf = outbuf;
2107 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2108 DEBUG(1, ("invalid command chain\n"));
2109 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2110 return false;
2113 if (chain_padding != 0) {
2114 memset(outbuf + old_size, 0, chain_padding);
2115 old_size += chain_padding;
2118 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2119 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2121 ofs = old_size;
2124 * Push the chained request:
2126 * wct field
2129 SCVAL(outbuf, ofs, wct);
2130 ofs += 1;
2133 * vwv array
2136 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2139 * HACK ALERT
2141 * Read&X has an offset into its data buffer at
2142 * vwv[6]. reply_read_andx has no idea anymore that it's
2143 * running from within a chain, so we have to fix up the
2144 * offset here.
2146 * Although it looks disgusting at this place, I want to keep
2147 * it here. The alternative would be to push knowledge about
2148 * the andx chain down into read&x again.
2151 if (smb_command == SMBreadX) {
2152 uint8_t *bytes_addr;
2154 if (wct < 7) {
2156 * Invalid read&x response
2158 return false;
2161 bytes_addr = outbuf + ofs /* vwv start */
2162 + sizeof(uint16_t) * wct /* vwv array */
2163 + sizeof(uint16_t) /* bcc */
2164 + 1; /* padding byte */
2166 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2167 bytes_addr - outbuf - 4);
2170 ofs += sizeof(uint16_t) * wct;
2173 * bcc (byte count)
2176 SSVAL(outbuf, ofs, num_bytes);
2177 ofs += sizeof(uint16_t);
2180 * The bytes field
2183 memcpy(outbuf + ofs, bytes, num_bytes);
2185 return true;
2188 bool smb1_is_chain(const uint8_t *buf)
2190 uint8_t cmd, wct, andx_cmd;
2192 cmd = CVAL(buf, smb_com);
2193 if (!is_andx_req(cmd)) {
2194 return false;
2196 wct = CVAL(buf, smb_wct);
2197 if (wct < 2) {
2198 return false;
2200 andx_cmd = CVAL(buf, smb_vwv);
2201 return (andx_cmd != 0xFF);
2204 bool smb1_walk_chain(const uint8_t *buf,
2205 bool (*fn)(uint8_t cmd,
2206 uint8_t wct, const uint16_t *vwv,
2207 uint16_t num_bytes, const uint8_t *bytes,
2208 void *private_data),
2209 void *private_data)
2211 size_t smblen = smb_len(buf);
2212 const char *smb_buf = smb_base(buf);
2213 uint8_t cmd, chain_cmd;
2214 uint8_t wct;
2215 const uint16_t *vwv;
2216 uint16_t num_bytes;
2217 const uint8_t *bytes;
2219 cmd = CVAL(buf, smb_com);
2220 wct = CVAL(buf, smb_wct);
2221 vwv = (const uint16_t *)(buf + smb_vwv);
2222 num_bytes = smb_buflen(buf);
2223 bytes = (const uint8_t *)smb_buf_const(buf);
2225 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2226 return false;
2229 if (!is_andx_req(cmd)) {
2230 return true;
2232 if (wct < 2) {
2233 return false;
2236 chain_cmd = CVAL(vwv, 0);
2238 while (chain_cmd != 0xff) {
2239 uint32_t chain_offset; /* uint32_t to avoid overflow */
2240 size_t length_needed;
2241 ptrdiff_t vwv_offset;
2243 chain_offset = SVAL(vwv+1, 0);
2246 * Check if the client tries to fool us. The chain
2247 * offset needs to point beyond the current request in
2248 * the chain, it needs to strictly grow. Otherwise we
2249 * might be tricked into an endless loop always
2250 * processing the same request over and over again. We
2251 * used to assume that vwv and the byte buffer array
2252 * in a chain are always attached, but OS/2 the
2253 * Write&X/Read&X chain puts the Read&X vwv array
2254 * right behind the Write&X vwv chain. The Write&X bcc
2255 * array is put behind the Read&X vwv array. So now we
2256 * check whether the chain offset points strictly
2257 * behind the previous vwv array. req->buf points
2258 * right after the vwv array of the previous
2259 * request. See
2260 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2261 * more information.
2264 vwv_offset = ((const char *)vwv - smb_buf);
2265 if (chain_offset <= vwv_offset) {
2266 return false;
2270 * Next check: Make sure the chain offset does not
2271 * point beyond the overall smb request length.
2274 length_needed = chain_offset+1; /* wct */
2275 if (length_needed > smblen) {
2276 return false;
2280 * Now comes the pointer magic. Goal here is to set up
2281 * vwv and buf correctly again. The chain offset (the
2282 * former vwv[1]) points at the new wct field.
2285 wct = CVAL(smb_buf, chain_offset);
2287 if (is_andx_req(chain_cmd) && (wct < 2)) {
2288 return false;
2292 * Next consistency check: Make the new vwv array fits
2293 * in the overall smb request.
2296 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2297 if (length_needed > smblen) {
2298 return false;
2300 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2303 * Now grab the new byte buffer....
2306 num_bytes = SVAL(vwv+wct, 0);
2309 * .. and check that it fits.
2312 length_needed += num_bytes;
2313 if (length_needed > smblen) {
2314 return false;
2316 bytes = (const uint8_t *)(vwv+wct+1);
2318 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2319 return false;
2322 if (!is_andx_req(chain_cmd)) {
2323 return true;
2325 chain_cmd = CVAL(vwv, 0);
2327 return true;
2330 static bool smb1_chain_length_cb(uint8_t cmd,
2331 uint8_t wct, const uint16_t *vwv,
2332 uint16_t num_bytes, const uint8_t *bytes,
2333 void *private_data)
2335 unsigned *count = (unsigned *)private_data;
2336 *count += 1;
2337 return true;
2340 unsigned smb1_chain_length(const uint8_t *buf)
2342 unsigned count = 0;
2344 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2345 return 0;
2347 return count;
2350 struct smb1_parse_chain_state {
2351 TALLOC_CTX *mem_ctx;
2352 const uint8_t *buf;
2353 struct smbd_server_connection *sconn;
2354 struct smbXsrv_connection *xconn;
2355 bool encrypted;
2356 uint32_t seqnum;
2358 struct smb_request **reqs;
2359 unsigned num_reqs;
2362 static bool smb1_parse_chain_cb(uint8_t cmd,
2363 uint8_t wct, const uint16_t *vwv,
2364 uint16_t num_bytes, const uint8_t *bytes,
2365 void *private_data)
2367 struct smb1_parse_chain_state *state =
2368 (struct smb1_parse_chain_state *)private_data;
2369 struct smb_request **reqs;
2370 struct smb_request *req;
2371 bool ok;
2373 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2374 struct smb_request *, state->num_reqs+1);
2375 if (reqs == NULL) {
2376 return false;
2378 state->reqs = reqs;
2380 req = talloc(reqs, struct smb_request);
2381 if (req == NULL) {
2382 return false;
2385 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2386 state->encrypted, state->seqnum);
2387 if (!ok) {
2388 return false;
2390 req->cmd = cmd;
2391 req->wct = wct;
2392 req->vwv = vwv;
2393 req->buflen = num_bytes;
2394 req->buf = bytes;
2396 reqs[state->num_reqs] = req;
2397 state->num_reqs += 1;
2398 return true;
2401 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2402 struct smbXsrv_connection *xconn,
2403 bool encrypted, uint32_t seqnum,
2404 struct smb_request ***reqs, unsigned *num_reqs)
2406 struct smbd_server_connection *sconn = NULL;
2407 struct smb1_parse_chain_state state;
2408 unsigned i;
2410 if (xconn != NULL) {
2411 sconn = xconn->client->sconn;
2414 state.mem_ctx = mem_ctx;
2415 state.buf = buf;
2416 state.sconn = sconn;
2417 state.xconn = xconn;
2418 state.encrypted = encrypted;
2419 state.seqnum = seqnum;
2420 state.reqs = NULL;
2421 state.num_reqs = 0;
2423 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2424 TALLOC_FREE(state.reqs);
2425 return false;
2427 for (i=0; i<state.num_reqs; i++) {
2428 state.reqs[i]->chain = state.reqs;
2430 *reqs = state.reqs;
2431 *num_reqs = state.num_reqs;
2432 return true;
2435 /****************************************************************************
2436 Check if services need reloading.
2437 ****************************************************************************/
2439 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2442 if (last_smb_conf_reload_time == 0) {
2443 last_smb_conf_reload_time = t;
2446 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2447 reload_services(sconn, conn_snum_used, true);
2448 last_smb_conf_reload_time = t;
2452 static bool fd_is_readable(int fd)
2454 int ret, revents;
2456 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2458 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2462 static void smbd_server_connection_write_handler(
2463 struct smbXsrv_connection *xconn)
2465 /* TODO: make write nonblocking */
2468 static void smbd_server_connection_read_handler(
2469 struct smbXsrv_connection *xconn, int fd)
2471 uint8_t *inbuf = NULL;
2472 size_t inbuf_len = 0;
2473 size_t unread_bytes = 0;
2474 bool encrypted = false;
2475 TALLOC_CTX *mem_ctx = talloc_tos();
2476 NTSTATUS status;
2477 uint32_t seqnum;
2479 bool async_echo = lp_async_smb_echo_handler();
2480 bool from_client = false;
2482 if (async_echo) {
2483 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2485 * This is the super-ugly hack to prefer the packets
2486 * forwarded by the echo handler over the ones by the
2487 * client directly
2489 fd = xconn->smb1.echo_handler.trusted_fd;
2493 from_client = (xconn->transport.sock == fd);
2495 if (async_echo && from_client) {
2496 smbd_lock_socket(xconn);
2498 if (!fd_is_readable(fd)) {
2499 DEBUG(10,("the echo listener was faster\n"));
2500 smbd_unlock_socket(xconn);
2501 return;
2505 /* TODO: make this completely nonblocking */
2506 status = receive_smb_talloc(mem_ctx, xconn, fd,
2507 (char **)(void *)&inbuf,
2508 0, /* timeout */
2509 &unread_bytes,
2510 &encrypted,
2511 &inbuf_len, &seqnum,
2512 !from_client /* trusted channel */);
2514 if (async_echo && from_client) {
2515 smbd_unlock_socket(xconn);
2518 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2519 goto process;
2521 if (NT_STATUS_IS_ERR(status)) {
2522 exit_server_cleanly("failed to receive smb request");
2524 if (!NT_STATUS_IS_OK(status)) {
2525 return;
2528 process:
2529 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2530 seqnum, encrypted, NULL);
2533 static void smbd_server_connection_handler(struct tevent_context *ev,
2534 struct tevent_fd *fde,
2535 uint16_t flags,
2536 void *private_data)
2538 struct smbXsrv_connection *xconn =
2539 talloc_get_type_abort(private_data,
2540 struct smbXsrv_connection);
2542 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2544 * we're not supposed to do any io
2546 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2547 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2548 return;
2551 if (flags & TEVENT_FD_WRITE) {
2552 smbd_server_connection_write_handler(xconn);
2553 return;
2555 if (flags & TEVENT_FD_READ) {
2556 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2557 return;
2561 static void smbd_server_echo_handler(struct tevent_context *ev,
2562 struct tevent_fd *fde,
2563 uint16_t flags,
2564 void *private_data)
2566 struct smbXsrv_connection *xconn =
2567 talloc_get_type_abort(private_data,
2568 struct smbXsrv_connection);
2570 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2572 * we're not supposed to do any io
2574 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2575 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2576 return;
2579 if (flags & TEVENT_FD_WRITE) {
2580 smbd_server_connection_write_handler(xconn);
2581 return;
2583 if (flags & TEVENT_FD_READ) {
2584 smbd_server_connection_read_handler(
2585 xconn, xconn->smb1.echo_handler.trusted_fd);
2586 return;
2590 struct smbd_release_ip_state {
2591 struct smbXsrv_connection *xconn;
2592 struct tevent_immediate *im;
2593 char addr[INET6_ADDRSTRLEN];
2596 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2597 struct tevent_immediate *im,
2598 void *private_data)
2600 struct smbd_release_ip_state *state =
2601 talloc_get_type_abort(private_data,
2602 struct smbd_release_ip_state);
2603 struct smbXsrv_connection *xconn = state->xconn;
2605 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2607 * smbd_server_connection_terminate() already triggered ?
2609 return;
2612 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2615 /****************************************************************************
2616 received when we should release a specific IP
2617 ****************************************************************************/
2618 static bool release_ip(const char *ip, void *priv)
2620 struct smbd_release_ip_state *state =
2621 talloc_get_type_abort(priv,
2622 struct smbd_release_ip_state);
2623 struct smbXsrv_connection *xconn = state->xconn;
2624 const char *addr = state->addr;
2625 const char *p = addr;
2627 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2628 /* avoid recursion */
2629 return false;
2632 if (strncmp("::ffff:", addr, 7) == 0) {
2633 p = addr + 7;
2636 DEBUG(10, ("Got release IP message for %s, "
2637 "our address is %s\n", ip, p));
2639 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2640 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2641 ip));
2643 * With SMB2 we should do a clean disconnect,
2644 * the previous_session_id in the session setup
2645 * will cleanup the old session, tcons and opens.
2647 * A clean disconnect is needed in order to support
2648 * durable handles.
2650 * Note: typically this is never triggered
2651 * as we got a TCP RST (triggered by ctdb event scripts)
2652 * before we get CTDB_SRVID_RELEASE_IP.
2654 * We used to call _exit(1) here, but as this was mostly never
2655 * triggered and has implication on our process model,
2656 * we can just use smbd_server_connection_terminate()
2657 * (also for SMB1).
2659 * We don't call smbd_server_connection_terminate() directly
2660 * as we might be called from within ctdbd_migrate(),
2661 * we need to defer our action to the next event loop
2663 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2664 smbd_release_ip_immediate, state);
2667 * Make sure we don't get any io on the connection.
2669 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2670 return true;
2673 return false;
2676 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2677 struct sockaddr_storage *srv,
2678 struct sockaddr_storage *clnt)
2680 struct smbd_release_ip_state *state;
2681 struct ctdbd_connection *cconn;
2683 cconn = messaging_ctdbd_connection();
2684 if (cconn == NULL) {
2685 return NT_STATUS_NO_MEMORY;
2688 state = talloc_zero(xconn, struct smbd_release_ip_state);
2689 if (state == NULL) {
2690 return NT_STATUS_NO_MEMORY;
2692 state->xconn = xconn;
2693 state->im = tevent_create_immediate(state);
2694 if (state->im == NULL) {
2695 return NT_STATUS_NO_MEMORY;
2697 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2698 return NT_STATUS_NO_MEMORY;
2701 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2704 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2705 void *private_data, uint32_t msg_type,
2706 struct server_id server_id, DATA_BLOB *data)
2708 struct smbd_server_connection *sconn = talloc_get_type_abort(
2709 private_data, struct smbd_server_connection);
2710 const char *ip = (char *) data->data;
2711 char *client_ip;
2713 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2715 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2716 talloc_tos());
2717 if (client_ip == NULL) {
2718 return;
2721 if (strequal(ip, client_ip)) {
2722 DEBUG(1, ("Got kill client message for %s - "
2723 "exiting immediately\n", ip));
2724 exit_server_cleanly("Forced disconnect for client");
2727 TALLOC_FREE(client_ip);
2731 * Send keepalive packets to our client
2733 static bool keepalive_fn(const struct timeval *now, void *private_data)
2735 struct smbd_server_connection *sconn = talloc_get_type_abort(
2736 private_data, struct smbd_server_connection);
2737 struct smbXsrv_connection *xconn = NULL;
2738 bool ret;
2740 if (sconn->using_smb2) {
2741 /* Don't do keepalives on an SMB2 connection. */
2742 return false;
2746 * With SMB1 we only have 1 connection
2748 xconn = sconn->client->connections;
2749 smbd_lock_socket(xconn);
2750 ret = send_keepalive(xconn->transport.sock);
2751 smbd_unlock_socket(xconn);
2753 if (!ret) {
2754 int saved_errno = errno;
2756 * Try and give an error message saying what
2757 * client failed.
2759 DEBUG(0, ("send_keepalive failed for client %s. "
2760 "Error %s - exiting\n",
2761 smbXsrv_connection_dbg(xconn),
2762 strerror(saved_errno)));
2763 errno = saved_errno;
2764 return False;
2766 return True;
2770 * Do the recurring check if we're idle
2772 static bool deadtime_fn(const struct timeval *now, void *private_data)
2774 struct smbd_server_connection *sconn =
2775 (struct smbd_server_connection *)private_data;
2777 if ((conn_num_open(sconn) == 0)
2778 || (conn_idle_all(sconn, now->tv_sec))) {
2779 DEBUG( 2, ( "Closing idle connection\n" ) );
2780 messaging_send(sconn->msg_ctx,
2781 messaging_server_id(sconn->msg_ctx),
2782 MSG_SHUTDOWN, &data_blob_null);
2783 return False;
2786 return True;
2790 * Do the recurring log file and smb.conf reload checks.
2793 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2795 struct smbd_server_connection *sconn = talloc_get_type_abort(
2796 private_data, struct smbd_server_connection);
2798 DEBUG(5, ("housekeeping\n"));
2800 change_to_root_user();
2802 /* update printer queue caches if necessary */
2803 update_monitored_printq_cache(sconn->msg_ctx);
2805 /* check if we need to reload services */
2806 check_reload(sconn, time_mono(NULL));
2809 * Force a log file check.
2811 force_check_log_size();
2812 check_log_size();
2813 return true;
2817 * Read an smb packet in the echo handler child, giving the parent
2818 * smbd one second to react once the socket becomes readable.
2821 struct smbd_echo_read_state {
2822 struct tevent_context *ev;
2823 struct smbXsrv_connection *xconn;
2825 char *buf;
2826 size_t buflen;
2827 uint32_t seqnum;
2830 static void smbd_echo_read_readable(struct tevent_req *subreq);
2831 static void smbd_echo_read_waited(struct tevent_req *subreq);
2833 static struct tevent_req *smbd_echo_read_send(
2834 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2835 struct smbXsrv_connection *xconn)
2837 struct tevent_req *req, *subreq;
2838 struct smbd_echo_read_state *state;
2840 req = tevent_req_create(mem_ctx, &state,
2841 struct smbd_echo_read_state);
2842 if (req == NULL) {
2843 return NULL;
2845 state->ev = ev;
2846 state->xconn = xconn;
2848 subreq = wait_for_read_send(state, ev, xconn->transport.sock);
2849 if (tevent_req_nomem(subreq, req)) {
2850 return tevent_req_post(req, ev);
2852 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2853 return req;
2856 static void smbd_echo_read_readable(struct tevent_req *subreq)
2858 struct tevent_req *req = tevent_req_callback_data(
2859 subreq, struct tevent_req);
2860 struct smbd_echo_read_state *state = tevent_req_data(
2861 req, struct smbd_echo_read_state);
2862 bool ok;
2863 int err;
2865 ok = wait_for_read_recv(subreq, &err);
2866 TALLOC_FREE(subreq);
2867 if (!ok) {
2868 tevent_req_nterror(req, map_nt_error_from_unix(err));
2869 return;
2873 * Give the parent smbd one second to step in
2876 subreq = tevent_wakeup_send(
2877 state, state->ev, timeval_current_ofs(1, 0));
2878 if (tevent_req_nomem(subreq, req)) {
2879 return;
2881 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2884 static void smbd_echo_read_waited(struct tevent_req *subreq)
2886 struct tevent_req *req = tevent_req_callback_data(
2887 subreq, struct tevent_req);
2888 struct smbd_echo_read_state *state = tevent_req_data(
2889 req, struct smbd_echo_read_state);
2890 struct smbXsrv_connection *xconn = state->xconn;
2891 bool ok;
2892 NTSTATUS status;
2893 size_t unread = 0;
2894 bool encrypted;
2896 ok = tevent_wakeup_recv(subreq);
2897 TALLOC_FREE(subreq);
2898 if (!ok) {
2899 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2900 return;
2903 ok = smbd_lock_socket_internal(xconn);
2904 if (!ok) {
2905 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2906 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2907 return;
2910 if (!fd_is_readable(xconn->transport.sock)) {
2911 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2912 (int)getpid()));
2914 ok = smbd_unlock_socket_internal(xconn);
2915 if (!ok) {
2916 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2917 DEBUG(1, ("%s: failed to unlock socket\n",
2918 __location__));
2919 return;
2922 subreq = wait_for_read_send(state, state->ev,
2923 xconn->transport.sock);
2924 if (tevent_req_nomem(subreq, req)) {
2925 return;
2927 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2928 return;
2931 status = receive_smb_talloc(state, xconn,
2932 xconn->transport.sock,
2933 &state->buf,
2934 0 /* timeout */,
2935 &unread,
2936 &encrypted,
2937 &state->buflen,
2938 &state->seqnum,
2939 false /* trusted_channel*/);
2941 if (tevent_req_nterror(req, status)) {
2942 tevent_req_nterror(req, status);
2943 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2944 (int)getpid(), nt_errstr(status)));
2945 return;
2948 ok = smbd_unlock_socket_internal(xconn);
2949 if (!ok) {
2950 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2951 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2952 return;
2954 tevent_req_done(req);
2957 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2958 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2960 struct smbd_echo_read_state *state = tevent_req_data(
2961 req, struct smbd_echo_read_state);
2962 NTSTATUS status;
2964 if (tevent_req_is_nterror(req, &status)) {
2965 return status;
2967 *pbuf = talloc_move(mem_ctx, &state->buf);
2968 *pbuflen = state->buflen;
2969 *pseqnum = state->seqnum;
2970 return NT_STATUS_OK;
2973 struct smbd_echo_state {
2974 struct tevent_context *ev;
2975 struct iovec *pending;
2976 struct smbd_server_connection *sconn;
2977 struct smbXsrv_connection *xconn;
2978 int parent_pipe;
2980 struct tevent_fd *parent_fde;
2982 struct tevent_req *write_req;
2985 static void smbd_echo_writer_done(struct tevent_req *req);
2987 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2989 int num_pending;
2991 if (state->write_req != NULL) {
2992 return;
2995 num_pending = talloc_array_length(state->pending);
2996 if (num_pending == 0) {
2997 return;
3000 state->write_req = writev_send(state, state->ev, NULL,
3001 state->parent_pipe, false,
3002 state->pending, num_pending);
3003 if (state->write_req == NULL) {
3004 DEBUG(1, ("writev_send failed\n"));
3005 exit(1);
3008 talloc_steal(state->write_req, state->pending);
3009 state->pending = NULL;
3011 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3012 state);
3015 static void smbd_echo_writer_done(struct tevent_req *req)
3017 struct smbd_echo_state *state = tevent_req_callback_data(
3018 req, struct smbd_echo_state);
3019 ssize_t written;
3020 int err;
3022 written = writev_recv(req, &err);
3023 TALLOC_FREE(req);
3024 state->write_req = NULL;
3025 if (written == -1) {
3026 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3027 exit(1);
3029 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3030 smbd_echo_activate_writer(state);
3033 static bool smbd_echo_reply(struct smbd_echo_state *state,
3034 uint8_t *inbuf, size_t inbuf_len,
3035 uint32_t seqnum)
3037 struct smb_request req;
3038 uint16_t num_replies;
3039 char *outbuf;
3040 bool ok;
3042 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3043 DEBUG(10, ("Got netbios keepalive\n"));
3045 * Just swallow it
3047 return true;
3050 if (inbuf_len < smb_size) {
3051 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3052 return false;
3054 if (!valid_smb_header(inbuf)) {
3055 DEBUG(10, ("Got invalid SMB header\n"));
3056 return false;
3059 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3060 seqnum)) {
3061 return false;
3063 req.inbuf = inbuf;
3065 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3066 smb_messages[req.cmd].name
3067 ? smb_messages[req.cmd].name : "unknown"));
3069 if (req.cmd != SMBecho) {
3070 return false;
3072 if (req.wct < 1) {
3073 return false;
3076 num_replies = SVAL(req.vwv+0, 0);
3077 if (num_replies != 1) {
3078 /* Not a Windows "Hey, you're still there?" request */
3079 return false;
3082 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3083 1, req.buflen)) {
3084 DEBUG(10, ("create_outbuf failed\n"));
3085 return false;
3087 req.outbuf = (uint8_t *)outbuf;
3089 SSVAL(req.outbuf, smb_vwv0, num_replies);
3091 if (req.buflen > 0) {
3092 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3095 ok = srv_send_smb(req.xconn,
3096 (char *)outbuf,
3097 true, seqnum+1,
3098 false, &req.pcd);
3099 TALLOC_FREE(outbuf);
3100 if (!ok) {
3101 exit(1);
3104 return true;
3107 static void smbd_echo_exit(struct tevent_context *ev,
3108 struct tevent_fd *fde, uint16_t flags,
3109 void *private_data)
3111 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3112 exit(0);
3115 static void smbd_echo_got_packet(struct tevent_req *req);
3117 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3118 int parent_pipe)
3120 struct smbd_echo_state *state;
3121 struct tevent_req *read_req;
3123 state = talloc_zero(xconn, struct smbd_echo_state);
3124 if (state == NULL) {
3125 DEBUG(1, ("talloc failed\n"));
3126 return;
3128 state->xconn = xconn;
3129 state->parent_pipe = parent_pipe;
3130 state->ev = s3_tevent_context_init(state);
3131 if (state->ev == NULL) {
3132 DEBUG(1, ("tevent_context_init failed\n"));
3133 TALLOC_FREE(state);
3134 return;
3136 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3137 TEVENT_FD_READ, smbd_echo_exit,
3138 state);
3139 if (state->parent_fde == NULL) {
3140 DEBUG(1, ("tevent_add_fd failed\n"));
3141 TALLOC_FREE(state);
3142 return;
3145 read_req = smbd_echo_read_send(state, state->ev, xconn);
3146 if (read_req == NULL) {
3147 DEBUG(1, ("smbd_echo_read_send failed\n"));
3148 TALLOC_FREE(state);
3149 return;
3151 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3153 while (true) {
3154 if (tevent_loop_once(state->ev) == -1) {
3155 DEBUG(1, ("tevent_loop_once failed: %s\n",
3156 strerror(errno)));
3157 break;
3160 TALLOC_FREE(state);
3163 static void smbd_echo_got_packet(struct tevent_req *req)
3165 struct smbd_echo_state *state = tevent_req_callback_data(
3166 req, struct smbd_echo_state);
3167 NTSTATUS status;
3168 char *buf = NULL;
3169 size_t buflen = 0;
3170 uint32_t seqnum = 0;
3171 bool reply;
3173 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3174 TALLOC_FREE(req);
3175 if (!NT_STATUS_IS_OK(status)) {
3176 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3177 nt_errstr(status)));
3178 exit(1);
3181 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3182 if (!reply) {
3183 size_t num_pending;
3184 struct iovec *tmp;
3185 struct iovec *iov;
3187 num_pending = talloc_array_length(state->pending);
3188 tmp = talloc_realloc(state, state->pending, struct iovec,
3189 num_pending+1);
3190 if (tmp == NULL) {
3191 DEBUG(1, ("talloc_realloc failed\n"));
3192 exit(1);
3194 state->pending = tmp;
3196 if (buflen >= smb_size) {
3198 * place the seqnum in the packet so that the main process
3199 * can reply with signing
3201 SIVAL(buf, smb_ss_field, seqnum);
3202 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3205 iov = &state->pending[num_pending];
3206 iov->iov_base = talloc_move(state->pending, &buf);
3207 iov->iov_len = buflen;
3209 DEBUG(10,("echo_handler[%d]: forward to main\n",
3210 (int)getpid()));
3211 smbd_echo_activate_writer(state);
3214 req = smbd_echo_read_send(state, state->ev, state->xconn);
3215 if (req == NULL) {
3216 DEBUG(1, ("smbd_echo_read_send failed\n"));
3217 exit(1);
3219 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3224 * Handle SMBecho requests in a forked child process
3226 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3228 int listener_pipe[2];
3229 int res;
3230 pid_t child;
3231 bool use_mutex = false;
3233 res = pipe(listener_pipe);
3234 if (res == -1) {
3235 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3236 return false;
3239 #ifdef HAVE_ROBUST_MUTEXES
3240 use_mutex = tdb_runtime_check_for_robust_mutexes();
3242 if (use_mutex) {
3243 pthread_mutexattr_t a;
3245 xconn->smb1.echo_handler.socket_mutex =
3246 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3247 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3248 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3249 strerror(errno)));
3250 goto fail;
3253 res = pthread_mutexattr_init(&a);
3254 if (res != 0) {
3255 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3256 strerror(res)));
3257 goto fail;
3259 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3260 if (res != 0) {
3261 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3262 strerror(res)));
3263 pthread_mutexattr_destroy(&a);
3264 goto fail;
3266 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3267 if (res != 0) {
3268 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3269 strerror(res)));
3270 pthread_mutexattr_destroy(&a);
3271 goto fail;
3273 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3274 if (res != 0) {
3275 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3276 "%s\n", strerror(res)));
3277 pthread_mutexattr_destroy(&a);
3278 goto fail;
3280 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3281 &a);
3282 pthread_mutexattr_destroy(&a);
3283 if (res != 0) {
3284 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3285 strerror(res)));
3286 goto fail;
3289 #endif
3291 if (!use_mutex) {
3292 xconn->smb1.echo_handler.socket_lock_fd =
3293 create_unlink_tmp(lp_lock_directory());
3294 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3295 DEBUG(1, ("Could not create lock fd: %s\n",
3296 strerror(errno)));
3297 goto fail;
3301 child = fork();
3302 if (child == 0) {
3303 NTSTATUS status;
3305 close(listener_pipe[0]);
3306 set_blocking(listener_pipe[1], false);
3308 status = reinit_after_fork(xconn->msg_ctx,
3309 xconn->ev_ctx,
3310 true);
3311 if (!NT_STATUS_IS_OK(status)) {
3312 DEBUG(1, ("reinit_after_fork failed: %s\n",
3313 nt_errstr(status)));
3314 exit(1);
3316 smbd_echo_loop(xconn, listener_pipe[1]);
3317 exit(0);
3319 close(listener_pipe[1]);
3320 listener_pipe[1] = -1;
3321 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3323 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3326 * Without smb signing this is the same as the normal smbd
3327 * listener. This needs to change once signing comes in.
3329 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3330 xconn,
3331 xconn->smb1.echo_handler.trusted_fd,
3332 TEVENT_FD_READ,
3333 smbd_server_echo_handler,
3334 xconn);
3335 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3336 DEBUG(1, ("event_add_fd failed\n"));
3337 goto fail;
3340 return true;
3342 fail:
3343 if (listener_pipe[0] != -1) {
3344 close(listener_pipe[0]);
3346 if (listener_pipe[1] != -1) {
3347 close(listener_pipe[1]);
3349 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3350 close(xconn->smb1.echo_handler.socket_lock_fd);
3352 #ifdef HAVE_ROBUST_MUTEXES
3353 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3354 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3355 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3357 #endif
3358 smbd_echo_init(xconn);
3360 return false;
3363 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3365 while (user) {
3366 if (user->session_info &&
3367 (user->session_info->unix_token->uid == uid)) {
3368 return true;
3370 user = user->next;
3372 return false;
3375 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3377 while (user) {
3378 if (user->session_info != NULL) {
3379 int i;
3380 struct security_unix_token *utok;
3382 utok = user->session_info->unix_token;
3383 if (utok->gid == gid) {
3384 return true;
3386 for(i=0; i<utok->ngroups; i++) {
3387 if (utok->groups[i] == gid) {
3388 return true;
3392 user = user->next;
3394 return false;
3397 static bool sid_in_use(const struct user_struct *user,
3398 const struct dom_sid *psid)
3400 while (user) {
3401 struct security_token *tok;
3403 if (user->session_info == NULL) {
3404 continue;
3406 tok = user->session_info->security_token;
3407 if (tok == NULL) {
3409 * Not sure session_info->security_token can
3410 * ever be NULL. This check might be not
3411 * necessary.
3413 continue;
3415 if (security_token_has_sid(tok, psid)) {
3416 return true;
3418 user = user->next;
3420 return false;
3423 static bool id_in_use(const struct user_struct *user,
3424 const struct id_cache_ref *id)
3426 switch(id->type) {
3427 case UID:
3428 return uid_in_use(user, id->id.uid);
3429 case GID:
3430 return gid_in_use(user, id->id.gid);
3431 case SID:
3432 return sid_in_use(user, &id->id.sid);
3433 default:
3434 break;
3436 return false;
3439 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3440 void *private_data,
3441 uint32_t msg_type,
3442 struct server_id server_id,
3443 DATA_BLOB* data)
3445 const char *msg = (data && data->data)
3446 ? (const char *)data->data : "<NULL>";
3447 struct id_cache_ref id;
3448 struct smbd_server_connection *sconn =
3449 talloc_get_type_abort(private_data,
3450 struct smbd_server_connection);
3452 if (!id_cache_ref_parse(msg, &id)) {
3453 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3454 return;
3457 if (id_in_use(sconn->users, &id)) {
3458 exit_server_cleanly(msg);
3460 id_cache_delete_from_cache(&id);
3463 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3464 enum protocol_types protocol)
3466 NTSTATUS status;
3468 set_Protocol(protocol);
3469 conn->protocol = protocol;
3471 if (protocol >= PROTOCOL_SMB2_02) {
3472 status = smb2srv_session_table_init(conn);
3473 if (!NT_STATUS_IS_OK(status)) {
3474 return status;
3477 status = smb2srv_open_table_init(conn);
3478 if (!NT_STATUS_IS_OK(status)) {
3479 return status;
3481 } else {
3482 status = smb1srv_session_table_init(conn);
3483 if (!NT_STATUS_IS_OK(status)) {
3484 return status;
3487 status = smb1srv_tcon_table_init(conn);
3488 if (!NT_STATUS_IS_OK(status)) {
3489 return status;
3492 status = smb1srv_open_table_init(conn);
3493 if (!NT_STATUS_IS_OK(status)) {
3494 return status;
3498 return NT_STATUS_OK;
3501 struct smbd_tevent_trace_state {
3502 TALLOC_CTX *frame;
3503 uint64_t smbd_idle_profstamp;
3506 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3507 void *private_data)
3509 struct smbd_tevent_trace_state *state =
3510 (struct smbd_tevent_trace_state *)private_data;
3512 switch (point) {
3513 case TEVENT_TRACE_BEFORE_WAIT:
3515 * This just removes compiler warning
3516 * without profile support
3518 state->smbd_idle_profstamp = 0;
3519 START_PROFILE_STAMP(smbd_idle, state->smbd_idle_profstamp);
3520 break;
3521 case TEVENT_TRACE_AFTER_WAIT:
3522 END_PROFILE_STAMP(smbd_idle, state->smbd_idle_profstamp);
3523 break;
3524 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3525 TALLOC_FREE(state->frame);
3526 state->frame = talloc_stackframe_pool(8192);
3527 break;
3528 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3529 TALLOC_FREE(state->frame);
3530 break;
3533 errno = 0;
3537 * Create a debug string for the connection
3539 * This is allocated to talloc_tos() or a string constant
3540 * in certain corner cases. The returned string should
3541 * hence not be free'd directly but only via the talloc stack.
3543 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3545 const char *ret;
3548 * TODO: this can be improved later
3549 * maybe including the client guid or more
3551 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3552 if (ret == NULL) {
3553 return "<tsocket_address_string() failed>";
3556 return ret;
3559 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3560 struct smbXsrv_connection **_xconn)
3562 TALLOC_CTX *frame = talloc_stackframe();
3563 struct smbXsrv_connection *xconn;
3564 struct sockaddr_storage ss_srv;
3565 void *sp_srv = (void *)&ss_srv;
3566 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3567 struct sockaddr_storage ss_clnt;
3568 void *sp_clnt = (void *)&ss_clnt;
3569 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3570 socklen_t sa_socklen;
3571 struct tsocket_address *local_address = NULL;
3572 struct tsocket_address *remote_address = NULL;
3573 const char *remaddr = NULL;
3574 char *p;
3575 const char *rhost = NULL;
3576 int ret;
3577 int tmp;
3579 *_xconn = NULL;
3581 xconn = talloc_zero(client, struct smbXsrv_connection);
3582 if (xconn == NULL) {
3583 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3584 TALLOC_FREE(frame);
3585 return NT_STATUS_NO_MEMORY;
3587 talloc_steal(frame, xconn);
3589 xconn->ev_ctx = client->ev_ctx;
3590 xconn->msg_ctx = client->msg_ctx;
3591 xconn->transport.sock = sock_fd;
3592 smbd_echo_init(xconn);
3593 xconn->protocol = PROTOCOL_NONE;
3595 /* Ensure child is set to blocking mode */
3596 set_blocking(sock_fd,True);
3598 set_socket_options(sock_fd, "SO_KEEPALIVE");
3599 set_socket_options(sock_fd, lp_socket_options());
3601 sa_socklen = sizeof(ss_clnt);
3602 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3603 if (ret != 0) {
3604 int saved_errno = errno;
3605 int level = (errno == ENOTCONN)?2:0;
3606 DEBUG(level,("getpeername() failed - %s\n",
3607 strerror(saved_errno)));
3608 TALLOC_FREE(frame);
3609 return map_nt_error_from_unix_common(saved_errno);
3611 ret = tsocket_address_bsd_from_sockaddr(xconn,
3612 sa_clnt, sa_socklen,
3613 &remote_address);
3614 if (ret != 0) {
3615 int saved_errno = errno;
3616 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3617 __location__, strerror(saved_errno)));
3618 TALLOC_FREE(frame);
3619 return map_nt_error_from_unix_common(saved_errno);
3622 sa_socklen = sizeof(ss_srv);
3623 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3624 if (ret != 0) {
3625 int saved_errno = errno;
3626 int level = (errno == ENOTCONN)?2:0;
3627 DEBUG(level,("getsockname() failed - %s\n",
3628 strerror(saved_errno)));
3629 TALLOC_FREE(frame);
3630 return map_nt_error_from_unix_common(saved_errno);
3632 ret = tsocket_address_bsd_from_sockaddr(xconn,
3633 sa_srv, sa_socklen,
3634 &local_address);
3635 if (ret != 0) {
3636 int saved_errno = errno;
3637 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3638 __location__, strerror(saved_errno)));
3639 TALLOC_FREE(frame);
3640 return map_nt_error_from_unix_common(saved_errno);
3643 if (tsocket_address_is_inet(remote_address, "ip")) {
3644 remaddr = tsocket_address_inet_addr_string(remote_address,
3645 talloc_tos());
3646 if (remaddr == NULL) {
3647 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3648 __location__, strerror(errno)));
3649 TALLOC_FREE(frame);
3650 return NT_STATUS_NO_MEMORY;
3652 } else {
3653 remaddr = "0.0.0.0";
3657 * Before the first packet, check the global hosts allow/ hosts deny
3658 * parameters before doing any parsing of packets passed to us by the
3659 * client. This prevents attacks on our parsing code from hosts not in
3660 * the hosts allow list.
3663 ret = get_remote_hostname(remote_address,
3664 &p, talloc_tos());
3665 if (ret < 0) {
3666 int saved_errno = errno;
3667 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3668 __location__, strerror(saved_errno)));
3669 TALLOC_FREE(frame);
3670 return map_nt_error_from_unix_common(saved_errno);
3672 rhost = p;
3673 if (strequal(rhost, "UNKNOWN")) {
3674 rhost = remaddr;
3677 xconn->local_address = local_address;
3678 xconn->remote_address = remote_address;
3679 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3680 if (xconn->remote_hostname == NULL) {
3681 return NT_STATUS_NO_MEMORY;
3684 if (!srv_init_signing(xconn)) {
3685 DEBUG(0, ("Failed to init smb_signing\n"));
3686 TALLOC_FREE(frame);
3687 return NT_STATUS_INTERNAL_ERROR;
3690 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3691 xconn->remote_hostname,
3692 remaddr)) {
3693 DEBUG( 1, ("Connection denied from %s to %s\n",
3694 tsocket_address_string(remote_address, talloc_tos()),
3695 tsocket_address_string(local_address, talloc_tos())));
3698 * We return a valid xconn
3699 * so that the caller can return an error message
3700 * to the client
3702 client->connections = xconn;
3703 xconn->client = client;
3704 talloc_steal(client, xconn);
3706 *_xconn = xconn;
3707 TALLOC_FREE(frame);
3708 return NT_STATUS_NETWORK_ACCESS_DENIED;
3711 DEBUG(10, ("Connection allowed from %s to %s\n",
3712 tsocket_address_string(remote_address, talloc_tos()),
3713 tsocket_address_string(local_address, talloc_tos())));
3715 if (lp_clustering()) {
3717 * We need to tell ctdb about our client's TCP
3718 * connection, so that for failover ctdbd can send
3719 * tickle acks, triggering a reconnection by the
3720 * client.
3722 NTSTATUS status;
3724 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3725 if (!NT_STATUS_IS_OK(status)) {
3726 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3727 nt_errstr(status)));
3731 tmp = lp_max_xmit();
3732 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3733 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3735 xconn->smb1.negprot.max_recv = tmp;
3737 xconn->smb1.sessions.done_sesssetup = false;
3738 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3740 xconn->transport.fde = tevent_add_fd(client->ev_ctx,
3741 xconn,
3742 sock_fd,
3743 TEVENT_FD_READ,
3744 smbd_server_connection_handler,
3745 xconn);
3746 if (!xconn->transport.fde) {
3747 TALLOC_FREE(frame);
3748 return NT_STATUS_NO_MEMORY;
3751 /* for now we only have one connection */
3752 DLIST_ADD_END(client->connections, xconn, NULL);
3753 xconn->client = client;
3754 talloc_steal(client, xconn);
3756 *_xconn = xconn;
3757 TALLOC_FREE(frame);
3758 return NT_STATUS_OK;
3761 /****************************************************************************
3762 Process commands from the client
3763 ****************************************************************************/
3765 void smbd_process(struct tevent_context *ev_ctx,
3766 struct messaging_context *msg_ctx,
3767 int sock_fd,
3768 bool interactive)
3770 struct smbd_tevent_trace_state trace_state = {
3771 .frame = talloc_stackframe(),
3773 struct smbXsrv_client *client = NULL;
3774 struct smbd_server_connection *sconn = NULL;
3775 struct smbXsrv_connection *xconn = NULL;
3776 const char *locaddr = NULL;
3777 const char *remaddr = NULL;
3778 int ret;
3779 NTSTATUS status;
3781 client = talloc_zero(ev_ctx, struct smbXsrv_client);
3782 if (client == NULL) {
3783 DEBUG(0,("talloc_zero(struct smbXsrv_client)\n"));
3784 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3788 * TODO: remove this...:-)
3790 global_smbXsrv_client = client;
3792 client->ev_ctx = ev_ctx;
3793 client->msg_ctx = msg_ctx;
3795 sconn = talloc_zero(client, struct smbd_server_connection);
3796 if (sconn == NULL) {
3797 exit_server("failed to create smbd_server_connection");
3800 client->sconn = sconn;
3801 sconn->client = client;
3803 sconn->ev_ctx = ev_ctx;
3804 sconn->msg_ctx = msg_ctx;
3806 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3808 * We're not making the decision here,
3809 * we're just allowing the client
3810 * to decide between SMB1 and SMB2
3811 * with the first negprot
3812 * packet.
3814 sconn->using_smb2 = true;
3817 if (!interactive) {
3818 smbd_setup_sig_term_handler(sconn);
3819 smbd_setup_sig_hup_handler(sconn);
3821 if (!serverid_register(messaging_server_id(msg_ctx),
3822 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3823 |FLAG_MSG_DBWRAP
3824 |FLAG_MSG_PRINT_GENERAL)) {
3825 exit_server_cleanly("Could not register myself in "
3826 "serverid.tdb");
3830 status = smbd_add_connection(client, sock_fd, &xconn);
3831 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3833 * send a negative session response "not listening on calling
3834 * name"
3836 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3837 (void)srv_send_smb(xconn,(char *)buf, false,
3838 0, false, NULL);
3839 exit_server_cleanly("connection denied");
3840 } else if (!NT_STATUS_IS_OK(status)) {
3841 exit_server_cleanly(nt_errstr(status));
3844 sconn->local_address =
3845 tsocket_address_copy(xconn->local_address, sconn);
3846 if (sconn->local_address == NULL) {
3847 exit_server_cleanly("tsocket_address_copy() failed");
3849 sconn->remote_address =
3850 tsocket_address_copy(xconn->remote_address, sconn);
3851 if (sconn->remote_address == NULL) {
3852 exit_server_cleanly("tsocket_address_copy() failed");
3854 sconn->remote_hostname =
3855 talloc_strdup(sconn, xconn->remote_hostname);
3856 if (sconn->remote_hostname == NULL) {
3857 exit_server_cleanly("tsocket_strdup() failed");
3860 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3861 locaddr = tsocket_address_inet_addr_string(
3862 sconn->local_address,
3863 talloc_tos());
3864 if (locaddr == NULL) {
3865 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3866 __location__, strerror(errno)));
3867 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3869 } else {
3870 locaddr = "0.0.0.0";
3873 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
3874 remaddr = tsocket_address_inet_addr_string(
3875 sconn->remote_address,
3876 talloc_tos());
3877 if (remaddr == NULL) {
3878 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3879 __location__, strerror(errno)));
3880 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3882 } else {
3883 remaddr = "0.0.0.0";
3886 /* this is needed so that we get decent entries
3887 in smbstatus for port 445 connects */
3888 set_remote_machine_name(remaddr, false);
3889 reload_services(sconn, conn_snum_used, true);
3890 sub_set_socket_ids(remaddr,
3891 sconn->remote_hostname,
3892 locaddr);
3894 if (lp_preload_modules()) {
3895 smb_load_modules(lp_preload_modules());
3898 smb_perfcount_init();
3900 if (!init_account_policy()) {
3901 exit_server("Could not open account policy tdb.\n");
3904 if (*lp_root_directory(talloc_tos())) {
3905 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3906 DEBUG(0,("Failed to change root to %s\n",
3907 lp_root_directory(talloc_tos())));
3908 exit_server("Failed to chroot()");
3910 if (chdir("/") == -1) {
3911 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3912 exit_server("Failed to chroot()");
3914 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3917 if (!file_init(sconn)) {
3918 exit_server("file_init() failed");
3921 /* Setup oplocks */
3922 if (!init_oplocks(sconn))
3923 exit_server("Failed to init oplocks");
3925 /* register our message handlers */
3926 messaging_register(sconn->msg_ctx, sconn,
3927 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3928 messaging_register(sconn->msg_ctx, sconn,
3929 MSG_SMB_CLOSE_FILE, msg_close_file);
3930 messaging_register(sconn->msg_ctx, sconn,
3931 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3933 id_cache_register_msgs(sconn->msg_ctx);
3934 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3935 messaging_register(sconn->msg_ctx, sconn,
3936 ID_CACHE_KILL, smbd_id_cache_kill);
3938 messaging_deregister(sconn->msg_ctx,
3939 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3940 messaging_register(sconn->msg_ctx, sconn,
3941 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3943 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3944 NULL);
3945 messaging_register(sconn->msg_ctx, sconn,
3946 MSG_SMB_KILL_CLIENT_IP,
3947 msg_kill_client_ip);
3949 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3952 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3953 * MSGs to all child processes
3955 messaging_deregister(sconn->msg_ctx,
3956 MSG_DEBUG, NULL);
3957 messaging_register(sconn->msg_ctx, NULL,
3958 MSG_DEBUG, debug_message);
3960 if ((lp_keepalive() != 0)
3961 && !(event_add_idle(ev_ctx, NULL,
3962 timeval_set(lp_keepalive(), 0),
3963 "keepalive", keepalive_fn,
3964 sconn))) {
3965 DEBUG(0, ("Could not add keepalive event\n"));
3966 exit(1);
3969 if (!(event_add_idle(ev_ctx, NULL,
3970 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3971 "deadtime", deadtime_fn, sconn))) {
3972 DEBUG(0, ("Could not add deadtime event\n"));
3973 exit(1);
3976 if (!(event_add_idle(ev_ctx, NULL,
3977 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3978 "housekeeping", housekeeping_fn, sconn))) {
3979 DEBUG(0, ("Could not add housekeeping event\n"));
3980 exit(1);
3983 if (!init_dptrs(sconn)) {
3984 exit_server("init_dptrs() failed");
3987 TALLOC_FREE(trace_state.frame);
3989 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
3990 &trace_state);
3992 ret = tevent_loop_wait(ev_ctx);
3993 if (ret != 0) {
3994 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
3995 " exiting\n", ret, strerror(errno)));
3998 TALLOC_FREE(trace_state.frame);
4000 exit_server_cleanly(NULL);
4003 bool req_is_in_chain(const struct smb_request *req)
4005 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4007 * We're right now handling a subsequent request, so we must
4008 * be in a chain
4010 return true;
4013 if (!is_andx_req(req->cmd)) {
4014 return false;
4017 if (req->wct < 2) {
4019 * Okay, an illegal request, but definitely not chained :-)
4021 return false;
4024 return (CVAL(req->vwv+0, 0) != 0xFF);