s3:smbd: pass smbXsrv_connection to construct_reply*()
[Samba.git] / source3 / smbd / process.c
blobe0af9fe6c8ae188deb77b187e47328f1dfd05ef4
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(sconn, 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 smbd_server_connection *sconn,
765 uint64_t mid)
767 struct pending_message_list *pml;
769 if (sconn->using_smb2) {
770 remove_deferred_open_message_smb2(sconn, mid);
771 return;
774 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
775 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
776 DEBUG(10,("remove_deferred_open_message_smb: "
777 "deleting mid %llu len %u\n",
778 (unsigned long long)mid,
779 (unsigned int)pml->buf.length ));
780 DLIST_REMOVE(sconn->deferred_open_queue, pml);
781 TALLOC_FREE(pml);
782 return;
787 /****************************************************************************
788 Move a sharing violation open retry message to the front of the list and
789 schedule it for immediate processing.
790 ****************************************************************************/
792 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
793 uint64_t mid)
795 struct pending_message_list *pml;
796 int i = 0;
798 if (sconn->using_smb2) {
799 return schedule_deferred_open_message_smb2(sconn, mid);
802 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
803 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
805 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
806 "msg_mid = %llu\n",
807 i++,
808 (unsigned long long)msg_mid ));
810 if (mid == msg_mid) {
811 struct tevent_timer *te;
813 if (pml->processed) {
814 /* A processed message should not be
815 * rescheduled. */
816 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
817 "message mid %llu was already processed\n",
818 (unsigned long long)msg_mid ));
819 continue;
822 DEBUG(10,("schedule_deferred_open_message_smb: "
823 "scheduling mid %llu\n",
824 (unsigned long long)mid ));
826 te = tevent_add_timer(pml->sconn->ev_ctx,
827 pml,
828 timeval_zero(),
829 smbd_deferred_open_timer,
830 pml);
831 if (!te) {
832 DEBUG(10,("schedule_deferred_open_message_smb: "
833 "event_add_timed() failed, "
834 "skipping mid %llu\n",
835 (unsigned long long)msg_mid ));
838 TALLOC_FREE(pml->te);
839 pml->te = te;
840 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
841 return true;
845 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
846 "find message mid %llu\n",
847 (unsigned long long)mid ));
849 return false;
852 /****************************************************************************
853 Return true if this mid is on the deferred queue and was not yet processed.
854 ****************************************************************************/
856 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
858 struct pending_message_list *pml;
860 if (sconn->using_smb2) {
861 return open_was_deferred_smb2(sconn, mid);
864 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
865 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
866 return True;
869 return False;
872 /****************************************************************************
873 Return the message queued by this mid.
874 ****************************************************************************/
876 static struct pending_message_list *get_deferred_open_message_smb(
877 struct smbd_server_connection *sconn, uint64_t mid)
879 struct pending_message_list *pml;
881 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
882 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
883 return pml;
886 return NULL;
889 /****************************************************************************
890 Get the state data queued by this mid.
891 ****************************************************************************/
893 bool get_deferred_open_message_state(struct smb_request *smbreq,
894 struct timeval *p_request_time,
895 struct deferred_open_record **open_rec)
897 struct pending_message_list *pml;
899 if (smbreq->sconn->using_smb2) {
900 return get_deferred_open_message_state_smb2(smbreq->smb2req,
901 p_request_time,
902 open_rec);
905 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
906 if (!pml) {
907 return false;
909 if (p_request_time) {
910 *p_request_time = pml->request_time;
912 if (open_rec != NULL) {
913 *open_rec = pml->open_rec;
915 return true;
918 /****************************************************************************
919 Function to push a deferred open smb message onto a linked list of local smb
920 messages ready for processing.
921 ****************************************************************************/
923 bool push_deferred_open_message_smb(struct smb_request *req,
924 struct timeval request_time,
925 struct timeval timeout,
926 struct file_id id,
927 struct deferred_open_record *open_rec)
929 struct timeval end_time;
931 if (req->smb2req) {
932 return push_deferred_open_message_smb2(req->smb2req,
933 request_time,
934 timeout,
936 open_rec);
939 if (req->unread_bytes) {
940 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
941 "unread_bytes = %u\n",
942 (unsigned int)req->unread_bytes ));
943 smb_panic("push_deferred_open_message_smb: "
944 "logic error unread_bytes != 0" );
947 end_time = timeval_sum(&request_time, &timeout);
949 DEBUG(10,("push_deferred_open_message_smb: pushing message "
950 "len %u mid %llu timeout time [%u.%06u]\n",
951 (unsigned int) smb_len(req->inbuf)+4,
952 (unsigned long long)req->mid,
953 (unsigned int)end_time.tv_sec,
954 (unsigned int)end_time.tv_usec));
956 return push_queued_message(req, request_time, end_time, open_rec);
959 static void smbd_sig_term_handler(struct tevent_context *ev,
960 struct tevent_signal *se,
961 int signum,
962 int count,
963 void *siginfo,
964 void *private_data)
966 exit_server_cleanly("termination signal");
969 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
971 struct tevent_signal *se;
973 se = tevent_add_signal(sconn->ev_ctx,
974 sconn,
975 SIGTERM, 0,
976 smbd_sig_term_handler,
977 sconn);
978 if (!se) {
979 exit_server("failed to setup SIGTERM handler");
983 static void smbd_sig_hup_handler(struct tevent_context *ev,
984 struct tevent_signal *se,
985 int signum,
986 int count,
987 void *siginfo,
988 void *private_data)
990 struct smbd_server_connection *sconn =
991 talloc_get_type_abort(private_data,
992 struct smbd_server_connection);
994 change_to_root_user();
995 DEBUG(1,("Reloading services after SIGHUP\n"));
996 reload_services(sconn, conn_snum_used, false);
999 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1001 struct tevent_signal *se;
1003 se = tevent_add_signal(sconn->ev_ctx,
1004 sconn,
1005 SIGHUP, 0,
1006 smbd_sig_hup_handler,
1007 sconn);
1008 if (!se) {
1009 exit_server("failed to setup SIGHUP handler");
1013 static void smbd_conf_updated(struct messaging_context *msg,
1014 void *private_data,
1015 uint32_t msg_type,
1016 struct server_id server_id,
1017 DATA_BLOB *data)
1019 struct smbd_server_connection *sconn =
1020 talloc_get_type_abort(private_data,
1021 struct smbd_server_connection);
1023 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1024 "updated. Reloading.\n"));
1025 change_to_root_user();
1026 reload_services(sconn, conn_snum_used, false);
1030 * Only allow 5 outstanding trans requests. We're allocating memory, so
1031 * prevent a DoS.
1034 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1036 int count = 0;
1037 for (; list != NULL; list = list->next) {
1039 if (list->mid == mid) {
1040 return NT_STATUS_INVALID_PARAMETER;
1043 count += 1;
1045 if (count > 5) {
1046 return NT_STATUS_INSUFFICIENT_RESOURCES;
1049 return NT_STATUS_OK;
1053 These flags determine some of the permissions required to do an operation
1055 Note that I don't set NEED_WRITE on some write operations because they
1056 are used by some brain-dead clients when printing, and I don't want to
1057 force write permissions on print services.
1059 #define AS_USER (1<<0)
1060 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1061 #define TIME_INIT (1<<2)
1062 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1063 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1064 #define DO_CHDIR (1<<6)
1067 define a list of possible SMB messages and their corresponding
1068 functions. Any message that has a NULL function is unimplemented -
1069 please feel free to contribute implementations!
1071 static const struct smb_message_struct {
1072 const char *name;
1073 void (*fn)(struct smb_request *req);
1074 int flags;
1075 } smb_messages[256] = {
1077 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1078 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1079 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1080 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1081 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1082 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1083 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1084 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1085 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1086 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1087 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1088 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1089 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1090 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1091 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1092 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1093 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1094 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1095 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1096 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1097 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1098 /* 0x15 */ { NULL, NULL, 0 },
1099 /* 0x16 */ { NULL, NULL, 0 },
1100 /* 0x17 */ { NULL, NULL, 0 },
1101 /* 0x18 */ { NULL, NULL, 0 },
1102 /* 0x19 */ { NULL, NULL, 0 },
1103 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1104 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1105 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1106 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1107 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1108 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1109 /* 0x20 */ { "SMBwritec", NULL,0},
1110 /* 0x21 */ { NULL, NULL, 0 },
1111 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1112 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1113 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1114 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1115 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1116 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1117 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1118 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1119 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1120 /* 0x2b */ { "SMBecho",reply_echo,0},
1121 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1122 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1123 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1124 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1125 /* 0x30 */ { NULL, NULL, 0 },
1126 /* 0x31 */ { NULL, NULL, 0 },
1127 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1128 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1129 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1130 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1131 /* 0x36 */ { NULL, NULL, 0 },
1132 /* 0x37 */ { NULL, NULL, 0 },
1133 /* 0x38 */ { NULL, NULL, 0 },
1134 /* 0x39 */ { NULL, NULL, 0 },
1135 /* 0x3a */ { NULL, NULL, 0 },
1136 /* 0x3b */ { NULL, NULL, 0 },
1137 /* 0x3c */ { NULL, NULL, 0 },
1138 /* 0x3d */ { NULL, NULL, 0 },
1139 /* 0x3e */ { NULL, NULL, 0 },
1140 /* 0x3f */ { NULL, NULL, 0 },
1141 /* 0x40 */ { NULL, NULL, 0 },
1142 /* 0x41 */ { NULL, NULL, 0 },
1143 /* 0x42 */ { NULL, NULL, 0 },
1144 /* 0x43 */ { NULL, NULL, 0 },
1145 /* 0x44 */ { NULL, NULL, 0 },
1146 /* 0x45 */ { NULL, NULL, 0 },
1147 /* 0x46 */ { NULL, NULL, 0 },
1148 /* 0x47 */ { NULL, NULL, 0 },
1149 /* 0x48 */ { NULL, NULL, 0 },
1150 /* 0x49 */ { NULL, NULL, 0 },
1151 /* 0x4a */ { NULL, NULL, 0 },
1152 /* 0x4b */ { NULL, NULL, 0 },
1153 /* 0x4c */ { NULL, NULL, 0 },
1154 /* 0x4d */ { NULL, NULL, 0 },
1155 /* 0x4e */ { NULL, NULL, 0 },
1156 /* 0x4f */ { NULL, NULL, 0 },
1157 /* 0x50 */ { NULL, NULL, 0 },
1158 /* 0x51 */ { NULL, NULL, 0 },
1159 /* 0x52 */ { NULL, NULL, 0 },
1160 /* 0x53 */ { NULL, NULL, 0 },
1161 /* 0x54 */ { NULL, NULL, 0 },
1162 /* 0x55 */ { NULL, NULL, 0 },
1163 /* 0x56 */ { NULL, NULL, 0 },
1164 /* 0x57 */ { NULL, NULL, 0 },
1165 /* 0x58 */ { NULL, NULL, 0 },
1166 /* 0x59 */ { NULL, NULL, 0 },
1167 /* 0x5a */ { NULL, NULL, 0 },
1168 /* 0x5b */ { NULL, NULL, 0 },
1169 /* 0x5c */ { NULL, NULL, 0 },
1170 /* 0x5d */ { NULL, NULL, 0 },
1171 /* 0x5e */ { NULL, NULL, 0 },
1172 /* 0x5f */ { NULL, NULL, 0 },
1173 /* 0x60 */ { NULL, NULL, 0 },
1174 /* 0x61 */ { NULL, NULL, 0 },
1175 /* 0x62 */ { NULL, NULL, 0 },
1176 /* 0x63 */ { NULL, NULL, 0 },
1177 /* 0x64 */ { NULL, NULL, 0 },
1178 /* 0x65 */ { NULL, NULL, 0 },
1179 /* 0x66 */ { NULL, NULL, 0 },
1180 /* 0x67 */ { NULL, NULL, 0 },
1181 /* 0x68 */ { NULL, NULL, 0 },
1182 /* 0x69 */ { NULL, NULL, 0 },
1183 /* 0x6a */ { NULL, NULL, 0 },
1184 /* 0x6b */ { NULL, NULL, 0 },
1185 /* 0x6c */ { NULL, NULL, 0 },
1186 /* 0x6d */ { NULL, NULL, 0 },
1187 /* 0x6e */ { NULL, NULL, 0 },
1188 /* 0x6f */ { NULL, NULL, 0 },
1189 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1190 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1191 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1192 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1193 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1194 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1195 /* 0x76 */ { NULL, NULL, 0 },
1196 /* 0x77 */ { NULL, NULL, 0 },
1197 /* 0x78 */ { NULL, NULL, 0 },
1198 /* 0x79 */ { NULL, NULL, 0 },
1199 /* 0x7a */ { NULL, NULL, 0 },
1200 /* 0x7b */ { NULL, NULL, 0 },
1201 /* 0x7c */ { NULL, NULL, 0 },
1202 /* 0x7d */ { NULL, NULL, 0 },
1203 /* 0x7e */ { NULL, NULL, 0 },
1204 /* 0x7f */ { NULL, NULL, 0 },
1205 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1206 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1207 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1208 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1209 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1210 /* 0x85 */ { NULL, NULL, 0 },
1211 /* 0x86 */ { NULL, NULL, 0 },
1212 /* 0x87 */ { NULL, NULL, 0 },
1213 /* 0x88 */ { NULL, NULL, 0 },
1214 /* 0x89 */ { NULL, NULL, 0 },
1215 /* 0x8a */ { NULL, NULL, 0 },
1216 /* 0x8b */ { NULL, NULL, 0 },
1217 /* 0x8c */ { NULL, NULL, 0 },
1218 /* 0x8d */ { NULL, NULL, 0 },
1219 /* 0x8e */ { NULL, NULL, 0 },
1220 /* 0x8f */ { NULL, NULL, 0 },
1221 /* 0x90 */ { NULL, NULL, 0 },
1222 /* 0x91 */ { NULL, NULL, 0 },
1223 /* 0x92 */ { NULL, NULL, 0 },
1224 /* 0x93 */ { NULL, NULL, 0 },
1225 /* 0x94 */ { NULL, NULL, 0 },
1226 /* 0x95 */ { NULL, NULL, 0 },
1227 /* 0x96 */ { NULL, NULL, 0 },
1228 /* 0x97 */ { NULL, NULL, 0 },
1229 /* 0x98 */ { NULL, NULL, 0 },
1230 /* 0x99 */ { NULL, NULL, 0 },
1231 /* 0x9a */ { NULL, NULL, 0 },
1232 /* 0x9b */ { NULL, NULL, 0 },
1233 /* 0x9c */ { NULL, NULL, 0 },
1234 /* 0x9d */ { NULL, NULL, 0 },
1235 /* 0x9e */ { NULL, NULL, 0 },
1236 /* 0x9f */ { NULL, NULL, 0 },
1237 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1238 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1239 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1240 /* 0xa3 */ { NULL, NULL, 0 },
1241 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1242 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1243 /* 0xa6 */ { NULL, NULL, 0 },
1244 /* 0xa7 */ { NULL, NULL, 0 },
1245 /* 0xa8 */ { NULL, NULL, 0 },
1246 /* 0xa9 */ { NULL, NULL, 0 },
1247 /* 0xaa */ { NULL, NULL, 0 },
1248 /* 0xab */ { NULL, NULL, 0 },
1249 /* 0xac */ { NULL, NULL, 0 },
1250 /* 0xad */ { NULL, NULL, 0 },
1251 /* 0xae */ { NULL, NULL, 0 },
1252 /* 0xaf */ { NULL, NULL, 0 },
1253 /* 0xb0 */ { NULL, NULL, 0 },
1254 /* 0xb1 */ { NULL, NULL, 0 },
1255 /* 0xb2 */ { NULL, NULL, 0 },
1256 /* 0xb3 */ { NULL, NULL, 0 },
1257 /* 0xb4 */ { NULL, NULL, 0 },
1258 /* 0xb5 */ { NULL, NULL, 0 },
1259 /* 0xb6 */ { NULL, NULL, 0 },
1260 /* 0xb7 */ { NULL, NULL, 0 },
1261 /* 0xb8 */ { NULL, NULL, 0 },
1262 /* 0xb9 */ { NULL, NULL, 0 },
1263 /* 0xba */ { NULL, NULL, 0 },
1264 /* 0xbb */ { NULL, NULL, 0 },
1265 /* 0xbc */ { NULL, NULL, 0 },
1266 /* 0xbd */ { NULL, NULL, 0 },
1267 /* 0xbe */ { NULL, NULL, 0 },
1268 /* 0xbf */ { NULL, NULL, 0 },
1269 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1270 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1271 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1272 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1273 /* 0xc4 */ { NULL, NULL, 0 },
1274 /* 0xc5 */ { NULL, NULL, 0 },
1275 /* 0xc6 */ { NULL, NULL, 0 },
1276 /* 0xc7 */ { NULL, NULL, 0 },
1277 /* 0xc8 */ { NULL, NULL, 0 },
1278 /* 0xc9 */ { NULL, NULL, 0 },
1279 /* 0xca */ { NULL, NULL, 0 },
1280 /* 0xcb */ { NULL, NULL, 0 },
1281 /* 0xcc */ { NULL, NULL, 0 },
1282 /* 0xcd */ { NULL, NULL, 0 },
1283 /* 0xce */ { NULL, NULL, 0 },
1284 /* 0xcf */ { NULL, NULL, 0 },
1285 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1286 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1287 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1288 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1289 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1290 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1291 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1292 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1293 /* 0xd8 */ { NULL, NULL, 0 },
1294 /* 0xd9 */ { NULL, NULL, 0 },
1295 /* 0xda */ { NULL, NULL, 0 },
1296 /* 0xdb */ { NULL, NULL, 0 },
1297 /* 0xdc */ { NULL, NULL, 0 },
1298 /* 0xdd */ { NULL, NULL, 0 },
1299 /* 0xde */ { NULL, NULL, 0 },
1300 /* 0xdf */ { NULL, NULL, 0 },
1301 /* 0xe0 */ { NULL, NULL, 0 },
1302 /* 0xe1 */ { NULL, NULL, 0 },
1303 /* 0xe2 */ { NULL, NULL, 0 },
1304 /* 0xe3 */ { NULL, NULL, 0 },
1305 /* 0xe4 */ { NULL, NULL, 0 },
1306 /* 0xe5 */ { NULL, NULL, 0 },
1307 /* 0xe6 */ { NULL, NULL, 0 },
1308 /* 0xe7 */ { NULL, NULL, 0 },
1309 /* 0xe8 */ { NULL, NULL, 0 },
1310 /* 0xe9 */ { NULL, NULL, 0 },
1311 /* 0xea */ { NULL, NULL, 0 },
1312 /* 0xeb */ { NULL, NULL, 0 },
1313 /* 0xec */ { NULL, NULL, 0 },
1314 /* 0xed */ { NULL, NULL, 0 },
1315 /* 0xee */ { NULL, NULL, 0 },
1316 /* 0xef */ { NULL, NULL, 0 },
1317 /* 0xf0 */ { NULL, NULL, 0 },
1318 /* 0xf1 */ { NULL, NULL, 0 },
1319 /* 0xf2 */ { NULL, NULL, 0 },
1320 /* 0xf3 */ { NULL, NULL, 0 },
1321 /* 0xf4 */ { NULL, NULL, 0 },
1322 /* 0xf5 */ { NULL, NULL, 0 },
1323 /* 0xf6 */ { NULL, NULL, 0 },
1324 /* 0xf7 */ { NULL, NULL, 0 },
1325 /* 0xf8 */ { NULL, NULL, 0 },
1326 /* 0xf9 */ { NULL, NULL, 0 },
1327 /* 0xfa */ { NULL, NULL, 0 },
1328 /* 0xfb */ { NULL, NULL, 0 },
1329 /* 0xfc */ { NULL, NULL, 0 },
1330 /* 0xfd */ { NULL, NULL, 0 },
1331 /* 0xfe */ { NULL, NULL, 0 },
1332 /* 0xff */ { NULL, NULL, 0 }
1336 /*******************************************************************
1337 allocate and initialize a reply packet
1338 ********************************************************************/
1340 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1341 const char *inbuf, char **outbuf, uint8_t num_words,
1342 uint32_t num_bytes)
1344 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1347 * Protect against integer wrap.
1348 * The SMB layer reply can be up to 0xFFFFFF bytes.
1350 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1351 char *msg;
1352 if (asprintf(&msg, "num_bytes too large: %u",
1353 (unsigned)num_bytes) == -1) {
1354 msg = discard_const_p(char, "num_bytes too large");
1356 smb_panic(msg);
1360 * Here we include the NBT header for now.
1362 *outbuf = talloc_array(mem_ctx, char,
1363 NBT_HDR_SIZE + smb_len);
1364 if (*outbuf == NULL) {
1365 return false;
1368 construct_reply_common(req, inbuf, *outbuf);
1369 srv_set_message(*outbuf, num_words, num_bytes, false);
1371 * Zero out the word area, the caller has to take care of the bcc area
1372 * himself
1374 if (num_words != 0) {
1375 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1378 return true;
1381 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1383 char *outbuf;
1384 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1385 num_bytes)) {
1386 smb_panic("could not allocate output buffer\n");
1388 req->outbuf = (uint8_t *)outbuf;
1392 /*******************************************************************
1393 Dump a packet to a file.
1394 ********************************************************************/
1396 static void smb_dump(const char *name, int type, const char *data)
1398 size_t len;
1399 int fd, i;
1400 char *fname = NULL;
1401 if (DEBUGLEVEL < 50) {
1402 return;
1405 len = smb_len_tcp(data)+4;
1406 for (i=1;i<100;i++) {
1407 fname = talloc_asprintf(talloc_tos(),
1408 "/tmp/%s.%d.%s",
1409 name,
1411 type ? "req" : "resp");
1412 if (fname == NULL) {
1413 return;
1415 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1416 if (fd != -1 || errno != EEXIST) break;
1417 TALLOC_FREE(fname);
1419 if (fd != -1) {
1420 ssize_t ret = write(fd, data, len);
1421 if (ret != len)
1422 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1423 close(fd);
1424 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1426 TALLOC_FREE(fname);
1429 /****************************************************************************
1430 Prepare everything for calling the actual request function, and potentially
1431 call the request function via the "new" interface.
1433 Return False if the "legacy" function needs to be called, everything is
1434 prepared.
1436 Return True if we're done.
1438 I know this API sucks, but it is the one with the least code change I could
1439 find.
1440 ****************************************************************************/
1442 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1444 int flags;
1445 uint64_t session_tag;
1446 connection_struct *conn = NULL;
1447 struct smbXsrv_connection *xconn = req->xconn;
1448 NTTIME now = timeval_to_nttime(&req->request_time);
1449 struct smbXsrv_session *session = NULL;
1450 NTSTATUS status;
1452 errno = 0;
1454 if (!xconn->smb1.negprot.done) {
1455 switch (type) {
1457 * Without a negprot the request must
1458 * either be a negprot, or one of the
1459 * evil old SMB mailslot messaging types.
1461 case SMBnegprot:
1462 case SMBsendstrt:
1463 case SMBsendend:
1464 case SMBsendtxt:
1465 break;
1466 default:
1467 exit_server_cleanly("The first request "
1468 "should be a negprot");
1472 if (smb_messages[type].fn == NULL) {
1473 DEBUG(0,("Unknown message type %d!\n",type));
1474 smb_dump("Unknown", 1, (const char *)req->inbuf);
1475 reply_unknown_new(req, type);
1476 return NULL;
1479 flags = smb_messages[type].flags;
1481 /* In share mode security we must ignore the vuid. */
1482 session_tag = req->vuid;
1483 conn = req->conn;
1485 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1486 (int)getpid(), (unsigned long)conn));
1488 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1490 /* Ensure this value is replaced in the incoming packet. */
1491 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1494 * Ensure the correct username is in current_user_info. This is a
1495 * really ugly bugfix for problems with multiple session_setup_and_X's
1496 * being done and allowing %U and %G substitutions to work correctly.
1497 * There is a reason this code is done here, don't move it unless you
1498 * know what you're doing... :-).
1499 * JRA.
1503 * lookup an existing session
1505 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1506 * here, the main check is still in change_to_user()
1508 status = smb1srv_session_lookup(xconn,
1509 session_tag,
1510 now,
1511 &session);
1512 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1513 switch (type) {
1514 case SMBsesssetupX:
1515 status = NT_STATUS_OK;
1516 break;
1517 default:
1518 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1519 (unsigned long long)session_tag,
1520 (unsigned long long)req->mid));
1521 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1522 return conn;
1526 if (session_tag != xconn->last_session_id) {
1527 struct user_struct *vuser = NULL;
1529 xconn->last_session_id = session_tag;
1530 if (session) {
1531 vuser = session->compat;
1533 if (vuser) {
1534 set_current_user_info(
1535 vuser->session_info->unix_info->sanitized_username,
1536 vuser->session_info->unix_info->unix_name,
1537 vuser->session_info->info->domain_name);
1541 /* Does this call need to be run as the connected user? */
1542 if (flags & AS_USER) {
1544 /* Does this call need a valid tree connection? */
1545 if (!conn) {
1547 * Amazingly, the error code depends on the command
1548 * (from Samba4).
1550 if (type == SMBntcreateX) {
1551 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1552 } else {
1553 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1555 return NULL;
1558 if (!change_to_user(conn,session_tag)) {
1559 DEBUG(0, ("Error: Could not change to user. Removing "
1560 "deferred open, mid=%llu.\n",
1561 (unsigned long long)req->mid));
1562 reply_force_doserror(req, ERRSRV, ERRbaduid);
1563 return conn;
1566 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1568 /* Does it need write permission? */
1569 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1570 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1571 return conn;
1574 /* IPC services are limited */
1575 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1576 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1577 return conn;
1579 } else {
1580 /* This call needs to be run as root */
1581 change_to_root_user();
1584 /* load service specific parameters */
1585 if (conn) {
1586 if (req->encrypted) {
1587 conn->encrypted_tid = true;
1588 /* encrypted required from now on. */
1589 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1590 } else if (ENCRYPTION_REQUIRED(conn)) {
1591 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1592 DEBUG(1,("service[%s] requires encryption"
1593 "%s ACCESS_DENIED. mid=%llu\n",
1594 lp_servicename(talloc_tos(), SNUM(conn)),
1595 smb_fn_name(type),
1596 (unsigned long long)req->mid));
1597 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1598 return conn;
1602 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1603 (flags & (AS_USER|DO_CHDIR)
1604 ?True:False))) {
1605 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1606 return conn;
1608 conn->num_smb_operations++;
1612 * Does this protocol need to be run as guest? (Only archane
1613 * messenger service requests have this...)
1615 if (flags & AS_GUEST) {
1616 char *raddr;
1617 bool ok;
1619 if (!change_to_guest()) {
1620 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1621 return conn;
1624 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1625 talloc_tos());
1626 if (raddr == NULL) {
1627 reply_nterror(req, NT_STATUS_NO_MEMORY);
1628 return conn;
1632 * Haven't we checked this in smbd_process already???
1635 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1636 xconn->remote_hostname, raddr);
1637 TALLOC_FREE(raddr);
1639 if (!ok) {
1640 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1641 return conn;
1645 smb_messages[type].fn(req);
1646 return req->conn;
1649 /****************************************************************************
1650 Construct a reply to the incoming packet.
1651 ****************************************************************************/
1653 static void construct_reply(struct smbXsrv_connection *xconn,
1654 char *inbuf, int size, size_t unread_bytes,
1655 uint32_t seqnum, bool encrypted,
1656 struct smb_perfcount_data *deferred_pcd)
1658 struct smbd_server_connection *sconn = xconn->sconn;
1659 struct smb_request *req;
1661 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1662 smb_panic("could not allocate smb_request");
1665 if (!init_smb_request(req, sconn, xconn, (uint8 *)inbuf, unread_bytes,
1666 encrypted, seqnum)) {
1667 exit_server_cleanly("Invalid SMB request");
1670 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1672 /* we popped this message off the queue - keep original perf data */
1673 if (deferred_pcd)
1674 req->pcd = *deferred_pcd;
1675 else {
1676 SMB_PERFCOUNT_START(&req->pcd);
1677 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1678 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1681 req->conn = switch_message(req->cmd, req);
1683 if (req->outbuf == NULL) {
1685 * Request has suspended itself, will come
1686 * back here.
1688 return;
1690 if (CVAL(req->outbuf,0) == 0) {
1691 show_msg((char *)req->outbuf);
1693 smb_request_done(req);
1696 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1697 char *inbuf, int size, uint32_t seqnum,
1698 bool encrypted,
1699 struct smb_perfcount_data *deferred_pcd)
1701 struct smb_request **reqs = NULL;
1702 struct smb_request *req;
1703 unsigned num_reqs;
1704 bool ok;
1706 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, xconn, encrypted,
1707 seqnum, &reqs, &num_reqs);
1708 if (!ok) {
1709 char errbuf[smb_size];
1710 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1711 __LINE__, __FILE__);
1712 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1713 NULL)) {
1714 exit_server_cleanly("construct_reply_chain: "
1715 "srv_send_smb failed.");
1717 return;
1720 req = reqs[0];
1721 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1723 req->conn = switch_message(req->cmd, req);
1725 if (req->outbuf == NULL) {
1727 * Request has suspended itself, will come
1728 * back here.
1730 return;
1732 smb_request_done(req);
1736 * To be called from an async SMB handler that is potentially chained
1737 * when it is finished for shipping.
1740 void smb_request_done(struct smb_request *req)
1742 struct smb_request **reqs = NULL;
1743 struct smb_request *first_req;
1744 size_t i, num_reqs, next_index;
1745 NTSTATUS status;
1747 if (req->chain == NULL) {
1748 first_req = req;
1749 goto shipit;
1752 reqs = req->chain;
1753 num_reqs = talloc_array_length(reqs);
1755 for (i=0; i<num_reqs; i++) {
1756 if (reqs[i] == req) {
1757 break;
1760 if (i == num_reqs) {
1762 * Invalid chain, should not happen
1764 status = NT_STATUS_INTERNAL_ERROR;
1765 goto error;
1767 next_index = i+1;
1769 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1770 struct smb_request *next = reqs[next_index];
1771 struct smbXsrv_tcon *tcon;
1772 NTTIME now = timeval_to_nttime(&req->request_time);
1774 next->vuid = SVAL(req->outbuf, smb_uid);
1775 next->tid = SVAL(req->outbuf, smb_tid);
1776 status = smb1srv_tcon_lookup(req->xconn, req->tid,
1777 now, &tcon);
1778 if (NT_STATUS_IS_OK(status)) {
1779 req->conn = tcon->compat;
1780 } else {
1781 req->conn = NULL;
1783 next->chain_fsp = req->chain_fsp;
1784 next->inbuf = req->inbuf;
1786 req = next;
1787 req->conn = switch_message(req->cmd, req);
1789 if (req->outbuf == NULL) {
1791 * Request has suspended itself, will come
1792 * back here.
1794 return;
1796 next_index += 1;
1799 first_req = reqs[0];
1801 for (i=1; i<next_index; i++) {
1802 bool ok;
1804 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1805 if (!ok) {
1806 status = NT_STATUS_INTERNAL_ERROR;
1807 goto error;
1811 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1812 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1815 * This scary statement intends to set the
1816 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1817 * to the value last_req->outbuf carries
1819 SSVAL(first_req->outbuf, smb_flg2,
1820 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1821 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1824 * Transfer the error codes from the subrequest to the main one
1826 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1827 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1829 _smb_setlen_large(
1830 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1832 shipit:
1833 if (!srv_send_smb(first_req->xconn,
1834 (char *)first_req->outbuf,
1835 true, first_req->seqnum+1,
1836 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1837 &first_req->pcd)) {
1838 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1839 "failed.");
1841 TALLOC_FREE(req); /* non-chained case */
1842 TALLOC_FREE(reqs); /* chained case */
1843 return;
1845 error:
1847 char errbuf[smb_size];
1848 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1849 if (!srv_send_smb(req->xconn, errbuf, true,
1850 req->seqnum+1, req->encrypted,
1851 NULL)) {
1852 exit_server_cleanly("construct_reply_chain: "
1853 "srv_send_smb failed.");
1856 TALLOC_FREE(req); /* non-chained case */
1857 TALLOC_FREE(reqs); /* chained case */
1860 /****************************************************************************
1861 Process an smb from the client
1862 ****************************************************************************/
1863 static void process_smb(struct smbXsrv_connection *xconn,
1864 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1865 uint32_t seqnum, bool encrypted,
1866 struct smb_perfcount_data *deferred_pcd)
1868 struct smbd_server_connection *sconn = xconn->sconn;
1869 int msg_type = CVAL(inbuf,0);
1871 DO_PROFILE_INC(smb_count);
1873 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1874 smb_len(inbuf) ) );
1875 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1876 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1878 if (msg_type != NBSSmessage) {
1880 * NetBIOS session request, keepalive, etc.
1882 reply_special(xconn, (char *)inbuf, nread);
1883 goto done;
1886 if (sconn->using_smb2) {
1887 /* At this point we're not really using smb2,
1888 * we make the decision here.. */
1889 if (smbd_is_smb2_header(inbuf, nread)) {
1890 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1891 size_t pdulen = nread - NBT_HDR_SIZE;
1892 smbd_smb2_first_negprot(xconn, inpdu, pdulen);
1893 return;
1894 } else if (nread >= smb_size && valid_smb_header(inbuf)
1895 && CVAL(inbuf, smb_com) != 0x72) {
1896 /* This is a non-negprot SMB1 packet.
1897 Disable SMB2 from now on. */
1898 sconn->using_smb2 = false;
1902 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1903 * so subtract 4 from it. */
1904 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1905 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1906 smb_len(inbuf)));
1908 /* special magic for immediate exit */
1909 if ((nread == 9) &&
1910 (IVAL(inbuf, 4) == 0x74697865) &&
1911 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1912 uint8_t exitcode = CVAL(inbuf, 8);
1913 DEBUG(1, ("Exiting immediately with code %d\n",
1914 (int)exitcode));
1915 exit(exitcode);
1918 exit_server_cleanly("Non-SMB packet");
1921 show_msg((char *)inbuf);
1923 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1924 construct_reply_chain(xconn, (char *)inbuf, nread,
1925 seqnum, encrypted, deferred_pcd);
1926 } else {
1927 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
1928 seqnum, encrypted, deferred_pcd);
1931 sconn->trans_num++;
1933 done:
1934 sconn->num_requests++;
1936 /* The timeout_processing function isn't run nearly
1937 often enough to implement 'max log size' without
1938 overrunning the size of the file by many megabytes.
1939 This is especially true if we are running at debug
1940 level 10. Checking every 50 SMBs is a nice
1941 tradeoff of performance vs log file size overrun. */
1943 if ((sconn->num_requests % 50) == 0 &&
1944 need_to_check_log_size()) {
1945 change_to_root_user();
1946 check_log_size();
1950 /****************************************************************************
1951 Return a string containing the function name of a SMB command.
1952 ****************************************************************************/
1954 const char *smb_fn_name(int type)
1956 const char *unknown_name = "SMBunknown";
1958 if (smb_messages[type].name == NULL)
1959 return(unknown_name);
1961 return(smb_messages[type].name);
1964 /****************************************************************************
1965 Helper functions for contruct_reply.
1966 ****************************************************************************/
1968 void add_to_common_flags2(uint32 v)
1970 common_flags2 |= v;
1973 void remove_from_common_flags2(uint32 v)
1975 common_flags2 &= ~v;
1978 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1979 char *outbuf)
1981 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1982 uint16_t out_flags2 = common_flags2;
1984 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1985 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1986 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1988 srv_set_message(outbuf,0,0,false);
1990 SCVAL(outbuf, smb_com, req->cmd);
1991 SIVAL(outbuf,smb_rcls,0);
1992 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1993 SSVAL(outbuf,smb_flg2, out_flags2);
1994 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1995 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1997 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1998 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1999 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2000 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2003 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2005 construct_reply_common(req, (const char *)req->inbuf, outbuf);
2009 * @brief Find the smb_cmd offset of the last command pushed
2010 * @param[in] buf The buffer we're building up
2011 * @retval Where can we put our next andx cmd?
2013 * While chaining requests, the "next" request we're looking at needs to put
2014 * its SMB_Command before the data the previous request already built up added
2015 * to the chain. Find the offset to the place where we have to put our cmd.
2018 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2020 uint8_t cmd;
2021 size_t ofs;
2023 cmd = CVAL(buf, smb_com);
2025 if (!is_andx_req(cmd)) {
2026 return false;
2029 ofs = smb_vwv0;
2031 while (CVAL(buf, ofs) != 0xff) {
2033 if (!is_andx_req(CVAL(buf, ofs))) {
2034 return false;
2038 * ofs is from start of smb header, so add the 4 length
2039 * bytes. The next cmd is right after the wct field.
2041 ofs = SVAL(buf, ofs+2) + 4 + 1;
2043 if (ofs+4 >= talloc_get_size(buf)) {
2044 return false;
2048 *pofs = ofs;
2049 return true;
2053 * @brief Do the smb chaining at a buffer level
2054 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2055 * @param[in] andx_buf Buffer to be appended
2058 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2060 uint8_t smb_command = CVAL(andx_buf, smb_com);
2061 uint8_t wct = CVAL(andx_buf, smb_wct);
2062 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2063 uint32_t num_bytes = smb_buflen(andx_buf);
2064 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2066 uint8_t *outbuf;
2067 size_t old_size, new_size;
2068 size_t ofs;
2069 size_t chain_padding = 0;
2070 size_t andx_cmd_ofs;
2073 old_size = talloc_get_size(*poutbuf);
2075 if ((old_size % 4) != 0) {
2077 * Align the wct field of subsequent requests to a 4-byte
2078 * boundary
2080 chain_padding = 4 - (old_size % 4);
2084 * After the old request comes the new wct field (1 byte), the vwv's
2085 * and the num_bytes field.
2088 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2089 new_size += num_bytes;
2091 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2092 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2093 (unsigned)new_size));
2094 return false;
2097 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2098 if (outbuf == NULL) {
2099 DEBUG(0, ("talloc failed\n"));
2100 return false;
2102 *poutbuf = outbuf;
2104 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2105 DEBUG(1, ("invalid command chain\n"));
2106 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2107 return false;
2110 if (chain_padding != 0) {
2111 memset(outbuf + old_size, 0, chain_padding);
2112 old_size += chain_padding;
2115 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2116 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2118 ofs = old_size;
2121 * Push the chained request:
2123 * wct field
2126 SCVAL(outbuf, ofs, wct);
2127 ofs += 1;
2130 * vwv array
2133 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2136 * HACK ALERT
2138 * Read&X has an offset into its data buffer at
2139 * vwv[6]. reply_read_andx has no idea anymore that it's
2140 * running from within a chain, so we have to fix up the
2141 * offset here.
2143 * Although it looks disgusting at this place, I want to keep
2144 * it here. The alternative would be to push knowledge about
2145 * the andx chain down into read&x again.
2148 if (smb_command == SMBreadX) {
2149 uint8_t *bytes_addr;
2151 if (wct < 7) {
2153 * Invalid read&x response
2155 return false;
2158 bytes_addr = outbuf + ofs /* vwv start */
2159 + sizeof(uint16_t) * wct /* vwv array */
2160 + sizeof(uint16_t) /* bcc */
2161 + 1; /* padding byte */
2163 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2164 bytes_addr - outbuf - 4);
2167 ofs += sizeof(uint16_t) * wct;
2170 * bcc (byte count)
2173 SSVAL(outbuf, ofs, num_bytes);
2174 ofs += sizeof(uint16_t);
2177 * The bytes field
2180 memcpy(outbuf + ofs, bytes, num_bytes);
2182 return true;
2185 bool smb1_is_chain(const uint8_t *buf)
2187 uint8_t cmd, wct, andx_cmd;
2189 cmd = CVAL(buf, smb_com);
2190 if (!is_andx_req(cmd)) {
2191 return false;
2193 wct = CVAL(buf, smb_wct);
2194 if (wct < 2) {
2195 return false;
2197 andx_cmd = CVAL(buf, smb_vwv);
2198 return (andx_cmd != 0xFF);
2201 bool smb1_walk_chain(const uint8_t *buf,
2202 bool (*fn)(uint8_t cmd,
2203 uint8_t wct, const uint16_t *vwv,
2204 uint16_t num_bytes, const uint8_t *bytes,
2205 void *private_data),
2206 void *private_data)
2208 size_t smblen = smb_len(buf);
2209 const char *smb_buf = smb_base(buf);
2210 uint8_t cmd, chain_cmd;
2211 uint8_t wct;
2212 const uint16_t *vwv;
2213 uint16_t num_bytes;
2214 const uint8_t *bytes;
2216 cmd = CVAL(buf, smb_com);
2217 wct = CVAL(buf, smb_wct);
2218 vwv = (const uint16_t *)(buf + smb_vwv);
2219 num_bytes = smb_buflen(buf);
2220 bytes = (const uint8_t *)smb_buf_const(buf);
2222 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2223 return false;
2226 if (!is_andx_req(cmd)) {
2227 return true;
2229 if (wct < 2) {
2230 return false;
2233 chain_cmd = CVAL(vwv, 0);
2235 while (chain_cmd != 0xff) {
2236 uint32_t chain_offset; /* uint32_t to avoid overflow */
2237 size_t length_needed;
2238 ptrdiff_t vwv_offset;
2240 chain_offset = SVAL(vwv+1, 0);
2243 * Check if the client tries to fool us. The chain
2244 * offset needs to point beyond the current request in
2245 * the chain, it needs to strictly grow. Otherwise we
2246 * might be tricked into an endless loop always
2247 * processing the same request over and over again. We
2248 * used to assume that vwv and the byte buffer array
2249 * in a chain are always attached, but OS/2 the
2250 * Write&X/Read&X chain puts the Read&X vwv array
2251 * right behind the Write&X vwv chain. The Write&X bcc
2252 * array is put behind the Read&X vwv array. So now we
2253 * check whether the chain offset points strictly
2254 * behind the previous vwv array. req->buf points
2255 * right after the vwv array of the previous
2256 * request. See
2257 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2258 * more information.
2261 vwv_offset = ((const char *)vwv - smb_buf);
2262 if (chain_offset <= vwv_offset) {
2263 return false;
2267 * Next check: Make sure the chain offset does not
2268 * point beyond the overall smb request length.
2271 length_needed = chain_offset+1; /* wct */
2272 if (length_needed > smblen) {
2273 return false;
2277 * Now comes the pointer magic. Goal here is to set up
2278 * vwv and buf correctly again. The chain offset (the
2279 * former vwv[1]) points at the new wct field.
2282 wct = CVAL(smb_buf, chain_offset);
2284 if (is_andx_req(chain_cmd) && (wct < 2)) {
2285 return false;
2289 * Next consistency check: Make the new vwv array fits
2290 * in the overall smb request.
2293 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2294 if (length_needed > smblen) {
2295 return false;
2297 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2300 * Now grab the new byte buffer....
2303 num_bytes = SVAL(vwv+wct, 0);
2306 * .. and check that it fits.
2309 length_needed += num_bytes;
2310 if (length_needed > smblen) {
2311 return false;
2313 bytes = (const uint8_t *)(vwv+wct+1);
2315 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2316 return false;
2319 if (!is_andx_req(chain_cmd)) {
2320 return true;
2322 chain_cmd = CVAL(vwv, 0);
2324 return true;
2327 static bool smb1_chain_length_cb(uint8_t cmd,
2328 uint8_t wct, const uint16_t *vwv,
2329 uint16_t num_bytes, const uint8_t *bytes,
2330 void *private_data)
2332 unsigned *count = (unsigned *)private_data;
2333 *count += 1;
2334 return true;
2337 unsigned smb1_chain_length(const uint8_t *buf)
2339 unsigned count = 0;
2341 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2342 return 0;
2344 return count;
2347 struct smb1_parse_chain_state {
2348 TALLOC_CTX *mem_ctx;
2349 const uint8_t *buf;
2350 struct smbd_server_connection *sconn;
2351 struct smbXsrv_connection *xconn;
2352 bool encrypted;
2353 uint32_t seqnum;
2355 struct smb_request **reqs;
2356 unsigned num_reqs;
2359 static bool smb1_parse_chain_cb(uint8_t cmd,
2360 uint8_t wct, const uint16_t *vwv,
2361 uint16_t num_bytes, const uint8_t *bytes,
2362 void *private_data)
2364 struct smb1_parse_chain_state *state =
2365 (struct smb1_parse_chain_state *)private_data;
2366 struct smb_request **reqs;
2367 struct smb_request *req;
2368 bool ok;
2370 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2371 struct smb_request *, state->num_reqs+1);
2372 if (reqs == NULL) {
2373 return false;
2375 state->reqs = reqs;
2377 req = talloc(reqs, struct smb_request);
2378 if (req == NULL) {
2379 return false;
2382 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2383 state->encrypted, state->seqnum);
2384 if (!ok) {
2385 return false;
2387 req->cmd = cmd;
2388 req->wct = wct;
2389 req->vwv = vwv;
2390 req->buflen = num_bytes;
2391 req->buf = bytes;
2393 reqs[state->num_reqs] = req;
2394 state->num_reqs += 1;
2395 return true;
2398 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2399 struct smbXsrv_connection *xconn,
2400 bool encrypted, uint32_t seqnum,
2401 struct smb_request ***reqs, unsigned *num_reqs)
2403 struct smbd_server_connection *sconn = NULL;
2404 struct smb1_parse_chain_state state;
2405 unsigned i;
2407 if (xconn != NULL) {
2408 sconn = xconn->sconn;
2411 state.mem_ctx = mem_ctx;
2412 state.buf = buf;
2413 state.sconn = sconn;
2414 state.xconn = xconn;
2415 state.encrypted = encrypted;
2416 state.seqnum = seqnum;
2417 state.reqs = NULL;
2418 state.num_reqs = 0;
2420 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2421 TALLOC_FREE(state.reqs);
2422 return false;
2424 for (i=0; i<state.num_reqs; i++) {
2425 state.reqs[i]->chain = state.reqs;
2427 *reqs = state.reqs;
2428 *num_reqs = state.num_reqs;
2429 return true;
2432 /****************************************************************************
2433 Check if services need reloading.
2434 ****************************************************************************/
2436 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2439 if (last_smb_conf_reload_time == 0) {
2440 last_smb_conf_reload_time = t;
2443 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2444 reload_services(sconn, conn_snum_used, true);
2445 last_smb_conf_reload_time = t;
2449 static bool fd_is_readable(int fd)
2451 int ret, revents;
2453 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2455 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2459 static void smbd_server_connection_write_handler(
2460 struct smbXsrv_connection *xconn)
2462 /* TODO: make write nonblocking */
2465 static void smbd_server_connection_read_handler(
2466 struct smbXsrv_connection *xconn, int fd)
2468 uint8_t *inbuf = NULL;
2469 size_t inbuf_len = 0;
2470 size_t unread_bytes = 0;
2471 bool encrypted = false;
2472 TALLOC_CTX *mem_ctx = talloc_tos();
2473 NTSTATUS status;
2474 uint32_t seqnum;
2476 bool async_echo = lp_async_smb_echo_handler();
2477 bool from_client = false;
2479 if (async_echo) {
2480 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2482 * This is the super-ugly hack to prefer the packets
2483 * forwarded by the echo handler over the ones by the
2484 * client directly
2486 fd = xconn->smb1.echo_handler.trusted_fd;
2490 from_client = (xconn->transport.sock == fd);
2492 if (async_echo && from_client) {
2493 smbd_lock_socket(xconn);
2495 if (!fd_is_readable(fd)) {
2496 DEBUG(10,("the echo listener was faster\n"));
2497 smbd_unlock_socket(xconn);
2498 return;
2502 /* TODO: make this completely nonblocking */
2503 status = receive_smb_talloc(mem_ctx, xconn, fd,
2504 (char **)(void *)&inbuf,
2505 0, /* timeout */
2506 &unread_bytes,
2507 &encrypted,
2508 &inbuf_len, &seqnum,
2509 !from_client /* trusted channel */);
2511 if (async_echo && from_client) {
2512 smbd_unlock_socket(xconn);
2515 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2516 goto process;
2518 if (NT_STATUS_IS_ERR(status)) {
2519 exit_server_cleanly("failed to receive smb request");
2521 if (!NT_STATUS_IS_OK(status)) {
2522 return;
2525 process:
2526 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2527 seqnum, encrypted, NULL);
2530 static void smbd_server_connection_handler(struct tevent_context *ev,
2531 struct tevent_fd *fde,
2532 uint16_t flags,
2533 void *private_data)
2535 struct smbXsrv_connection *xconn =
2536 talloc_get_type_abort(private_data,
2537 struct smbXsrv_connection);
2539 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2541 * we're not supposed to do any io
2543 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2544 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2545 return;
2548 if (flags & TEVENT_FD_WRITE) {
2549 smbd_server_connection_write_handler(xconn);
2550 return;
2552 if (flags & TEVENT_FD_READ) {
2553 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2554 return;
2558 static void smbd_server_echo_handler(struct tevent_context *ev,
2559 struct tevent_fd *fde,
2560 uint16_t flags,
2561 void *private_data)
2563 struct smbXsrv_connection *xconn =
2564 talloc_get_type_abort(private_data,
2565 struct smbXsrv_connection);
2567 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2569 * we're not supposed to do any io
2571 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2572 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2573 return;
2576 if (flags & TEVENT_FD_WRITE) {
2577 smbd_server_connection_write_handler(xconn);
2578 return;
2580 if (flags & TEVENT_FD_READ) {
2581 smbd_server_connection_read_handler(
2582 xconn, xconn->smb1.echo_handler.trusted_fd);
2583 return;
2587 struct smbd_release_ip_state {
2588 struct smbXsrv_connection *xconn;
2589 struct tevent_immediate *im;
2590 char addr[INET6_ADDRSTRLEN];
2593 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2594 struct tevent_immediate *im,
2595 void *private_data)
2597 struct smbd_release_ip_state *state =
2598 talloc_get_type_abort(private_data,
2599 struct smbd_release_ip_state);
2600 struct smbXsrv_connection *xconn = state->xconn;
2602 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2604 * smbd_server_connection_terminate() already triggered ?
2606 return;
2609 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2612 /****************************************************************************
2613 received when we should release a specific IP
2614 ****************************************************************************/
2615 static bool release_ip(const char *ip, void *priv)
2617 struct smbd_release_ip_state *state =
2618 talloc_get_type_abort(priv,
2619 struct smbd_release_ip_state);
2620 struct smbXsrv_connection *xconn = state->xconn;
2621 const char *addr = state->addr;
2622 const char *p = addr;
2624 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2625 /* avoid recursion */
2626 return false;
2629 if (strncmp("::ffff:", addr, 7) == 0) {
2630 p = addr + 7;
2633 DEBUG(10, ("Got release IP message for %s, "
2634 "our address is %s\n", ip, p));
2636 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2637 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2638 ip));
2640 * With SMB2 we should do a clean disconnect,
2641 * the previous_session_id in the session setup
2642 * will cleanup the old session, tcons and opens.
2644 * A clean disconnect is needed in order to support
2645 * durable handles.
2647 * Note: typically this is never triggered
2648 * as we got a TCP RST (triggered by ctdb event scripts)
2649 * before we get CTDB_SRVID_RELEASE_IP.
2651 * We used to call _exit(1) here, but as this was mostly never
2652 * triggered and has implication on our process model,
2653 * we can just use smbd_server_connection_terminate()
2654 * (also for SMB1).
2656 * We don't call smbd_server_connection_terminate() directly
2657 * as we might be called from within ctdbd_migrate(),
2658 * we need to defer our action to the next event loop
2660 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2661 smbd_release_ip_immediate, state);
2664 * Make sure we don't get any io on the connection.
2666 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2667 return true;
2670 return false;
2673 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2674 struct sockaddr_storage *srv,
2675 struct sockaddr_storage *clnt)
2677 struct smbd_release_ip_state *state;
2678 struct ctdbd_connection *cconn;
2680 cconn = messaging_ctdbd_connection();
2681 if (cconn == NULL) {
2682 return NT_STATUS_NO_MEMORY;
2685 state = talloc_zero(xconn, struct smbd_release_ip_state);
2686 if (state == NULL) {
2687 return NT_STATUS_NO_MEMORY;
2689 state->xconn = xconn;
2690 state->im = tevent_create_immediate(state);
2691 if (state->im == NULL) {
2692 return NT_STATUS_NO_MEMORY;
2694 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2695 return NT_STATUS_NO_MEMORY;
2698 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2701 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2702 void *private_data, uint32_t msg_type,
2703 struct server_id server_id, DATA_BLOB *data)
2705 struct smbd_server_connection *sconn = talloc_get_type_abort(
2706 private_data, struct smbd_server_connection);
2707 const char *ip = (char *) data->data;
2708 char *client_ip;
2710 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2712 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2713 talloc_tos());
2714 if (client_ip == NULL) {
2715 return;
2718 if (strequal(ip, client_ip)) {
2719 DEBUG(1, ("Got kill client message for %s - "
2720 "exiting immediately\n", ip));
2721 exit_server_cleanly("Forced disconnect for client");
2724 TALLOC_FREE(client_ip);
2728 * Send keepalive packets to our client
2730 static bool keepalive_fn(const struct timeval *now, void *private_data)
2732 struct smbd_server_connection *sconn = talloc_get_type_abort(
2733 private_data, struct smbd_server_connection);
2734 struct smbXsrv_connection *xconn = sconn->conn;
2735 bool ret;
2737 if (sconn->using_smb2) {
2738 /* Don't do keepalives on an SMB2 connection. */
2739 return false;
2742 smbd_lock_socket(xconn);
2743 ret = send_keepalive(xconn->transport.sock);
2744 smbd_unlock_socket(xconn);
2746 if (!ret) {
2747 int saved_errno = errno;
2749 * Try and give an error message saying what
2750 * client failed.
2752 DEBUG(0, ("send_keepalive failed for client %s. "
2753 "Error %s - exiting\n",
2754 smbXsrv_connection_dbg(xconn),
2755 strerror(saved_errno)));
2756 errno = saved_errno;
2757 return False;
2759 return True;
2763 * Do the recurring check if we're idle
2765 static bool deadtime_fn(const struct timeval *now, void *private_data)
2767 struct smbd_server_connection *sconn =
2768 (struct smbd_server_connection *)private_data;
2770 if ((conn_num_open(sconn) == 0)
2771 || (conn_idle_all(sconn, now->tv_sec))) {
2772 DEBUG( 2, ( "Closing idle connection\n" ) );
2773 messaging_send(sconn->msg_ctx,
2774 messaging_server_id(sconn->msg_ctx),
2775 MSG_SHUTDOWN, &data_blob_null);
2776 return False;
2779 return True;
2783 * Do the recurring log file and smb.conf reload checks.
2786 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2788 struct smbd_server_connection *sconn = talloc_get_type_abort(
2789 private_data, struct smbd_server_connection);
2791 DEBUG(5, ("housekeeping\n"));
2793 change_to_root_user();
2795 /* update printer queue caches if necessary */
2796 update_monitored_printq_cache(sconn->msg_ctx);
2798 /* check if we need to reload services */
2799 check_reload(sconn, time_mono(NULL));
2802 * Force a log file check.
2804 force_check_log_size();
2805 check_log_size();
2806 return true;
2810 * Read an smb packet in the echo handler child, giving the parent
2811 * smbd one second to react once the socket becomes readable.
2814 struct smbd_echo_read_state {
2815 struct tevent_context *ev;
2816 struct smbXsrv_connection *xconn;
2818 char *buf;
2819 size_t buflen;
2820 uint32_t seqnum;
2823 static void smbd_echo_read_readable(struct tevent_req *subreq);
2824 static void smbd_echo_read_waited(struct tevent_req *subreq);
2826 static struct tevent_req *smbd_echo_read_send(
2827 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2828 struct smbXsrv_connection *xconn)
2830 struct tevent_req *req, *subreq;
2831 struct smbd_echo_read_state *state;
2833 req = tevent_req_create(mem_ctx, &state,
2834 struct smbd_echo_read_state);
2835 if (req == NULL) {
2836 return NULL;
2838 state->ev = ev;
2839 state->xconn = xconn;
2841 subreq = wait_for_read_send(state, ev, xconn->transport.sock);
2842 if (tevent_req_nomem(subreq, req)) {
2843 return tevent_req_post(req, ev);
2845 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2846 return req;
2849 static void smbd_echo_read_readable(struct tevent_req *subreq)
2851 struct tevent_req *req = tevent_req_callback_data(
2852 subreq, struct tevent_req);
2853 struct smbd_echo_read_state *state = tevent_req_data(
2854 req, struct smbd_echo_read_state);
2855 bool ok;
2856 int err;
2858 ok = wait_for_read_recv(subreq, &err);
2859 TALLOC_FREE(subreq);
2860 if (!ok) {
2861 tevent_req_nterror(req, map_nt_error_from_unix(err));
2862 return;
2866 * Give the parent smbd one second to step in
2869 subreq = tevent_wakeup_send(
2870 state, state->ev, timeval_current_ofs(1, 0));
2871 if (tevent_req_nomem(subreq, req)) {
2872 return;
2874 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2877 static void smbd_echo_read_waited(struct tevent_req *subreq)
2879 struct tevent_req *req = tevent_req_callback_data(
2880 subreq, struct tevent_req);
2881 struct smbd_echo_read_state *state = tevent_req_data(
2882 req, struct smbd_echo_read_state);
2883 struct smbXsrv_connection *xconn = state->xconn;
2884 bool ok;
2885 NTSTATUS status;
2886 size_t unread = 0;
2887 bool encrypted;
2889 ok = tevent_wakeup_recv(subreq);
2890 TALLOC_FREE(subreq);
2891 if (!ok) {
2892 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2893 return;
2896 ok = smbd_lock_socket_internal(xconn);
2897 if (!ok) {
2898 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2899 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2900 return;
2903 if (!fd_is_readable(xconn->transport.sock)) {
2904 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2905 (int)getpid()));
2907 ok = smbd_unlock_socket_internal(xconn);
2908 if (!ok) {
2909 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2910 DEBUG(1, ("%s: failed to unlock socket\n",
2911 __location__));
2912 return;
2915 subreq = wait_for_read_send(state, state->ev,
2916 xconn->transport.sock);
2917 if (tevent_req_nomem(subreq, req)) {
2918 return;
2920 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2921 return;
2924 status = receive_smb_talloc(state, xconn,
2925 xconn->transport.sock,
2926 &state->buf,
2927 0 /* timeout */,
2928 &unread,
2929 &encrypted,
2930 &state->buflen,
2931 &state->seqnum,
2932 false /* trusted_channel*/);
2934 if (tevent_req_nterror(req, status)) {
2935 tevent_req_nterror(req, status);
2936 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2937 (int)getpid(), nt_errstr(status)));
2938 return;
2941 ok = smbd_unlock_socket_internal(xconn);
2942 if (!ok) {
2943 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2944 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2945 return;
2947 tevent_req_done(req);
2950 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2951 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2953 struct smbd_echo_read_state *state = tevent_req_data(
2954 req, struct smbd_echo_read_state);
2955 NTSTATUS status;
2957 if (tevent_req_is_nterror(req, &status)) {
2958 return status;
2960 *pbuf = talloc_move(mem_ctx, &state->buf);
2961 *pbuflen = state->buflen;
2962 *pseqnum = state->seqnum;
2963 return NT_STATUS_OK;
2966 struct smbd_echo_state {
2967 struct tevent_context *ev;
2968 struct iovec *pending;
2969 struct smbd_server_connection *sconn;
2970 struct smbXsrv_connection *xconn;
2971 int parent_pipe;
2973 struct tevent_fd *parent_fde;
2975 struct tevent_req *write_req;
2978 static void smbd_echo_writer_done(struct tevent_req *req);
2980 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2982 int num_pending;
2984 if (state->write_req != NULL) {
2985 return;
2988 num_pending = talloc_array_length(state->pending);
2989 if (num_pending == 0) {
2990 return;
2993 state->write_req = writev_send(state, state->ev, NULL,
2994 state->parent_pipe, false,
2995 state->pending, num_pending);
2996 if (state->write_req == NULL) {
2997 DEBUG(1, ("writev_send failed\n"));
2998 exit(1);
3001 talloc_steal(state->write_req, state->pending);
3002 state->pending = NULL;
3004 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3005 state);
3008 static void smbd_echo_writer_done(struct tevent_req *req)
3010 struct smbd_echo_state *state = tevent_req_callback_data(
3011 req, struct smbd_echo_state);
3012 ssize_t written;
3013 int err;
3015 written = writev_recv(req, &err);
3016 TALLOC_FREE(req);
3017 state->write_req = NULL;
3018 if (written == -1) {
3019 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3020 exit(1);
3022 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3023 smbd_echo_activate_writer(state);
3026 static bool smbd_echo_reply(struct smbd_echo_state *state,
3027 uint8_t *inbuf, size_t inbuf_len,
3028 uint32_t seqnum)
3030 struct smb_request req;
3031 uint16_t num_replies;
3032 char *outbuf;
3033 bool ok;
3035 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3036 DEBUG(10, ("Got netbios keepalive\n"));
3038 * Just swallow it
3040 return true;
3043 if (inbuf_len < smb_size) {
3044 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3045 return false;
3047 if (!valid_smb_header(inbuf)) {
3048 DEBUG(10, ("Got invalid SMB header\n"));
3049 return false;
3052 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3053 seqnum)) {
3054 return false;
3056 req.inbuf = inbuf;
3058 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3059 smb_messages[req.cmd].name
3060 ? smb_messages[req.cmd].name : "unknown"));
3062 if (req.cmd != SMBecho) {
3063 return false;
3065 if (req.wct < 1) {
3066 return false;
3069 num_replies = SVAL(req.vwv+0, 0);
3070 if (num_replies != 1) {
3071 /* Not a Windows "Hey, you're still there?" request */
3072 return false;
3075 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3076 1, req.buflen)) {
3077 DEBUG(10, ("create_outbuf failed\n"));
3078 return false;
3080 req.outbuf = (uint8_t *)outbuf;
3082 SSVAL(req.outbuf, smb_vwv0, num_replies);
3084 if (req.buflen > 0) {
3085 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3088 ok = srv_send_smb(req.xconn,
3089 (char *)outbuf,
3090 true, seqnum+1,
3091 false, &req.pcd);
3092 TALLOC_FREE(outbuf);
3093 if (!ok) {
3094 exit(1);
3097 return true;
3100 static void smbd_echo_exit(struct tevent_context *ev,
3101 struct tevent_fd *fde, uint16_t flags,
3102 void *private_data)
3104 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3105 exit(0);
3108 static void smbd_echo_got_packet(struct tevent_req *req);
3110 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3111 int parent_pipe)
3113 struct smbd_echo_state *state;
3114 struct tevent_req *read_req;
3116 state = talloc_zero(xconn, struct smbd_echo_state);
3117 if (state == NULL) {
3118 DEBUG(1, ("talloc failed\n"));
3119 return;
3121 state->xconn = xconn;
3122 state->parent_pipe = parent_pipe;
3123 state->ev = s3_tevent_context_init(state);
3124 if (state->ev == NULL) {
3125 DEBUG(1, ("tevent_context_init failed\n"));
3126 TALLOC_FREE(state);
3127 return;
3129 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3130 TEVENT_FD_READ, smbd_echo_exit,
3131 state);
3132 if (state->parent_fde == NULL) {
3133 DEBUG(1, ("tevent_add_fd failed\n"));
3134 TALLOC_FREE(state);
3135 return;
3138 read_req = smbd_echo_read_send(state, state->ev, xconn);
3139 if (read_req == NULL) {
3140 DEBUG(1, ("smbd_echo_read_send failed\n"));
3141 TALLOC_FREE(state);
3142 return;
3144 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3146 while (true) {
3147 if (tevent_loop_once(state->ev) == -1) {
3148 DEBUG(1, ("tevent_loop_once failed: %s\n",
3149 strerror(errno)));
3150 break;
3153 TALLOC_FREE(state);
3156 static void smbd_echo_got_packet(struct tevent_req *req)
3158 struct smbd_echo_state *state = tevent_req_callback_data(
3159 req, struct smbd_echo_state);
3160 NTSTATUS status;
3161 char *buf = NULL;
3162 size_t buflen = 0;
3163 uint32_t seqnum = 0;
3164 bool reply;
3166 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3167 TALLOC_FREE(req);
3168 if (!NT_STATUS_IS_OK(status)) {
3169 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3170 nt_errstr(status)));
3171 exit(1);
3174 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3175 if (!reply) {
3176 size_t num_pending;
3177 struct iovec *tmp;
3178 struct iovec *iov;
3180 num_pending = talloc_array_length(state->pending);
3181 tmp = talloc_realloc(state, state->pending, struct iovec,
3182 num_pending+1);
3183 if (tmp == NULL) {
3184 DEBUG(1, ("talloc_realloc failed\n"));
3185 exit(1);
3187 state->pending = tmp;
3189 if (buflen >= smb_size) {
3191 * place the seqnum in the packet so that the main process
3192 * can reply with signing
3194 SIVAL(buf, smb_ss_field, seqnum);
3195 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3198 iov = &state->pending[num_pending];
3199 iov->iov_base = talloc_move(state->pending, &buf);
3200 iov->iov_len = buflen;
3202 DEBUG(10,("echo_handler[%d]: forward to main\n",
3203 (int)getpid()));
3204 smbd_echo_activate_writer(state);
3207 req = smbd_echo_read_send(state, state->ev, state->xconn);
3208 if (req == NULL) {
3209 DEBUG(1, ("smbd_echo_read_send failed\n"));
3210 exit(1);
3212 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3217 * Handle SMBecho requests in a forked child process
3219 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3221 int listener_pipe[2];
3222 int res;
3223 pid_t child;
3224 bool use_mutex = false;
3226 res = pipe(listener_pipe);
3227 if (res == -1) {
3228 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3229 return false;
3232 #ifdef HAVE_ROBUST_MUTEXES
3233 use_mutex = tdb_runtime_check_for_robust_mutexes();
3235 if (use_mutex) {
3236 pthread_mutexattr_t a;
3238 xconn->smb1.echo_handler.socket_mutex =
3239 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3240 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3241 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3242 strerror(errno)));
3243 goto fail;
3246 res = pthread_mutexattr_init(&a);
3247 if (res != 0) {
3248 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3249 strerror(res)));
3250 goto fail;
3252 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3253 if (res != 0) {
3254 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3255 strerror(res)));
3256 pthread_mutexattr_destroy(&a);
3257 goto fail;
3259 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3260 if (res != 0) {
3261 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3262 strerror(res)));
3263 pthread_mutexattr_destroy(&a);
3264 goto fail;
3266 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3267 if (res != 0) {
3268 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3269 "%s\n", strerror(res)));
3270 pthread_mutexattr_destroy(&a);
3271 goto fail;
3273 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3274 &a);
3275 pthread_mutexattr_destroy(&a);
3276 if (res != 0) {
3277 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3278 strerror(res)));
3279 goto fail;
3282 #endif
3284 if (!use_mutex) {
3285 xconn->smb1.echo_handler.socket_lock_fd =
3286 create_unlink_tmp(lp_lock_directory());
3287 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3288 DEBUG(1, ("Could not create lock fd: %s\n",
3289 strerror(errno)));
3290 goto fail;
3294 child = fork();
3295 if (child == 0) {
3296 NTSTATUS status;
3298 close(listener_pipe[0]);
3299 set_blocking(listener_pipe[1], false);
3301 status = reinit_after_fork(xconn->msg_ctx,
3302 xconn->ev_ctx,
3303 true);
3304 if (!NT_STATUS_IS_OK(status)) {
3305 DEBUG(1, ("reinit_after_fork failed: %s\n",
3306 nt_errstr(status)));
3307 exit(1);
3309 smbd_echo_loop(xconn, listener_pipe[1]);
3310 exit(0);
3312 close(listener_pipe[1]);
3313 listener_pipe[1] = -1;
3314 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3316 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3319 * Without smb signing this is the same as the normal smbd
3320 * listener. This needs to change once signing comes in.
3322 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3323 xconn,
3324 xconn->smb1.echo_handler.trusted_fd,
3325 TEVENT_FD_READ,
3326 smbd_server_echo_handler,
3327 xconn);
3328 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3329 DEBUG(1, ("event_add_fd failed\n"));
3330 goto fail;
3333 return true;
3335 fail:
3336 if (listener_pipe[0] != -1) {
3337 close(listener_pipe[0]);
3339 if (listener_pipe[1] != -1) {
3340 close(listener_pipe[1]);
3342 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3343 close(xconn->smb1.echo_handler.socket_lock_fd);
3345 #ifdef HAVE_ROBUST_MUTEXES
3346 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3347 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3348 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3350 #endif
3351 smbd_echo_init(xconn);
3353 return false;
3356 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3358 while (user) {
3359 if (user->session_info &&
3360 (user->session_info->unix_token->uid == uid)) {
3361 return true;
3363 user = user->next;
3365 return false;
3368 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3370 while (user) {
3371 if (user->session_info != NULL) {
3372 int i;
3373 struct security_unix_token *utok;
3375 utok = user->session_info->unix_token;
3376 if (utok->gid == gid) {
3377 return true;
3379 for(i=0; i<utok->ngroups; i++) {
3380 if (utok->groups[i] == gid) {
3381 return true;
3385 user = user->next;
3387 return false;
3390 static bool sid_in_use(const struct user_struct *user,
3391 const struct dom_sid *psid)
3393 while (user) {
3394 struct security_token *tok;
3396 if (user->session_info == NULL) {
3397 continue;
3399 tok = user->session_info->security_token;
3400 if (tok == NULL) {
3402 * Not sure session_info->security_token can
3403 * ever be NULL. This check might be not
3404 * necessary.
3406 continue;
3408 if (security_token_has_sid(tok, psid)) {
3409 return true;
3411 user = user->next;
3413 return false;
3416 static bool id_in_use(const struct user_struct *user,
3417 const struct id_cache_ref *id)
3419 switch(id->type) {
3420 case UID:
3421 return uid_in_use(user, id->id.uid);
3422 case GID:
3423 return gid_in_use(user, id->id.gid);
3424 case SID:
3425 return sid_in_use(user, &id->id.sid);
3426 default:
3427 break;
3429 return false;
3432 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3433 void *private_data,
3434 uint32_t msg_type,
3435 struct server_id server_id,
3436 DATA_BLOB* data)
3438 const char *msg = (data && data->data)
3439 ? (const char *)data->data : "<NULL>";
3440 struct id_cache_ref id;
3441 struct smbd_server_connection *sconn =
3442 talloc_get_type_abort(private_data,
3443 struct smbd_server_connection);
3445 if (!id_cache_ref_parse(msg, &id)) {
3446 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3447 return;
3450 if (id_in_use(sconn->users, &id)) {
3451 exit_server_cleanly(msg);
3453 id_cache_delete_from_cache(&id);
3456 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3457 enum protocol_types protocol)
3459 NTSTATUS status;
3461 set_Protocol(protocol);
3462 conn->protocol = protocol;
3464 if (protocol >= PROTOCOL_SMB2_02) {
3465 status = smb2srv_session_table_init(conn);
3466 if (!NT_STATUS_IS_OK(status)) {
3467 return status;
3470 status = smb2srv_open_table_init(conn);
3471 if (!NT_STATUS_IS_OK(status)) {
3472 return status;
3474 } else {
3475 status = smb1srv_session_table_init(conn);
3476 if (!NT_STATUS_IS_OK(status)) {
3477 return status;
3480 status = smb1srv_tcon_table_init(conn);
3481 if (!NT_STATUS_IS_OK(status)) {
3482 return status;
3485 status = smb1srv_open_table_init(conn);
3486 if (!NT_STATUS_IS_OK(status)) {
3487 return status;
3491 return NT_STATUS_OK;
3494 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3495 void *private_data)
3497 struct smbXsrv_connection *conn =
3498 talloc_get_type_abort(private_data,
3499 struct smbXsrv_connection);
3501 switch (point) {
3502 case TEVENT_TRACE_BEFORE_WAIT:
3504 * This just removes compiler warning
3505 * without profile support
3507 conn->smbd_idle_profstamp = 0;
3508 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3509 break;
3510 case TEVENT_TRACE_AFTER_WAIT:
3511 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3512 break;
3513 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3514 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3515 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3516 break;
3517 #endif
3522 * Create a debug string for the connection
3524 * This is allocated to talloc_tos() or a string constant
3525 * in certain corner cases. The returned string should
3526 * hence not be free'd directly but only via the talloc stack.
3528 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3530 const char *ret;
3533 * TODO: this can be improved later
3534 * maybe including the client guid or more
3536 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3537 if (ret == NULL) {
3538 return "<tsocket_address_string() failed>";
3541 return ret;
3544 /****************************************************************************
3545 Process commands from the client
3546 ****************************************************************************/
3548 void smbd_process(struct tevent_context *ev_ctx,
3549 struct messaging_context *msg_ctx,
3550 int sock_fd,
3551 bool interactive)
3553 TALLOC_CTX *frame = talloc_stackframe();
3554 struct smbXsrv_connection *xconn;
3555 struct smbd_server_connection *sconn;
3556 struct sockaddr_storage ss_srv;
3557 void *sp_srv = (void *)&ss_srv;
3558 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3559 struct sockaddr_storage ss_clnt;
3560 void *sp_clnt = (void *)&ss_clnt;
3561 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3562 socklen_t sa_socklen;
3563 struct tsocket_address *local_address = NULL;
3564 struct tsocket_address *remote_address = NULL;
3565 const char *locaddr = NULL;
3566 const char *remaddr = NULL;
3567 char *rhost;
3568 int ret;
3569 int tmp;
3571 xconn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3572 if (xconn == NULL) {
3573 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3574 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3577 xconn->ev_ctx = ev_ctx;
3578 xconn->msg_ctx = msg_ctx;
3579 xconn->transport.sock = sock_fd;
3580 smbd_echo_init(xconn);
3582 sconn = talloc_zero(xconn, struct smbd_server_connection);
3583 if (!sconn) {
3584 exit_server("failed to create smbd_server_connection");
3587 xconn->sconn = sconn;
3588 sconn->conn = xconn;
3591 * TODO: remove this...:-)
3593 global_smbXsrv_connection = xconn;
3595 sconn->ev_ctx = ev_ctx;
3596 sconn->msg_ctx = msg_ctx;
3598 if (!interactive) {
3599 smbd_setup_sig_term_handler(sconn);
3600 smbd_setup_sig_hup_handler(sconn);
3602 if (!serverid_register(messaging_server_id(msg_ctx),
3603 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3604 |FLAG_MSG_DBWRAP
3605 |FLAG_MSG_PRINT_GENERAL)) {
3606 exit_server_cleanly("Could not register myself in "
3607 "serverid.tdb");
3611 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3613 * We're not making the decision here,
3614 * we're just allowing the client
3615 * to decide between SMB1 and SMB2
3616 * with the first negprot
3617 * packet.
3619 sconn->using_smb2 = true;
3622 /* Ensure child is set to blocking mode */
3623 set_blocking(sock_fd,True);
3625 set_socket_options(sock_fd, "SO_KEEPALIVE");
3626 set_socket_options(sock_fd, lp_socket_options());
3628 sa_socklen = sizeof(ss_clnt);
3629 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3630 if (ret != 0) {
3631 int level = (errno == ENOTCONN)?2:0;
3632 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3633 exit_server_cleanly("getpeername() failed.\n");
3635 ret = tsocket_address_bsd_from_sockaddr(sconn,
3636 sa_clnt, sa_socklen,
3637 &remote_address);
3638 if (ret != 0) {
3639 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3640 __location__, strerror(errno)));
3641 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3644 sa_socklen = sizeof(ss_srv);
3645 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3646 if (ret != 0) {
3647 int level = (errno == ENOTCONN)?2:0;
3648 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3649 exit_server_cleanly("getsockname() failed.\n");
3651 ret = tsocket_address_bsd_from_sockaddr(sconn,
3652 sa_srv, sa_socklen,
3653 &local_address);
3654 if (ret != 0) {
3655 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3656 __location__, strerror(errno)));
3657 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3660 sconn->local_address = local_address;
3661 sconn->remote_address = remote_address;
3663 if (tsocket_address_is_inet(local_address, "ip")) {
3664 locaddr = tsocket_address_inet_addr_string(
3665 sconn->local_address,
3666 talloc_tos());
3667 if (locaddr == NULL) {
3668 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3669 __location__, strerror(errno)));
3670 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3672 } else {
3673 locaddr = "0.0.0.0";
3676 if (tsocket_address_is_inet(remote_address, "ip")) {
3677 remaddr = tsocket_address_inet_addr_string(
3678 sconn->remote_address,
3679 talloc_tos());
3680 if (remaddr == NULL) {
3681 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3682 __location__, strerror(errno)));
3683 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3685 } else {
3686 remaddr = "0.0.0.0";
3689 /* this is needed so that we get decent entries
3690 in smbstatus for port 445 connects */
3691 set_remote_machine_name(remaddr, false);
3692 reload_services(sconn, conn_snum_used, true);
3695 * Before the first packet, check the global hosts allow/ hosts deny
3696 * parameters before doing any parsing of packets passed to us by the
3697 * client. This prevents attacks on our parsing code from hosts not in
3698 * the hosts allow list.
3701 ret = get_remote_hostname(remote_address,
3702 &rhost,
3703 talloc_tos());
3704 if (ret < 0) {
3705 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3706 __location__, strerror(errno)));
3707 exit_server_cleanly("get_remote_hostname failed.\n");
3709 if (strequal(rhost, "UNKNOWN")) {
3710 rhost = talloc_strdup(talloc_tos(), remaddr);
3712 sconn->remote_hostname = talloc_move(sconn, &rhost);
3714 sub_set_socket_ids(remaddr,
3715 sconn->remote_hostname,
3716 locaddr);
3718 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3719 sconn->remote_hostname,
3720 remaddr)) {
3722 * send a negative session response "not listening on calling
3723 * name"
3725 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3726 DEBUG( 1, ("Connection denied from %s to %s\n",
3727 tsocket_address_string(remote_address, talloc_tos()),
3728 tsocket_address_string(local_address, talloc_tos())));
3729 (void)srv_send_smb(xconn,(char *)buf, false,
3730 0, false, NULL);
3731 exit_server_cleanly("connection denied");
3734 DEBUG(10, ("Connection allowed from %s to %s\n",
3735 tsocket_address_string(remote_address, talloc_tos()),
3736 tsocket_address_string(local_address, talloc_tos())));
3738 if (lp_preload_modules()) {
3739 smb_load_modules(lp_preload_modules());
3742 smb_perfcount_init();
3744 if (!init_account_policy()) {
3745 exit_server("Could not open account policy tdb.\n");
3748 if (*lp_root_directory(talloc_tos())) {
3749 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3750 DEBUG(0,("Failed to change root to %s\n",
3751 lp_root_directory(talloc_tos())));
3752 exit_server("Failed to chroot()");
3754 if (chdir("/") == -1) {
3755 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3756 exit_server("Failed to chroot()");
3758 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3761 if (!srv_init_signing(xconn)) {
3762 exit_server("Failed to init smb_signing");
3765 if (!file_init(sconn)) {
3766 exit_server("file_init() failed");
3769 /* Setup oplocks */
3770 if (!init_oplocks(sconn))
3771 exit_server("Failed to init oplocks");
3773 /* register our message handlers */
3774 messaging_register(sconn->msg_ctx, sconn,
3775 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3776 messaging_register(sconn->msg_ctx, sconn,
3777 MSG_SMB_CLOSE_FILE, msg_close_file);
3778 messaging_register(sconn->msg_ctx, sconn,
3779 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3781 id_cache_register_msgs(sconn->msg_ctx);
3782 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3783 messaging_register(sconn->msg_ctx, sconn,
3784 ID_CACHE_KILL, smbd_id_cache_kill);
3786 messaging_deregister(sconn->msg_ctx,
3787 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3788 messaging_register(sconn->msg_ctx, sconn,
3789 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3791 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3792 NULL);
3793 messaging_register(sconn->msg_ctx, sconn,
3794 MSG_SMB_KILL_CLIENT_IP,
3795 msg_kill_client_ip);
3797 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3800 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3801 * MSGs to all child processes
3803 messaging_deregister(sconn->msg_ctx,
3804 MSG_DEBUG, NULL);
3805 messaging_register(sconn->msg_ctx, NULL,
3806 MSG_DEBUG, debug_message);
3808 if ((lp_keepalive() != 0)
3809 && !(event_add_idle(ev_ctx, NULL,
3810 timeval_set(lp_keepalive(), 0),
3811 "keepalive", keepalive_fn,
3812 sconn))) {
3813 DEBUG(0, ("Could not add keepalive event\n"));
3814 exit(1);
3817 if (!(event_add_idle(ev_ctx, NULL,
3818 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3819 "deadtime", deadtime_fn, sconn))) {
3820 DEBUG(0, ("Could not add deadtime event\n"));
3821 exit(1);
3824 if (!(event_add_idle(ev_ctx, NULL,
3825 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3826 "housekeeping", housekeeping_fn, sconn))) {
3827 DEBUG(0, ("Could not add housekeeping event\n"));
3828 exit(1);
3831 if (lp_clustering()) {
3833 * We need to tell ctdb about our client's TCP
3834 * connection, so that for failover ctdbd can send
3835 * tickle acks, triggering a reconnection by the
3836 * client.
3838 NTSTATUS status;
3840 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3841 if (!NT_STATUS_IS_OK(status)) {
3842 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3843 nt_errstr(status)));
3847 tmp = lp_max_xmit();
3848 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3849 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3851 xconn->smb1.negprot.max_recv = tmp;
3853 xconn->smb1.sessions.done_sesssetup = false;
3854 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3856 if (!init_dptrs(sconn)) {
3857 exit_server("init_dptrs() failed");
3860 xconn->transport.fde = tevent_add_fd(ev_ctx,
3861 xconn,
3862 sock_fd,
3863 TEVENT_FD_READ,
3864 smbd_server_connection_handler,
3865 xconn);
3866 if (!xconn->transport.fde) {
3867 exit_server("failed to create smbd_server_connection fde");
3870 sconn->conn->local_address = sconn->local_address;
3871 sconn->conn->remote_address = sconn->remote_address;
3872 sconn->conn->remote_hostname = sconn->remote_hostname;
3873 sconn->conn->protocol = PROTOCOL_NONE;
3875 TALLOC_FREE(frame);
3877 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, xconn);
3879 while (True) {
3880 frame = talloc_stackframe_pool(8192);
3882 errno = 0;
3883 if (tevent_loop_once(ev_ctx) == -1) {
3884 if (errno != EINTR) {
3885 DEBUG(3, ("tevent_loop_once failed: %s,"
3886 " exiting\n", strerror(errno) ));
3887 break;
3891 TALLOC_FREE(frame);
3894 exit_server_cleanly(NULL);
3897 bool req_is_in_chain(const struct smb_request *req)
3899 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3901 * We're right now handling a subsequent request, so we must
3902 * be in a chain
3904 return true;
3907 if (!is_andx_req(req->cmd)) {
3908 return false;
3911 if (req->wct < 2) {
3913 * Okay, an illegal request, but definitely not chained :-)
3915 return false;
3918 return (CVAL(req->vwv+0, 0) != 0xFF);