s3:smbd: move sconn->smb1.negprot.* to xconn->smb1.negprot.*
[Samba.git] / source3 / smbd / process.c
blob3c5d025704fe18ff1f628d0d6e0b5a704755a76f
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 tevent_timer *te;
51 struct smb_perfcount_data pcd;
52 uint32_t seqnum;
53 bool encrypted;
54 bool processed;
55 DATA_BLOB buf;
56 struct deferred_open_record *open_rec;
59 static void construct_reply_common(struct smb_request *req, const char *inbuf,
60 char *outbuf);
61 static struct pending_message_list *get_deferred_open_message_smb(
62 struct smbd_server_connection *sconn, uint64_t mid);
63 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
65 void smbd_echo_init(struct smbd_server_connection *sconn)
67 sconn->smb1.echo_handler.trusted_fd = -1;
68 sconn->smb1.echo_handler.socket_lock_fd = -1;
69 #ifdef HAVE_ROBUST_MUTEXES
70 sconn->smb1.echo_handler.socket_mutex = NULL;
71 #endif
74 static bool smbd_echo_active(struct smbd_server_connection *sconn)
76 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
77 return true;
80 #ifdef HAVE_ROBUST_MUTEXES
81 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
82 return true;
84 #endif
86 return false;
89 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
91 if (!smbd_echo_active(sconn)) {
92 return true;
95 sconn->smb1.echo_handler.ref_count++;
97 if (sconn->smb1.echo_handler.ref_count > 1) {
98 return true;
101 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
103 #ifdef HAVE_ROBUST_MUTEXES
104 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
105 int ret = EINTR;
107 while (ret == EINTR) {
108 ret = pthread_mutex_lock(
109 sconn->smb1.echo_handler.socket_mutex);
110 if (ret == 0) {
111 break;
114 if (ret != 0) {
115 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
116 strerror(ret)));
117 return false;
120 #endif
122 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
123 bool ok;
125 do {
126 ok = fcntl_lock(
127 sconn->smb1.echo_handler.socket_lock_fd,
128 F_SETLKW, 0, 0, F_WRLCK);
129 } while (!ok && (errno == EINTR));
131 if (!ok) {
132 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
133 return false;
137 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
139 return true;
142 void smbd_lock_socket(struct smbd_server_connection *sconn)
144 if (!smbd_lock_socket_internal(sconn)) {
145 exit_server_cleanly("failed to lock socket");
149 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
151 if (!smbd_echo_active(sconn)) {
152 return true;
155 sconn->smb1.echo_handler.ref_count--;
157 if (sconn->smb1.echo_handler.ref_count > 0) {
158 return true;
161 #ifdef HAVE_ROBUST_MUTEXES
162 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
163 int ret = EINTR;
165 while (ret == EINTR) {
166 ret = pthread_mutex_unlock(
167 sconn->smb1.echo_handler.socket_mutex);
168 if (ret == 0) {
169 break;
172 if (ret != 0) {
173 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
174 strerror(ret)));
175 return false;
178 #endif
180 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
181 bool ok;
183 do {
184 ok = fcntl_lock(
185 sconn->smb1.echo_handler.socket_lock_fd,
186 F_SETLKW, 0, 0, F_UNLCK);
187 } while (!ok && (errno == EINTR));
189 if (!ok) {
190 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
191 return false;
195 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
197 return true;
200 void smbd_unlock_socket(struct smbd_server_connection *sconn)
202 if (!smbd_unlock_socket_internal(sconn)) {
203 exit_server_cleanly("failed to unlock socket");
207 /* Accessor function for smb_read_error for smbd functions. */
209 /****************************************************************************
210 Send an smb to a fd.
211 ****************************************************************************/
213 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
214 bool do_signing, uint32_t seqnum,
215 bool do_encrypt,
216 struct smb_perfcount_data *pcd)
218 struct smbXsrv_connection *xconn = sconn->conn;
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(sconn);
232 if (do_signing) {
233 /* Sign the outgoing packet if required. */
234 srv_calculate_sign_mac(sconn, buf_out, seqnum);
237 if (do_encrypt) {
238 NTSTATUS status = srv_encrypt_buffer(sconn, 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(sconn, buf_out);
264 goto out;
267 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
268 srv_free_enc_buffer(sconn, buf_out);
269 out:
270 SMB_PERFCOUNT_END(pcd);
272 smbd_unlock_socket(sconn);
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(struct smbd_server_connection *sconn,
295 const uint8_t *inbuf)
297 if (is_encrypted_packet(sconn, inbuf)) {
298 return true;
301 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
302 * but it just looks weird to call strncmp for this one.
304 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
307 /* Socket functions for smbd packet processing. */
309 static bool valid_packet_size(size_t len)
312 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
313 * of header. Don't print the error if this fits.... JRA.
316 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
317 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
318 (unsigned long)len));
319 return false;
321 return true;
324 static NTSTATUS read_packet_remainder(int fd, char *buffer,
325 unsigned int timeout, ssize_t len)
327 NTSTATUS status;
329 if (len <= 0) {
330 return NT_STATUS_OK;
333 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
334 if (!NT_STATUS_IS_OK(status)) {
335 char addr[INET6_ADDRSTRLEN];
336 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
337 "error = %s.\n",
338 get_peer_addr(fd, addr, sizeof(addr)),
339 nt_errstr(status)));
341 return status;
344 /****************************************************************************
345 Attempt a zerocopy writeX read. We know here that len > smb_size-4
346 ****************************************************************************/
349 * Unfortunately, earlier versions of smbclient/libsmbclient
350 * don't send this "standard" writeX header. I've fixed this
351 * for 3.2 but we'll use the old method with earlier versions.
352 * Windows and CIFSFS at least use this standard size. Not
353 * sure about MacOSX.
356 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
357 (2*14) + /* word count (including bcc) */ \
358 1 /* pad byte */)
360 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
361 const char lenbuf[4],
362 struct smbd_server_connection *sconn,
363 int sock,
364 char **buffer,
365 unsigned int timeout,
366 size_t *p_unread,
367 size_t *len_ret)
369 /* Size of a WRITEX call (+4 byte len). */
370 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
371 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
372 ssize_t toread;
373 NTSTATUS status;
375 memcpy(writeX_header, lenbuf, 4);
377 status = read_fd_with_timeout(
378 sock, writeX_header + 4,
379 STANDARD_WRITE_AND_X_HEADER_SIZE,
380 STANDARD_WRITE_AND_X_HEADER_SIZE,
381 timeout, NULL);
383 if (!NT_STATUS_IS_OK(status)) {
384 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
385 "error = %s.\n",
386 tsocket_address_string(sconn->remote_address,
387 talloc_tos()),
388 nt_errstr(status)));
389 return status;
393 * Ok - now try and see if this is a possible
394 * valid writeX call.
397 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
399 * If the data offset is beyond what
400 * we've read, drain the extra bytes.
402 uint16_t doff = SVAL(writeX_header,smb_vwv11);
403 ssize_t newlen;
405 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
406 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
407 if (drain_socket(sock, drain) != drain) {
408 smb_panic("receive_smb_raw_talloc_partial_read:"
409 " failed to drain pending bytes");
411 } else {
412 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
415 /* Spoof down the length and null out the bcc. */
416 set_message_bcc(writeX_header, 0);
417 newlen = smb_len(writeX_header);
419 /* Copy the header we've written. */
421 *buffer = (char *)talloc_memdup(mem_ctx,
422 writeX_header,
423 sizeof(writeX_header));
425 if (*buffer == NULL) {
426 DEBUG(0, ("Could not allocate inbuf of length %d\n",
427 (int)sizeof(writeX_header)));
428 return NT_STATUS_NO_MEMORY;
431 /* Work out the remaining bytes. */
432 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
433 *len_ret = newlen + 4;
434 return NT_STATUS_OK;
437 if (!valid_packet_size(len)) {
438 return NT_STATUS_INVALID_PARAMETER;
442 * Not a valid writeX call. Just do the standard
443 * talloc and return.
446 *buffer = talloc_array(mem_ctx, char, len+4);
448 if (*buffer == NULL) {
449 DEBUG(0, ("Could not allocate inbuf of length %d\n",
450 (int)len+4));
451 return NT_STATUS_NO_MEMORY;
454 /* Copy in what we already read. */
455 memcpy(*buffer,
456 writeX_header,
457 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
458 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
460 if(toread > 0) {
461 status = read_packet_remainder(
462 sock,
463 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
464 timeout, toread);
466 if (!NT_STATUS_IS_OK(status)) {
467 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
468 nt_errstr(status)));
469 return status;
473 *len_ret = len + 4;
474 return NT_STATUS_OK;
477 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
478 struct smbd_server_connection *sconn,
479 int sock,
480 char **buffer, unsigned int timeout,
481 size_t *p_unread, size_t *plen)
483 char lenbuf[4];
484 size_t len;
485 int min_recv_size = lp_min_receive_file_size();
486 NTSTATUS status;
488 *p_unread = 0;
490 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
491 &len);
492 if (!NT_STATUS_IS_OK(status)) {
493 return status;
496 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
497 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
498 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
499 !srv_is_signing_active(sconn) &&
500 sconn->smb1.echo_handler.trusted_fde == NULL) {
502 return receive_smb_raw_talloc_partial_read(
503 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
504 p_unread, plen);
507 if (!valid_packet_size(len)) {
508 return NT_STATUS_INVALID_PARAMETER;
512 * The +4 here can't wrap, we've checked the length above already.
515 *buffer = talloc_array(mem_ctx, char, len+4);
517 if (*buffer == NULL) {
518 DEBUG(0, ("Could not allocate inbuf of length %d\n",
519 (int)len+4));
520 return NT_STATUS_NO_MEMORY;
523 memcpy(*buffer, lenbuf, sizeof(lenbuf));
525 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
526 if (!NT_STATUS_IS_OK(status)) {
527 return status;
530 *plen = len + 4;
531 return NT_STATUS_OK;
534 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
535 struct smbd_server_connection *sconn,
536 int sock,
537 char **buffer, unsigned int timeout,
538 size_t *p_unread, bool *p_encrypted,
539 size_t *p_len,
540 uint32_t *seqnum,
541 bool trusted_channel)
543 size_t len = 0;
544 NTSTATUS status;
546 *p_encrypted = false;
548 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
549 p_unread, &len);
550 if (!NT_STATUS_IS_OK(status)) {
551 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
552 ("receive_smb_raw_talloc failed for client %s "
553 "read error = %s.\n",
554 tsocket_address_string(sconn->remote_address,
555 talloc_tos()),
556 nt_errstr(status)) );
557 return status;
560 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
561 status = srv_decrypt_buffer(sconn, *buffer);
562 if (!NT_STATUS_IS_OK(status)) {
563 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
564 "incoming packet! Error %s\n",
565 nt_errstr(status) ));
566 return status;
568 *p_encrypted = true;
571 /* Check the incoming SMB signature. */
572 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
573 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
574 "incoming packet!\n"));
575 return NT_STATUS_INVALID_NETWORK_RESPONSE;
578 *p_len = len;
579 return NT_STATUS_OK;
583 * Initialize a struct smb_request from an inbuf
586 static bool init_smb_request(struct smb_request *req,
587 struct smbd_server_connection *sconn,
588 const uint8 *inbuf,
589 size_t unread_bytes, bool encrypted,
590 uint32_t seqnum)
592 struct smbXsrv_tcon *tcon;
593 NTSTATUS status;
594 NTTIME now;
595 size_t req_size = smb_len(inbuf) + 4;
597 /* Ensure we have at least smb_size bytes. */
598 if (req_size < smb_size) {
599 DEBUG(0,("init_smb_request: invalid request size %u\n",
600 (unsigned int)req_size ));
601 return false;
604 req->request_time = timeval_current();
605 now = timeval_to_nttime(&req->request_time);
607 req->cmd = CVAL(inbuf, smb_com);
608 req->flags2 = SVAL(inbuf, smb_flg2);
609 req->smbpid = SVAL(inbuf, smb_pid);
610 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
611 req->seqnum = seqnum;
612 req->vuid = SVAL(inbuf, smb_uid);
613 req->tid = SVAL(inbuf, smb_tid);
614 req->wct = CVAL(inbuf, smb_wct);
615 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
616 req->buflen = smb_buflen(inbuf);
617 req->buf = (const uint8_t *)smb_buf_const(inbuf);
618 req->unread_bytes = unread_bytes;
619 req->encrypted = encrypted;
620 req->sconn = sconn;
621 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
622 if (NT_STATUS_IS_OK(status)) {
623 req->conn = tcon->compat;
624 } else {
625 req->conn = NULL;
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 smbd_server_connection *conn,
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 TALLOC_CTX *mem_ctx = talloc_tos();
668 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
669 uint8_t *inbuf;
671 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
672 msg->buf.length);
673 if (inbuf == NULL) {
674 exit_server("smbd_deferred_open_timer: talloc failed\n");
675 return;
678 /* We leave this message on the queue so the open code can
679 know this is a retry. */
680 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
681 (unsigned long long)mid ));
683 /* Mark the message as processed so this is not
684 * re-processed in error. */
685 msg->processed = true;
687 process_smb(sconn, inbuf,
688 msg->buf.length, 0,
689 msg->seqnum, msg->encrypted, &msg->pcd);
691 /* If it's still there and was processed, remove it. */
692 msg = get_deferred_open_message_smb(sconn, mid);
693 if (msg && msg->processed) {
694 remove_deferred_open_message_smb(sconn, mid);
698 /****************************************************************************
699 Function to push a message onto the tail of a linked list of smb messages ready
700 for processing.
701 ****************************************************************************/
703 static bool push_queued_message(struct smb_request *req,
704 struct timeval request_time,
705 struct timeval end_time,
706 struct deferred_open_record *open_rec)
708 int msg_len = smb_len(req->inbuf) + 4;
709 struct pending_message_list *msg;
711 msg = talloc_zero(NULL, struct pending_message_list);
713 if(msg == NULL) {
714 DEBUG(0,("push_message: malloc fail (1)\n"));
715 return False;
717 msg->sconn = req->sconn;
719 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
720 if(msg->buf.data == NULL) {
721 DEBUG(0,("push_message: malloc fail (2)\n"));
722 TALLOC_FREE(msg);
723 return False;
726 msg->request_time = request_time;
727 msg->seqnum = req->seqnum;
728 msg->encrypted = req->encrypted;
729 msg->processed = false;
730 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
732 if (open_rec) {
733 msg->open_rec = talloc_move(msg, &open_rec);
736 #if 0
737 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
738 msg,
739 end_time,
740 smbd_deferred_open_timer,
741 msg);
742 if (!msg->te) {
743 DEBUG(0,("push_message: event_add_timed failed\n"));
744 TALLOC_FREE(msg);
745 return false;
747 #endif
749 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
750 struct pending_message_list *);
752 DEBUG(10,("push_message: pushed message length %u on "
753 "deferred_open_queue\n", (unsigned int)msg_len));
755 return True;
758 /****************************************************************************
759 Function to delete a sharing violation open message by mid.
760 ****************************************************************************/
762 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
763 uint64_t mid)
765 struct pending_message_list *pml;
767 if (sconn->using_smb2) {
768 remove_deferred_open_message_smb2(sconn, mid);
769 return;
772 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
773 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
774 DEBUG(10,("remove_deferred_open_message_smb: "
775 "deleting mid %llu len %u\n",
776 (unsigned long long)mid,
777 (unsigned int)pml->buf.length ));
778 DLIST_REMOVE(sconn->deferred_open_queue, pml);
779 TALLOC_FREE(pml);
780 return;
785 /****************************************************************************
786 Move a sharing violation open retry message to the front of the list and
787 schedule it for immediate processing.
788 ****************************************************************************/
790 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
791 uint64_t mid)
793 struct pending_message_list *pml;
794 int i = 0;
796 if (sconn->using_smb2) {
797 return schedule_deferred_open_message_smb2(sconn, mid);
800 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
801 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
803 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
804 "msg_mid = %llu\n",
805 i++,
806 (unsigned long long)msg_mid ));
808 if (mid == msg_mid) {
809 struct tevent_timer *te;
811 if (pml->processed) {
812 /* A processed message should not be
813 * rescheduled. */
814 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
815 "message mid %llu was already processed\n",
816 (unsigned long long)msg_mid ));
817 continue;
820 DEBUG(10,("schedule_deferred_open_message_smb: "
821 "scheduling mid %llu\n",
822 (unsigned long long)mid ));
824 te = tevent_add_timer(pml->sconn->ev_ctx,
825 pml,
826 timeval_zero(),
827 smbd_deferred_open_timer,
828 pml);
829 if (!te) {
830 DEBUG(10,("schedule_deferred_open_message_smb: "
831 "event_add_timed() failed, "
832 "skipping mid %llu\n",
833 (unsigned long long)msg_mid ));
836 TALLOC_FREE(pml->te);
837 pml->te = te;
838 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
839 return true;
843 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
844 "find message mid %llu\n",
845 (unsigned long long)mid ));
847 return false;
850 /****************************************************************************
851 Return true if this mid is on the deferred queue and was not yet processed.
852 ****************************************************************************/
854 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
856 struct pending_message_list *pml;
858 if (sconn->using_smb2) {
859 return open_was_deferred_smb2(sconn, mid);
862 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
863 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
864 return True;
867 return False;
870 /****************************************************************************
871 Return the message queued by this mid.
872 ****************************************************************************/
874 static struct pending_message_list *get_deferred_open_message_smb(
875 struct smbd_server_connection *sconn, uint64_t mid)
877 struct pending_message_list *pml;
879 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
880 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
881 return pml;
884 return NULL;
887 /****************************************************************************
888 Get the state data queued by this mid.
889 ****************************************************************************/
891 bool get_deferred_open_message_state(struct smb_request *smbreq,
892 struct timeval *p_request_time,
893 struct deferred_open_record **open_rec)
895 struct pending_message_list *pml;
897 if (smbreq->sconn->using_smb2) {
898 return get_deferred_open_message_state_smb2(smbreq->smb2req,
899 p_request_time,
900 open_rec);
903 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
904 if (!pml) {
905 return false;
907 if (p_request_time) {
908 *p_request_time = pml->request_time;
910 if (open_rec != NULL) {
911 *open_rec = pml->open_rec;
913 return true;
916 /****************************************************************************
917 Function to push a deferred open smb message onto a linked list of local smb
918 messages ready for processing.
919 ****************************************************************************/
921 bool push_deferred_open_message_smb(struct smb_request *req,
922 struct timeval request_time,
923 struct timeval timeout,
924 struct file_id id,
925 struct deferred_open_record *open_rec)
927 struct timeval end_time;
929 if (req->smb2req) {
930 return push_deferred_open_message_smb2(req->smb2req,
931 request_time,
932 timeout,
934 open_rec);
937 if (req->unread_bytes) {
938 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
939 "unread_bytes = %u\n",
940 (unsigned int)req->unread_bytes ));
941 smb_panic("push_deferred_open_message_smb: "
942 "logic error unread_bytes != 0" );
945 end_time = timeval_sum(&request_time, &timeout);
947 DEBUG(10,("push_deferred_open_message_smb: pushing message "
948 "len %u mid %llu timeout time [%u.%06u]\n",
949 (unsigned int) smb_len(req->inbuf)+4,
950 (unsigned long long)req->mid,
951 (unsigned int)end_time.tv_sec,
952 (unsigned int)end_time.tv_usec));
954 return push_queued_message(req, request_time, end_time, open_rec);
957 static void smbd_sig_term_handler(struct tevent_context *ev,
958 struct tevent_signal *se,
959 int signum,
960 int count,
961 void *siginfo,
962 void *private_data)
964 exit_server_cleanly("termination signal");
967 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
969 struct tevent_signal *se;
971 se = tevent_add_signal(sconn->ev_ctx,
972 sconn,
973 SIGTERM, 0,
974 smbd_sig_term_handler,
975 sconn);
976 if (!se) {
977 exit_server("failed to setup SIGTERM handler");
981 static void smbd_sig_hup_handler(struct tevent_context *ev,
982 struct tevent_signal *se,
983 int signum,
984 int count,
985 void *siginfo,
986 void *private_data)
988 struct smbd_server_connection *sconn =
989 talloc_get_type_abort(private_data,
990 struct smbd_server_connection);
992 change_to_root_user();
993 DEBUG(1,("Reloading services after SIGHUP\n"));
994 reload_services(sconn, conn_snum_used, false);
997 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
999 struct tevent_signal *se;
1001 se = tevent_add_signal(sconn->ev_ctx,
1002 sconn,
1003 SIGHUP, 0,
1004 smbd_sig_hup_handler,
1005 sconn);
1006 if (!se) {
1007 exit_server("failed to setup SIGHUP handler");
1011 static void smbd_conf_updated(struct messaging_context *msg,
1012 void *private_data,
1013 uint32_t msg_type,
1014 struct server_id server_id,
1015 DATA_BLOB *data)
1017 struct smbd_server_connection *sconn =
1018 talloc_get_type_abort(private_data,
1019 struct smbd_server_connection);
1021 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1022 "updated. Reloading.\n"));
1023 change_to_root_user();
1024 reload_services(sconn, conn_snum_used, false);
1028 * Only allow 5 outstanding trans requests. We're allocating memory, so
1029 * prevent a DoS.
1032 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1034 int count = 0;
1035 for (; list != NULL; list = list->next) {
1037 if (list->mid == mid) {
1038 return NT_STATUS_INVALID_PARAMETER;
1041 count += 1;
1043 if (count > 5) {
1044 return NT_STATUS_INSUFFICIENT_RESOURCES;
1047 return NT_STATUS_OK;
1051 These flags determine some of the permissions required to do an operation
1053 Note that I don't set NEED_WRITE on some write operations because they
1054 are used by some brain-dead clients when printing, and I don't want to
1055 force write permissions on print services.
1057 #define AS_USER (1<<0)
1058 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1059 #define TIME_INIT (1<<2)
1060 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1061 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1062 #define DO_CHDIR (1<<6)
1065 define a list of possible SMB messages and their corresponding
1066 functions. Any message that has a NULL function is unimplemented -
1067 please feel free to contribute implementations!
1069 static const struct smb_message_struct {
1070 const char *name;
1071 void (*fn)(struct smb_request *req);
1072 int flags;
1073 } smb_messages[256] = {
1075 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1076 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1077 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1078 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1079 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1080 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1081 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1082 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1083 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1084 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1085 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1086 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1087 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1088 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1089 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1090 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1091 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1092 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1093 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1094 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1095 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1096 /* 0x15 */ { NULL, NULL, 0 },
1097 /* 0x16 */ { NULL, NULL, 0 },
1098 /* 0x17 */ { NULL, NULL, 0 },
1099 /* 0x18 */ { NULL, NULL, 0 },
1100 /* 0x19 */ { NULL, NULL, 0 },
1101 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1102 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1103 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1104 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1105 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1106 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1107 /* 0x20 */ { "SMBwritec", NULL,0},
1108 /* 0x21 */ { NULL, NULL, 0 },
1109 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1110 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1111 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1112 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1113 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1114 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1115 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1116 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1117 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1118 /* 0x2b */ { "SMBecho",reply_echo,0},
1119 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1120 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1121 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1122 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1123 /* 0x30 */ { NULL, NULL, 0 },
1124 /* 0x31 */ { NULL, NULL, 0 },
1125 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1126 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1127 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1128 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1129 /* 0x36 */ { NULL, NULL, 0 },
1130 /* 0x37 */ { NULL, NULL, 0 },
1131 /* 0x38 */ { NULL, NULL, 0 },
1132 /* 0x39 */ { NULL, NULL, 0 },
1133 /* 0x3a */ { NULL, NULL, 0 },
1134 /* 0x3b */ { NULL, NULL, 0 },
1135 /* 0x3c */ { NULL, NULL, 0 },
1136 /* 0x3d */ { NULL, NULL, 0 },
1137 /* 0x3e */ { NULL, NULL, 0 },
1138 /* 0x3f */ { NULL, NULL, 0 },
1139 /* 0x40 */ { NULL, NULL, 0 },
1140 /* 0x41 */ { NULL, NULL, 0 },
1141 /* 0x42 */ { NULL, NULL, 0 },
1142 /* 0x43 */ { NULL, NULL, 0 },
1143 /* 0x44 */ { NULL, NULL, 0 },
1144 /* 0x45 */ { NULL, NULL, 0 },
1145 /* 0x46 */ { NULL, NULL, 0 },
1146 /* 0x47 */ { NULL, NULL, 0 },
1147 /* 0x48 */ { NULL, NULL, 0 },
1148 /* 0x49 */ { NULL, NULL, 0 },
1149 /* 0x4a */ { NULL, NULL, 0 },
1150 /* 0x4b */ { NULL, NULL, 0 },
1151 /* 0x4c */ { NULL, NULL, 0 },
1152 /* 0x4d */ { NULL, NULL, 0 },
1153 /* 0x4e */ { NULL, NULL, 0 },
1154 /* 0x4f */ { NULL, NULL, 0 },
1155 /* 0x50 */ { NULL, NULL, 0 },
1156 /* 0x51 */ { NULL, NULL, 0 },
1157 /* 0x52 */ { NULL, NULL, 0 },
1158 /* 0x53 */ { NULL, NULL, 0 },
1159 /* 0x54 */ { NULL, NULL, 0 },
1160 /* 0x55 */ { NULL, NULL, 0 },
1161 /* 0x56 */ { NULL, NULL, 0 },
1162 /* 0x57 */ { NULL, NULL, 0 },
1163 /* 0x58 */ { NULL, NULL, 0 },
1164 /* 0x59 */ { NULL, NULL, 0 },
1165 /* 0x5a */ { NULL, NULL, 0 },
1166 /* 0x5b */ { NULL, NULL, 0 },
1167 /* 0x5c */ { NULL, NULL, 0 },
1168 /* 0x5d */ { NULL, NULL, 0 },
1169 /* 0x5e */ { NULL, NULL, 0 },
1170 /* 0x5f */ { NULL, NULL, 0 },
1171 /* 0x60 */ { NULL, NULL, 0 },
1172 /* 0x61 */ { NULL, NULL, 0 },
1173 /* 0x62 */ { NULL, NULL, 0 },
1174 /* 0x63 */ { NULL, NULL, 0 },
1175 /* 0x64 */ { NULL, NULL, 0 },
1176 /* 0x65 */ { NULL, NULL, 0 },
1177 /* 0x66 */ { NULL, NULL, 0 },
1178 /* 0x67 */ { NULL, NULL, 0 },
1179 /* 0x68 */ { NULL, NULL, 0 },
1180 /* 0x69 */ { NULL, NULL, 0 },
1181 /* 0x6a */ { NULL, NULL, 0 },
1182 /* 0x6b */ { NULL, NULL, 0 },
1183 /* 0x6c */ { NULL, NULL, 0 },
1184 /* 0x6d */ { NULL, NULL, 0 },
1185 /* 0x6e */ { NULL, NULL, 0 },
1186 /* 0x6f */ { NULL, NULL, 0 },
1187 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1188 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1189 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1190 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1191 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1192 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1193 /* 0x76 */ { NULL, NULL, 0 },
1194 /* 0x77 */ { NULL, NULL, 0 },
1195 /* 0x78 */ { NULL, NULL, 0 },
1196 /* 0x79 */ { NULL, NULL, 0 },
1197 /* 0x7a */ { NULL, NULL, 0 },
1198 /* 0x7b */ { NULL, NULL, 0 },
1199 /* 0x7c */ { NULL, NULL, 0 },
1200 /* 0x7d */ { NULL, NULL, 0 },
1201 /* 0x7e */ { NULL, NULL, 0 },
1202 /* 0x7f */ { NULL, NULL, 0 },
1203 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1204 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1205 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1206 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1207 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1208 /* 0x85 */ { NULL, NULL, 0 },
1209 /* 0x86 */ { NULL, NULL, 0 },
1210 /* 0x87 */ { NULL, NULL, 0 },
1211 /* 0x88 */ { NULL, NULL, 0 },
1212 /* 0x89 */ { NULL, NULL, 0 },
1213 /* 0x8a */ { NULL, NULL, 0 },
1214 /* 0x8b */ { NULL, NULL, 0 },
1215 /* 0x8c */ { NULL, NULL, 0 },
1216 /* 0x8d */ { NULL, NULL, 0 },
1217 /* 0x8e */ { NULL, NULL, 0 },
1218 /* 0x8f */ { NULL, NULL, 0 },
1219 /* 0x90 */ { NULL, NULL, 0 },
1220 /* 0x91 */ { NULL, NULL, 0 },
1221 /* 0x92 */ { NULL, NULL, 0 },
1222 /* 0x93 */ { NULL, NULL, 0 },
1223 /* 0x94 */ { NULL, NULL, 0 },
1224 /* 0x95 */ { NULL, NULL, 0 },
1225 /* 0x96 */ { NULL, NULL, 0 },
1226 /* 0x97 */ { NULL, NULL, 0 },
1227 /* 0x98 */ { NULL, NULL, 0 },
1228 /* 0x99 */ { NULL, NULL, 0 },
1229 /* 0x9a */ { NULL, NULL, 0 },
1230 /* 0x9b */ { NULL, NULL, 0 },
1231 /* 0x9c */ { NULL, NULL, 0 },
1232 /* 0x9d */ { NULL, NULL, 0 },
1233 /* 0x9e */ { NULL, NULL, 0 },
1234 /* 0x9f */ { NULL, NULL, 0 },
1235 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1236 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1237 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1238 /* 0xa3 */ { NULL, NULL, 0 },
1239 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1240 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1241 /* 0xa6 */ { NULL, NULL, 0 },
1242 /* 0xa7 */ { NULL, NULL, 0 },
1243 /* 0xa8 */ { NULL, NULL, 0 },
1244 /* 0xa9 */ { NULL, NULL, 0 },
1245 /* 0xaa */ { NULL, NULL, 0 },
1246 /* 0xab */ { NULL, NULL, 0 },
1247 /* 0xac */ { NULL, NULL, 0 },
1248 /* 0xad */ { NULL, NULL, 0 },
1249 /* 0xae */ { NULL, NULL, 0 },
1250 /* 0xaf */ { NULL, NULL, 0 },
1251 /* 0xb0 */ { NULL, NULL, 0 },
1252 /* 0xb1 */ { NULL, NULL, 0 },
1253 /* 0xb2 */ { NULL, NULL, 0 },
1254 /* 0xb3 */ { NULL, NULL, 0 },
1255 /* 0xb4 */ { NULL, NULL, 0 },
1256 /* 0xb5 */ { NULL, NULL, 0 },
1257 /* 0xb6 */ { NULL, NULL, 0 },
1258 /* 0xb7 */ { NULL, NULL, 0 },
1259 /* 0xb8 */ { NULL, NULL, 0 },
1260 /* 0xb9 */ { NULL, NULL, 0 },
1261 /* 0xba */ { NULL, NULL, 0 },
1262 /* 0xbb */ { NULL, NULL, 0 },
1263 /* 0xbc */ { NULL, NULL, 0 },
1264 /* 0xbd */ { NULL, NULL, 0 },
1265 /* 0xbe */ { NULL, NULL, 0 },
1266 /* 0xbf */ { NULL, NULL, 0 },
1267 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1268 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1269 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1270 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1271 /* 0xc4 */ { NULL, NULL, 0 },
1272 /* 0xc5 */ { NULL, NULL, 0 },
1273 /* 0xc6 */ { NULL, NULL, 0 },
1274 /* 0xc7 */ { NULL, NULL, 0 },
1275 /* 0xc8 */ { NULL, NULL, 0 },
1276 /* 0xc9 */ { NULL, NULL, 0 },
1277 /* 0xca */ { NULL, NULL, 0 },
1278 /* 0xcb */ { NULL, NULL, 0 },
1279 /* 0xcc */ { NULL, NULL, 0 },
1280 /* 0xcd */ { NULL, NULL, 0 },
1281 /* 0xce */ { NULL, NULL, 0 },
1282 /* 0xcf */ { NULL, NULL, 0 },
1283 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1284 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1285 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1286 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1287 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1288 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1289 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1290 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1291 /* 0xd8 */ { NULL, NULL, 0 },
1292 /* 0xd9 */ { NULL, NULL, 0 },
1293 /* 0xda */ { NULL, NULL, 0 },
1294 /* 0xdb */ { NULL, NULL, 0 },
1295 /* 0xdc */ { NULL, NULL, 0 },
1296 /* 0xdd */ { NULL, NULL, 0 },
1297 /* 0xde */ { NULL, NULL, 0 },
1298 /* 0xdf */ { NULL, NULL, 0 },
1299 /* 0xe0 */ { NULL, NULL, 0 },
1300 /* 0xe1 */ { NULL, NULL, 0 },
1301 /* 0xe2 */ { NULL, NULL, 0 },
1302 /* 0xe3 */ { NULL, NULL, 0 },
1303 /* 0xe4 */ { NULL, NULL, 0 },
1304 /* 0xe5 */ { NULL, NULL, 0 },
1305 /* 0xe6 */ { NULL, NULL, 0 },
1306 /* 0xe7 */ { NULL, NULL, 0 },
1307 /* 0xe8 */ { NULL, NULL, 0 },
1308 /* 0xe9 */ { NULL, NULL, 0 },
1309 /* 0xea */ { NULL, NULL, 0 },
1310 /* 0xeb */ { NULL, NULL, 0 },
1311 /* 0xec */ { NULL, NULL, 0 },
1312 /* 0xed */ { NULL, NULL, 0 },
1313 /* 0xee */ { NULL, NULL, 0 },
1314 /* 0xef */ { NULL, NULL, 0 },
1315 /* 0xf0 */ { NULL, NULL, 0 },
1316 /* 0xf1 */ { NULL, NULL, 0 },
1317 /* 0xf2 */ { NULL, NULL, 0 },
1318 /* 0xf3 */ { NULL, NULL, 0 },
1319 /* 0xf4 */ { NULL, NULL, 0 },
1320 /* 0xf5 */ { NULL, NULL, 0 },
1321 /* 0xf6 */ { NULL, NULL, 0 },
1322 /* 0xf7 */ { NULL, NULL, 0 },
1323 /* 0xf8 */ { NULL, NULL, 0 },
1324 /* 0xf9 */ { NULL, NULL, 0 },
1325 /* 0xfa */ { NULL, NULL, 0 },
1326 /* 0xfb */ { NULL, NULL, 0 },
1327 /* 0xfc */ { NULL, NULL, 0 },
1328 /* 0xfd */ { NULL, NULL, 0 },
1329 /* 0xfe */ { NULL, NULL, 0 },
1330 /* 0xff */ { NULL, NULL, 0 }
1334 /*******************************************************************
1335 allocate and initialize a reply packet
1336 ********************************************************************/
1338 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1339 const char *inbuf, char **outbuf, uint8_t num_words,
1340 uint32_t num_bytes)
1342 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1345 * Protect against integer wrap.
1346 * The SMB layer reply can be up to 0xFFFFFF bytes.
1348 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1349 char *msg;
1350 if (asprintf(&msg, "num_bytes too large: %u",
1351 (unsigned)num_bytes) == -1) {
1352 msg = discard_const_p(char, "num_bytes too large");
1354 smb_panic(msg);
1358 * Here we include the NBT header for now.
1360 *outbuf = talloc_array(mem_ctx, char,
1361 NBT_HDR_SIZE + smb_len);
1362 if (*outbuf == NULL) {
1363 return false;
1366 construct_reply_common(req, inbuf, *outbuf);
1367 srv_set_message(*outbuf, num_words, num_bytes, false);
1369 * Zero out the word area, the caller has to take care of the bcc area
1370 * himself
1372 if (num_words != 0) {
1373 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1376 return true;
1379 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1381 char *outbuf;
1382 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1383 num_bytes)) {
1384 smb_panic("could not allocate output buffer\n");
1386 req->outbuf = (uint8_t *)outbuf;
1390 /*******************************************************************
1391 Dump a packet to a file.
1392 ********************************************************************/
1394 static void smb_dump(const char *name, int type, const char *data)
1396 size_t len;
1397 int fd, i;
1398 char *fname = NULL;
1399 if (DEBUGLEVEL < 50) {
1400 return;
1403 len = smb_len_tcp(data)+4;
1404 for (i=1;i<100;i++) {
1405 fname = talloc_asprintf(talloc_tos(),
1406 "/tmp/%s.%d.%s",
1407 name,
1409 type ? "req" : "resp");
1410 if (fname == NULL) {
1411 return;
1413 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1414 if (fd != -1 || errno != EEXIST) break;
1415 TALLOC_FREE(fname);
1417 if (fd != -1) {
1418 ssize_t ret = write(fd, data, len);
1419 if (ret != len)
1420 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1421 close(fd);
1422 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1424 TALLOC_FREE(fname);
1427 /****************************************************************************
1428 Prepare everything for calling the actual request function, and potentially
1429 call the request function via the "new" interface.
1431 Return False if the "legacy" function needs to be called, everything is
1432 prepared.
1434 Return True if we're done.
1436 I know this API sucks, but it is the one with the least code change I could
1437 find.
1438 ****************************************************************************/
1440 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1442 int flags;
1443 uint64_t session_tag;
1444 connection_struct *conn = NULL;
1445 struct smbd_server_connection *sconn = req->sconn;
1446 NTTIME now = timeval_to_nttime(&req->request_time);
1447 struct smbXsrv_session *session = NULL;
1448 NTSTATUS status;
1450 errno = 0;
1452 if (smb_messages[type].fn == NULL) {
1453 DEBUG(0,("Unknown message type %d!\n",type));
1454 smb_dump("Unknown", 1, (const char *)req->inbuf);
1455 reply_unknown_new(req, type);
1456 return NULL;
1459 flags = smb_messages[type].flags;
1461 /* In share mode security we must ignore the vuid. */
1462 session_tag = req->vuid;
1463 conn = req->conn;
1465 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1466 (int)getpid(), (unsigned long)conn));
1468 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1470 /* Ensure this value is replaced in the incoming packet. */
1471 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1474 * Ensure the correct username is in current_user_info. This is a
1475 * really ugly bugfix for problems with multiple session_setup_and_X's
1476 * being done and allowing %U and %G substitutions to work correctly.
1477 * There is a reason this code is done here, don't move it unless you
1478 * know what you're doing... :-).
1479 * JRA.
1483 * lookup an existing session
1485 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1486 * here, the main check is still in change_to_user()
1488 status = smb1srv_session_lookup(sconn->conn,
1489 session_tag,
1490 now,
1491 &session);
1492 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1493 switch (type) {
1494 case SMBsesssetupX:
1495 status = NT_STATUS_OK;
1496 break;
1497 default:
1498 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1499 (unsigned long long)session_tag,
1500 (unsigned long long)req->mid));
1501 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1502 return conn;
1506 if (session_tag != sconn->conn->last_session_id) {
1507 struct user_struct *vuser = NULL;
1509 sconn->conn->last_session_id = session_tag;
1510 if (session) {
1511 vuser = session->compat;
1513 if (vuser) {
1514 set_current_user_info(
1515 vuser->session_info->unix_info->sanitized_username,
1516 vuser->session_info->unix_info->unix_name,
1517 vuser->session_info->info->domain_name);
1521 /* Does this call need to be run as the connected user? */
1522 if (flags & AS_USER) {
1524 /* Does this call need a valid tree connection? */
1525 if (!conn) {
1527 * Amazingly, the error code depends on the command
1528 * (from Samba4).
1530 if (type == SMBntcreateX) {
1531 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1532 } else {
1533 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1535 return NULL;
1538 if (!change_to_user(conn,session_tag)) {
1539 DEBUG(0, ("Error: Could not change to user. Removing "
1540 "deferred open, mid=%llu.\n",
1541 (unsigned long long)req->mid));
1542 reply_force_doserror(req, ERRSRV, ERRbaduid);
1543 return conn;
1546 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1548 /* Does it need write permission? */
1549 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1550 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1551 return conn;
1554 /* IPC services are limited */
1555 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1556 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1557 return conn;
1559 } else {
1560 /* This call needs to be run as root */
1561 change_to_root_user();
1564 /* load service specific parameters */
1565 if (conn) {
1566 if (req->encrypted) {
1567 conn->encrypted_tid = true;
1568 /* encrypted required from now on. */
1569 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1570 } else if (ENCRYPTION_REQUIRED(conn)) {
1571 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1572 DEBUG(1,("service[%s] requires encryption"
1573 "%s ACCESS_DENIED. mid=%llu\n",
1574 lp_servicename(talloc_tos(), SNUM(conn)),
1575 smb_fn_name(type),
1576 (unsigned long long)req->mid));
1577 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1578 return conn;
1582 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1583 (flags & (AS_USER|DO_CHDIR)
1584 ?True:False))) {
1585 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1586 return conn;
1588 conn->num_smb_operations++;
1592 * Does this protocol need to be run as guest? (Only archane
1593 * messenger service requests have this...)
1595 if (flags & AS_GUEST) {
1596 char *raddr;
1597 bool ok;
1599 if (!change_to_guest()) {
1600 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1601 return conn;
1604 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1605 talloc_tos());
1606 if (raddr == NULL) {
1607 reply_nterror(req, NT_STATUS_NO_MEMORY);
1608 return conn;
1612 * Haven't we checked this in smbd_process already???
1615 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1616 sconn->remote_hostname, raddr);
1617 TALLOC_FREE(raddr);
1619 if (!ok) {
1620 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1621 return conn;
1625 smb_messages[type].fn(req);
1626 return req->conn;
1629 /****************************************************************************
1630 Construct a reply to the incoming packet.
1631 ****************************************************************************/
1633 static void construct_reply(struct smbd_server_connection *sconn,
1634 char *inbuf, int size, size_t unread_bytes,
1635 uint32_t seqnum, bool encrypted,
1636 struct smb_perfcount_data *deferred_pcd)
1638 connection_struct *conn;
1639 struct smb_request *req;
1641 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1642 smb_panic("could not allocate smb_request");
1645 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1646 encrypted, seqnum)) {
1647 exit_server_cleanly("Invalid SMB request");
1650 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1652 /* we popped this message off the queue - keep original perf data */
1653 if (deferred_pcd)
1654 req->pcd = *deferred_pcd;
1655 else {
1656 SMB_PERFCOUNT_START(&req->pcd);
1657 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1658 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1661 conn = switch_message(req->cmd, req);
1663 if (req->outbuf == NULL) {
1664 return;
1667 if (CVAL(req->outbuf,0) == 0) {
1668 show_msg((char *)req->outbuf);
1671 if (!srv_send_smb(req->sconn,
1672 (char *)req->outbuf,
1673 true, req->seqnum+1,
1674 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1675 &req->pcd)) {
1676 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1679 TALLOC_FREE(req);
1681 return;
1684 static void construct_reply_chain(struct smbd_server_connection *sconn,
1685 char *inbuf, int size, uint32_t seqnum,
1686 bool encrypted,
1687 struct smb_perfcount_data *deferred_pcd)
1689 struct smb_request **reqs = NULL;
1690 struct smb_request *req;
1691 unsigned num_reqs;
1692 bool ok;
1694 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1695 seqnum, &reqs, &num_reqs);
1696 if (!ok) {
1697 char errbuf[smb_size];
1698 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1699 __LINE__, __FILE__);
1700 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1701 NULL)) {
1702 exit_server_cleanly("construct_reply_chain: "
1703 "srv_send_smb failed.");
1705 return;
1708 req = reqs[0];
1709 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1711 req->conn = switch_message(req->cmd, req);
1713 if (req->outbuf == NULL) {
1715 * Request has suspended itself, will come
1716 * back here.
1718 return;
1720 smb_request_done(req);
1724 * To be called from an async SMB handler that is potentially chained
1725 * when it is finished for shipping.
1728 void smb_request_done(struct smb_request *req)
1730 struct smb_request **reqs = NULL;
1731 struct smb_request *first_req;
1732 size_t i, num_reqs, next_index;
1733 NTSTATUS status;
1735 if (req->chain == NULL) {
1736 first_req = req;
1737 goto shipit;
1740 reqs = req->chain;
1741 num_reqs = talloc_array_length(reqs);
1743 for (i=0; i<num_reqs; i++) {
1744 if (reqs[i] == req) {
1745 break;
1748 if (i == num_reqs) {
1750 * Invalid chain, should not happen
1752 status = NT_STATUS_INTERNAL_ERROR;
1753 goto error;
1755 next_index = i+1;
1757 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1758 struct smb_request *next = reqs[next_index];
1759 struct smbXsrv_tcon *tcon;
1760 NTTIME now = timeval_to_nttime(&req->request_time);
1762 next->vuid = SVAL(req->outbuf, smb_uid);
1763 next->tid = SVAL(req->outbuf, smb_tid);
1764 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1765 now, &tcon);
1766 if (NT_STATUS_IS_OK(status)) {
1767 req->conn = tcon->compat;
1768 } else {
1769 req->conn = NULL;
1771 next->chain_fsp = req->chain_fsp;
1772 next->inbuf = req->inbuf;
1774 req = next;
1775 req->conn = switch_message(req->cmd, req);
1777 if (req->outbuf == NULL) {
1779 * Request has suspended itself, will come
1780 * back here.
1782 return;
1784 next_index += 1;
1787 first_req = reqs[0];
1789 for (i=1; i<next_index; i++) {
1790 bool ok;
1792 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1793 if (!ok) {
1794 status = NT_STATUS_INTERNAL_ERROR;
1795 goto error;
1799 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1800 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1803 * This scary statement intends to set the
1804 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1805 * to the value last_req->outbuf carries
1807 SSVAL(first_req->outbuf, smb_flg2,
1808 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1809 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1812 * Transfer the error codes from the subrequest to the main one
1814 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1815 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1817 _smb_setlen_large(
1818 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1820 shipit:
1821 if (!srv_send_smb(first_req->sconn,
1822 (char *)first_req->outbuf,
1823 true, first_req->seqnum+1,
1824 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1825 &first_req->pcd)) {
1826 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1827 "failed.");
1829 TALLOC_FREE(req); /* non-chained case */
1830 TALLOC_FREE(reqs); /* chained case */
1831 return;
1833 error:
1835 char errbuf[smb_size];
1836 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1837 if (!srv_send_smb(req->sconn, errbuf, true,
1838 req->seqnum+1, req->encrypted,
1839 NULL)) {
1840 exit_server_cleanly("construct_reply_chain: "
1841 "srv_send_smb failed.");
1844 TALLOC_FREE(req); /* non-chained case */
1845 TALLOC_FREE(reqs); /* chained case */
1848 /****************************************************************************
1849 Process an smb from the client
1850 ****************************************************************************/
1851 static void process_smb(struct smbd_server_connection *sconn,
1852 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1853 uint32_t seqnum, bool encrypted,
1854 struct smb_perfcount_data *deferred_pcd)
1856 int msg_type = CVAL(inbuf,0);
1858 DO_PROFILE_INC(smb_count);
1860 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1861 smb_len(inbuf) ) );
1862 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1863 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1865 if (msg_type != NBSSmessage) {
1867 * NetBIOS session request, keepalive, etc.
1869 reply_special(sconn, (char *)inbuf, nread);
1870 goto done;
1873 if (sconn->using_smb2) {
1874 /* At this point we're not really using smb2,
1875 * we make the decision here.. */
1876 if (smbd_is_smb2_header(inbuf, nread)) {
1877 smbd_smb2_first_negprot(sconn, inbuf, nread);
1878 return;
1879 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1880 && CVAL(inbuf, smb_com) != 0x72) {
1881 /* This is a non-negprot SMB1 packet.
1882 Disable SMB2 from now on. */
1883 sconn->using_smb2 = false;
1887 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1888 * so subtract 4 from it. */
1889 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1890 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1891 smb_len(inbuf)));
1893 /* special magic for immediate exit */
1894 if ((nread == 9) &&
1895 (IVAL(inbuf, 4) == 0x74697865) &&
1896 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1897 uint8_t exitcode = CVAL(inbuf, 8);
1898 DEBUG(1, ("Exiting immediately with code %d\n",
1899 (int)exitcode));
1900 exit(exitcode);
1903 exit_server_cleanly("Non-SMB packet");
1906 show_msg((char *)inbuf);
1908 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1909 construct_reply_chain(sconn, (char *)inbuf, nread,
1910 seqnum, encrypted, deferred_pcd);
1911 } else {
1912 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1913 seqnum, encrypted, deferred_pcd);
1916 sconn->trans_num++;
1918 done:
1919 sconn->num_requests++;
1921 /* The timeout_processing function isn't run nearly
1922 often enough to implement 'max log size' without
1923 overrunning the size of the file by many megabytes.
1924 This is especially true if we are running at debug
1925 level 10. Checking every 50 SMBs is a nice
1926 tradeoff of performance vs log file size overrun. */
1928 if ((sconn->num_requests % 50) == 0 &&
1929 need_to_check_log_size()) {
1930 change_to_root_user();
1931 check_log_size();
1935 /****************************************************************************
1936 Return a string containing the function name of a SMB command.
1937 ****************************************************************************/
1939 const char *smb_fn_name(int type)
1941 const char *unknown_name = "SMBunknown";
1943 if (smb_messages[type].name == NULL)
1944 return(unknown_name);
1946 return(smb_messages[type].name);
1949 /****************************************************************************
1950 Helper functions for contruct_reply.
1951 ****************************************************************************/
1953 void add_to_common_flags2(uint32 v)
1955 common_flags2 |= v;
1958 void remove_from_common_flags2(uint32 v)
1960 common_flags2 &= ~v;
1963 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1964 char *outbuf)
1966 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1967 uint16_t out_flags2 = common_flags2;
1969 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1970 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1971 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1973 srv_set_message(outbuf,0,0,false);
1975 SCVAL(outbuf, smb_com, req->cmd);
1976 SIVAL(outbuf,smb_rcls,0);
1977 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1978 SSVAL(outbuf,smb_flg2, out_flags2);
1979 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1980 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1982 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1983 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1984 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1985 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1988 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1990 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1994 * @brief Find the smb_cmd offset of the last command pushed
1995 * @param[in] buf The buffer we're building up
1996 * @retval Where can we put our next andx cmd?
1998 * While chaining requests, the "next" request we're looking at needs to put
1999 * its SMB_Command before the data the previous request already built up added
2000 * to the chain. Find the offset to the place where we have to put our cmd.
2003 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2005 uint8_t cmd;
2006 size_t ofs;
2008 cmd = CVAL(buf, smb_com);
2010 if (!is_andx_req(cmd)) {
2011 return false;
2014 ofs = smb_vwv0;
2016 while (CVAL(buf, ofs) != 0xff) {
2018 if (!is_andx_req(CVAL(buf, ofs))) {
2019 return false;
2023 * ofs is from start of smb header, so add the 4 length
2024 * bytes. The next cmd is right after the wct field.
2026 ofs = SVAL(buf, ofs+2) + 4 + 1;
2028 if (ofs+4 >= talloc_get_size(buf)) {
2029 return false;
2033 *pofs = ofs;
2034 return true;
2038 * @brief Do the smb chaining at a buffer level
2039 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2040 * @param[in] andx_buf Buffer to be appended
2043 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2045 uint8_t smb_command = CVAL(andx_buf, smb_com);
2046 uint8_t wct = CVAL(andx_buf, smb_wct);
2047 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2048 uint32_t num_bytes = smb_buflen(andx_buf);
2049 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2051 uint8_t *outbuf;
2052 size_t old_size, new_size;
2053 size_t ofs;
2054 size_t chain_padding = 0;
2055 size_t andx_cmd_ofs;
2058 old_size = talloc_get_size(*poutbuf);
2060 if ((old_size % 4) != 0) {
2062 * Align the wct field of subsequent requests to a 4-byte
2063 * boundary
2065 chain_padding = 4 - (old_size % 4);
2069 * After the old request comes the new wct field (1 byte), the vwv's
2070 * and the num_bytes field.
2073 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2074 new_size += num_bytes;
2076 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2077 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2078 (unsigned)new_size));
2079 return false;
2082 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2083 if (outbuf == NULL) {
2084 DEBUG(0, ("talloc failed\n"));
2085 return false;
2087 *poutbuf = outbuf;
2089 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2090 DEBUG(1, ("invalid command chain\n"));
2091 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2092 return false;
2095 if (chain_padding != 0) {
2096 memset(outbuf + old_size, 0, chain_padding);
2097 old_size += chain_padding;
2100 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2101 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2103 ofs = old_size;
2106 * Push the chained request:
2108 * wct field
2111 SCVAL(outbuf, ofs, wct);
2112 ofs += 1;
2115 * vwv array
2118 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2121 * HACK ALERT
2123 * Read&X has an offset into its data buffer at
2124 * vwv[6]. reply_read_andx has no idea anymore that it's
2125 * running from within a chain, so we have to fix up the
2126 * offset here.
2128 * Although it looks disgusting at this place, I want to keep
2129 * it here. The alternative would be to push knowledge about
2130 * the andx chain down into read&x again.
2133 if (smb_command == SMBreadX) {
2134 uint8_t *bytes_addr;
2136 if (wct < 7) {
2138 * Invalid read&x response
2140 return false;
2143 bytes_addr = outbuf + ofs /* vwv start */
2144 + sizeof(uint16_t) * wct /* vwv array */
2145 + sizeof(uint16_t); /* bcc */
2147 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2148 bytes_addr - outbuf - 4);
2151 ofs += sizeof(uint16_t) * wct;
2154 * bcc (byte count)
2157 SSVAL(outbuf, ofs, num_bytes);
2158 ofs += sizeof(uint16_t);
2161 * The bytes field
2164 memcpy(outbuf + ofs, bytes, num_bytes);
2166 return true;
2169 bool smb1_is_chain(const uint8_t *buf)
2171 uint8_t cmd, wct, andx_cmd;
2173 cmd = CVAL(buf, smb_com);
2174 if (!is_andx_req(cmd)) {
2175 return false;
2177 wct = CVAL(buf, smb_wct);
2178 if (wct < 2) {
2179 return false;
2181 andx_cmd = CVAL(buf, smb_vwv);
2182 return (andx_cmd != 0xFF);
2185 bool smb1_walk_chain(const uint8_t *buf,
2186 bool (*fn)(uint8_t cmd,
2187 uint8_t wct, const uint16_t *vwv,
2188 uint16_t num_bytes, const uint8_t *bytes,
2189 void *private_data),
2190 void *private_data)
2192 size_t smblen = smb_len(buf);
2193 const char *smb_buf = smb_base(buf);
2194 uint8_t cmd, chain_cmd;
2195 uint8_t wct;
2196 const uint16_t *vwv;
2197 uint16_t num_bytes;
2198 const uint8_t *bytes;
2200 cmd = CVAL(buf, smb_com);
2201 wct = CVAL(buf, smb_wct);
2202 vwv = (const uint16_t *)(buf + smb_vwv);
2203 num_bytes = smb_buflen(buf);
2204 bytes = (const uint8_t *)smb_buf_const(buf);
2206 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2207 return false;
2210 if (!is_andx_req(cmd)) {
2211 return true;
2213 if (wct < 2) {
2214 return false;
2217 chain_cmd = CVAL(vwv, 0);
2219 while (chain_cmd != 0xff) {
2220 uint32_t chain_offset; /* uint32_t to avoid overflow */
2221 size_t length_needed;
2222 ptrdiff_t vwv_offset;
2224 chain_offset = SVAL(vwv+1, 0);
2227 * Check if the client tries to fool us. The chain
2228 * offset needs to point beyond the current request in
2229 * the chain, it needs to strictly grow. Otherwise we
2230 * might be tricked into an endless loop always
2231 * processing the same request over and over again. We
2232 * used to assume that vwv and the byte buffer array
2233 * in a chain are always attached, but OS/2 the
2234 * Write&X/Read&X chain puts the Read&X vwv array
2235 * right behind the Write&X vwv chain. The Write&X bcc
2236 * array is put behind the Read&X vwv array. So now we
2237 * check whether the chain offset points strictly
2238 * behind the previous vwv array. req->buf points
2239 * right after the vwv array of the previous
2240 * request. See
2241 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2242 * more information.
2245 vwv_offset = ((const char *)vwv - smb_buf);
2246 if (chain_offset <= vwv_offset) {
2247 return false;
2251 * Next check: Make sure the chain offset does not
2252 * point beyond the overall smb request length.
2255 length_needed = chain_offset+1; /* wct */
2256 if (length_needed > smblen) {
2257 return false;
2261 * Now comes the pointer magic. Goal here is to set up
2262 * vwv and buf correctly again. The chain offset (the
2263 * former vwv[1]) points at the new wct field.
2266 wct = CVAL(smb_buf, chain_offset);
2268 if (is_andx_req(chain_cmd) && (wct < 2)) {
2269 return false;
2273 * Next consistency check: Make the new vwv array fits
2274 * in the overall smb request.
2277 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2278 if (length_needed > smblen) {
2279 return false;
2281 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2284 * Now grab the new byte buffer....
2287 num_bytes = SVAL(vwv+wct, 0);
2290 * .. and check that it fits.
2293 length_needed += num_bytes;
2294 if (length_needed > smblen) {
2295 return false;
2297 bytes = (const uint8_t *)(vwv+wct+1);
2299 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2300 return false;
2303 if (!is_andx_req(chain_cmd)) {
2304 return true;
2306 chain_cmd = CVAL(vwv, 0);
2308 return true;
2311 static bool smb1_chain_length_cb(uint8_t cmd,
2312 uint8_t wct, const uint16_t *vwv,
2313 uint16_t num_bytes, const uint8_t *bytes,
2314 void *private_data)
2316 unsigned *count = (unsigned *)private_data;
2317 *count += 1;
2318 return true;
2321 unsigned smb1_chain_length(const uint8_t *buf)
2323 unsigned count = 0;
2325 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2326 return 0;
2328 return count;
2331 struct smb1_parse_chain_state {
2332 TALLOC_CTX *mem_ctx;
2333 const uint8_t *buf;
2334 struct smbd_server_connection *sconn;
2335 bool encrypted;
2336 uint32_t seqnum;
2338 struct smb_request **reqs;
2339 unsigned num_reqs;
2342 static bool smb1_parse_chain_cb(uint8_t cmd,
2343 uint8_t wct, const uint16_t *vwv,
2344 uint16_t num_bytes, const uint8_t *bytes,
2345 void *private_data)
2347 struct smb1_parse_chain_state *state =
2348 (struct smb1_parse_chain_state *)private_data;
2349 struct smb_request **reqs;
2350 struct smb_request *req;
2351 bool ok;
2353 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2354 struct smb_request *, state->num_reqs+1);
2355 if (reqs == NULL) {
2356 return false;
2358 state->reqs = reqs;
2360 req = talloc(reqs, struct smb_request);
2361 if (req == NULL) {
2362 return false;
2365 ok = init_smb_request(req, state->sconn, state->buf, 0,
2366 state->encrypted, state->seqnum);
2367 if (!ok) {
2368 return false;
2370 req->cmd = cmd;
2371 req->wct = wct;
2372 req->vwv = vwv;
2373 req->buflen = num_bytes;
2374 req->buf = bytes;
2376 reqs[state->num_reqs] = req;
2377 state->num_reqs += 1;
2378 return true;
2381 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2382 struct smbd_server_connection *sconn,
2383 bool encrypted, uint32_t seqnum,
2384 struct smb_request ***reqs, unsigned *num_reqs)
2386 struct smb1_parse_chain_state state;
2387 unsigned i;
2389 state.mem_ctx = mem_ctx;
2390 state.buf = buf;
2391 state.sconn = sconn;
2392 state.encrypted = encrypted;
2393 state.seqnum = seqnum;
2394 state.reqs = NULL;
2395 state.num_reqs = 0;
2397 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2398 TALLOC_FREE(state.reqs);
2399 return false;
2401 for (i=0; i<state.num_reqs; i++) {
2402 state.reqs[i]->chain = state.reqs;
2404 *reqs = state.reqs;
2405 *num_reqs = state.num_reqs;
2406 return true;
2409 /****************************************************************************
2410 Check if services need reloading.
2411 ****************************************************************************/
2413 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2416 if (last_smb_conf_reload_time == 0) {
2417 last_smb_conf_reload_time = t;
2420 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2421 reload_services(sconn, conn_snum_used, true);
2422 last_smb_conf_reload_time = t;
2426 static bool fd_is_readable(int fd)
2428 int ret, revents;
2430 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2432 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2436 static void smbd_server_connection_write_handler(
2437 struct smbd_server_connection *sconn)
2439 /* TODO: make write nonblocking */
2442 static void smbd_server_connection_read_handler(
2443 struct smbd_server_connection *sconn, int fd)
2445 struct smbXsrv_connection *xconn = sconn->conn;
2446 uint8_t *inbuf = NULL;
2447 size_t inbuf_len = 0;
2448 size_t unread_bytes = 0;
2449 bool encrypted = false;
2450 TALLOC_CTX *mem_ctx = talloc_tos();
2451 NTSTATUS status;
2452 uint32_t seqnum;
2454 bool async_echo = lp_async_smb_echo_handler();
2455 bool from_client = false;
2457 if (async_echo) {
2458 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2460 * This is the super-ugly hack to prefer the packets
2461 * forwarded by the echo handler over the ones by the
2462 * client directly
2464 fd = sconn->smb1.echo_handler.trusted_fd;
2468 from_client = (xconn->transport.sock == fd);
2470 if (async_echo && from_client) {
2471 smbd_lock_socket(sconn);
2473 if (!fd_is_readable(fd)) {
2474 DEBUG(10,("the echo listener was faster\n"));
2475 smbd_unlock_socket(sconn);
2476 return;
2480 /* TODO: make this completely nonblocking */
2481 status = receive_smb_talloc(mem_ctx, sconn, fd,
2482 (char **)(void *)&inbuf,
2483 0, /* timeout */
2484 &unread_bytes,
2485 &encrypted,
2486 &inbuf_len, &seqnum,
2487 !from_client /* trusted channel */);
2489 if (async_echo && from_client) {
2490 smbd_unlock_socket(sconn);
2493 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2494 goto process;
2496 if (NT_STATUS_IS_ERR(status)) {
2497 exit_server_cleanly("failed to receive smb request");
2499 if (!NT_STATUS_IS_OK(status)) {
2500 return;
2503 process:
2504 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2505 seqnum, encrypted, NULL);
2508 static void smbd_server_connection_handler(struct tevent_context *ev,
2509 struct tevent_fd *fde,
2510 uint16_t flags,
2511 void *private_data)
2513 struct smbd_server_connection *conn = talloc_get_type(private_data,
2514 struct smbd_server_connection);
2515 struct smbXsrv_connection *xconn = conn->conn;
2517 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2519 * we're not supposed to do any io
2521 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2522 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2523 return;
2526 if (flags & TEVENT_FD_WRITE) {
2527 smbd_server_connection_write_handler(conn);
2528 return;
2530 if (flags & TEVENT_FD_READ) {
2531 smbd_server_connection_read_handler(conn, xconn->transport.sock);
2532 return;
2536 static void smbd_server_echo_handler(struct tevent_context *ev,
2537 struct tevent_fd *fde,
2538 uint16_t flags,
2539 void *private_data)
2541 struct smbd_server_connection *conn = talloc_get_type(private_data,
2542 struct smbd_server_connection);
2543 struct smbXsrv_connection *xconn = conn->conn;
2545 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2547 * we're not supposed to do any io
2549 TEVENT_FD_NOT_READABLE(conn->smb1.echo_handler.trusted_fde);
2550 TEVENT_FD_NOT_WRITEABLE(conn->smb1.echo_handler.trusted_fde);
2551 return;
2554 if (flags & TEVENT_FD_WRITE) {
2555 smbd_server_connection_write_handler(conn);
2556 return;
2558 if (flags & TEVENT_FD_READ) {
2559 smbd_server_connection_read_handler(
2560 conn, conn->smb1.echo_handler.trusted_fd);
2561 return;
2565 struct smbd_release_ip_state {
2566 struct smbd_server_connection *sconn;
2567 struct tevent_immediate *im;
2568 char addr[INET6_ADDRSTRLEN];
2571 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2572 struct tevent_immediate *im,
2573 void *private_data)
2575 struct smbd_release_ip_state *state =
2576 talloc_get_type_abort(private_data,
2577 struct smbd_release_ip_state);
2578 struct smbXsrv_connection *xconn = state->sconn->conn;
2580 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2582 * smbd_server_connection_terminate() already triggered ?
2584 return;
2587 smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
2590 /****************************************************************************
2591 received when we should release a specific IP
2592 ****************************************************************************/
2593 static bool release_ip(const char *ip, void *priv)
2595 struct smbd_release_ip_state *state =
2596 talloc_get_type_abort(priv,
2597 struct smbd_release_ip_state);
2598 struct smbXsrv_connection *xconn = state->sconn->conn;
2599 const char *addr = state->addr;
2600 const char *p = addr;
2602 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2603 /* avoid recursion */
2604 return false;
2607 if (strncmp("::ffff:", addr, 7) == 0) {
2608 p = addr + 7;
2611 DEBUG(10, ("Got release IP message for %s, "
2612 "our address is %s\n", ip, p));
2614 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2615 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2616 ip));
2618 * With SMB2 we should do a clean disconnect,
2619 * the previous_session_id in the session setup
2620 * will cleanup the old session, tcons and opens.
2622 * A clean disconnect is needed in order to support
2623 * durable handles.
2625 * Note: typically this is never triggered
2626 * as we got a TCP RST (triggered by ctdb event scripts)
2627 * before we get CTDB_SRVID_RELEASE_IP.
2629 * We used to call _exit(1) here, but as this was mostly never
2630 * triggered and has implication on our process model,
2631 * we can just use smbd_server_connection_terminate()
2632 * (also for SMB1).
2634 * We don't call smbd_server_connection_terminate() directly
2635 * as we might be called from within ctdbd_migrate(),
2636 * we need to defer our action to the next event loop
2638 tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
2639 smbd_release_ip_immediate, state);
2642 * Make sure we don't get any io on the connection.
2644 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2645 return true;
2648 return false;
2651 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2652 struct sockaddr_storage *srv,
2653 struct sockaddr_storage *clnt)
2655 struct smbd_release_ip_state *state;
2656 struct ctdbd_connection *cconn;
2658 cconn = messaging_ctdbd_connection();
2659 if (cconn == NULL) {
2660 return NT_STATUS_NO_MEMORY;
2663 state = talloc_zero(sconn, struct smbd_release_ip_state);
2664 if (state == NULL) {
2665 return NT_STATUS_NO_MEMORY;
2667 state->sconn = sconn;
2668 state->im = tevent_create_immediate(state);
2669 if (state->im == NULL) {
2670 return NT_STATUS_NO_MEMORY;
2672 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2673 return NT_STATUS_NO_MEMORY;
2676 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2679 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2680 void *private_data, uint32_t msg_type,
2681 struct server_id server_id, DATA_BLOB *data)
2683 struct smbd_server_connection *sconn = talloc_get_type_abort(
2684 private_data, struct smbd_server_connection);
2685 const char *ip = (char *) data->data;
2686 char *client_ip;
2688 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2690 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2691 talloc_tos());
2692 if (client_ip == NULL) {
2693 return;
2696 if (strequal(ip, client_ip)) {
2697 DEBUG(1, ("Got kill client message for %s - "
2698 "exiting immediately\n", ip));
2699 exit_server_cleanly("Forced disconnect for client");
2702 TALLOC_FREE(client_ip);
2706 * Send keepalive packets to our client
2708 static bool keepalive_fn(const struct timeval *now, void *private_data)
2710 struct smbd_server_connection *sconn = talloc_get_type_abort(
2711 private_data, struct smbd_server_connection);
2712 struct smbXsrv_connection *xconn = sconn->conn;
2713 bool ret;
2715 if (sconn->using_smb2) {
2716 /* Don't do keepalives on an SMB2 connection. */
2717 return false;
2720 smbd_lock_socket(sconn);
2721 ret = send_keepalive(xconn->transport.sock);
2722 smbd_unlock_socket(sconn);
2724 if (!ret) {
2725 int saved_errno = errno;
2727 * Try and give an error message saying what
2728 * client failed.
2730 DEBUG(0, ("send_keepalive failed for client %s. "
2731 "Error %s - exiting\n",
2732 smbXsrv_connection_dbg(xconn),
2733 strerror(saved_errno)));
2734 errno = saved_errno;
2735 return False;
2737 return True;
2741 * Do the recurring check if we're idle
2743 static bool deadtime_fn(const struct timeval *now, void *private_data)
2745 struct smbd_server_connection *sconn =
2746 (struct smbd_server_connection *)private_data;
2748 if ((conn_num_open(sconn) == 0)
2749 || (conn_idle_all(sconn, now->tv_sec))) {
2750 DEBUG( 2, ( "Closing idle connection\n" ) );
2751 messaging_send(sconn->msg_ctx,
2752 messaging_server_id(sconn->msg_ctx),
2753 MSG_SHUTDOWN, &data_blob_null);
2754 return False;
2757 return True;
2761 * Do the recurring log file and smb.conf reload checks.
2764 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2766 struct smbd_server_connection *sconn = talloc_get_type_abort(
2767 private_data, struct smbd_server_connection);
2769 DEBUG(5, ("housekeeping\n"));
2771 change_to_root_user();
2773 /* update printer queue caches if necessary */
2774 update_monitored_printq_cache(sconn->msg_ctx);
2776 /* check if we need to reload services */
2777 check_reload(sconn, time_mono(NULL));
2780 * Force a log file check.
2782 force_check_log_size();
2783 check_log_size();
2784 return true;
2788 * Read an smb packet in the echo handler child, giving the parent
2789 * smbd one second to react once the socket becomes readable.
2792 struct smbd_echo_read_state {
2793 struct tevent_context *ev;
2794 struct smbd_server_connection *sconn;
2796 char *buf;
2797 size_t buflen;
2798 uint32_t seqnum;
2801 static void smbd_echo_read_readable(struct tevent_req *subreq);
2802 static void smbd_echo_read_waited(struct tevent_req *subreq);
2804 static struct tevent_req *smbd_echo_read_send(
2805 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2806 struct smbd_server_connection *sconn)
2808 struct tevent_req *req, *subreq;
2809 struct smbd_echo_read_state *state;
2810 struct smbXsrv_connection *xconn = sconn->conn;
2812 req = tevent_req_create(mem_ctx, &state,
2813 struct smbd_echo_read_state);
2814 if (req == NULL) {
2815 return NULL;
2817 state->ev = ev;
2818 state->sconn = sconn;
2820 subreq = wait_for_read_send(state, ev, xconn->transport.sock);
2821 if (tevent_req_nomem(subreq, req)) {
2822 return tevent_req_post(req, ev);
2824 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2825 return req;
2828 static void smbd_echo_read_readable(struct tevent_req *subreq)
2830 struct tevent_req *req = tevent_req_callback_data(
2831 subreq, struct tevent_req);
2832 struct smbd_echo_read_state *state = tevent_req_data(
2833 req, struct smbd_echo_read_state);
2834 bool ok;
2835 int err;
2837 ok = wait_for_read_recv(subreq, &err);
2838 TALLOC_FREE(subreq);
2839 if (!ok) {
2840 tevent_req_nterror(req, map_nt_error_from_unix(err));
2841 return;
2845 * Give the parent smbd one second to step in
2848 subreq = tevent_wakeup_send(
2849 state, state->ev, timeval_current_ofs(1, 0));
2850 if (tevent_req_nomem(subreq, req)) {
2851 return;
2853 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2856 static void smbd_echo_read_waited(struct tevent_req *subreq)
2858 struct tevent_req *req = tevent_req_callback_data(
2859 subreq, struct tevent_req);
2860 struct smbd_echo_read_state *state = tevent_req_data(
2861 req, struct smbd_echo_read_state);
2862 struct smbd_server_connection *sconn = state->sconn;
2863 struct smbXsrv_connection *xconn = sconn->conn;
2864 bool ok;
2865 NTSTATUS status;
2866 size_t unread = 0;
2867 bool encrypted;
2869 ok = tevent_wakeup_recv(subreq);
2870 TALLOC_FREE(subreq);
2871 if (!ok) {
2872 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2873 return;
2876 ok = smbd_lock_socket_internal(sconn);
2877 if (!ok) {
2878 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2879 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2880 return;
2883 if (!fd_is_readable(xconn->transport.sock)) {
2884 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2885 (int)getpid()));
2887 ok = smbd_unlock_socket_internal(sconn);
2888 if (!ok) {
2889 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2890 DEBUG(1, ("%s: failed to unlock socket\n",
2891 __location__));
2892 return;
2895 subreq = wait_for_read_send(state, state->ev,
2896 xconn->transport.sock);
2897 if (tevent_req_nomem(subreq, req)) {
2898 return;
2900 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2901 return;
2904 status = receive_smb_talloc(state, sconn,
2905 xconn->transport.sock,
2906 &state->buf,
2907 0 /* timeout */,
2908 &unread,
2909 &encrypted,
2910 &state->buflen,
2911 &state->seqnum,
2912 false /* trusted_channel*/);
2914 if (tevent_req_nterror(req, status)) {
2915 tevent_req_nterror(req, status);
2916 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2917 (int)getpid(), nt_errstr(status)));
2918 return;
2921 ok = smbd_unlock_socket_internal(sconn);
2922 if (!ok) {
2923 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2924 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2925 return;
2927 tevent_req_done(req);
2930 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2931 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2933 struct smbd_echo_read_state *state = tevent_req_data(
2934 req, struct smbd_echo_read_state);
2935 NTSTATUS status;
2937 if (tevent_req_is_nterror(req, &status)) {
2938 return status;
2940 *pbuf = talloc_move(mem_ctx, &state->buf);
2941 *pbuflen = state->buflen;
2942 *pseqnum = state->seqnum;
2943 return NT_STATUS_OK;
2946 struct smbd_echo_state {
2947 struct tevent_context *ev;
2948 struct iovec *pending;
2949 struct smbd_server_connection *sconn;
2950 int parent_pipe;
2952 struct tevent_fd *parent_fde;
2954 struct tevent_req *write_req;
2957 static void smbd_echo_writer_done(struct tevent_req *req);
2959 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2961 int num_pending;
2963 if (state->write_req != NULL) {
2964 return;
2967 num_pending = talloc_array_length(state->pending);
2968 if (num_pending == 0) {
2969 return;
2972 state->write_req = writev_send(state, state->ev, NULL,
2973 state->parent_pipe, false,
2974 state->pending, num_pending);
2975 if (state->write_req == NULL) {
2976 DEBUG(1, ("writev_send failed\n"));
2977 exit(1);
2980 talloc_steal(state->write_req, state->pending);
2981 state->pending = NULL;
2983 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2984 state);
2987 static void smbd_echo_writer_done(struct tevent_req *req)
2989 struct smbd_echo_state *state = tevent_req_callback_data(
2990 req, struct smbd_echo_state);
2991 ssize_t written;
2992 int err;
2994 written = writev_recv(req, &err);
2995 TALLOC_FREE(req);
2996 state->write_req = NULL;
2997 if (written == -1) {
2998 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2999 exit(1);
3001 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3002 smbd_echo_activate_writer(state);
3005 static bool smbd_echo_reply(struct smbd_echo_state *state,
3006 uint8_t *inbuf, size_t inbuf_len,
3007 uint32_t seqnum)
3009 struct smb_request req;
3010 uint16_t num_replies;
3011 char *outbuf;
3012 bool ok;
3014 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3015 DEBUG(10, ("Got netbios keepalive\n"));
3017 * Just swallow it
3019 return true;
3022 if (inbuf_len < smb_size) {
3023 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3024 return false;
3026 if (!valid_smb_header(state->sconn, inbuf)) {
3027 DEBUG(10, ("Got invalid SMB header\n"));
3028 return false;
3031 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
3032 seqnum)) {
3033 return false;
3035 req.inbuf = inbuf;
3037 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3038 smb_messages[req.cmd].name
3039 ? smb_messages[req.cmd].name : "unknown"));
3041 if (req.cmd != SMBecho) {
3042 return false;
3044 if (req.wct < 1) {
3045 return false;
3048 num_replies = SVAL(req.vwv+0, 0);
3049 if (num_replies != 1) {
3050 /* Not a Windows "Hey, you're still there?" request */
3051 return false;
3054 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3055 1, req.buflen)) {
3056 DEBUG(10, ("create_outbuf failed\n"));
3057 return false;
3059 req.outbuf = (uint8_t *)outbuf;
3061 SSVAL(req.outbuf, smb_vwv0, num_replies);
3063 if (req.buflen > 0) {
3064 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3067 ok = srv_send_smb(req.sconn,
3068 (char *)outbuf,
3069 true, seqnum+1,
3070 false, &req.pcd);
3071 TALLOC_FREE(outbuf);
3072 if (!ok) {
3073 exit(1);
3076 return true;
3079 static void smbd_echo_exit(struct tevent_context *ev,
3080 struct tevent_fd *fde, uint16_t flags,
3081 void *private_data)
3083 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3084 exit(0);
3087 static void smbd_echo_got_packet(struct tevent_req *req);
3089 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3090 int parent_pipe)
3092 struct smbd_echo_state *state;
3093 struct tevent_req *read_req;
3095 state = talloc_zero(sconn, struct smbd_echo_state);
3096 if (state == NULL) {
3097 DEBUG(1, ("talloc failed\n"));
3098 return;
3100 state->sconn = sconn;
3101 state->parent_pipe = parent_pipe;
3102 state->ev = s3_tevent_context_init(state);
3103 if (state->ev == NULL) {
3104 DEBUG(1, ("tevent_context_init failed\n"));
3105 TALLOC_FREE(state);
3106 return;
3108 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3109 TEVENT_FD_READ, smbd_echo_exit,
3110 state);
3111 if (state->parent_fde == NULL) {
3112 DEBUG(1, ("tevent_add_fd failed\n"));
3113 TALLOC_FREE(state);
3114 return;
3117 read_req = smbd_echo_read_send(state, state->ev, sconn);
3118 if (read_req == NULL) {
3119 DEBUG(1, ("smbd_echo_read_send failed\n"));
3120 TALLOC_FREE(state);
3121 return;
3123 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3125 while (true) {
3126 if (tevent_loop_once(state->ev) == -1) {
3127 DEBUG(1, ("tevent_loop_once failed: %s\n",
3128 strerror(errno)));
3129 break;
3132 TALLOC_FREE(state);
3135 static void smbd_echo_got_packet(struct tevent_req *req)
3137 struct smbd_echo_state *state = tevent_req_callback_data(
3138 req, struct smbd_echo_state);
3139 NTSTATUS status;
3140 char *buf = NULL;
3141 size_t buflen = 0;
3142 uint32_t seqnum = 0;
3143 bool reply;
3145 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3146 TALLOC_FREE(req);
3147 if (!NT_STATUS_IS_OK(status)) {
3148 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3149 nt_errstr(status)));
3150 exit(1);
3153 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3154 if (!reply) {
3155 size_t num_pending;
3156 struct iovec *tmp;
3157 struct iovec *iov;
3159 num_pending = talloc_array_length(state->pending);
3160 tmp = talloc_realloc(state, state->pending, struct iovec,
3161 num_pending+1);
3162 if (tmp == NULL) {
3163 DEBUG(1, ("talloc_realloc failed\n"));
3164 exit(1);
3166 state->pending = tmp;
3168 if (buflen >= smb_size) {
3170 * place the seqnum in the packet so that the main process
3171 * can reply with signing
3173 SIVAL(buf, smb_ss_field, seqnum);
3174 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3177 iov = &state->pending[num_pending];
3178 iov->iov_base = talloc_move(state->pending, &buf);
3179 iov->iov_len = buflen;
3181 DEBUG(10,("echo_handler[%d]: forward to main\n",
3182 (int)getpid()));
3183 smbd_echo_activate_writer(state);
3186 req = smbd_echo_read_send(state, state->ev, state->sconn);
3187 if (req == NULL) {
3188 DEBUG(1, ("smbd_echo_read_send failed\n"));
3189 exit(1);
3191 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3196 * Handle SMBecho requests in a forked child process
3198 bool fork_echo_handler(struct smbd_server_connection *sconn)
3200 int listener_pipe[2];
3201 int res;
3202 pid_t child;
3203 bool use_mutex = false;
3205 res = pipe(listener_pipe);
3206 if (res == -1) {
3207 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3208 return false;
3211 #ifdef HAVE_ROBUST_MUTEXES
3212 use_mutex = tdb_runtime_check_for_robust_mutexes();
3214 if (use_mutex) {
3215 pthread_mutexattr_t a;
3217 sconn->smb1.echo_handler.socket_mutex =
3218 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3219 if (sconn->smb1.echo_handler.socket_mutex == NULL) {
3220 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3221 strerror(errno)));
3222 goto fail;
3225 res = pthread_mutexattr_init(&a);
3226 if (res != 0) {
3227 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3228 strerror(res)));
3229 goto fail;
3231 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3232 if (res != 0) {
3233 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3234 strerror(res)));
3235 pthread_mutexattr_destroy(&a);
3236 goto fail;
3238 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3239 if (res != 0) {
3240 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3241 strerror(res)));
3242 pthread_mutexattr_destroy(&a);
3243 goto fail;
3245 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3246 if (res != 0) {
3247 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3248 "%s\n", strerror(res)));
3249 pthread_mutexattr_destroy(&a);
3250 goto fail;
3252 res = pthread_mutex_init(sconn->smb1.echo_handler.socket_mutex,
3253 &a);
3254 pthread_mutexattr_destroy(&a);
3255 if (res != 0) {
3256 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3257 strerror(res)));
3258 goto fail;
3261 #endif
3263 if (!use_mutex) {
3264 sconn->smb1.echo_handler.socket_lock_fd =
3265 create_unlink_tmp(lp_lock_directory());
3266 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3267 DEBUG(1, ("Could not create lock fd: %s\n",
3268 strerror(errno)));
3269 goto fail;
3273 child = fork();
3274 if (child == 0) {
3275 NTSTATUS status;
3277 close(listener_pipe[0]);
3278 set_blocking(listener_pipe[1], false);
3280 status = reinit_after_fork(sconn->msg_ctx,
3281 sconn->ev_ctx,
3282 true);
3283 if (!NT_STATUS_IS_OK(status)) {
3284 DEBUG(1, ("reinit_after_fork failed: %s\n",
3285 nt_errstr(status)));
3286 exit(1);
3288 smbd_echo_loop(sconn, listener_pipe[1]);
3289 exit(0);
3291 close(listener_pipe[1]);
3292 listener_pipe[1] = -1;
3293 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3295 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3298 * Without smb signing this is the same as the normal smbd
3299 * listener. This needs to change once signing comes in.
3301 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3302 sconn,
3303 sconn->smb1.echo_handler.trusted_fd,
3304 TEVENT_FD_READ,
3305 smbd_server_echo_handler,
3306 sconn);
3307 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3308 DEBUG(1, ("event_add_fd failed\n"));
3309 goto fail;
3312 return true;
3314 fail:
3315 if (listener_pipe[0] != -1) {
3316 close(listener_pipe[0]);
3318 if (listener_pipe[1] != -1) {
3319 close(listener_pipe[1]);
3321 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3322 close(sconn->smb1.echo_handler.socket_lock_fd);
3325 #ifdef HAVE_ROBUST_MUTEXES
3326 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
3327 pthread_mutex_destroy(sconn->smb1.echo_handler.socket_mutex);
3328 anonymous_shared_free(sconn->smb1.echo_handler.socket_mutex);
3330 #endif
3331 smbd_echo_init(sconn);
3333 return false;
3336 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3338 while (user) {
3339 if (user->session_info &&
3340 (user->session_info->unix_token->uid == uid)) {
3341 return true;
3343 user = user->next;
3345 return false;
3348 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3350 while (user) {
3351 if (user->session_info != NULL) {
3352 int i;
3353 struct security_unix_token *utok;
3355 utok = user->session_info->unix_token;
3356 if (utok->gid == gid) {
3357 return true;
3359 for(i=0; i<utok->ngroups; i++) {
3360 if (utok->groups[i] == gid) {
3361 return true;
3365 user = user->next;
3367 return false;
3370 static bool sid_in_use(const struct user_struct *user,
3371 const struct dom_sid *psid)
3373 while (user) {
3374 struct security_token *tok;
3376 if (user->session_info == NULL) {
3377 continue;
3379 tok = user->session_info->security_token;
3380 if (tok == NULL) {
3382 * Not sure session_info->security_token can
3383 * ever be NULL. This check might be not
3384 * necessary.
3386 continue;
3388 if (security_token_has_sid(tok, psid)) {
3389 return true;
3391 user = user->next;
3393 return false;
3396 static bool id_in_use(const struct user_struct *user,
3397 const struct id_cache_ref *id)
3399 switch(id->type) {
3400 case UID:
3401 return uid_in_use(user, id->id.uid);
3402 case GID:
3403 return gid_in_use(user, id->id.gid);
3404 case SID:
3405 return sid_in_use(user, &id->id.sid);
3406 default:
3407 break;
3409 return false;
3412 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3413 void *private_data,
3414 uint32_t msg_type,
3415 struct server_id server_id,
3416 DATA_BLOB* data)
3418 const char *msg = (data && data->data)
3419 ? (const char *)data->data : "<NULL>";
3420 struct id_cache_ref id;
3421 struct smbd_server_connection *sconn =
3422 talloc_get_type_abort(private_data,
3423 struct smbd_server_connection);
3425 if (!id_cache_ref_parse(msg, &id)) {
3426 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3427 return;
3430 if (id_in_use(sconn->users, &id)) {
3431 exit_server_cleanly(msg);
3433 id_cache_delete_from_cache(&id);
3436 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3437 enum protocol_types protocol)
3439 NTSTATUS status;
3441 set_Protocol(protocol);
3442 conn->protocol = protocol;
3444 if (protocol >= PROTOCOL_SMB2_02) {
3445 status = smb2srv_session_table_init(conn);
3446 if (!NT_STATUS_IS_OK(status)) {
3447 return status;
3450 status = smb2srv_open_table_init(conn);
3451 if (!NT_STATUS_IS_OK(status)) {
3452 return status;
3454 } else {
3455 status = smb1srv_session_table_init(conn);
3456 if (!NT_STATUS_IS_OK(status)) {
3457 return status;
3460 status = smb1srv_tcon_table_init(conn);
3461 if (!NT_STATUS_IS_OK(status)) {
3462 return status;
3465 status = smb1srv_open_table_init(conn);
3466 if (!NT_STATUS_IS_OK(status)) {
3467 return status;
3471 return NT_STATUS_OK;
3474 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3475 void *private_data)
3477 struct smbXsrv_connection *conn =
3478 talloc_get_type_abort(private_data,
3479 struct smbXsrv_connection);
3481 switch (point) {
3482 case TEVENT_TRACE_BEFORE_WAIT:
3484 * This just removes compiler warning
3485 * without profile support
3487 conn->smbd_idle_profstamp = 0;
3488 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3489 break;
3490 case TEVENT_TRACE_AFTER_WAIT:
3491 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3492 break;
3493 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3494 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3495 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3496 break;
3497 #endif
3502 * Create a debug string for the connection
3504 * This is allocated to talloc_tos() or a string constant
3505 * in certain corner cases. The returned string should
3506 * hence not be free'd directly but only via the talloc stack.
3508 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3510 const char *ret;
3513 * TODO: this can be improved later
3514 * maybe including the client guid or more
3516 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3517 if (ret == NULL) {
3518 return "<tsocket_address_string() failed>";
3521 return ret;
3524 /****************************************************************************
3525 Process commands from the client
3526 ****************************************************************************/
3528 void smbd_process(struct tevent_context *ev_ctx,
3529 struct messaging_context *msg_ctx,
3530 int sock_fd,
3531 bool interactive)
3533 TALLOC_CTX *frame = talloc_stackframe();
3534 struct smbXsrv_connection *conn;
3535 struct smbd_server_connection *sconn;
3536 struct sockaddr_storage ss_srv;
3537 void *sp_srv = (void *)&ss_srv;
3538 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3539 struct sockaddr_storage ss_clnt;
3540 void *sp_clnt = (void *)&ss_clnt;
3541 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3542 socklen_t sa_socklen;
3543 struct tsocket_address *local_address = NULL;
3544 struct tsocket_address *remote_address = NULL;
3545 const char *locaddr = NULL;
3546 const char *remaddr = NULL;
3547 char *rhost;
3548 int ret;
3549 int tmp;
3551 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3552 if (conn == NULL) {
3553 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3554 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3557 conn->ev_ctx = ev_ctx;
3558 conn->msg_ctx = msg_ctx;
3559 conn->transport.sock = sock_fd;
3561 sconn = talloc_zero(conn, struct smbd_server_connection);
3562 if (!sconn) {
3563 exit_server("failed to create smbd_server_connection");
3566 conn->sconn = sconn;
3567 sconn->conn = conn;
3570 * TODO: remove this...:-)
3572 global_smbXsrv_connection = conn;
3574 sconn->ev_ctx = ev_ctx;
3575 sconn->msg_ctx = msg_ctx;
3576 smbd_echo_init(sconn);
3578 if (!interactive) {
3579 smbd_setup_sig_term_handler(sconn);
3580 smbd_setup_sig_hup_handler(sconn);
3582 if (!serverid_register(messaging_server_id(msg_ctx),
3583 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3584 |FLAG_MSG_DBWRAP
3585 |FLAG_MSG_PRINT_GENERAL)) {
3586 exit_server_cleanly("Could not register myself in "
3587 "serverid.tdb");
3591 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3593 * We're not making the decision here,
3594 * we're just allowing the client
3595 * to decide between SMB1 and SMB2
3596 * with the first negprot
3597 * packet.
3599 sconn->using_smb2 = true;
3602 /* Ensure child is set to blocking mode */
3603 set_blocking(sock_fd,True);
3605 set_socket_options(sock_fd, "SO_KEEPALIVE");
3606 set_socket_options(sock_fd, lp_socket_options());
3608 sa_socklen = sizeof(ss_clnt);
3609 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3610 if (ret != 0) {
3611 int level = (errno == ENOTCONN)?2:0;
3612 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3613 exit_server_cleanly("getpeername() failed.\n");
3615 ret = tsocket_address_bsd_from_sockaddr(sconn,
3616 sa_clnt, sa_socklen,
3617 &remote_address);
3618 if (ret != 0) {
3619 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3620 __location__, strerror(errno)));
3621 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3624 sa_socklen = sizeof(ss_srv);
3625 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3626 if (ret != 0) {
3627 int level = (errno == ENOTCONN)?2:0;
3628 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3629 exit_server_cleanly("getsockname() failed.\n");
3631 ret = tsocket_address_bsd_from_sockaddr(sconn,
3632 sa_srv, sa_socklen,
3633 &local_address);
3634 if (ret != 0) {
3635 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3636 __location__, strerror(errno)));
3637 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3640 sconn->local_address = local_address;
3641 sconn->remote_address = remote_address;
3643 if (tsocket_address_is_inet(local_address, "ip")) {
3644 locaddr = tsocket_address_inet_addr_string(
3645 sconn->local_address,
3646 talloc_tos());
3647 if (locaddr == NULL) {
3648 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3649 __location__, strerror(errno)));
3650 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3652 } else {
3653 locaddr = "0.0.0.0";
3656 if (tsocket_address_is_inet(remote_address, "ip")) {
3657 remaddr = tsocket_address_inet_addr_string(
3658 sconn->remote_address,
3659 talloc_tos());
3660 if (remaddr == NULL) {
3661 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3662 __location__, strerror(errno)));
3663 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3665 } else {
3666 remaddr = "0.0.0.0";
3669 /* this is needed so that we get decent entries
3670 in smbstatus for port 445 connects */
3671 set_remote_machine_name(remaddr, false);
3672 reload_services(sconn, conn_snum_used, true);
3675 * Before the first packet, check the global hosts allow/ hosts deny
3676 * parameters before doing any parsing of packets passed to us by the
3677 * client. This prevents attacks on our parsing code from hosts not in
3678 * the hosts allow list.
3681 ret = get_remote_hostname(remote_address,
3682 &rhost,
3683 talloc_tos());
3684 if (ret < 0) {
3685 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3686 __location__, strerror(errno)));
3687 exit_server_cleanly("get_remote_hostname failed.\n");
3689 if (strequal(rhost, "UNKNOWN")) {
3690 rhost = talloc_strdup(talloc_tos(), remaddr);
3692 sconn->remote_hostname = talloc_move(sconn, &rhost);
3694 sub_set_socket_ids(remaddr,
3695 sconn->remote_hostname,
3696 locaddr);
3698 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3699 sconn->remote_hostname,
3700 remaddr)) {
3702 * send a negative session response "not listening on calling
3703 * name"
3705 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3706 DEBUG( 1, ("Connection denied from %s to %s\n",
3707 tsocket_address_string(remote_address, talloc_tos()),
3708 tsocket_address_string(local_address, talloc_tos())));
3709 (void)srv_send_smb(sconn,(char *)buf, false,
3710 0, false, NULL);
3711 exit_server_cleanly("connection denied");
3714 DEBUG(10, ("Connection allowed from %s to %s\n",
3715 tsocket_address_string(remote_address, talloc_tos()),
3716 tsocket_address_string(local_address, talloc_tos())));
3718 if (lp_preload_modules()) {
3719 smb_load_modules(lp_preload_modules());
3722 smb_perfcount_init();
3724 if (!init_account_policy()) {
3725 exit_server("Could not open account policy tdb.\n");
3728 if (*lp_root_directory(talloc_tos())) {
3729 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3730 DEBUG(0,("Failed to change root to %s\n",
3731 lp_root_directory(talloc_tos())));
3732 exit_server("Failed to chroot()");
3734 if (chdir("/") == -1) {
3735 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3736 exit_server("Failed to chroot()");
3738 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3741 if (!srv_init_signing(sconn)) {
3742 exit_server("Failed to init smb_signing");
3745 if (!file_init(sconn)) {
3746 exit_server("file_init() failed");
3749 /* Setup oplocks */
3750 if (!init_oplocks(sconn))
3751 exit_server("Failed to init oplocks");
3753 /* register our message handlers */
3754 messaging_register(sconn->msg_ctx, sconn,
3755 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3756 messaging_register(sconn->msg_ctx, sconn,
3757 MSG_SMB_CLOSE_FILE, msg_close_file);
3758 messaging_register(sconn->msg_ctx, sconn,
3759 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3761 id_cache_register_msgs(sconn->msg_ctx);
3762 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3763 messaging_register(sconn->msg_ctx, sconn,
3764 ID_CACHE_KILL, smbd_id_cache_kill);
3766 messaging_deregister(sconn->msg_ctx,
3767 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3768 messaging_register(sconn->msg_ctx, sconn,
3769 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3771 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3772 NULL);
3773 messaging_register(sconn->msg_ctx, sconn,
3774 MSG_SMB_KILL_CLIENT_IP,
3775 msg_kill_client_ip);
3777 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3780 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3781 * MSGs to all child processes
3783 messaging_deregister(sconn->msg_ctx,
3784 MSG_DEBUG, NULL);
3785 messaging_register(sconn->msg_ctx, NULL,
3786 MSG_DEBUG, debug_message);
3788 if ((lp_keepalive() != 0)
3789 && !(event_add_idle(ev_ctx, NULL,
3790 timeval_set(lp_keepalive(), 0),
3791 "keepalive", keepalive_fn,
3792 sconn))) {
3793 DEBUG(0, ("Could not add keepalive event\n"));
3794 exit(1);
3797 if (!(event_add_idle(ev_ctx, NULL,
3798 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3799 "deadtime", deadtime_fn, sconn))) {
3800 DEBUG(0, ("Could not add deadtime event\n"));
3801 exit(1);
3804 if (!(event_add_idle(ev_ctx, NULL,
3805 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3806 "housekeeping", housekeeping_fn, sconn))) {
3807 DEBUG(0, ("Could not add housekeeping event\n"));
3808 exit(1);
3811 if (lp_clustering()) {
3813 * We need to tell ctdb about our client's TCP
3814 * connection, so that for failover ctdbd can send
3815 * tickle acks, triggering a reconnection by the
3816 * client.
3818 NTSTATUS status;
3820 status = smbd_register_ips(sconn, &ss_srv, &ss_clnt);
3821 if (!NT_STATUS_IS_OK(status)) {
3822 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3823 nt_errstr(status)));
3827 tmp = lp_max_xmit();
3828 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3829 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3831 conn->smb1.negprot.max_recv = tmp;
3833 sconn->smb1.sessions.done_sesssetup = false;
3834 sconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3836 if (!init_dptrs(sconn)) {
3837 exit_server("init_dptrs() failed");
3840 conn->transport.fde = tevent_add_fd(ev_ctx,
3841 sconn,
3842 sock_fd,
3843 TEVENT_FD_READ,
3844 smbd_server_connection_handler,
3845 sconn);
3846 if (!conn->transport.fde) {
3847 exit_server("failed to create smbd_server_connection fde");
3850 sconn->conn->local_address = sconn->local_address;
3851 sconn->conn->remote_address = sconn->remote_address;
3852 sconn->conn->remote_hostname = sconn->remote_hostname;
3853 sconn->conn->protocol = PROTOCOL_NONE;
3855 TALLOC_FREE(frame);
3857 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3859 while (True) {
3860 frame = talloc_stackframe_pool(8192);
3862 errno = 0;
3863 if (tevent_loop_once(ev_ctx) == -1) {
3864 if (errno != EINTR) {
3865 DEBUG(3, ("tevent_loop_once failed: %s,"
3866 " exiting\n", strerror(errno) ));
3867 break;
3871 TALLOC_FREE(frame);
3874 exit_server_cleanly(NULL);
3877 bool req_is_in_chain(const struct smb_request *req)
3879 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3881 * We're right now handling a subsequent request, so we must
3882 * be in a chain
3884 return true;
3887 if (!is_andx_req(req->cmd)) {
3888 return false;
3891 if (req->wct < 2) {
3893 * Okay, an illegal request, but definitely not chained :-)
3895 return false;
3898 return (CVAL(req->vwv+0, 0) != 0xFF);