build: Move uid_wrapper to third_party
[Samba.git] / source3 / smbd / process.c
blobb5f528fc78ad8292dbd820b612cd693bfb3aa585
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 "lib/messages_ctdb.h"
36 #include "smbprofile.h"
37 #include "rpc_server/spoolss/srv_spoolss_nt.h"
38 #include "libsmb/libsmb.h"
39 #include "../lib/util/tevent_ntstatus.h"
40 #include "../libcli/security/dom_sid.h"
41 #include "../libcli/security/security_token.h"
42 #include "lib/id_cache.h"
43 #include "lib/util/sys_rw_data.h"
44 #include "serverid.h"
45 #include "system/threads.h"
47 /* Internal message queue for deferred opens. */
48 struct pending_message_list {
49 struct pending_message_list *next, *prev;
50 struct timeval request_time; /* When was this first issued? */
51 struct smbd_server_connection *sconn;
52 struct smbXsrv_connection *xconn;
53 struct tevent_timer *te;
54 struct smb_perfcount_data pcd;
55 uint32_t seqnum;
56 bool encrypted;
57 bool processed;
58 DATA_BLOB buf;
59 struct deferred_open_record *open_rec;
62 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
63 char *outbuf);
64 static struct pending_message_list *get_deferred_open_message_smb(
65 struct smbd_server_connection *sconn, uint64_t mid);
66 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
68 static void smbd_echo_init(struct smbXsrv_connection *xconn)
70 xconn->smb1.echo_handler.trusted_fd = -1;
71 xconn->smb1.echo_handler.socket_lock_fd = -1;
72 #ifdef HAVE_ROBUST_MUTEXES
73 xconn->smb1.echo_handler.socket_mutex = NULL;
74 #endif
77 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
79 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
80 return true;
83 #ifdef HAVE_ROBUST_MUTEXES
84 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
85 return true;
87 #endif
89 return false;
92 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
94 if (!smbd_echo_active(xconn)) {
95 return true;
98 xconn->smb1.echo_handler.ref_count++;
100 if (xconn->smb1.echo_handler.ref_count > 1) {
101 return true;
104 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
106 #ifdef HAVE_ROBUST_MUTEXES
107 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
108 int ret = EINTR;
110 while (ret == EINTR) {
111 ret = pthread_mutex_lock(
112 xconn->smb1.echo_handler.socket_mutex);
113 if (ret == 0) {
114 break;
117 if (ret != 0) {
118 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
119 strerror(ret)));
120 return false;
123 #endif
125 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
126 bool ok;
128 do {
129 ok = fcntl_lock(
130 xconn->smb1.echo_handler.socket_lock_fd,
131 F_SETLKW, 0, 0, F_WRLCK);
132 } while (!ok && (errno == EINTR));
134 if (!ok) {
135 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
136 return false;
140 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
142 return true;
145 void smbd_lock_socket(struct smbXsrv_connection *xconn)
147 if (!smbd_lock_socket_internal(xconn)) {
148 exit_server_cleanly("failed to lock socket");
152 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
154 if (!smbd_echo_active(xconn)) {
155 return true;
158 xconn->smb1.echo_handler.ref_count--;
160 if (xconn->smb1.echo_handler.ref_count > 0) {
161 return true;
164 #ifdef HAVE_ROBUST_MUTEXES
165 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
166 int ret = EINTR;
168 while (ret == EINTR) {
169 ret = pthread_mutex_unlock(
170 xconn->smb1.echo_handler.socket_mutex);
171 if (ret == 0) {
172 break;
175 if (ret != 0) {
176 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
177 strerror(ret)));
178 return false;
181 #endif
183 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
184 bool ok;
186 do {
187 ok = fcntl_lock(
188 xconn->smb1.echo_handler.socket_lock_fd,
189 F_SETLKW, 0, 0, F_UNLCK);
190 } while (!ok && (errno == EINTR));
192 if (!ok) {
193 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
194 return false;
198 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
200 return true;
203 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
205 if (!smbd_unlock_socket_internal(xconn)) {
206 exit_server_cleanly("failed to unlock socket");
210 /* Accessor function for smb_read_error for smbd functions. */
212 /****************************************************************************
213 Send an smb to a fd.
214 ****************************************************************************/
216 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
217 bool do_signing, uint32_t seqnum,
218 bool do_encrypt,
219 struct smb_perfcount_data *pcd)
221 size_t len = 0;
222 ssize_t ret;
223 char *buf_out = buffer;
225 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
227 * we're not supposed to do any io
229 return true;
232 smbd_lock_socket(xconn);
234 if (do_signing) {
235 /* Sign the outgoing packet if required. */
236 srv_calculate_sign_mac(xconn, buf_out, seqnum);
239 if (do_encrypt) {
240 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
241 if (!NT_STATUS_IS_OK(status)) {
242 DEBUG(0, ("send_smb: SMB encryption failed "
243 "on outgoing packet! Error %s\n",
244 nt_errstr(status) ));
245 ret = -1;
246 goto out;
250 len = smb_len_large(buf_out) + 4;
252 ret = write_data(xconn->transport.sock, buf_out, len);
253 if (ret <= 0) {
254 int saved_errno = errno;
256 * Try and give an error message saying what
257 * client failed.
259 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
260 (int)getpid(), (int)len,
261 smbXsrv_connection_dbg(xconn),
262 (int)ret, strerror(saved_errno)));
263 errno = saved_errno;
265 srv_free_enc_buffer(xconn, buf_out);
266 goto out;
269 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
270 srv_free_enc_buffer(xconn, buf_out);
271 out:
272 SMB_PERFCOUNT_END(pcd);
274 smbd_unlock_socket(xconn);
275 return (ret > 0);
278 /*******************************************************************
279 Setup the word count and byte count for a smb message.
280 ********************************************************************/
282 int srv_set_message(char *buf,
283 int num_words,
284 int num_bytes,
285 bool zero)
287 if (zero && (num_words || num_bytes)) {
288 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
290 SCVAL(buf,smb_wct,num_words);
291 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
292 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
293 return (smb_size + num_words*2 + num_bytes);
296 static bool valid_smb_header(const uint8_t *inbuf)
298 if (is_encrypted_packet(inbuf)) {
299 return true;
302 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
303 * but it just looks weird to call strncmp for this one.
305 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
308 /* Socket functions for smbd packet processing. */
310 static bool valid_packet_size(size_t len)
313 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
314 * of header. Don't print the error if this fits.... JRA.
317 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
318 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
319 (unsigned long)len));
320 return false;
322 return true;
325 static NTSTATUS read_packet_remainder(int fd, char *buffer,
326 unsigned int timeout, ssize_t len)
328 NTSTATUS status;
330 if (len <= 0) {
331 return NT_STATUS_OK;
334 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
335 if (!NT_STATUS_IS_OK(status)) {
336 char addr[INET6_ADDRSTRLEN];
337 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
338 "error = %s.\n",
339 get_peer_addr(fd, addr, sizeof(addr)),
340 nt_errstr(status)));
342 return status;
345 /****************************************************************************
346 Attempt a zerocopy writeX read. We know here that len > smb_size-4
347 ****************************************************************************/
350 * Unfortunately, earlier versions of smbclient/libsmbclient
351 * don't send this "standard" writeX header. I've fixed this
352 * for 3.2 but we'll use the old method with earlier versions.
353 * Windows and CIFSFS at least use this standard size. Not
354 * sure about MacOSX.
357 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
358 (2*14) + /* word count (including bcc) */ \
359 1 /* pad byte */)
361 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
362 const char lenbuf[4],
363 struct smbXsrv_connection *xconn,
364 int sock,
365 char **buffer,
366 unsigned int timeout,
367 size_t *p_unread,
368 size_t *len_ret)
370 /* Size of a WRITEX call (+4 byte len). */
371 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
372 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
373 ssize_t toread;
374 NTSTATUS status;
376 memcpy(writeX_header, lenbuf, 4);
378 status = read_fd_with_timeout(
379 sock, writeX_header + 4,
380 STANDARD_WRITE_AND_X_HEADER_SIZE,
381 STANDARD_WRITE_AND_X_HEADER_SIZE,
382 timeout, NULL);
384 if (!NT_STATUS_IS_OK(status)) {
385 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
386 "error = %s.\n",
387 smbXsrv_connection_dbg(xconn),
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(xconn, (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 smbXsrv_connection *xconn,
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(xconn) &&
500 xconn->smb1.echo_handler.trusted_fde == NULL) {
502 return receive_smb_raw_talloc_partial_read(
503 mem_ctx, lenbuf, xconn, 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 smbXsrv_connection *xconn,
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, xconn, 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 smbXsrv_connection_dbg(xconn),
555 nt_errstr(status)) );
556 return status;
559 if (is_encrypted_packet((uint8_t *)*buffer)) {
560 status = srv_decrypt_buffer(xconn, *buffer);
561 if (!NT_STATUS_IS_OK(status)) {
562 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
563 "incoming packet! Error %s\n",
564 nt_errstr(status) ));
565 return status;
567 *p_encrypted = true;
570 /* Check the incoming SMB signature. */
571 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
572 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
573 "incoming packet!\n"));
574 return NT_STATUS_INVALID_NETWORK_RESPONSE;
577 *p_len = len;
578 return NT_STATUS_OK;
582 * Initialize a struct smb_request from an inbuf
585 static bool init_smb_request(struct smb_request *req,
586 struct smbd_server_connection *sconn,
587 struct smbXsrv_connection *xconn,
588 const uint8_t *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 req->xconn = xconn;
622 req->conn = NULL;
623 if (xconn != NULL) {
624 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
625 if (NT_STATUS_IS_OK(status)) {
626 req->conn = tcon->compat;
629 req->chain_fsp = NULL;
630 req->smb2req = NULL;
631 req->priv_paths = NULL;
632 req->chain = NULL;
633 req->posix_pathnames = lp_posix_pathnames();
634 smb_init_perfcount_data(&req->pcd);
636 /* Ensure we have at least wct words and 2 bytes of bcc. */
637 if (smb_size + req->wct*2 > req_size) {
638 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
639 (unsigned int)req->wct,
640 (unsigned int)req_size));
641 return false;
643 /* Ensure bcc is correct. */
644 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
645 DEBUG(0,("init_smb_request: invalid bcc number %u "
646 "(wct = %u, size %u)\n",
647 (unsigned int)req->buflen,
648 (unsigned int)req->wct,
649 (unsigned int)req_size));
650 return false;
653 req->outbuf = NULL;
654 return true;
657 static void process_smb(struct smbXsrv_connection *xconn,
658 uint8_t *inbuf, size_t nread, size_t unread_bytes,
659 uint32_t seqnum, bool encrypted,
660 struct smb_perfcount_data *deferred_pcd);
662 static void smbd_deferred_open_timer(struct tevent_context *ev,
663 struct tevent_timer *te,
664 struct timeval _tval,
665 void *private_data)
667 struct pending_message_list *msg = talloc_get_type(private_data,
668 struct pending_message_list);
669 struct smbd_server_connection *sconn = msg->sconn;
670 struct smbXsrv_connection *xconn = msg->xconn;
671 TALLOC_CTX *mem_ctx = talloc_tos();
672 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
673 uint8_t *inbuf;
675 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
676 msg->buf.length);
677 if (inbuf == NULL) {
678 exit_server("smbd_deferred_open_timer: talloc failed\n");
679 return;
682 /* We leave this message on the queue so the open code can
683 know this is a retry. */
684 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
685 (unsigned long long)mid ));
687 /* Mark the message as processed so this is not
688 * re-processed in error. */
689 msg->processed = true;
691 process_smb(xconn, inbuf,
692 msg->buf.length, 0,
693 msg->seqnum, msg->encrypted, &msg->pcd);
695 /* If it's still there and was processed, remove it. */
696 msg = get_deferred_open_message_smb(sconn, mid);
697 if (msg && msg->processed) {
698 remove_deferred_open_message_smb(xconn, mid);
702 /****************************************************************************
703 Function to push a message onto the tail of a linked list of smb messages ready
704 for processing.
705 ****************************************************************************/
707 static bool push_queued_message(struct smb_request *req,
708 struct timeval request_time,
709 struct timeval end_time,
710 struct deferred_open_record *open_rec)
712 int msg_len = smb_len(req->inbuf) + 4;
713 struct pending_message_list *msg;
715 msg = talloc_zero(NULL, struct pending_message_list);
717 if(msg == NULL) {
718 DEBUG(0,("push_message: malloc fail (1)\n"));
719 return False;
721 msg->sconn = req->sconn;
722 msg->xconn = req->xconn;
724 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
725 if(msg->buf.data == NULL) {
726 DEBUG(0,("push_message: malloc fail (2)\n"));
727 TALLOC_FREE(msg);
728 return False;
731 msg->request_time = request_time;
732 msg->seqnum = req->seqnum;
733 msg->encrypted = req->encrypted;
734 msg->processed = false;
735 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
737 if (open_rec) {
738 msg->open_rec = talloc_move(msg, &open_rec);
741 #if 0
742 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
743 msg,
744 end_time,
745 smbd_deferred_open_timer,
746 msg);
747 if (!msg->te) {
748 DEBUG(0,("push_message: event_add_timed failed\n"));
749 TALLOC_FREE(msg);
750 return false;
752 #endif
754 DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
756 DEBUG(10,("push_message: pushed message length %u on "
757 "deferred_open_queue\n", (unsigned int)msg_len));
759 return True;
762 /****************************************************************************
763 Function to delete a sharing violation open message by mid.
764 ****************************************************************************/
766 void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
767 uint64_t mid)
769 struct smbd_server_connection *sconn = xconn->client->sconn;
770 struct pending_message_list *pml;
772 if (sconn->using_smb2) {
773 remove_deferred_open_message_smb2(xconn, mid);
774 return;
777 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
778 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
779 DEBUG(10,("remove_deferred_open_message_smb: "
780 "deleting mid %llu len %u\n",
781 (unsigned long long)mid,
782 (unsigned int)pml->buf.length ));
783 DLIST_REMOVE(sconn->deferred_open_queue, pml);
784 TALLOC_FREE(pml);
785 return;
790 /****************************************************************************
791 Move a sharing violation open retry message to the front of the list and
792 schedule it for immediate processing.
793 ****************************************************************************/
795 bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
796 uint64_t mid)
798 struct smbd_server_connection *sconn = xconn->client->sconn;
799 struct pending_message_list *pml;
800 int i = 0;
802 if (sconn->using_smb2) {
803 return schedule_deferred_open_message_smb2(xconn, mid);
806 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
807 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
809 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
810 "msg_mid = %llu\n",
811 i++,
812 (unsigned long long)msg_mid ));
814 if (mid == msg_mid) {
815 struct tevent_timer *te;
817 if (pml->processed) {
818 /* A processed message should not be
819 * rescheduled. */
820 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
821 "message mid %llu was already processed\n",
822 (unsigned long long)msg_mid ));
823 continue;
826 DEBUG(10,("schedule_deferred_open_message_smb: "
827 "scheduling mid %llu\n",
828 (unsigned long long)mid ));
830 te = tevent_add_timer(pml->sconn->ev_ctx,
831 pml,
832 timeval_zero(),
833 smbd_deferred_open_timer,
834 pml);
835 if (!te) {
836 DEBUG(10,("schedule_deferred_open_message_smb: "
837 "event_add_timed() failed, "
838 "skipping mid %llu\n",
839 (unsigned long long)msg_mid ));
842 TALLOC_FREE(pml->te);
843 pml->te = te;
844 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
845 return true;
849 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
850 "find message mid %llu\n",
851 (unsigned long long)mid ));
853 return false;
856 /****************************************************************************
857 Return true if this mid is on the deferred queue and was not yet processed.
858 ****************************************************************************/
860 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
862 struct smbd_server_connection *sconn = xconn->client->sconn;
863 struct pending_message_list *pml;
865 if (sconn->using_smb2) {
866 return open_was_deferred_smb2(xconn, mid);
869 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
870 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
871 return True;
874 return False;
877 /****************************************************************************
878 Return the message queued by this mid.
879 ****************************************************************************/
881 static struct pending_message_list *get_deferred_open_message_smb(
882 struct smbd_server_connection *sconn, uint64_t mid)
884 struct pending_message_list *pml;
886 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
887 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
888 return pml;
891 return NULL;
894 /****************************************************************************
895 Get the state data queued by this mid.
896 ****************************************************************************/
898 bool get_deferred_open_message_state(struct smb_request *smbreq,
899 struct timeval *p_request_time,
900 struct deferred_open_record **open_rec)
902 struct pending_message_list *pml;
904 if (smbreq->sconn->using_smb2) {
905 return get_deferred_open_message_state_smb2(smbreq->smb2req,
906 p_request_time,
907 open_rec);
910 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
911 if (!pml) {
912 return false;
914 if (p_request_time) {
915 *p_request_time = pml->request_time;
917 if (open_rec != NULL) {
918 *open_rec = pml->open_rec;
920 return true;
923 /****************************************************************************
924 Function to push a deferred open smb message onto a linked list of local smb
925 messages ready for processing.
926 ****************************************************************************/
928 bool push_deferred_open_message_smb(struct smb_request *req,
929 struct timeval request_time,
930 struct timeval timeout,
931 struct file_id id,
932 struct deferred_open_record *open_rec)
934 struct timeval end_time;
936 if (req->smb2req) {
937 return push_deferred_open_message_smb2(req->smb2req,
938 request_time,
939 timeout,
941 open_rec);
944 if (req->unread_bytes) {
945 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
946 "unread_bytes = %u\n",
947 (unsigned int)req->unread_bytes ));
948 smb_panic("push_deferred_open_message_smb: "
949 "logic error unread_bytes != 0" );
952 end_time = timeval_sum(&request_time, &timeout);
954 DEBUG(10,("push_deferred_open_message_smb: pushing message "
955 "len %u mid %llu timeout time [%u.%06u]\n",
956 (unsigned int) smb_len(req->inbuf)+4,
957 (unsigned long long)req->mid,
958 (unsigned int)end_time.tv_sec,
959 (unsigned int)end_time.tv_usec));
961 return push_queued_message(req, request_time, end_time, open_rec);
964 static void smbd_sig_term_handler(struct tevent_context *ev,
965 struct tevent_signal *se,
966 int signum,
967 int count,
968 void *siginfo,
969 void *private_data)
971 exit_server_cleanly("termination signal");
974 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
976 struct tevent_signal *se;
978 se = tevent_add_signal(sconn->ev_ctx,
979 sconn,
980 SIGTERM, 0,
981 smbd_sig_term_handler,
982 sconn);
983 if (!se) {
984 exit_server("failed to setup SIGTERM handler");
988 static void smbd_sig_hup_handler(struct tevent_context *ev,
989 struct tevent_signal *se,
990 int signum,
991 int count,
992 void *siginfo,
993 void *private_data)
995 struct smbd_server_connection *sconn =
996 talloc_get_type_abort(private_data,
997 struct smbd_server_connection);
999 change_to_root_user();
1000 DEBUG(1,("Reloading services after SIGHUP\n"));
1001 reload_services(sconn, conn_snum_used, false);
1004 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1006 struct tevent_signal *se;
1008 se = tevent_add_signal(sconn->ev_ctx,
1009 sconn,
1010 SIGHUP, 0,
1011 smbd_sig_hup_handler,
1012 sconn);
1013 if (!se) {
1014 exit_server("failed to setup SIGHUP handler");
1018 static void smbd_conf_updated(struct messaging_context *msg,
1019 void *private_data,
1020 uint32_t msg_type,
1021 struct server_id server_id,
1022 DATA_BLOB *data)
1024 struct smbd_server_connection *sconn =
1025 talloc_get_type_abort(private_data,
1026 struct smbd_server_connection);
1028 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1029 "updated. Reloading.\n"));
1030 change_to_root_user();
1031 reload_services(sconn, conn_snum_used, false);
1035 * Only allow 5 outstanding trans requests. We're allocating memory, so
1036 * prevent a DoS.
1039 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1041 int count = 0;
1042 for (; list != NULL; list = list->next) {
1044 if (list->mid == mid) {
1045 return NT_STATUS_INVALID_PARAMETER;
1048 count += 1;
1050 if (count > 5) {
1051 return NT_STATUS_INSUFFICIENT_RESOURCES;
1054 return NT_STATUS_OK;
1058 These flags determine some of the permissions required to do an operation
1060 Note that I don't set NEED_WRITE on some write operations because they
1061 are used by some brain-dead clients when printing, and I don't want to
1062 force write permissions on print services.
1064 #define AS_USER (1<<0)
1065 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1066 #define TIME_INIT (1<<2)
1067 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1068 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1069 #define DO_CHDIR (1<<6)
1072 define a list of possible SMB messages and their corresponding
1073 functions. Any message that has a NULL function is unimplemented -
1074 please feel free to contribute implementations!
1076 static const struct smb_message_struct {
1077 const char *name;
1078 void (*fn)(struct smb_request *req);
1079 int flags;
1080 } smb_messages[256] = {
1082 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1083 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1084 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1085 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1086 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1087 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1088 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1089 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1090 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1091 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1092 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1093 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1094 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1095 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1096 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1097 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1098 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1099 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1100 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1101 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1102 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1103 /* 0x15 */ { NULL, NULL, 0 },
1104 /* 0x16 */ { NULL, NULL, 0 },
1105 /* 0x17 */ { NULL, NULL, 0 },
1106 /* 0x18 */ { NULL, NULL, 0 },
1107 /* 0x19 */ { NULL, NULL, 0 },
1108 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1109 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1110 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1111 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1112 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1113 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1114 /* 0x20 */ { "SMBwritec", NULL,0},
1115 /* 0x21 */ { NULL, NULL, 0 },
1116 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1117 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1118 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1119 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1120 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1121 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1122 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1123 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1124 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1125 /* 0x2b */ { "SMBecho",reply_echo,0},
1126 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1127 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1128 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1129 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1130 /* 0x30 */ { NULL, NULL, 0 },
1131 /* 0x31 */ { NULL, NULL, 0 },
1132 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1133 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1134 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1135 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1136 /* 0x36 */ { NULL, NULL, 0 },
1137 /* 0x37 */ { NULL, NULL, 0 },
1138 /* 0x38 */ { NULL, NULL, 0 },
1139 /* 0x39 */ { NULL, NULL, 0 },
1140 /* 0x3a */ { NULL, NULL, 0 },
1141 /* 0x3b */ { NULL, NULL, 0 },
1142 /* 0x3c */ { NULL, NULL, 0 },
1143 /* 0x3d */ { NULL, NULL, 0 },
1144 /* 0x3e */ { NULL, NULL, 0 },
1145 /* 0x3f */ { NULL, NULL, 0 },
1146 /* 0x40 */ { NULL, NULL, 0 },
1147 /* 0x41 */ { NULL, NULL, 0 },
1148 /* 0x42 */ { NULL, NULL, 0 },
1149 /* 0x43 */ { NULL, NULL, 0 },
1150 /* 0x44 */ { NULL, NULL, 0 },
1151 /* 0x45 */ { NULL, NULL, 0 },
1152 /* 0x46 */ { NULL, NULL, 0 },
1153 /* 0x47 */ { NULL, NULL, 0 },
1154 /* 0x48 */ { NULL, NULL, 0 },
1155 /* 0x49 */ { NULL, NULL, 0 },
1156 /* 0x4a */ { NULL, NULL, 0 },
1157 /* 0x4b */ { NULL, NULL, 0 },
1158 /* 0x4c */ { NULL, NULL, 0 },
1159 /* 0x4d */ { NULL, NULL, 0 },
1160 /* 0x4e */ { NULL, NULL, 0 },
1161 /* 0x4f */ { NULL, NULL, 0 },
1162 /* 0x50 */ { NULL, NULL, 0 },
1163 /* 0x51 */ { NULL, NULL, 0 },
1164 /* 0x52 */ { NULL, NULL, 0 },
1165 /* 0x53 */ { NULL, NULL, 0 },
1166 /* 0x54 */ { NULL, NULL, 0 },
1167 /* 0x55 */ { NULL, NULL, 0 },
1168 /* 0x56 */ { NULL, NULL, 0 },
1169 /* 0x57 */ { NULL, NULL, 0 },
1170 /* 0x58 */ { NULL, NULL, 0 },
1171 /* 0x59 */ { NULL, NULL, 0 },
1172 /* 0x5a */ { NULL, NULL, 0 },
1173 /* 0x5b */ { NULL, NULL, 0 },
1174 /* 0x5c */ { NULL, NULL, 0 },
1175 /* 0x5d */ { NULL, NULL, 0 },
1176 /* 0x5e */ { NULL, NULL, 0 },
1177 /* 0x5f */ { NULL, NULL, 0 },
1178 /* 0x60 */ { NULL, NULL, 0 },
1179 /* 0x61 */ { NULL, NULL, 0 },
1180 /* 0x62 */ { NULL, NULL, 0 },
1181 /* 0x63 */ { NULL, NULL, 0 },
1182 /* 0x64 */ { NULL, NULL, 0 },
1183 /* 0x65 */ { NULL, NULL, 0 },
1184 /* 0x66 */ { NULL, NULL, 0 },
1185 /* 0x67 */ { NULL, NULL, 0 },
1186 /* 0x68 */ { NULL, NULL, 0 },
1187 /* 0x69 */ { NULL, NULL, 0 },
1188 /* 0x6a */ { NULL, NULL, 0 },
1189 /* 0x6b */ { NULL, NULL, 0 },
1190 /* 0x6c */ { NULL, NULL, 0 },
1191 /* 0x6d */ { NULL, NULL, 0 },
1192 /* 0x6e */ { NULL, NULL, 0 },
1193 /* 0x6f */ { NULL, NULL, 0 },
1194 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1195 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1196 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1197 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1198 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1199 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1200 /* 0x76 */ { NULL, NULL, 0 },
1201 /* 0x77 */ { NULL, NULL, 0 },
1202 /* 0x78 */ { NULL, NULL, 0 },
1203 /* 0x79 */ { NULL, NULL, 0 },
1204 /* 0x7a */ { NULL, NULL, 0 },
1205 /* 0x7b */ { NULL, NULL, 0 },
1206 /* 0x7c */ { NULL, NULL, 0 },
1207 /* 0x7d */ { NULL, NULL, 0 },
1208 /* 0x7e */ { NULL, NULL, 0 },
1209 /* 0x7f */ { NULL, NULL, 0 },
1210 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1211 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1212 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1213 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1214 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1215 /* 0x85 */ { NULL, NULL, 0 },
1216 /* 0x86 */ { NULL, NULL, 0 },
1217 /* 0x87 */ { NULL, NULL, 0 },
1218 /* 0x88 */ { NULL, NULL, 0 },
1219 /* 0x89 */ { NULL, NULL, 0 },
1220 /* 0x8a */ { NULL, NULL, 0 },
1221 /* 0x8b */ { NULL, NULL, 0 },
1222 /* 0x8c */ { NULL, NULL, 0 },
1223 /* 0x8d */ { NULL, NULL, 0 },
1224 /* 0x8e */ { NULL, NULL, 0 },
1225 /* 0x8f */ { NULL, NULL, 0 },
1226 /* 0x90 */ { NULL, NULL, 0 },
1227 /* 0x91 */ { NULL, NULL, 0 },
1228 /* 0x92 */ { NULL, NULL, 0 },
1229 /* 0x93 */ { NULL, NULL, 0 },
1230 /* 0x94 */ { NULL, NULL, 0 },
1231 /* 0x95 */ { NULL, NULL, 0 },
1232 /* 0x96 */ { NULL, NULL, 0 },
1233 /* 0x97 */ { NULL, NULL, 0 },
1234 /* 0x98 */ { NULL, NULL, 0 },
1235 /* 0x99 */ { NULL, NULL, 0 },
1236 /* 0x9a */ { NULL, NULL, 0 },
1237 /* 0x9b */ { NULL, NULL, 0 },
1238 /* 0x9c */ { NULL, NULL, 0 },
1239 /* 0x9d */ { NULL, NULL, 0 },
1240 /* 0x9e */ { NULL, NULL, 0 },
1241 /* 0x9f */ { NULL, NULL, 0 },
1242 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1243 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1244 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1245 /* 0xa3 */ { NULL, NULL, 0 },
1246 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1247 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1248 /* 0xa6 */ { NULL, NULL, 0 },
1249 /* 0xa7 */ { NULL, NULL, 0 },
1250 /* 0xa8 */ { NULL, NULL, 0 },
1251 /* 0xa9 */ { NULL, NULL, 0 },
1252 /* 0xaa */ { NULL, NULL, 0 },
1253 /* 0xab */ { NULL, NULL, 0 },
1254 /* 0xac */ { NULL, NULL, 0 },
1255 /* 0xad */ { NULL, NULL, 0 },
1256 /* 0xae */ { NULL, NULL, 0 },
1257 /* 0xaf */ { NULL, NULL, 0 },
1258 /* 0xb0 */ { NULL, NULL, 0 },
1259 /* 0xb1 */ { NULL, NULL, 0 },
1260 /* 0xb2 */ { NULL, NULL, 0 },
1261 /* 0xb3 */ { NULL, NULL, 0 },
1262 /* 0xb4 */ { NULL, NULL, 0 },
1263 /* 0xb5 */ { NULL, NULL, 0 },
1264 /* 0xb6 */ { NULL, NULL, 0 },
1265 /* 0xb7 */ { NULL, NULL, 0 },
1266 /* 0xb8 */ { NULL, NULL, 0 },
1267 /* 0xb9 */ { NULL, NULL, 0 },
1268 /* 0xba */ { NULL, NULL, 0 },
1269 /* 0xbb */ { NULL, NULL, 0 },
1270 /* 0xbc */ { NULL, NULL, 0 },
1271 /* 0xbd */ { NULL, NULL, 0 },
1272 /* 0xbe */ { NULL, NULL, 0 },
1273 /* 0xbf */ { NULL, NULL, 0 },
1274 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1275 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1276 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1277 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1278 /* 0xc4 */ { NULL, NULL, 0 },
1279 /* 0xc5 */ { NULL, NULL, 0 },
1280 /* 0xc6 */ { NULL, NULL, 0 },
1281 /* 0xc7 */ { NULL, NULL, 0 },
1282 /* 0xc8 */ { NULL, NULL, 0 },
1283 /* 0xc9 */ { NULL, NULL, 0 },
1284 /* 0xca */ { NULL, NULL, 0 },
1285 /* 0xcb */ { NULL, NULL, 0 },
1286 /* 0xcc */ { NULL, NULL, 0 },
1287 /* 0xcd */ { NULL, NULL, 0 },
1288 /* 0xce */ { NULL, NULL, 0 },
1289 /* 0xcf */ { NULL, NULL, 0 },
1290 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1291 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1292 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1293 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1294 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1295 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1296 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1297 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1298 /* 0xd8 */ { NULL, NULL, 0 },
1299 /* 0xd9 */ { NULL, NULL, 0 },
1300 /* 0xda */ { NULL, NULL, 0 },
1301 /* 0xdb */ { NULL, NULL, 0 },
1302 /* 0xdc */ { NULL, NULL, 0 },
1303 /* 0xdd */ { NULL, NULL, 0 },
1304 /* 0xde */ { NULL, NULL, 0 },
1305 /* 0xdf */ { NULL, NULL, 0 },
1306 /* 0xe0 */ { NULL, NULL, 0 },
1307 /* 0xe1 */ { NULL, NULL, 0 },
1308 /* 0xe2 */ { NULL, NULL, 0 },
1309 /* 0xe3 */ { NULL, NULL, 0 },
1310 /* 0xe4 */ { NULL, NULL, 0 },
1311 /* 0xe5 */ { NULL, NULL, 0 },
1312 /* 0xe6 */ { NULL, NULL, 0 },
1313 /* 0xe7 */ { NULL, NULL, 0 },
1314 /* 0xe8 */ { NULL, NULL, 0 },
1315 /* 0xe9 */ { NULL, NULL, 0 },
1316 /* 0xea */ { NULL, NULL, 0 },
1317 /* 0xeb */ { NULL, NULL, 0 },
1318 /* 0xec */ { NULL, NULL, 0 },
1319 /* 0xed */ { NULL, NULL, 0 },
1320 /* 0xee */ { NULL, NULL, 0 },
1321 /* 0xef */ { NULL, NULL, 0 },
1322 /* 0xf0 */ { NULL, NULL, 0 },
1323 /* 0xf1 */ { NULL, NULL, 0 },
1324 /* 0xf2 */ { NULL, NULL, 0 },
1325 /* 0xf3 */ { NULL, NULL, 0 },
1326 /* 0xf4 */ { NULL, NULL, 0 },
1327 /* 0xf5 */ { NULL, NULL, 0 },
1328 /* 0xf6 */ { NULL, NULL, 0 },
1329 /* 0xf7 */ { NULL, NULL, 0 },
1330 /* 0xf8 */ { NULL, NULL, 0 },
1331 /* 0xf9 */ { NULL, NULL, 0 },
1332 /* 0xfa */ { NULL, NULL, 0 },
1333 /* 0xfb */ { NULL, NULL, 0 },
1334 /* 0xfc */ { NULL, NULL, 0 },
1335 /* 0xfd */ { NULL, NULL, 0 },
1336 /* 0xfe */ { NULL, NULL, 0 },
1337 /* 0xff */ { NULL, NULL, 0 }
1341 /*******************************************************************
1342 allocate and initialize a reply packet
1343 ********************************************************************/
1345 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1346 const uint8_t *inbuf, char **outbuf,
1347 uint8_t num_words, uint32_t num_bytes)
1349 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1352 * Protect against integer wrap.
1353 * The SMB layer reply can be up to 0xFFFFFF bytes.
1355 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1356 char *msg;
1357 if (asprintf(&msg, "num_bytes too large: %u",
1358 (unsigned)num_bytes) == -1) {
1359 msg = discard_const_p(char, "num_bytes too large");
1361 smb_panic(msg);
1365 * Here we include the NBT header for now.
1367 *outbuf = talloc_array(mem_ctx, char,
1368 NBT_HDR_SIZE + smb_len);
1369 if (*outbuf == NULL) {
1370 return false;
1373 construct_reply_common(req->cmd, inbuf, *outbuf);
1374 srv_set_message(*outbuf, num_words, num_bytes, false);
1376 * Zero out the word area, the caller has to take care of the bcc area
1377 * himself
1379 if (num_words != 0) {
1380 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1383 return true;
1386 void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1388 char *outbuf;
1389 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1390 num_bytes)) {
1391 smb_panic("could not allocate output buffer\n");
1393 req->outbuf = (uint8_t *)outbuf;
1397 /*******************************************************************
1398 Dump a packet to a file.
1399 ********************************************************************/
1401 static void smb_dump(const char *name, int type, const char *data)
1403 size_t len;
1404 int fd, i;
1405 char *fname = NULL;
1406 if (DEBUGLEVEL < 50) {
1407 return;
1410 len = smb_len_tcp(data)+4;
1411 for (i=1;i<100;i++) {
1412 fname = talloc_asprintf(talloc_tos(),
1413 "/tmp/%s.%d.%s",
1414 name,
1416 type ? "req" : "resp");
1417 if (fname == NULL) {
1418 return;
1420 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1421 if (fd != -1 || errno != EEXIST) break;
1422 TALLOC_FREE(fname);
1424 if (fd != -1) {
1425 ssize_t ret = write(fd, data, len);
1426 if (ret != len)
1427 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1428 close(fd);
1429 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1431 TALLOC_FREE(fname);
1434 static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
1435 struct smb_request *req,
1436 uint8_t type,
1437 bool *update_session_globalp,
1438 bool *update_tcon_globalp)
1440 connection_struct *conn = req->conn;
1441 struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
1442 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
1443 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1444 bool update_session = false;
1445 bool update_tcon = false;
1447 if (req->encrypted) {
1448 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
1451 if (srv_is_signing_active(req->xconn)) {
1452 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
1453 } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
1455 * echo can be unsigned. Sesssion setup except final
1456 * session setup response too
1458 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1461 update_session |= smbXsrv_set_crypto_flag(
1462 &session->global->encryption_flags, encrypt_flag);
1463 update_session |= smbXsrv_set_crypto_flag(
1464 &session->global->signing_flags, sign_flag);
1466 if (tcon) {
1467 update_tcon |= smbXsrv_set_crypto_flag(
1468 &tcon->global->encryption_flags, encrypt_flag);
1469 update_tcon |= smbXsrv_set_crypto_flag(
1470 &tcon->global->signing_flags, sign_flag);
1473 if (update_session) {
1474 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1477 *update_session_globalp = update_session;
1478 *update_tcon_globalp = update_tcon;
1479 return;
1482 /****************************************************************************
1483 Prepare everything for calling the actual request function, and potentially
1484 call the request function via the "new" interface.
1486 Return False if the "legacy" function needs to be called, everything is
1487 prepared.
1489 Return True if we're done.
1491 I know this API sucks, but it is the one with the least code change I could
1492 find.
1493 ****************************************************************************/
1495 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1497 int flags;
1498 uint64_t session_tag;
1499 connection_struct *conn = NULL;
1500 struct smbXsrv_connection *xconn = req->xconn;
1501 NTTIME now = timeval_to_nttime(&req->request_time);
1502 struct smbXsrv_session *session = NULL;
1503 NTSTATUS status;
1505 errno = 0;
1507 if (!xconn->smb1.negprot.done) {
1508 switch (type) {
1510 * Without a negprot the request must
1511 * either be a negprot, or one of the
1512 * evil old SMB mailslot messaging types.
1514 case SMBnegprot:
1515 case SMBsendstrt:
1516 case SMBsendend:
1517 case SMBsendtxt:
1518 break;
1519 default:
1520 exit_server_cleanly("The first request "
1521 "should be a negprot");
1525 if (smb_messages[type].fn == NULL) {
1526 DEBUG(0,("Unknown message type %d!\n",type));
1527 smb_dump("Unknown", 1, (const char *)req->inbuf);
1528 reply_unknown_new(req, type);
1529 return NULL;
1532 flags = smb_messages[type].flags;
1534 /* In share mode security we must ignore the vuid. */
1535 session_tag = req->vuid;
1536 conn = req->conn;
1538 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1539 (int)getpid(), (unsigned long)conn));
1541 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1543 /* Ensure this value is replaced in the incoming packet. */
1544 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1547 * Ensure the correct username is in current_user_info. This is a
1548 * really ugly bugfix for problems with multiple session_setup_and_X's
1549 * being done and allowing %U and %G substitutions to work correctly.
1550 * There is a reason this code is done here, don't move it unless you
1551 * know what you're doing... :-).
1552 * JRA.
1556 * lookup an existing session
1558 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1559 * here, the main check is still in change_to_user()
1561 status = smb1srv_session_lookup(xconn,
1562 session_tag,
1563 now,
1564 &session);
1565 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1566 switch (type) {
1567 case SMBsesssetupX:
1568 status = NT_STATUS_OK;
1569 break;
1570 default:
1571 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1572 (unsigned long long)session_tag,
1573 (unsigned long long)req->mid));
1574 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1575 return conn;
1579 if (session_tag != xconn->client->last_session_id) {
1580 struct user_struct *vuser = NULL;
1582 xconn->client->last_session_id = session_tag;
1583 if (session) {
1584 vuser = session->compat;
1586 if (vuser) {
1587 set_current_user_info(
1588 vuser->session_info->unix_info->sanitized_username,
1589 vuser->session_info->unix_info->unix_name,
1590 vuser->session_info->info->domain_name);
1594 /* Does this call need to be run as the connected user? */
1595 if (flags & AS_USER) {
1597 /* Does this call need a valid tree connection? */
1598 if (!conn) {
1600 * Amazingly, the error code depends on the command
1601 * (from Samba4).
1603 if (type == SMBntcreateX) {
1604 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1605 } else {
1606 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1608 return NULL;
1611 if (!change_to_user(conn,session_tag)) {
1612 DEBUG(0, ("Error: Could not change to user. Removing "
1613 "deferred open, mid=%llu.\n",
1614 (unsigned long long)req->mid));
1615 reply_force_doserror(req, ERRSRV, ERRbaduid);
1616 return conn;
1619 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1621 /* Does it need write permission? */
1622 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1623 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1624 return conn;
1627 /* IPC services are limited */
1628 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1629 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1630 return conn;
1632 } else {
1633 /* This call needs to be run as root */
1634 change_to_root_user();
1637 /* load service specific parameters */
1638 if (conn) {
1639 if (req->encrypted) {
1640 conn->encrypted_tid = true;
1641 /* encrypted required from now on. */
1642 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1643 } else if (ENCRYPTION_REQUIRED(conn)) {
1644 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1645 DEBUG(1,("service[%s] requires encryption"
1646 "%s ACCESS_DENIED. mid=%llu\n",
1647 lp_servicename(talloc_tos(), SNUM(conn)),
1648 smb_fn_name(type),
1649 (unsigned long long)req->mid));
1650 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1651 return conn;
1655 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1656 (flags & (AS_USER|DO_CHDIR)
1657 ?True:False))) {
1658 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1659 return conn;
1661 conn->num_smb_operations++;
1665 * Does this protocol need to be run as guest? (Only archane
1666 * messenger service requests have this...)
1668 if (flags & AS_GUEST) {
1669 char *raddr;
1670 bool ok;
1672 if (!change_to_guest()) {
1673 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1674 return conn;
1677 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1678 talloc_tos());
1679 if (raddr == NULL) {
1680 reply_nterror(req, NT_STATUS_NO_MEMORY);
1681 return conn;
1685 * Haven't we checked this in smbd_process already???
1688 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1689 xconn->remote_hostname, raddr);
1690 TALLOC_FREE(raddr);
1692 if (!ok) {
1693 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1694 return conn;
1699 * Update encryption and signing state tracking flags that are
1700 * used by smbstatus to display signing and encryption status.
1702 if (session != NULL) {
1703 bool update_session_global = false;
1704 bool update_tcon_global = false;
1706 smb1srv_update_crypto_flags(session, req, type,
1707 &update_session_global,
1708 &update_tcon_global);
1710 if (update_session_global) {
1711 status = smbXsrv_session_update(session);
1712 if (!NT_STATUS_IS_OK(status)) {
1713 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1714 return conn;
1718 if (update_tcon_global) {
1719 status = smbXsrv_tcon_update(req->conn->tcon);
1720 if (!NT_STATUS_IS_OK(status)) {
1721 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1722 return conn;
1727 smb_messages[type].fn(req);
1728 return req->conn;
1731 /****************************************************************************
1732 Construct a reply to the incoming packet.
1733 ****************************************************************************/
1735 static void construct_reply(struct smbXsrv_connection *xconn,
1736 char *inbuf, int size, size_t unread_bytes,
1737 uint32_t seqnum, bool encrypted,
1738 struct smb_perfcount_data *deferred_pcd)
1740 struct smbd_server_connection *sconn = xconn->client->sconn;
1741 struct smb_request *req;
1743 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1744 smb_panic("could not allocate smb_request");
1747 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1748 encrypted, seqnum)) {
1749 exit_server_cleanly("Invalid SMB request");
1752 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1754 /* we popped this message off the queue - keep original perf data */
1755 if (deferred_pcd)
1756 req->pcd = *deferred_pcd;
1757 else {
1758 SMB_PERFCOUNT_START(&req->pcd);
1759 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1760 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1763 req->conn = switch_message(req->cmd, req);
1765 if (req->outbuf == NULL) {
1767 * Request has suspended itself, will come
1768 * back here.
1770 return;
1772 if (CVAL(req->outbuf,0) == 0) {
1773 show_msg((char *)req->outbuf);
1775 smb_request_done(req);
1778 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1779 char *inbuf, int size, uint32_t seqnum,
1780 bool encrypted,
1781 struct smb_perfcount_data *deferred_pcd)
1783 struct smb_request **reqs = NULL;
1784 struct smb_request *req;
1785 unsigned num_reqs;
1786 bool ok;
1788 ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
1789 seqnum, &reqs, &num_reqs);
1790 if (!ok) {
1791 char errbuf[smb_size];
1792 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1793 __LINE__, __FILE__);
1794 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1795 NULL)) {
1796 exit_server_cleanly("construct_reply_chain: "
1797 "srv_send_smb failed.");
1799 return;
1802 req = reqs[0];
1803 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1805 req->conn = switch_message(req->cmd, req);
1807 if (req->outbuf == NULL) {
1809 * Request has suspended itself, will come
1810 * back here.
1812 return;
1814 smb_request_done(req);
1818 * To be called from an async SMB handler that is potentially chained
1819 * when it is finished for shipping.
1822 void smb_request_done(struct smb_request *req)
1824 struct smb_request **reqs = NULL;
1825 struct smb_request *first_req;
1826 size_t i, num_reqs, next_index;
1827 NTSTATUS status;
1829 if (req->chain == NULL) {
1830 first_req = req;
1831 goto shipit;
1834 reqs = req->chain;
1835 num_reqs = talloc_array_length(reqs);
1837 for (i=0; i<num_reqs; i++) {
1838 if (reqs[i] == req) {
1839 break;
1842 if (i == num_reqs) {
1844 * Invalid chain, should not happen
1846 status = NT_STATUS_INTERNAL_ERROR;
1847 goto error;
1849 next_index = i+1;
1851 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1852 struct smb_request *next = reqs[next_index];
1853 struct smbXsrv_tcon *tcon;
1854 NTTIME now = timeval_to_nttime(&req->request_time);
1856 next->vuid = SVAL(req->outbuf, smb_uid);
1857 next->tid = SVAL(req->outbuf, smb_tid);
1858 status = smb1srv_tcon_lookup(req->xconn, next->tid,
1859 now, &tcon);
1861 if (NT_STATUS_IS_OK(status)) {
1862 next->conn = tcon->compat;
1863 } else {
1864 next->conn = NULL;
1866 next->chain_fsp = req->chain_fsp;
1867 next->inbuf = req->inbuf;
1869 req = next;
1870 req->conn = switch_message(req->cmd, req);
1872 if (req->outbuf == NULL) {
1874 * Request has suspended itself, will come
1875 * back here.
1877 return;
1879 next_index += 1;
1882 first_req = reqs[0];
1884 for (i=1; i<next_index; i++) {
1885 bool ok;
1887 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1888 if (!ok) {
1889 status = NT_STATUS_INTERNAL_ERROR;
1890 goto error;
1894 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1895 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1898 * This scary statement intends to set the
1899 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1900 * to the value last_req->outbuf carries
1902 SSVAL(first_req->outbuf, smb_flg2,
1903 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1904 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1907 * Transfer the error codes from the subrequest to the main one
1909 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1910 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1912 _smb_setlen_large(
1913 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1915 shipit:
1916 if (!srv_send_smb(first_req->xconn,
1917 (char *)first_req->outbuf,
1918 true, first_req->seqnum+1,
1919 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1920 &first_req->pcd)) {
1921 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1922 "failed.");
1924 TALLOC_FREE(req); /* non-chained case */
1925 TALLOC_FREE(reqs); /* chained case */
1926 return;
1928 error:
1930 char errbuf[smb_size];
1931 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1932 if (!srv_send_smb(req->xconn, errbuf, true,
1933 req->seqnum+1, req->encrypted,
1934 NULL)) {
1935 exit_server_cleanly("construct_reply_chain: "
1936 "srv_send_smb failed.");
1939 TALLOC_FREE(req); /* non-chained case */
1940 TALLOC_FREE(reqs); /* chained case */
1943 /****************************************************************************
1944 Process an smb from the client
1945 ****************************************************************************/
1946 static void process_smb(struct smbXsrv_connection *xconn,
1947 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1948 uint32_t seqnum, bool encrypted,
1949 struct smb_perfcount_data *deferred_pcd)
1951 struct smbd_server_connection *sconn = xconn->client->sconn;
1952 int msg_type = CVAL(inbuf,0);
1954 DO_PROFILE_INC(request);
1956 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1957 smb_len(inbuf) ) );
1958 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1959 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1961 if (msg_type != NBSSmessage) {
1963 * NetBIOS session request, keepalive, etc.
1965 reply_special(xconn, (char *)inbuf, nread);
1966 goto done;
1969 if (sconn->using_smb2) {
1970 /* At this point we're not really using smb2,
1971 * we make the decision here.. */
1972 if (smbd_is_smb2_header(inbuf, nread)) {
1973 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1974 size_t pdulen = nread - NBT_HDR_SIZE;
1975 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1976 return;
1978 if (nread >= smb_size && valid_smb_header(inbuf)
1979 && CVAL(inbuf, smb_com) != 0x72) {
1980 /* This is a non-negprot SMB1 packet.
1981 Disable SMB2 from now on. */
1982 sconn->using_smb2 = false;
1986 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1987 * so subtract 4 from it. */
1988 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1989 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1990 smb_len(inbuf)));
1992 /* special magic for immediate exit */
1993 if ((nread == 9) &&
1994 (IVAL(inbuf, 4) == 0x74697865) &&
1995 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1996 uint8_t exitcode = CVAL(inbuf, 8);
1997 DEBUG(1, ("Exiting immediately with code %d\n",
1998 (int)exitcode));
1999 exit(exitcode);
2002 exit_server_cleanly("Non-SMB packet");
2005 show_msg((char *)inbuf);
2007 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
2008 construct_reply_chain(xconn, (char *)inbuf, nread,
2009 seqnum, encrypted, deferred_pcd);
2010 } else {
2011 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
2012 seqnum, encrypted, deferred_pcd);
2015 sconn->trans_num++;
2017 done:
2018 sconn->num_requests++;
2020 /* The timeout_processing function isn't run nearly
2021 often enough to implement 'max log size' without
2022 overrunning the size of the file by many megabytes.
2023 This is especially true if we are running at debug
2024 level 10. Checking every 50 SMBs is a nice
2025 tradeoff of performance vs log file size overrun. */
2027 if ((sconn->num_requests % 50) == 0 &&
2028 need_to_check_log_size()) {
2029 change_to_root_user();
2030 check_log_size();
2034 /****************************************************************************
2035 Return a string containing the function name of a SMB command.
2036 ****************************************************************************/
2038 const char *smb_fn_name(int type)
2040 const char *unknown_name = "SMBunknown";
2042 if (smb_messages[type].name == NULL)
2043 return(unknown_name);
2045 return(smb_messages[type].name);
2048 /****************************************************************************
2049 Helper functions for contruct_reply.
2050 ****************************************************************************/
2052 void add_to_common_flags2(uint32_t v)
2054 common_flags2 |= v;
2057 void remove_from_common_flags2(uint32_t v)
2059 common_flags2 &= ~v;
2062 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
2063 char *outbuf)
2065 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
2066 uint16_t out_flags2 = common_flags2;
2068 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
2069 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
2070 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
2072 srv_set_message(outbuf,0,0,false);
2074 SCVAL(outbuf, smb_com, cmd);
2075 SIVAL(outbuf,smb_rcls,0);
2076 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
2077 SSVAL(outbuf,smb_flg2, out_flags2);
2078 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
2079 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2081 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2082 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2083 SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
2084 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2085 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2088 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2090 construct_reply_common(req->cmd, req->inbuf, outbuf);
2094 * @brief Find the smb_cmd offset of the last command pushed
2095 * @param[in] buf The buffer we're building up
2096 * @retval Where can we put our next andx cmd?
2098 * While chaining requests, the "next" request we're looking at needs to put
2099 * its SMB_Command before the data the previous request already built up added
2100 * to the chain. Find the offset to the place where we have to put our cmd.
2103 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2105 uint8_t cmd;
2106 size_t ofs;
2108 cmd = CVAL(buf, smb_com);
2110 if (!is_andx_req(cmd)) {
2111 return false;
2114 ofs = smb_vwv0;
2116 while (CVAL(buf, ofs) != 0xff) {
2118 if (!is_andx_req(CVAL(buf, ofs))) {
2119 return false;
2123 * ofs is from start of smb header, so add the 4 length
2124 * bytes. The next cmd is right after the wct field.
2126 ofs = SVAL(buf, ofs+2) + 4 + 1;
2128 if (ofs+4 >= talloc_get_size(buf)) {
2129 return false;
2133 *pofs = ofs;
2134 return true;
2138 * @brief Do the smb chaining at a buffer level
2139 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2140 * @param[in] andx_buf Buffer to be appended
2143 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2145 uint8_t smb_command = CVAL(andx_buf, smb_com);
2146 uint8_t wct = CVAL(andx_buf, smb_wct);
2147 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2148 uint32_t num_bytes = smb_buflen(andx_buf);
2149 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2151 uint8_t *outbuf;
2152 size_t old_size, new_size;
2153 size_t ofs;
2154 size_t chain_padding = 0;
2155 size_t andx_cmd_ofs;
2158 old_size = talloc_get_size(*poutbuf);
2160 if ((old_size % 4) != 0) {
2162 * Align the wct field of subsequent requests to a 4-byte
2163 * boundary
2165 chain_padding = 4 - (old_size % 4);
2169 * After the old request comes the new wct field (1 byte), the vwv's
2170 * and the num_bytes field.
2173 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2174 new_size += num_bytes;
2176 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2177 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2178 (unsigned)new_size));
2179 return false;
2182 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2183 if (outbuf == NULL) {
2184 DEBUG(0, ("talloc failed\n"));
2185 return false;
2187 *poutbuf = outbuf;
2189 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2190 DEBUG(1, ("invalid command chain\n"));
2191 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2192 return false;
2195 if (chain_padding != 0) {
2196 memset(outbuf + old_size, 0, chain_padding);
2197 old_size += chain_padding;
2200 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2201 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2203 ofs = old_size;
2206 * Push the chained request:
2208 * wct field
2211 SCVAL(outbuf, ofs, wct);
2212 ofs += 1;
2215 * vwv array
2218 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2221 * HACK ALERT
2223 * Read&X has an offset into its data buffer at
2224 * vwv[6]. reply_read_andx has no idea anymore that it's
2225 * running from within a chain, so we have to fix up the
2226 * offset here.
2228 * Although it looks disgusting at this place, I want to keep
2229 * it here. The alternative would be to push knowledge about
2230 * the andx chain down into read&x again.
2233 if (smb_command == SMBreadX) {
2234 uint8_t *bytes_addr;
2236 if (wct < 7) {
2238 * Invalid read&x response
2240 return false;
2243 bytes_addr = outbuf + ofs /* vwv start */
2244 + sizeof(uint16_t) * wct /* vwv array */
2245 + sizeof(uint16_t) /* bcc */
2246 + 1; /* padding byte */
2248 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2249 bytes_addr - outbuf - 4);
2252 ofs += sizeof(uint16_t) * wct;
2255 * bcc (byte count)
2258 SSVAL(outbuf, ofs, num_bytes);
2259 ofs += sizeof(uint16_t);
2262 * The bytes field
2265 memcpy(outbuf + ofs, bytes, num_bytes);
2267 return true;
2270 bool smb1_is_chain(const uint8_t *buf)
2272 uint8_t cmd, wct, andx_cmd;
2274 cmd = CVAL(buf, smb_com);
2275 if (!is_andx_req(cmd)) {
2276 return false;
2278 wct = CVAL(buf, smb_wct);
2279 if (wct < 2) {
2280 return false;
2282 andx_cmd = CVAL(buf, smb_vwv);
2283 return (andx_cmd != 0xFF);
2286 bool smb1_walk_chain(const uint8_t *buf,
2287 bool (*fn)(uint8_t cmd,
2288 uint8_t wct, const uint16_t *vwv,
2289 uint16_t num_bytes, const uint8_t *bytes,
2290 void *private_data),
2291 void *private_data)
2293 size_t smblen = smb_len(buf);
2294 const char *smb_buf = smb_base(buf);
2295 uint8_t cmd, chain_cmd;
2296 uint8_t wct;
2297 const uint16_t *vwv;
2298 uint16_t num_bytes;
2299 const uint8_t *bytes;
2301 cmd = CVAL(buf, smb_com);
2302 wct = CVAL(buf, smb_wct);
2303 vwv = (const uint16_t *)(buf + smb_vwv);
2304 num_bytes = smb_buflen(buf);
2305 bytes = (const uint8_t *)smb_buf_const(buf);
2307 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2308 return false;
2311 if (!is_andx_req(cmd)) {
2312 return true;
2314 if (wct < 2) {
2315 return false;
2318 chain_cmd = CVAL(vwv, 0);
2320 while (chain_cmd != 0xff) {
2321 uint32_t chain_offset; /* uint32_t to avoid overflow */
2322 size_t length_needed;
2323 ptrdiff_t vwv_offset;
2325 chain_offset = SVAL(vwv+1, 0);
2328 * Check if the client tries to fool us. The chain
2329 * offset needs to point beyond the current request in
2330 * the chain, it needs to strictly grow. Otherwise we
2331 * might be tricked into an endless loop always
2332 * processing the same request over and over again. We
2333 * used to assume that vwv and the byte buffer array
2334 * in a chain are always attached, but OS/2 the
2335 * Write&X/Read&X chain puts the Read&X vwv array
2336 * right behind the Write&X vwv chain. The Write&X bcc
2337 * array is put behind the Read&X vwv array. So now we
2338 * check whether the chain offset points strictly
2339 * behind the previous vwv array. req->buf points
2340 * right after the vwv array of the previous
2341 * request. See
2342 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2343 * more information.
2346 vwv_offset = ((const char *)vwv - smb_buf);
2347 if (chain_offset <= vwv_offset) {
2348 return false;
2352 * Next check: Make sure the chain offset does not
2353 * point beyond the overall smb request length.
2356 length_needed = chain_offset+1; /* wct */
2357 if (length_needed > smblen) {
2358 return false;
2362 * Now comes the pointer magic. Goal here is to set up
2363 * vwv and buf correctly again. The chain offset (the
2364 * former vwv[1]) points at the new wct field.
2367 wct = CVAL(smb_buf, chain_offset);
2369 if (is_andx_req(chain_cmd) && (wct < 2)) {
2370 return false;
2374 * Next consistency check: Make the new vwv array fits
2375 * in the overall smb request.
2378 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2379 if (length_needed > smblen) {
2380 return false;
2382 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2385 * Now grab the new byte buffer....
2388 num_bytes = SVAL(vwv+wct, 0);
2391 * .. and check that it fits.
2394 length_needed += num_bytes;
2395 if (length_needed > smblen) {
2396 return false;
2398 bytes = (const uint8_t *)(vwv+wct+1);
2400 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2401 return false;
2404 if (!is_andx_req(chain_cmd)) {
2405 return true;
2407 chain_cmd = CVAL(vwv, 0);
2409 return true;
2412 static bool smb1_chain_length_cb(uint8_t cmd,
2413 uint8_t wct, const uint16_t *vwv,
2414 uint16_t num_bytes, const uint8_t *bytes,
2415 void *private_data)
2417 unsigned *count = (unsigned *)private_data;
2418 *count += 1;
2419 return true;
2422 unsigned smb1_chain_length(const uint8_t *buf)
2424 unsigned count = 0;
2426 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2427 return 0;
2429 return count;
2432 struct smb1_parse_chain_state {
2433 TALLOC_CTX *mem_ctx;
2434 const uint8_t *buf;
2435 struct smbd_server_connection *sconn;
2436 struct smbXsrv_connection *xconn;
2437 bool encrypted;
2438 uint32_t seqnum;
2440 struct smb_request **reqs;
2441 unsigned num_reqs;
2444 static bool smb1_parse_chain_cb(uint8_t cmd,
2445 uint8_t wct, const uint16_t *vwv,
2446 uint16_t num_bytes, const uint8_t *bytes,
2447 void *private_data)
2449 struct smb1_parse_chain_state *state =
2450 (struct smb1_parse_chain_state *)private_data;
2451 struct smb_request **reqs;
2452 struct smb_request *req;
2453 bool ok;
2455 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2456 struct smb_request *, state->num_reqs+1);
2457 if (reqs == NULL) {
2458 return false;
2460 state->reqs = reqs;
2462 req = talloc(reqs, struct smb_request);
2463 if (req == NULL) {
2464 return false;
2467 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2468 state->encrypted, state->seqnum);
2469 if (!ok) {
2470 return false;
2472 req->cmd = cmd;
2473 req->wct = wct;
2474 req->vwv = vwv;
2475 req->buflen = num_bytes;
2476 req->buf = bytes;
2478 reqs[state->num_reqs] = req;
2479 state->num_reqs += 1;
2480 return true;
2483 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2484 struct smbXsrv_connection *xconn,
2485 bool encrypted, uint32_t seqnum,
2486 struct smb_request ***reqs, unsigned *num_reqs)
2488 struct smbd_server_connection *sconn = NULL;
2489 struct smb1_parse_chain_state state;
2490 unsigned i;
2492 if (xconn != NULL) {
2493 sconn = xconn->client->sconn;
2496 state.mem_ctx = mem_ctx;
2497 state.buf = buf;
2498 state.sconn = sconn;
2499 state.xconn = xconn;
2500 state.encrypted = encrypted;
2501 state.seqnum = seqnum;
2502 state.reqs = NULL;
2503 state.num_reqs = 0;
2505 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2506 TALLOC_FREE(state.reqs);
2507 return false;
2509 for (i=0; i<state.num_reqs; i++) {
2510 state.reqs[i]->chain = state.reqs;
2512 *reqs = state.reqs;
2513 *num_reqs = state.num_reqs;
2514 return true;
2517 /****************************************************************************
2518 Check if services need reloading.
2519 ****************************************************************************/
2521 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2524 if (last_smb_conf_reload_time == 0) {
2525 last_smb_conf_reload_time = t;
2528 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2529 reload_services(sconn, conn_snum_used, true);
2530 last_smb_conf_reload_time = t;
2534 static bool fd_is_readable(int fd)
2536 int ret, revents;
2538 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2540 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2544 static void smbd_server_connection_write_handler(
2545 struct smbXsrv_connection *xconn)
2547 /* TODO: make write nonblocking */
2550 static void smbd_server_connection_read_handler(
2551 struct smbXsrv_connection *xconn, int fd)
2553 uint8_t *inbuf = NULL;
2554 size_t inbuf_len = 0;
2555 size_t unread_bytes = 0;
2556 bool encrypted = false;
2557 TALLOC_CTX *mem_ctx = talloc_tos();
2558 NTSTATUS status;
2559 uint32_t seqnum;
2561 bool async_echo = lp_async_smb_echo_handler();
2562 bool from_client = false;
2564 if (async_echo) {
2565 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2567 * This is the super-ugly hack to prefer the packets
2568 * forwarded by the echo handler over the ones by the
2569 * client directly
2571 fd = xconn->smb1.echo_handler.trusted_fd;
2575 from_client = (xconn->transport.sock == fd);
2577 if (async_echo && from_client) {
2578 smbd_lock_socket(xconn);
2580 if (!fd_is_readable(fd)) {
2581 DEBUG(10,("the echo listener was faster\n"));
2582 smbd_unlock_socket(xconn);
2583 return;
2587 /* TODO: make this completely nonblocking */
2588 status = receive_smb_talloc(mem_ctx, xconn, fd,
2589 (char **)(void *)&inbuf,
2590 0, /* timeout */
2591 &unread_bytes,
2592 &encrypted,
2593 &inbuf_len, &seqnum,
2594 !from_client /* trusted channel */);
2596 if (async_echo && from_client) {
2597 smbd_unlock_socket(xconn);
2600 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2601 goto process;
2603 if (NT_STATUS_IS_ERR(status)) {
2604 exit_server_cleanly("failed to receive smb request");
2606 if (!NT_STATUS_IS_OK(status)) {
2607 return;
2610 process:
2611 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2612 seqnum, encrypted, NULL);
2615 static void smbd_server_connection_handler(struct tevent_context *ev,
2616 struct tevent_fd *fde,
2617 uint16_t flags,
2618 void *private_data)
2620 struct smbXsrv_connection *xconn =
2621 talloc_get_type_abort(private_data,
2622 struct smbXsrv_connection);
2624 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2626 * we're not supposed to do any io
2628 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2629 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2630 return;
2633 if (flags & TEVENT_FD_WRITE) {
2634 smbd_server_connection_write_handler(xconn);
2635 return;
2637 if (flags & TEVENT_FD_READ) {
2638 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2639 return;
2643 static void smbd_server_echo_handler(struct tevent_context *ev,
2644 struct tevent_fd *fde,
2645 uint16_t flags,
2646 void *private_data)
2648 struct smbXsrv_connection *xconn =
2649 talloc_get_type_abort(private_data,
2650 struct smbXsrv_connection);
2652 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2654 * we're not supposed to do any io
2656 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2657 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2658 return;
2661 if (flags & TEVENT_FD_WRITE) {
2662 smbd_server_connection_write_handler(xconn);
2663 return;
2665 if (flags & TEVENT_FD_READ) {
2666 smbd_server_connection_read_handler(
2667 xconn, xconn->smb1.echo_handler.trusted_fd);
2668 return;
2672 struct smbd_release_ip_state {
2673 struct smbXsrv_connection *xconn;
2674 struct tevent_immediate *im;
2675 char addr[INET6_ADDRSTRLEN];
2678 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2679 struct tevent_immediate *im,
2680 void *private_data)
2682 struct smbd_release_ip_state *state =
2683 talloc_get_type_abort(private_data,
2684 struct smbd_release_ip_state);
2685 struct smbXsrv_connection *xconn = state->xconn;
2687 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2689 * smbd_server_connection_terminate() already triggered ?
2691 return;
2694 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2697 /****************************************************************************
2698 received when we should release a specific IP
2699 ****************************************************************************/
2700 static int release_ip(struct tevent_context *ev,
2701 uint32_t src_vnn, uint32_t dst_vnn,
2702 uint64_t dst_srvid,
2703 const uint8_t *msg, size_t msglen,
2704 void *private_data)
2706 struct smbd_release_ip_state *state =
2707 talloc_get_type_abort(private_data,
2708 struct smbd_release_ip_state);
2709 struct smbXsrv_connection *xconn = state->xconn;
2710 const char *ip;
2711 const char *addr = state->addr;
2712 const char *p = addr;
2714 if (msglen == 0) {
2715 return 0;
2717 if (msg[msglen-1] != '\0') {
2718 return 0;
2721 ip = (const char *)msg;
2723 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2724 /* avoid recursion */
2725 return 0;
2728 if (strncmp("::ffff:", addr, 7) == 0) {
2729 p = addr + 7;
2732 DEBUG(10, ("Got release IP message for %s, "
2733 "our address is %s\n", ip, p));
2735 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2736 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2737 ip));
2739 * With SMB2 we should do a clean disconnect,
2740 * the previous_session_id in the session setup
2741 * will cleanup the old session, tcons and opens.
2743 * A clean disconnect is needed in order to support
2744 * durable handles.
2746 * Note: typically this is never triggered
2747 * as we got a TCP RST (triggered by ctdb event scripts)
2748 * before we get CTDB_SRVID_RELEASE_IP.
2750 * We used to call _exit(1) here, but as this was mostly never
2751 * triggered and has implication on our process model,
2752 * we can just use smbd_server_connection_terminate()
2753 * (also for SMB1).
2755 * We don't call smbd_server_connection_terminate() directly
2756 * as we might be called from within ctdbd_migrate(),
2757 * we need to defer our action to the next event loop
2759 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2760 smbd_release_ip_immediate, state);
2763 * Make sure we don't get any io on the connection.
2765 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2766 return EADDRNOTAVAIL;
2769 return 0;
2772 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2773 struct sockaddr_storage *srv,
2774 struct sockaddr_storage *clnt)
2776 struct smbd_release_ip_state *state;
2777 struct ctdbd_connection *cconn;
2778 int ret;
2780 cconn = messaging_ctdb_connection();
2781 if (cconn == NULL) {
2782 return NT_STATUS_NO_MEMORY;
2785 state = talloc_zero(xconn, struct smbd_release_ip_state);
2786 if (state == NULL) {
2787 return NT_STATUS_NO_MEMORY;
2789 state->xconn = xconn;
2790 state->im = tevent_create_immediate(state);
2791 if (state->im == NULL) {
2792 return NT_STATUS_NO_MEMORY;
2794 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2795 return NT_STATUS_NO_MEMORY;
2798 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2799 if (ret != 0) {
2800 return map_nt_error_from_unix(ret);
2802 return NT_STATUS_OK;
2805 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2806 void *private_data, uint32_t msg_type,
2807 struct server_id server_id, DATA_BLOB *data)
2809 struct smbd_server_connection *sconn = talloc_get_type_abort(
2810 private_data, struct smbd_server_connection);
2811 const char *ip = (char *) data->data;
2812 char *client_ip;
2814 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2816 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2817 talloc_tos());
2818 if (client_ip == NULL) {
2819 return;
2822 if (strequal(ip, client_ip)) {
2823 DBG_WARNING("Got kill client message for %s - "
2824 "exiting immediately\n", ip);
2825 exit_server_cleanly("Forced disconnect for client");
2828 TALLOC_FREE(client_ip);
2832 * Send keepalive packets to our client
2834 static bool keepalive_fn(const struct timeval *now, void *private_data)
2836 struct smbd_server_connection *sconn = talloc_get_type_abort(
2837 private_data, struct smbd_server_connection);
2838 struct smbXsrv_connection *xconn = NULL;
2839 bool ret;
2841 if (sconn->using_smb2) {
2842 /* Don't do keepalives on an SMB2 connection. */
2843 return false;
2847 * With SMB1 we only have 1 connection
2849 xconn = sconn->client->connections;
2850 smbd_lock_socket(xconn);
2851 ret = send_keepalive(xconn->transport.sock);
2852 smbd_unlock_socket(xconn);
2854 if (!ret) {
2855 int saved_errno = errno;
2857 * Try and give an error message saying what
2858 * client failed.
2860 DEBUG(0, ("send_keepalive failed for client %s. "
2861 "Error %s - exiting\n",
2862 smbXsrv_connection_dbg(xconn),
2863 strerror(saved_errno)));
2864 errno = saved_errno;
2865 return False;
2867 return True;
2871 * Do the recurring check if we're idle
2873 static bool deadtime_fn(const struct timeval *now, void *private_data)
2875 struct smbd_server_connection *sconn =
2876 (struct smbd_server_connection *)private_data;
2878 if ((conn_num_open(sconn) == 0)
2879 || (conn_idle_all(sconn, now->tv_sec))) {
2880 DEBUG( 2, ( "Closing idle connection\n" ) );
2881 messaging_send(sconn->msg_ctx,
2882 messaging_server_id(sconn->msg_ctx),
2883 MSG_SHUTDOWN, &data_blob_null);
2884 return False;
2887 return True;
2891 * Do the recurring log file and smb.conf reload checks.
2894 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2896 struct smbd_server_connection *sconn = talloc_get_type_abort(
2897 private_data, struct smbd_server_connection);
2899 DEBUG(5, ("housekeeping\n"));
2901 change_to_root_user();
2903 /* update printer queue caches if necessary */
2904 update_monitored_printq_cache(sconn->msg_ctx);
2906 /* check if we need to reload services */
2907 check_reload(sconn, time_mono(NULL));
2910 * Force a log file check.
2912 force_check_log_size();
2913 check_log_size();
2914 return true;
2918 * Read an smb packet in the echo handler child, giving the parent
2919 * smbd one second to react once the socket becomes readable.
2922 struct smbd_echo_read_state {
2923 struct tevent_context *ev;
2924 struct smbXsrv_connection *xconn;
2926 char *buf;
2927 size_t buflen;
2928 uint32_t seqnum;
2931 static void smbd_echo_read_readable(struct tevent_req *subreq);
2932 static void smbd_echo_read_waited(struct tevent_req *subreq);
2934 static struct tevent_req *smbd_echo_read_send(
2935 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2936 struct smbXsrv_connection *xconn)
2938 struct tevent_req *req, *subreq;
2939 struct smbd_echo_read_state *state;
2941 req = tevent_req_create(mem_ctx, &state,
2942 struct smbd_echo_read_state);
2943 if (req == NULL) {
2944 return NULL;
2946 state->ev = ev;
2947 state->xconn = xconn;
2949 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2950 if (tevent_req_nomem(subreq, req)) {
2951 return tevent_req_post(req, ev);
2953 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2954 return req;
2957 static void smbd_echo_read_readable(struct tevent_req *subreq)
2959 struct tevent_req *req = tevent_req_callback_data(
2960 subreq, struct tevent_req);
2961 struct smbd_echo_read_state *state = tevent_req_data(
2962 req, struct smbd_echo_read_state);
2963 bool ok;
2964 int err;
2966 ok = wait_for_read_recv(subreq, &err);
2967 TALLOC_FREE(subreq);
2968 if (!ok) {
2969 tevent_req_nterror(req, map_nt_error_from_unix(err));
2970 return;
2974 * Give the parent smbd one second to step in
2977 subreq = tevent_wakeup_send(
2978 state, state->ev, timeval_current_ofs(1, 0));
2979 if (tevent_req_nomem(subreq, req)) {
2980 return;
2982 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2985 static void smbd_echo_read_waited(struct tevent_req *subreq)
2987 struct tevent_req *req = tevent_req_callback_data(
2988 subreq, struct tevent_req);
2989 struct smbd_echo_read_state *state = tevent_req_data(
2990 req, struct smbd_echo_read_state);
2991 struct smbXsrv_connection *xconn = state->xconn;
2992 bool ok;
2993 NTSTATUS status;
2994 size_t unread = 0;
2995 bool encrypted;
2997 ok = tevent_wakeup_recv(subreq);
2998 TALLOC_FREE(subreq);
2999 if (!ok) {
3000 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
3001 return;
3004 ok = smbd_lock_socket_internal(xconn);
3005 if (!ok) {
3006 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3007 DEBUG(0, ("%s: failed to lock socket\n", __location__));
3008 return;
3011 if (!fd_is_readable(xconn->transport.sock)) {
3012 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3013 (int)getpid()));
3015 ok = smbd_unlock_socket_internal(xconn);
3016 if (!ok) {
3017 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3018 DEBUG(1, ("%s: failed to unlock socket\n",
3019 __location__));
3020 return;
3023 subreq = wait_for_read_send(state, state->ev,
3024 xconn->transport.sock, false);
3025 if (tevent_req_nomem(subreq, req)) {
3026 return;
3028 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
3029 return;
3032 status = receive_smb_talloc(state, xconn,
3033 xconn->transport.sock,
3034 &state->buf,
3035 0 /* timeout */,
3036 &unread,
3037 &encrypted,
3038 &state->buflen,
3039 &state->seqnum,
3040 false /* trusted_channel*/);
3042 if (tevent_req_nterror(req, status)) {
3043 tevent_req_nterror(req, status);
3044 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3045 (int)getpid(), nt_errstr(status)));
3046 return;
3049 ok = smbd_unlock_socket_internal(xconn);
3050 if (!ok) {
3051 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3052 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
3053 return;
3055 tevent_req_done(req);
3058 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3059 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
3061 struct smbd_echo_read_state *state = tevent_req_data(
3062 req, struct smbd_echo_read_state);
3063 NTSTATUS status;
3065 if (tevent_req_is_nterror(req, &status)) {
3066 return status;
3068 *pbuf = talloc_move(mem_ctx, &state->buf);
3069 *pbuflen = state->buflen;
3070 *pseqnum = state->seqnum;
3071 return NT_STATUS_OK;
3074 struct smbd_echo_state {
3075 struct tevent_context *ev;
3076 struct iovec *pending;
3077 struct smbd_server_connection *sconn;
3078 struct smbXsrv_connection *xconn;
3079 int parent_pipe;
3081 struct tevent_fd *parent_fde;
3083 struct tevent_req *write_req;
3086 static void smbd_echo_writer_done(struct tevent_req *req);
3088 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3090 int num_pending;
3092 if (state->write_req != NULL) {
3093 return;
3096 num_pending = talloc_array_length(state->pending);
3097 if (num_pending == 0) {
3098 return;
3101 state->write_req = writev_send(state, state->ev, NULL,
3102 state->parent_pipe, false,
3103 state->pending, num_pending);
3104 if (state->write_req == NULL) {
3105 DEBUG(1, ("writev_send failed\n"));
3106 exit(1);
3109 talloc_steal(state->write_req, state->pending);
3110 state->pending = NULL;
3112 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3113 state);
3116 static void smbd_echo_writer_done(struct tevent_req *req)
3118 struct smbd_echo_state *state = tevent_req_callback_data(
3119 req, struct smbd_echo_state);
3120 ssize_t written;
3121 int err;
3123 written = writev_recv(req, &err);
3124 TALLOC_FREE(req);
3125 state->write_req = NULL;
3126 if (written == -1) {
3127 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3128 exit(1);
3130 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3131 smbd_echo_activate_writer(state);
3134 static bool smbd_echo_reply(struct smbd_echo_state *state,
3135 uint8_t *inbuf, size_t inbuf_len,
3136 uint32_t seqnum)
3138 struct smb_request req;
3139 uint16_t num_replies;
3140 char *outbuf;
3141 bool ok;
3143 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3144 DEBUG(10, ("Got netbios keepalive\n"));
3146 * Just swallow it
3148 return true;
3151 if (inbuf_len < smb_size) {
3152 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3153 return false;
3155 if (!valid_smb_header(inbuf)) {
3156 DEBUG(10, ("Got invalid SMB header\n"));
3157 return false;
3160 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3161 seqnum)) {
3162 return false;
3164 req.inbuf = inbuf;
3166 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3167 smb_messages[req.cmd].name
3168 ? smb_messages[req.cmd].name : "unknown"));
3170 if (req.cmd != SMBecho) {
3171 return false;
3173 if (req.wct < 1) {
3174 return false;
3177 num_replies = SVAL(req.vwv+0, 0);
3178 if (num_replies != 1) {
3179 /* Not a Windows "Hey, you're still there?" request */
3180 return false;
3183 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3184 1, req.buflen)) {
3185 DEBUG(10, ("create_outbuf failed\n"));
3186 return false;
3188 req.outbuf = (uint8_t *)outbuf;
3190 SSVAL(req.outbuf, smb_vwv0, num_replies);
3192 if (req.buflen > 0) {
3193 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3196 ok = srv_send_smb(req.xconn,
3197 (char *)outbuf,
3198 true, seqnum+1,
3199 false, &req.pcd);
3200 TALLOC_FREE(outbuf);
3201 if (!ok) {
3202 exit(1);
3205 return true;
3208 static void smbd_echo_exit(struct tevent_context *ev,
3209 struct tevent_fd *fde, uint16_t flags,
3210 void *private_data)
3212 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3213 exit(0);
3216 static void smbd_echo_got_packet(struct tevent_req *req);
3218 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3219 int parent_pipe)
3221 struct smbd_echo_state *state;
3222 struct tevent_req *read_req;
3224 state = talloc_zero(xconn, struct smbd_echo_state);
3225 if (state == NULL) {
3226 DEBUG(1, ("talloc failed\n"));
3227 return;
3229 state->xconn = xconn;
3230 state->parent_pipe = parent_pipe;
3231 state->ev = samba_tevent_context_init(state);
3232 if (state->ev == NULL) {
3233 DEBUG(1, ("samba_tevent_context_init failed\n"));
3234 TALLOC_FREE(state);
3235 return;
3237 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3238 TEVENT_FD_READ, smbd_echo_exit,
3239 state);
3240 if (state->parent_fde == NULL) {
3241 DEBUG(1, ("tevent_add_fd failed\n"));
3242 TALLOC_FREE(state);
3243 return;
3246 read_req = smbd_echo_read_send(state, state->ev, xconn);
3247 if (read_req == NULL) {
3248 DEBUG(1, ("smbd_echo_read_send failed\n"));
3249 TALLOC_FREE(state);
3250 return;
3252 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3254 while (true) {
3255 if (tevent_loop_once(state->ev) == -1) {
3256 DEBUG(1, ("tevent_loop_once failed: %s\n",
3257 strerror(errno)));
3258 break;
3261 TALLOC_FREE(state);
3264 static void smbd_echo_got_packet(struct tevent_req *req)
3266 struct smbd_echo_state *state = tevent_req_callback_data(
3267 req, struct smbd_echo_state);
3268 NTSTATUS status;
3269 char *buf = NULL;
3270 size_t buflen = 0;
3271 uint32_t seqnum = 0;
3272 bool reply;
3274 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3275 TALLOC_FREE(req);
3276 if (!NT_STATUS_IS_OK(status)) {
3277 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3278 nt_errstr(status)));
3279 exit(1);
3282 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3283 if (!reply) {
3284 size_t num_pending;
3285 struct iovec *tmp;
3286 struct iovec *iov;
3288 num_pending = talloc_array_length(state->pending);
3289 tmp = talloc_realloc(state, state->pending, struct iovec,
3290 num_pending+1);
3291 if (tmp == NULL) {
3292 DEBUG(1, ("talloc_realloc failed\n"));
3293 exit(1);
3295 state->pending = tmp;
3297 if (buflen >= smb_size) {
3299 * place the seqnum in the packet so that the main process
3300 * can reply with signing
3302 SIVAL(buf, smb_ss_field, seqnum);
3303 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3306 iov = &state->pending[num_pending];
3307 iov->iov_base = talloc_move(state->pending, &buf);
3308 iov->iov_len = buflen;
3310 DEBUG(10,("echo_handler[%d]: forward to main\n",
3311 (int)getpid()));
3312 smbd_echo_activate_writer(state);
3315 req = smbd_echo_read_send(state, state->ev, state->xconn);
3316 if (req == NULL) {
3317 DEBUG(1, ("smbd_echo_read_send failed\n"));
3318 exit(1);
3320 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3325 * Handle SMBecho requests in a forked child process
3327 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3329 int listener_pipe[2];
3330 int res;
3331 pid_t child;
3332 bool use_mutex = false;
3334 res = pipe(listener_pipe);
3335 if (res == -1) {
3336 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3337 return false;
3340 #ifdef HAVE_ROBUST_MUTEXES
3341 use_mutex = tdb_runtime_check_for_robust_mutexes();
3343 if (use_mutex) {
3344 pthread_mutexattr_t a;
3346 xconn->smb1.echo_handler.socket_mutex =
3347 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3348 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3349 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3350 strerror(errno)));
3351 goto fail;
3354 res = pthread_mutexattr_init(&a);
3355 if (res != 0) {
3356 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3357 strerror(res)));
3358 goto fail;
3360 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3361 if (res != 0) {
3362 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3363 strerror(res)));
3364 pthread_mutexattr_destroy(&a);
3365 goto fail;
3367 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3368 if (res != 0) {
3369 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3370 strerror(res)));
3371 pthread_mutexattr_destroy(&a);
3372 goto fail;
3374 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3375 if (res != 0) {
3376 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3377 "%s\n", strerror(res)));
3378 pthread_mutexattr_destroy(&a);
3379 goto fail;
3381 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3382 &a);
3383 pthread_mutexattr_destroy(&a);
3384 if (res != 0) {
3385 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3386 strerror(res)));
3387 goto fail;
3390 #endif
3392 if (!use_mutex) {
3393 xconn->smb1.echo_handler.socket_lock_fd =
3394 create_unlink_tmp(lp_lock_directory());
3395 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3396 DEBUG(1, ("Could not create lock fd: %s\n",
3397 strerror(errno)));
3398 goto fail;
3402 child = fork();
3403 if (child == 0) {
3404 NTSTATUS status;
3406 close(listener_pipe[0]);
3407 set_blocking(listener_pipe[1], false);
3409 status = smbd_reinit_after_fork(xconn->msg_ctx, xconn->ev_ctx,
3410 true, "smbd-echo");
3411 if (!NT_STATUS_IS_OK(status)) {
3412 DEBUG(1, ("reinit_after_fork failed: %s\n",
3413 nt_errstr(status)));
3414 exit(1);
3416 smbd_echo_loop(xconn, listener_pipe[1]);
3417 exit(0);
3419 close(listener_pipe[1]);
3420 listener_pipe[1] = -1;
3421 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3423 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3426 * Without smb signing this is the same as the normal smbd
3427 * listener. This needs to change once signing comes in.
3429 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3430 xconn,
3431 xconn->smb1.echo_handler.trusted_fd,
3432 TEVENT_FD_READ,
3433 smbd_server_echo_handler,
3434 xconn);
3435 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3436 DEBUG(1, ("event_add_fd failed\n"));
3437 goto fail;
3440 return true;
3442 fail:
3443 if (listener_pipe[0] != -1) {
3444 close(listener_pipe[0]);
3446 if (listener_pipe[1] != -1) {
3447 close(listener_pipe[1]);
3449 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3450 close(xconn->smb1.echo_handler.socket_lock_fd);
3452 #ifdef HAVE_ROBUST_MUTEXES
3453 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3454 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3455 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3457 #endif
3458 smbd_echo_init(xconn);
3460 return false;
3463 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3465 while (user) {
3466 if (user->session_info &&
3467 (user->session_info->unix_token->uid == uid)) {
3468 return true;
3470 user = user->next;
3472 return false;
3475 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3477 while (user) {
3478 if (user->session_info != NULL) {
3479 int i;
3480 struct security_unix_token *utok;
3482 utok = user->session_info->unix_token;
3483 if (utok->gid == gid) {
3484 return true;
3486 for(i=0; i<utok->ngroups; i++) {
3487 if (utok->groups[i] == gid) {
3488 return true;
3492 user = user->next;
3494 return false;
3497 static bool sid_in_use(const struct user_struct *user,
3498 const struct dom_sid *psid)
3500 while (user) {
3501 struct security_token *tok;
3503 if (user->session_info == NULL) {
3504 continue;
3506 tok = user->session_info->security_token;
3507 if (tok == NULL) {
3509 * Not sure session_info->security_token can
3510 * ever be NULL. This check might be not
3511 * necessary.
3513 continue;
3515 if (security_token_has_sid(tok, psid)) {
3516 return true;
3518 user = user->next;
3520 return false;
3523 static bool id_in_use(const struct user_struct *user,
3524 const struct id_cache_ref *id)
3526 switch(id->type) {
3527 case UID:
3528 return uid_in_use(user, id->id.uid);
3529 case GID:
3530 return gid_in_use(user, id->id.gid);
3531 case SID:
3532 return sid_in_use(user, &id->id.sid);
3533 default:
3534 break;
3536 return false;
3539 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3540 void *private_data,
3541 uint32_t msg_type,
3542 struct server_id server_id,
3543 DATA_BLOB* data)
3545 const char *msg = (data && data->data)
3546 ? (const char *)data->data : "<NULL>";
3547 struct id_cache_ref id;
3548 struct smbd_server_connection *sconn =
3549 talloc_get_type_abort(private_data,
3550 struct smbd_server_connection);
3552 if (!id_cache_ref_parse(msg, &id)) {
3553 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3554 return;
3557 if (id_in_use(sconn->users, &id)) {
3558 exit_server_cleanly(msg);
3560 id_cache_delete_from_cache(&id);
3563 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3564 enum protocol_types protocol)
3566 NTSTATUS status;
3568 conn->protocol = protocol;
3570 if (conn->client->session_table != NULL) {
3571 return NT_STATUS_OK;
3574 if (protocol >= PROTOCOL_SMB2_02) {
3575 status = smb2srv_session_table_init(conn);
3576 if (!NT_STATUS_IS_OK(status)) {
3577 conn->protocol = PROTOCOL_NONE;
3578 return status;
3581 status = smb2srv_open_table_init(conn);
3582 if (!NT_STATUS_IS_OK(status)) {
3583 conn->protocol = PROTOCOL_NONE;
3584 return status;
3586 } else {
3587 status = smb1srv_session_table_init(conn);
3588 if (!NT_STATUS_IS_OK(status)) {
3589 conn->protocol = PROTOCOL_NONE;
3590 return status;
3593 status = smb1srv_tcon_table_init(conn);
3594 if (!NT_STATUS_IS_OK(status)) {
3595 conn->protocol = PROTOCOL_NONE;
3596 return status;
3599 status = smb1srv_open_table_init(conn);
3600 if (!NT_STATUS_IS_OK(status)) {
3601 conn->protocol = PROTOCOL_NONE;
3602 return status;
3606 set_Protocol(protocol);
3607 return NT_STATUS_OK;
3610 struct smbd_tevent_trace_state {
3611 struct tevent_context *ev;
3612 TALLOC_CTX *frame;
3613 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3616 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3617 void *private_data)
3619 struct smbd_tevent_trace_state *state =
3620 (struct smbd_tevent_trace_state *)private_data;
3622 switch (point) {
3623 case TEVENT_TRACE_BEFORE_WAIT:
3624 if (!smbprofile_dump_pending()) {
3626 * If there's no dump pending
3627 * we don't want to schedule a new 1 sec timer.
3629 * Instead we want to sleep as long as nothing happens.
3631 smbprofile_dump_setup(NULL);
3633 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3634 break;
3635 case TEVENT_TRACE_AFTER_WAIT:
3636 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3637 if (!smbprofile_dump_pending()) {
3639 * We need to flush our state after sleeping
3640 * (hopefully a long time).
3642 smbprofile_dump();
3644 * future profiling events should trigger timers
3645 * on our main event context.
3647 smbprofile_dump_setup(state->ev);
3649 break;
3650 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3651 TALLOC_FREE(state->frame);
3652 state->frame = talloc_stackframe_pool(8192);
3653 break;
3654 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3655 TALLOC_FREE(state->frame);
3656 break;
3659 errno = 0;
3663 * Create a debug string for the connection
3665 * This is allocated to talloc_tos() or a string constant
3666 * in certain corner cases. The returned string should
3667 * hence not be free'd directly but only via the talloc stack.
3669 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3671 const char *ret;
3674 * TODO: this can be improved later
3675 * maybe including the client guid or more
3677 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3678 if (ret == NULL) {
3679 return "<tsocket_address_string() failed>";
3682 return ret;
3685 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3686 struct smbXsrv_connection **_xconn)
3688 TALLOC_CTX *frame = talloc_stackframe();
3689 struct smbXsrv_connection *xconn;
3690 struct sockaddr_storage ss_srv;
3691 void *sp_srv = (void *)&ss_srv;
3692 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3693 struct sockaddr_storage ss_clnt;
3694 void *sp_clnt = (void *)&ss_clnt;
3695 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3696 socklen_t sa_socklen;
3697 struct tsocket_address *local_address = NULL;
3698 struct tsocket_address *remote_address = NULL;
3699 const char *remaddr = NULL;
3700 char *p;
3701 const char *rhost = NULL;
3702 int ret;
3703 int tmp;
3705 *_xconn = NULL;
3707 DO_PROFILE_INC(connect);
3709 xconn = talloc_zero(client, struct smbXsrv_connection);
3710 if (xconn == NULL) {
3711 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3712 TALLOC_FREE(frame);
3713 return NT_STATUS_NO_MEMORY;
3715 talloc_steal(frame, xconn);
3717 xconn->ev_ctx = client->ev_ctx;
3718 xconn->msg_ctx = client->msg_ctx;
3719 xconn->transport.sock = sock_fd;
3720 smbd_echo_init(xconn);
3721 xconn->protocol = PROTOCOL_NONE;
3723 /* Ensure child is set to blocking mode */
3724 set_blocking(sock_fd,True);
3726 set_socket_options(sock_fd, "SO_KEEPALIVE");
3727 set_socket_options(sock_fd, lp_socket_options());
3729 sa_socklen = sizeof(ss_clnt);
3730 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3731 if (ret != 0) {
3732 int saved_errno = errno;
3733 int level = (errno == ENOTCONN)?2:0;
3734 DEBUG(level,("getpeername() failed - %s\n",
3735 strerror(saved_errno)));
3736 TALLOC_FREE(frame);
3737 return map_nt_error_from_unix_common(saved_errno);
3739 ret = tsocket_address_bsd_from_sockaddr(xconn,
3740 sa_clnt, sa_socklen,
3741 &remote_address);
3742 if (ret != 0) {
3743 int saved_errno = errno;
3744 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3745 __location__, strerror(saved_errno)));
3746 TALLOC_FREE(frame);
3747 return map_nt_error_from_unix_common(saved_errno);
3750 sa_socklen = sizeof(ss_srv);
3751 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3752 if (ret != 0) {
3753 int saved_errno = errno;
3754 int level = (errno == ENOTCONN)?2:0;
3755 DEBUG(level,("getsockname() failed - %s\n",
3756 strerror(saved_errno)));
3757 TALLOC_FREE(frame);
3758 return map_nt_error_from_unix_common(saved_errno);
3760 ret = tsocket_address_bsd_from_sockaddr(xconn,
3761 sa_srv, sa_socklen,
3762 &local_address);
3763 if (ret != 0) {
3764 int saved_errno = errno;
3765 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3766 __location__, strerror(saved_errno)));
3767 TALLOC_FREE(frame);
3768 return map_nt_error_from_unix_common(saved_errno);
3771 if (tsocket_address_is_inet(remote_address, "ip")) {
3772 remaddr = tsocket_address_inet_addr_string(remote_address,
3773 talloc_tos());
3774 if (remaddr == NULL) {
3775 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3776 __location__, strerror(errno)));
3777 TALLOC_FREE(frame);
3778 return NT_STATUS_NO_MEMORY;
3780 } else {
3781 remaddr = "0.0.0.0";
3785 * Before the first packet, check the global hosts allow/ hosts deny
3786 * parameters before doing any parsing of packets passed to us by the
3787 * client. This prevents attacks on our parsing code from hosts not in
3788 * the hosts allow list.
3791 ret = get_remote_hostname(remote_address,
3792 &p, talloc_tos());
3793 if (ret < 0) {
3794 int saved_errno = errno;
3795 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3796 __location__, strerror(saved_errno)));
3797 TALLOC_FREE(frame);
3798 return map_nt_error_from_unix_common(saved_errno);
3800 rhost = p;
3801 if (strequal(rhost, "UNKNOWN")) {
3802 rhost = remaddr;
3805 xconn->local_address = local_address;
3806 xconn->remote_address = remote_address;
3807 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3808 if (xconn->remote_hostname == NULL) {
3809 return NT_STATUS_NO_MEMORY;
3812 if (!srv_init_signing(xconn)) {
3813 DEBUG(0, ("Failed to init smb_signing\n"));
3814 TALLOC_FREE(frame);
3815 return NT_STATUS_INTERNAL_ERROR;
3818 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3819 xconn->remote_hostname,
3820 remaddr)) {
3821 DEBUG( 1, ("Connection denied from %s to %s\n",
3822 tsocket_address_string(remote_address, talloc_tos()),
3823 tsocket_address_string(local_address, talloc_tos())));
3826 * We return a valid xconn
3827 * so that the caller can return an error message
3828 * to the client
3830 client->connections = xconn;
3831 xconn->client = client;
3832 talloc_steal(client, xconn);
3834 *_xconn = xconn;
3835 TALLOC_FREE(frame);
3836 return NT_STATUS_NETWORK_ACCESS_DENIED;
3839 DEBUG(10, ("Connection allowed from %s to %s\n",
3840 tsocket_address_string(remote_address, talloc_tos()),
3841 tsocket_address_string(local_address, talloc_tos())));
3843 if (lp_clustering()) {
3845 * We need to tell ctdb about our client's TCP
3846 * connection, so that for failover ctdbd can send
3847 * tickle acks, triggering a reconnection by the
3848 * client.
3850 NTSTATUS status;
3852 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3853 if (!NT_STATUS_IS_OK(status)) {
3854 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3855 nt_errstr(status)));
3859 tmp = lp_max_xmit();
3860 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3861 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3863 xconn->smb1.negprot.max_recv = tmp;
3865 xconn->smb1.sessions.done_sesssetup = false;
3866 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3868 xconn->transport.fde = tevent_add_fd(client->ev_ctx,
3869 xconn,
3870 sock_fd,
3871 TEVENT_FD_READ,
3872 smbd_server_connection_handler,
3873 xconn);
3874 if (!xconn->transport.fde) {
3875 TALLOC_FREE(frame);
3876 return NT_STATUS_NO_MEMORY;
3879 /* for now we only have one connection */
3880 DLIST_ADD_END(client->connections, xconn);
3881 xconn->client = client;
3882 talloc_steal(client, xconn);
3884 *_xconn = xconn;
3885 TALLOC_FREE(frame);
3886 return NT_STATUS_OK;
3889 /****************************************************************************
3890 Process commands from the client
3891 ****************************************************************************/
3893 void smbd_process(struct tevent_context *ev_ctx,
3894 struct messaging_context *msg_ctx,
3895 int sock_fd,
3896 bool interactive)
3898 struct smbd_tevent_trace_state trace_state = {
3899 .ev = ev_ctx,
3900 .frame = talloc_stackframe(),
3902 struct smbXsrv_client *client = NULL;
3903 struct smbd_server_connection *sconn = NULL;
3904 struct smbXsrv_connection *xconn = NULL;
3905 const char *locaddr = NULL;
3906 const char *remaddr = NULL;
3907 int ret;
3908 NTSTATUS status;
3909 struct timeval tv = timeval_current();
3910 NTTIME now = timeval_to_nttime(&tv);
3911 char *chroot_dir = NULL;
3912 int rc;
3914 status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
3915 if (!NT_STATUS_IS_OK(status)) {
3916 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
3917 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3921 * TODO: remove this...:-)
3923 global_smbXsrv_client = client;
3925 sconn = talloc_zero(client, struct smbd_server_connection);
3926 if (sconn == NULL) {
3927 exit_server("failed to create smbd_server_connection");
3930 client->sconn = sconn;
3931 sconn->client = client;
3933 sconn->ev_ctx = ev_ctx;
3934 sconn->msg_ctx = msg_ctx;
3936 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3938 * We're not making the decision here,
3939 * we're just allowing the client
3940 * to decide between SMB1 and SMB2
3941 * with the first negprot
3942 * packet.
3944 sconn->using_smb2 = true;
3947 if (!interactive) {
3948 smbd_setup_sig_term_handler(sconn);
3949 smbd_setup_sig_hup_handler(sconn);
3951 if (!serverid_register(messaging_server_id(msg_ctx),
3952 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3953 |FLAG_MSG_DBWRAP
3954 |FLAG_MSG_PRINT_GENERAL)) {
3955 exit_server_cleanly("Could not register myself in "
3956 "serverid.tdb");
3960 status = smbd_add_connection(client, sock_fd, &xconn);
3961 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3963 * send a negative session response "not listening on calling
3964 * name"
3966 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3967 (void)srv_send_smb(xconn,(char *)buf, false,
3968 0, false, NULL);
3969 exit_server_cleanly("connection denied");
3970 } else if (!NT_STATUS_IS_OK(status)) {
3971 exit_server_cleanly(nt_errstr(status));
3974 sconn->local_address =
3975 tsocket_address_copy(xconn->local_address, sconn);
3976 if (sconn->local_address == NULL) {
3977 exit_server_cleanly("tsocket_address_copy() failed");
3979 sconn->remote_address =
3980 tsocket_address_copy(xconn->remote_address, sconn);
3981 if (sconn->remote_address == NULL) {
3982 exit_server_cleanly("tsocket_address_copy() failed");
3984 sconn->remote_hostname =
3985 talloc_strdup(sconn, xconn->remote_hostname);
3986 if (sconn->remote_hostname == NULL) {
3987 exit_server_cleanly("tsocket_strdup() failed");
3990 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3991 locaddr = tsocket_address_inet_addr_string(
3992 sconn->local_address,
3993 talloc_tos());
3994 if (locaddr == NULL) {
3995 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3996 __location__, strerror(errno)));
3997 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3999 } else {
4000 locaddr = "0.0.0.0";
4003 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
4004 remaddr = tsocket_address_inet_addr_string(
4005 sconn->remote_address,
4006 talloc_tos());
4007 if (remaddr == NULL) {
4008 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4009 __location__, strerror(errno)));
4010 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4012 } else {
4013 remaddr = "0.0.0.0";
4016 /* this is needed so that we get decent entries
4017 in smbstatus for port 445 connects */
4018 set_remote_machine_name(remaddr, false);
4019 reload_services(sconn, conn_snum_used, true);
4020 sub_set_socket_ids(remaddr,
4021 sconn->remote_hostname,
4022 locaddr);
4024 if (lp_preload_modules()) {
4025 smb_load_all_modules_absoute_path(lp_preload_modules());
4028 smb_perfcount_init();
4030 if (!init_account_policy()) {
4031 exit_server("Could not open account policy tdb.\n");
4034 chroot_dir = lp_root_directory(talloc_tos());
4035 if (chroot_dir[0] != '\0') {
4036 rc = chdir(chroot_dir);
4037 if (rc != 0) {
4038 DBG_ERR("Failed to chdir to %s\n", chroot_dir);
4039 exit_server("Failed to chdir()");
4042 rc = chroot(chroot_dir);
4043 if (rc != 0) {
4044 DBG_ERR("Failed to change root to %s\n", chroot_dir);
4045 exit_server("Failed to chroot()");
4047 DBG_WARNING("Changed root to %s\n", chroot_dir);
4049 TALLOC_FREE(chroot_dir);
4052 if (!file_init(sconn)) {
4053 exit_server("file_init() failed");
4056 /* Setup oplocks */
4057 if (!init_oplocks(sconn))
4058 exit_server("Failed to init oplocks");
4060 /* register our message handlers */
4061 messaging_register(sconn->msg_ctx, sconn,
4062 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4063 messaging_register(sconn->msg_ctx, sconn,
4064 MSG_SMB_CLOSE_FILE, msg_close_file);
4065 messaging_register(sconn->msg_ctx, sconn,
4066 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
4068 id_cache_register_msgs(sconn->msg_ctx);
4069 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
4070 messaging_register(sconn->msg_ctx, sconn,
4071 ID_CACHE_KILL, smbd_id_cache_kill);
4073 messaging_deregister(sconn->msg_ctx,
4074 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
4075 messaging_register(sconn->msg_ctx, sconn,
4076 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
4078 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
4079 NULL);
4080 messaging_register(sconn->msg_ctx, sconn,
4081 MSG_SMB_KILL_CLIENT_IP,
4082 msg_kill_client_ip);
4084 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
4087 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4088 * MSGs to all child processes
4090 messaging_deregister(sconn->msg_ctx,
4091 MSG_DEBUG, NULL);
4092 messaging_register(sconn->msg_ctx, NULL,
4093 MSG_DEBUG, debug_message);
4095 if ((lp_keepalive() != 0)
4096 && !(event_add_idle(ev_ctx, NULL,
4097 timeval_set(lp_keepalive(), 0),
4098 "keepalive", keepalive_fn,
4099 sconn))) {
4100 DEBUG(0, ("Could not add keepalive event\n"));
4101 exit(1);
4104 if (!(event_add_idle(ev_ctx, NULL,
4105 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4106 "deadtime", deadtime_fn, sconn))) {
4107 DEBUG(0, ("Could not add deadtime event\n"));
4108 exit(1);
4111 if (!(event_add_idle(ev_ctx, NULL,
4112 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4113 "housekeeping", housekeeping_fn, sconn))) {
4114 DEBUG(0, ("Could not add housekeeping event\n"));
4115 exit(1);
4118 smbprofile_dump_setup(ev_ctx);
4120 if (!init_dptrs(sconn)) {
4121 exit_server("init_dptrs() failed");
4124 TALLOC_FREE(trace_state.frame);
4126 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4127 &trace_state);
4129 ret = tevent_loop_wait(ev_ctx);
4130 if (ret != 0) {
4131 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4132 " exiting\n", ret, strerror(errno)));
4135 TALLOC_FREE(trace_state.frame);
4137 exit_server_cleanly(NULL);
4140 bool req_is_in_chain(const struct smb_request *req)
4142 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4144 * We're right now handling a subsequent request, so we must
4145 * be in a chain
4147 return true;
4150 if (!is_andx_req(req->cmd)) {
4151 return false;
4154 if (req->wct < 2) {
4156 * Okay, an illegal request, but definitely not chained :-)
4158 return false;
4161 return (CVAL(req->vwv+0, 0) != 0xFF);