s3:smbd: call pthreadpool_tevent_init() already in smbd_process()
[Samba.git] / source3 / smbd / process.c
blob516ac4cb2904dffcf30ac2fdb9ba58f14d365a1f
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 "system/threads.h"
45 #include "lib/pthreadpool/pthreadpool_tevent.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;
167 ret = pthread_mutex_unlock(
168 xconn->smb1.echo_handler.socket_mutex);
169 if (ret != 0) {
170 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
171 strerror(ret)));
172 return false;
175 #endif
177 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
178 bool ok;
180 do {
181 ok = fcntl_lock(
182 xconn->smb1.echo_handler.socket_lock_fd,
183 F_SETLKW, 0, 0, F_UNLCK);
184 } while (!ok && (errno == EINTR));
186 if (!ok) {
187 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
188 return false;
192 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
194 return true;
197 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
199 if (!smbd_unlock_socket_internal(xconn)) {
200 exit_server_cleanly("failed to unlock socket");
204 /* Accessor function for smb_read_error for smbd functions. */
206 /****************************************************************************
207 Send an smb to a fd.
208 ****************************************************************************/
210 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
211 bool do_signing, uint32_t seqnum,
212 bool do_encrypt,
213 struct smb_perfcount_data *pcd)
215 size_t len = 0;
216 ssize_t ret;
217 char *buf_out = buffer;
219 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
221 * we're not supposed to do any io
223 return true;
226 smbd_lock_socket(xconn);
228 if (do_signing) {
229 /* Sign the outgoing packet if required. */
230 srv_calculate_sign_mac(xconn, buf_out, seqnum);
233 if (do_encrypt) {
234 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
235 if (!NT_STATUS_IS_OK(status)) {
236 DEBUG(0, ("send_smb: SMB encryption failed "
237 "on outgoing packet! Error %s\n",
238 nt_errstr(status) ));
239 ret = -1;
240 goto out;
244 len = smb_len_large(buf_out) + 4;
246 ret = write_data(xconn->transport.sock, buf_out, len);
247 if (ret <= 0) {
248 int saved_errno = errno;
250 * Try and give an error message saying what
251 * client failed.
253 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
254 (int)getpid(), (int)len,
255 smbXsrv_connection_dbg(xconn),
256 (int)ret, strerror(saved_errno)));
257 errno = saved_errno;
259 srv_free_enc_buffer(xconn, buf_out);
260 goto out;
263 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
264 srv_free_enc_buffer(xconn, buf_out);
265 out:
266 SMB_PERFCOUNT_END(pcd);
268 smbd_unlock_socket(xconn);
269 return (ret > 0);
272 /*******************************************************************
273 Setup the word count and byte count for a smb message.
274 ********************************************************************/
276 int srv_set_message(char *buf,
277 int num_words,
278 int num_bytes,
279 bool zero)
281 if (zero && (num_words || num_bytes)) {
282 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
284 SCVAL(buf,smb_wct,num_words);
285 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
286 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
287 return (smb_size + num_words*2 + num_bytes);
290 static bool valid_smb_header(const uint8_t *inbuf)
292 if (is_encrypted_packet(inbuf)) {
293 return true;
296 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
297 * but it just looks weird to call strncmp for this one.
299 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
302 /* Socket functions for smbd packet processing. */
304 static bool valid_packet_size(size_t len)
307 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
308 * of header. Don't print the error if this fits.... JRA.
311 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
312 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
313 (unsigned long)len));
314 return false;
316 return true;
319 static NTSTATUS read_packet_remainder(int fd, char *buffer,
320 unsigned int timeout, ssize_t len)
322 NTSTATUS status;
324 if (len <= 0) {
325 return NT_STATUS_OK;
328 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
329 if (!NT_STATUS_IS_OK(status)) {
330 char addr[INET6_ADDRSTRLEN];
331 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
332 "error = %s.\n",
333 get_peer_addr(fd, addr, sizeof(addr)),
334 nt_errstr(status)));
336 return status;
339 /****************************************************************************
340 Attempt a zerocopy writeX read. We know here that len > smb_size-4
341 ****************************************************************************/
344 * Unfortunately, earlier versions of smbclient/libsmbclient
345 * don't send this "standard" writeX header. I've fixed this
346 * for 3.2 but we'll use the old method with earlier versions.
347 * Windows and CIFSFS at least use this standard size. Not
348 * sure about MacOSX.
351 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
352 (2*14) + /* word count (including bcc) */ \
353 1 /* pad byte */)
355 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
356 const char lenbuf[4],
357 struct smbXsrv_connection *xconn,
358 int sock,
359 char **buffer,
360 unsigned int timeout,
361 size_t *p_unread,
362 size_t *len_ret)
364 /* Size of a WRITEX call (+4 byte len). */
365 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
366 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
367 ssize_t toread;
368 NTSTATUS status;
370 memcpy(writeX_header, lenbuf, 4);
372 status = read_fd_with_timeout(
373 sock, writeX_header + 4,
374 STANDARD_WRITE_AND_X_HEADER_SIZE,
375 STANDARD_WRITE_AND_X_HEADER_SIZE,
376 timeout, NULL);
378 if (!NT_STATUS_IS_OK(status)) {
379 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
380 "error = %s.\n",
381 smbXsrv_connection_dbg(xconn),
382 nt_errstr(status)));
383 return status;
387 * Ok - now try and see if this is a possible
388 * valid writeX call.
391 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
393 * If the data offset is beyond what
394 * we've read, drain the extra bytes.
396 uint16_t doff = SVAL(writeX_header,smb_vwv11);
397 ssize_t newlen;
399 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
400 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
401 if (drain_socket(sock, drain) != drain) {
402 smb_panic("receive_smb_raw_talloc_partial_read:"
403 " failed to drain pending bytes");
405 } else {
406 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
409 /* Spoof down the length and null out the bcc. */
410 set_message_bcc(writeX_header, 0);
411 newlen = smb_len(writeX_header);
413 /* Copy the header we've written. */
415 *buffer = (char *)talloc_memdup(mem_ctx,
416 writeX_header,
417 sizeof(writeX_header));
419 if (*buffer == NULL) {
420 DEBUG(0, ("Could not allocate inbuf of length %d\n",
421 (int)sizeof(writeX_header)));
422 return NT_STATUS_NO_MEMORY;
425 /* Work out the remaining bytes. */
426 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
427 *len_ret = newlen + 4;
428 return NT_STATUS_OK;
431 if (!valid_packet_size(len)) {
432 return NT_STATUS_INVALID_PARAMETER;
436 * Not a valid writeX call. Just do the standard
437 * talloc and return.
440 *buffer = talloc_array(mem_ctx, char, len+4);
442 if (*buffer == NULL) {
443 DEBUG(0, ("Could not allocate inbuf of length %d\n",
444 (int)len+4));
445 return NT_STATUS_NO_MEMORY;
448 /* Copy in what we already read. */
449 memcpy(*buffer,
450 writeX_header,
451 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
452 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
454 if(toread > 0) {
455 status = read_packet_remainder(
456 sock,
457 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
458 timeout, toread);
460 if (!NT_STATUS_IS_OK(status)) {
461 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
462 nt_errstr(status)));
463 return status;
467 *len_ret = len + 4;
468 return NT_STATUS_OK;
471 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
472 struct smbXsrv_connection *xconn,
473 int sock,
474 char **buffer, unsigned int timeout,
475 size_t *p_unread, size_t *plen)
477 char lenbuf[4];
478 size_t len;
479 int min_recv_size = lp_min_receive_file_size();
480 NTSTATUS status;
482 *p_unread = 0;
484 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
485 &len);
486 if (!NT_STATUS_IS_OK(status)) {
487 return status;
490 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
491 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
492 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
493 !srv_is_signing_active(xconn) &&
494 xconn->smb1.echo_handler.trusted_fde == NULL) {
496 return receive_smb_raw_talloc_partial_read(
497 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
498 p_unread, plen);
501 if (!valid_packet_size(len)) {
502 return NT_STATUS_INVALID_PARAMETER;
506 * The +4 here can't wrap, we've checked the length above already.
509 *buffer = talloc_array(mem_ctx, char, len+4);
511 if (*buffer == NULL) {
512 DEBUG(0, ("Could not allocate inbuf of length %d\n",
513 (int)len+4));
514 return NT_STATUS_NO_MEMORY;
517 memcpy(*buffer, lenbuf, sizeof(lenbuf));
519 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
520 if (!NT_STATUS_IS_OK(status)) {
521 return status;
524 *plen = len + 4;
525 return NT_STATUS_OK;
528 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
529 struct smbXsrv_connection *xconn,
530 int sock,
531 char **buffer, unsigned int timeout,
532 size_t *p_unread, bool *p_encrypted,
533 size_t *p_len,
534 uint32_t *seqnum,
535 bool trusted_channel)
537 size_t len = 0;
538 NTSTATUS status;
540 *p_encrypted = false;
542 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
543 p_unread, &len);
544 if (!NT_STATUS_IS_OK(status)) {
545 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
546 ("receive_smb_raw_talloc failed for client %s "
547 "read error = %s.\n",
548 smbXsrv_connection_dbg(xconn),
549 nt_errstr(status)) );
550 return status;
553 if (is_encrypted_packet((uint8_t *)*buffer)) {
554 status = srv_decrypt_buffer(xconn, *buffer);
555 if (!NT_STATUS_IS_OK(status)) {
556 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
557 "incoming packet! Error %s\n",
558 nt_errstr(status) ));
559 return status;
561 *p_encrypted = true;
564 /* Check the incoming SMB signature. */
565 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
566 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
567 "incoming packet!\n"));
568 return NT_STATUS_INVALID_NETWORK_RESPONSE;
571 *p_len = len;
572 return NT_STATUS_OK;
576 * Initialize a struct smb_request from an inbuf
579 static bool init_smb_request(struct smb_request *req,
580 struct smbd_server_connection *sconn,
581 struct smbXsrv_connection *xconn,
582 const uint8_t *inbuf,
583 size_t unread_bytes, bool encrypted,
584 uint32_t seqnum)
586 struct smbXsrv_tcon *tcon;
587 NTSTATUS status;
588 NTTIME now;
589 size_t req_size = smb_len(inbuf) + 4;
591 /* Ensure we have at least smb_size bytes. */
592 if (req_size < smb_size) {
593 DEBUG(0,("init_smb_request: invalid request size %u\n",
594 (unsigned int)req_size ));
595 return false;
598 req->request_time = timeval_current();
599 now = timeval_to_nttime(&req->request_time);
601 req->cmd = CVAL(inbuf, smb_com);
602 req->flags2 = SVAL(inbuf, smb_flg2);
603 req->smbpid = SVAL(inbuf, smb_pid);
604 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
605 req->seqnum = seqnum;
606 req->vuid = SVAL(inbuf, smb_uid);
607 req->tid = SVAL(inbuf, smb_tid);
608 req->wct = CVAL(inbuf, smb_wct);
609 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
610 req->buflen = smb_buflen(inbuf);
611 req->buf = (const uint8_t *)smb_buf_const(inbuf);
612 req->unread_bytes = unread_bytes;
613 req->encrypted = encrypted;
614 req->sconn = sconn;
615 req->xconn = xconn;
616 req->conn = NULL;
617 if (xconn != NULL) {
618 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
619 if (NT_STATUS_IS_OK(status)) {
620 req->conn = tcon->compat;
623 req->chain_fsp = NULL;
624 req->smb2req = NULL;
625 req->priv_paths = NULL;
626 req->chain = NULL;
627 req->posix_pathnames = lp_posix_pathnames();
628 smb_init_perfcount_data(&req->pcd);
630 /* Ensure we have at least wct words and 2 bytes of bcc. */
631 if (smb_size + req->wct*2 > req_size) {
632 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
633 (unsigned int)req->wct,
634 (unsigned int)req_size));
635 return false;
637 /* Ensure bcc is correct. */
638 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
639 DEBUG(0,("init_smb_request: invalid bcc number %u "
640 "(wct = %u, size %u)\n",
641 (unsigned int)req->buflen,
642 (unsigned int)req->wct,
643 (unsigned int)req_size));
644 return false;
647 req->outbuf = NULL;
648 return true;
651 static void process_smb(struct smbXsrv_connection *xconn,
652 uint8_t *inbuf, size_t nread, size_t unread_bytes,
653 uint32_t seqnum, bool encrypted,
654 struct smb_perfcount_data *deferred_pcd);
656 static void smbd_deferred_open_timer(struct tevent_context *ev,
657 struct tevent_timer *te,
658 struct timeval _tval,
659 void *private_data)
661 struct pending_message_list *msg = talloc_get_type(private_data,
662 struct pending_message_list);
663 struct smbd_server_connection *sconn = msg->sconn;
664 struct smbXsrv_connection *xconn = msg->xconn;
665 TALLOC_CTX *mem_ctx = talloc_tos();
666 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
667 uint8_t *inbuf;
669 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
670 msg->buf.length);
671 if (inbuf == NULL) {
672 exit_server("smbd_deferred_open_timer: talloc failed\n");
673 return;
676 /* We leave this message on the queue so the open code can
677 know this is a retry. */
678 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
679 (unsigned long long)mid ));
681 /* Mark the message as processed so this is not
682 * re-processed in error. */
683 msg->processed = true;
685 process_smb(xconn, inbuf,
686 msg->buf.length, 0,
687 msg->seqnum, msg->encrypted, &msg->pcd);
689 /* If it's still there and was processed, remove it. */
690 msg = get_deferred_open_message_smb(sconn, mid);
691 if (msg && msg->processed) {
692 remove_deferred_open_message_smb(xconn, mid);
696 /****************************************************************************
697 Function to push a message onto the tail of a linked list of smb messages ready
698 for processing.
699 ****************************************************************************/
701 static bool push_queued_message(struct smb_request *req,
702 struct timeval request_time,
703 struct timeval end_time,
704 struct deferred_open_record *open_rec)
706 int msg_len = smb_len(req->inbuf) + 4;
707 struct pending_message_list *msg;
709 msg = talloc_zero(NULL, struct pending_message_list);
711 if(msg == NULL) {
712 DEBUG(0,("push_message: malloc fail (1)\n"));
713 return False;
715 msg->sconn = req->sconn;
716 msg->xconn = req->xconn;
718 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
719 if(msg->buf.data == NULL) {
720 DEBUG(0,("push_message: malloc fail (2)\n"));
721 TALLOC_FREE(msg);
722 return False;
725 msg->request_time = request_time;
726 msg->seqnum = req->seqnum;
727 msg->encrypted = req->encrypted;
728 msg->processed = false;
729 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
731 if (open_rec) {
732 msg->open_rec = talloc_move(msg, &open_rec);
735 #if 0
736 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
737 msg,
738 end_time,
739 smbd_deferred_open_timer,
740 msg);
741 if (!msg->te) {
742 DEBUG(0,("push_message: event_add_timed failed\n"));
743 TALLOC_FREE(msg);
744 return false;
746 #endif
748 DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
750 DEBUG(10,("push_message: pushed message length %u on "
751 "deferred_open_queue\n", (unsigned int)msg_len));
753 return True;
756 /****************************************************************************
757 Function to delete a sharing violation open message by mid.
758 ****************************************************************************/
760 void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
761 uint64_t mid)
763 struct smbd_server_connection *sconn = xconn->client->sconn;
764 struct pending_message_list *pml;
766 if (sconn->using_smb2) {
767 remove_deferred_open_message_smb2(xconn, mid);
768 return;
771 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
772 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
773 DEBUG(10,("remove_deferred_open_message_smb: "
774 "deleting mid %llu len %u\n",
775 (unsigned long long)mid,
776 (unsigned int)pml->buf.length ));
777 DLIST_REMOVE(sconn->deferred_open_queue, pml);
778 TALLOC_FREE(pml);
779 return;
784 /****************************************************************************
785 Move a sharing violation open retry message to the front of the list and
786 schedule it for immediate processing.
787 ****************************************************************************/
789 bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
790 uint64_t mid)
792 struct smbd_server_connection *sconn = xconn->client->sconn;
793 struct pending_message_list *pml;
794 int i = 0;
796 if (sconn->using_smb2) {
797 return schedule_deferred_open_message_smb2(xconn, mid);
800 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
801 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
803 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
804 "msg_mid = %llu\n",
805 i++,
806 (unsigned long long)msg_mid ));
808 if (mid == msg_mid) {
809 struct tevent_timer *te;
811 if (pml->processed) {
812 /* A processed message should not be
813 * rescheduled. */
814 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
815 "message mid %llu was already processed\n",
816 (unsigned long long)msg_mid ));
817 continue;
820 DEBUG(10,("schedule_deferred_open_message_smb: "
821 "scheduling mid %llu\n",
822 (unsigned long long)mid ));
824 te = tevent_add_timer(pml->sconn->ev_ctx,
825 pml,
826 timeval_zero(),
827 smbd_deferred_open_timer,
828 pml);
829 if (!te) {
830 DEBUG(10,("schedule_deferred_open_message_smb: "
831 "event_add_timed() failed, "
832 "skipping mid %llu\n",
833 (unsigned long long)msg_mid ));
836 TALLOC_FREE(pml->te);
837 pml->te = te;
838 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
839 return true;
843 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
844 "find message mid %llu\n",
845 (unsigned long long)mid ));
847 return false;
850 /****************************************************************************
851 Return true if this mid is on the deferred queue and was not yet processed.
852 ****************************************************************************/
854 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
856 struct smbd_server_connection *sconn = xconn->client->sconn;
857 struct pending_message_list *pml;
859 if (sconn->using_smb2) {
860 return open_was_deferred_smb2(xconn, mid);
863 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
864 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
865 return True;
868 return False;
871 /****************************************************************************
872 Return the message queued by this mid.
873 ****************************************************************************/
875 static struct pending_message_list *get_deferred_open_message_smb(
876 struct smbd_server_connection *sconn, uint64_t mid)
878 struct pending_message_list *pml;
880 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
881 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
882 return pml;
885 return NULL;
888 /****************************************************************************
889 Get the state data queued by this mid.
890 ****************************************************************************/
892 bool get_deferred_open_message_state(struct smb_request *smbreq,
893 struct timeval *p_request_time,
894 struct deferred_open_record **open_rec)
896 struct pending_message_list *pml;
898 if (smbreq->sconn->using_smb2) {
899 return get_deferred_open_message_state_smb2(smbreq->smb2req,
900 p_request_time,
901 open_rec);
904 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
905 if (!pml) {
906 return false;
908 if (p_request_time) {
909 *p_request_time = pml->request_time;
911 if (open_rec != NULL) {
912 *open_rec = pml->open_rec;
914 return true;
917 /****************************************************************************
918 Function to push a deferred open smb message onto a linked list of local smb
919 messages ready for processing.
920 ****************************************************************************/
922 bool push_deferred_open_message_smb(struct smb_request *req,
923 struct timeval request_time,
924 struct timeval timeout,
925 struct file_id id,
926 struct deferred_open_record *open_rec)
928 struct timeval end_time;
930 if (req->smb2req) {
931 return push_deferred_open_message_smb2(req->smb2req,
932 request_time,
933 timeout,
935 open_rec);
938 if (req->unread_bytes) {
939 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
940 "unread_bytes = %u\n",
941 (unsigned int)req->unread_bytes ));
942 smb_panic("push_deferred_open_message_smb: "
943 "logic error unread_bytes != 0" );
946 end_time = timeval_sum(&request_time, &timeout);
948 DEBUG(10,("push_deferred_open_message_smb: pushing message "
949 "len %u mid %llu timeout time [%u.%06u]\n",
950 (unsigned int) smb_len(req->inbuf)+4,
951 (unsigned long long)req->mid,
952 (unsigned int)end_time.tv_sec,
953 (unsigned int)end_time.tv_usec));
955 return push_queued_message(req, request_time, end_time, open_rec);
958 static void smbd_sig_term_handler(struct tevent_context *ev,
959 struct tevent_signal *se,
960 int signum,
961 int count,
962 void *siginfo,
963 void *private_data)
965 exit_server_cleanly("termination signal");
968 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
970 struct tevent_signal *se;
972 se = tevent_add_signal(sconn->ev_ctx,
973 sconn,
974 SIGTERM, 0,
975 smbd_sig_term_handler,
976 sconn);
977 if (!se) {
978 exit_server("failed to setup SIGTERM handler");
982 static void smbd_sig_hup_handler(struct tevent_context *ev,
983 struct tevent_signal *se,
984 int signum,
985 int count,
986 void *siginfo,
987 void *private_data)
989 struct smbd_server_connection *sconn =
990 talloc_get_type_abort(private_data,
991 struct smbd_server_connection);
993 change_to_root_user();
994 DEBUG(1,("Reloading services after SIGHUP\n"));
995 reload_services(sconn, conn_snum_used, false);
998 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1000 struct tevent_signal *se;
1002 se = tevent_add_signal(sconn->ev_ctx,
1003 sconn,
1004 SIGHUP, 0,
1005 smbd_sig_hup_handler,
1006 sconn);
1007 if (!se) {
1008 exit_server("failed to setup SIGHUP handler");
1012 static void smbd_conf_updated(struct messaging_context *msg,
1013 void *private_data,
1014 uint32_t msg_type,
1015 struct server_id server_id,
1016 DATA_BLOB *data)
1018 struct smbd_server_connection *sconn =
1019 talloc_get_type_abort(private_data,
1020 struct smbd_server_connection);
1022 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1023 "updated. Reloading.\n"));
1024 change_to_root_user();
1025 reload_services(sconn, conn_snum_used, false);
1029 * Only allow 5 outstanding trans requests. We're allocating memory, so
1030 * prevent a DoS.
1033 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1035 int count = 0;
1036 for (; list != NULL; list = list->next) {
1038 if (list->mid == mid) {
1039 return NT_STATUS_INVALID_PARAMETER;
1042 count += 1;
1044 if (count > 5) {
1045 return NT_STATUS_INSUFFICIENT_RESOURCES;
1048 return NT_STATUS_OK;
1052 These flags determine some of the permissions required to do an operation
1054 Note that I don't set NEED_WRITE on some write operations because they
1055 are used by some brain-dead clients when printing, and I don't want to
1056 force write permissions on print services.
1058 #define AS_USER (1<<0)
1059 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1060 #define TIME_INIT (1<<2)
1061 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1062 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1063 #define DO_CHDIR (1<<6)
1066 define a list of possible SMB messages and their corresponding
1067 functions. Any message that has a NULL function is unimplemented -
1068 please feel free to contribute implementations!
1070 static const struct smb_message_struct {
1071 const char *name;
1072 void (*fn)(struct smb_request *req);
1073 int flags;
1074 } smb_messages[256] = {
1076 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1077 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1078 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1079 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1080 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1081 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1082 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1083 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1084 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1085 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1086 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1087 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1088 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1089 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1090 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1091 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1092 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1093 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1094 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1095 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1096 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1097 /* 0x15 */ { NULL, NULL, 0 },
1098 /* 0x16 */ { NULL, NULL, 0 },
1099 /* 0x17 */ { NULL, NULL, 0 },
1100 /* 0x18 */ { NULL, NULL, 0 },
1101 /* 0x19 */ { NULL, NULL, 0 },
1102 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1103 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1104 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1105 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1106 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1107 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1108 /* 0x20 */ { "SMBwritec", NULL,0},
1109 /* 0x21 */ { NULL, NULL, 0 },
1110 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1111 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1112 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1113 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1114 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1115 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1116 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1117 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1118 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1119 /* 0x2b */ { "SMBecho",reply_echo,0},
1120 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1121 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1122 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1123 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1124 /* 0x30 */ { NULL, NULL, 0 },
1125 /* 0x31 */ { NULL, NULL, 0 },
1126 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1127 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1128 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1129 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1130 /* 0x36 */ { NULL, NULL, 0 },
1131 /* 0x37 */ { NULL, NULL, 0 },
1132 /* 0x38 */ { NULL, NULL, 0 },
1133 /* 0x39 */ { NULL, NULL, 0 },
1134 /* 0x3a */ { NULL, NULL, 0 },
1135 /* 0x3b */ { NULL, NULL, 0 },
1136 /* 0x3c */ { NULL, NULL, 0 },
1137 /* 0x3d */ { NULL, NULL, 0 },
1138 /* 0x3e */ { NULL, NULL, 0 },
1139 /* 0x3f */ { NULL, NULL, 0 },
1140 /* 0x40 */ { NULL, NULL, 0 },
1141 /* 0x41 */ { NULL, NULL, 0 },
1142 /* 0x42 */ { NULL, NULL, 0 },
1143 /* 0x43 */ { NULL, NULL, 0 },
1144 /* 0x44 */ { NULL, NULL, 0 },
1145 /* 0x45 */ { NULL, NULL, 0 },
1146 /* 0x46 */ { NULL, NULL, 0 },
1147 /* 0x47 */ { NULL, NULL, 0 },
1148 /* 0x48 */ { NULL, NULL, 0 },
1149 /* 0x49 */ { NULL, NULL, 0 },
1150 /* 0x4a */ { NULL, NULL, 0 },
1151 /* 0x4b */ { NULL, NULL, 0 },
1152 /* 0x4c */ { NULL, NULL, 0 },
1153 /* 0x4d */ { NULL, NULL, 0 },
1154 /* 0x4e */ { NULL, NULL, 0 },
1155 /* 0x4f */ { NULL, NULL, 0 },
1156 /* 0x50 */ { NULL, NULL, 0 },
1157 /* 0x51 */ { NULL, NULL, 0 },
1158 /* 0x52 */ { NULL, NULL, 0 },
1159 /* 0x53 */ { NULL, NULL, 0 },
1160 /* 0x54 */ { NULL, NULL, 0 },
1161 /* 0x55 */ { NULL, NULL, 0 },
1162 /* 0x56 */ { NULL, NULL, 0 },
1163 /* 0x57 */ { NULL, NULL, 0 },
1164 /* 0x58 */ { NULL, NULL, 0 },
1165 /* 0x59 */ { NULL, NULL, 0 },
1166 /* 0x5a */ { NULL, NULL, 0 },
1167 /* 0x5b */ { NULL, NULL, 0 },
1168 /* 0x5c */ { NULL, NULL, 0 },
1169 /* 0x5d */ { NULL, NULL, 0 },
1170 /* 0x5e */ { NULL, NULL, 0 },
1171 /* 0x5f */ { NULL, NULL, 0 },
1172 /* 0x60 */ { NULL, NULL, 0 },
1173 /* 0x61 */ { NULL, NULL, 0 },
1174 /* 0x62 */ { NULL, NULL, 0 },
1175 /* 0x63 */ { NULL, NULL, 0 },
1176 /* 0x64 */ { NULL, NULL, 0 },
1177 /* 0x65 */ { NULL, NULL, 0 },
1178 /* 0x66 */ { NULL, NULL, 0 },
1179 /* 0x67 */ { NULL, NULL, 0 },
1180 /* 0x68 */ { NULL, NULL, 0 },
1181 /* 0x69 */ { NULL, NULL, 0 },
1182 /* 0x6a */ { NULL, NULL, 0 },
1183 /* 0x6b */ { NULL, NULL, 0 },
1184 /* 0x6c */ { NULL, NULL, 0 },
1185 /* 0x6d */ { NULL, NULL, 0 },
1186 /* 0x6e */ { NULL, NULL, 0 },
1187 /* 0x6f */ { NULL, NULL, 0 },
1188 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1189 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1190 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1191 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1192 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1193 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1194 /* 0x76 */ { NULL, NULL, 0 },
1195 /* 0x77 */ { NULL, NULL, 0 },
1196 /* 0x78 */ { NULL, NULL, 0 },
1197 /* 0x79 */ { NULL, NULL, 0 },
1198 /* 0x7a */ { NULL, NULL, 0 },
1199 /* 0x7b */ { NULL, NULL, 0 },
1200 /* 0x7c */ { NULL, NULL, 0 },
1201 /* 0x7d */ { NULL, NULL, 0 },
1202 /* 0x7e */ { NULL, NULL, 0 },
1203 /* 0x7f */ { NULL, NULL, 0 },
1204 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1205 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1206 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1207 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1208 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1209 /* 0x85 */ { NULL, NULL, 0 },
1210 /* 0x86 */ { NULL, NULL, 0 },
1211 /* 0x87 */ { NULL, NULL, 0 },
1212 /* 0x88 */ { NULL, NULL, 0 },
1213 /* 0x89 */ { NULL, NULL, 0 },
1214 /* 0x8a */ { NULL, NULL, 0 },
1215 /* 0x8b */ { NULL, NULL, 0 },
1216 /* 0x8c */ { NULL, NULL, 0 },
1217 /* 0x8d */ { NULL, NULL, 0 },
1218 /* 0x8e */ { NULL, NULL, 0 },
1219 /* 0x8f */ { NULL, NULL, 0 },
1220 /* 0x90 */ { NULL, NULL, 0 },
1221 /* 0x91 */ { NULL, NULL, 0 },
1222 /* 0x92 */ { NULL, NULL, 0 },
1223 /* 0x93 */ { NULL, NULL, 0 },
1224 /* 0x94 */ { NULL, NULL, 0 },
1225 /* 0x95 */ { NULL, NULL, 0 },
1226 /* 0x96 */ { NULL, NULL, 0 },
1227 /* 0x97 */ { NULL, NULL, 0 },
1228 /* 0x98 */ { NULL, NULL, 0 },
1229 /* 0x99 */ { NULL, NULL, 0 },
1230 /* 0x9a */ { NULL, NULL, 0 },
1231 /* 0x9b */ { NULL, NULL, 0 },
1232 /* 0x9c */ { NULL, NULL, 0 },
1233 /* 0x9d */ { NULL, NULL, 0 },
1234 /* 0x9e */ { NULL, NULL, 0 },
1235 /* 0x9f */ { NULL, NULL, 0 },
1236 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1237 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1238 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1239 /* 0xa3 */ { NULL, NULL, 0 },
1240 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1241 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1242 /* 0xa6 */ { NULL, NULL, 0 },
1243 /* 0xa7 */ { NULL, NULL, 0 },
1244 /* 0xa8 */ { NULL, NULL, 0 },
1245 /* 0xa9 */ { NULL, NULL, 0 },
1246 /* 0xaa */ { NULL, NULL, 0 },
1247 /* 0xab */ { NULL, NULL, 0 },
1248 /* 0xac */ { NULL, NULL, 0 },
1249 /* 0xad */ { NULL, NULL, 0 },
1250 /* 0xae */ { NULL, NULL, 0 },
1251 /* 0xaf */ { NULL, NULL, 0 },
1252 /* 0xb0 */ { NULL, NULL, 0 },
1253 /* 0xb1 */ { NULL, NULL, 0 },
1254 /* 0xb2 */ { NULL, NULL, 0 },
1255 /* 0xb3 */ { NULL, NULL, 0 },
1256 /* 0xb4 */ { NULL, NULL, 0 },
1257 /* 0xb5 */ { NULL, NULL, 0 },
1258 /* 0xb6 */ { NULL, NULL, 0 },
1259 /* 0xb7 */ { NULL, NULL, 0 },
1260 /* 0xb8 */ { NULL, NULL, 0 },
1261 /* 0xb9 */ { NULL, NULL, 0 },
1262 /* 0xba */ { NULL, NULL, 0 },
1263 /* 0xbb */ { NULL, NULL, 0 },
1264 /* 0xbc */ { NULL, NULL, 0 },
1265 /* 0xbd */ { NULL, NULL, 0 },
1266 /* 0xbe */ { NULL, NULL, 0 },
1267 /* 0xbf */ { NULL, NULL, 0 },
1268 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1269 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1270 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1271 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1272 /* 0xc4 */ { NULL, NULL, 0 },
1273 /* 0xc5 */ { NULL, NULL, 0 },
1274 /* 0xc6 */ { NULL, NULL, 0 },
1275 /* 0xc7 */ { NULL, NULL, 0 },
1276 /* 0xc8 */ { NULL, NULL, 0 },
1277 /* 0xc9 */ { NULL, NULL, 0 },
1278 /* 0xca */ { NULL, NULL, 0 },
1279 /* 0xcb */ { NULL, NULL, 0 },
1280 /* 0xcc */ { NULL, NULL, 0 },
1281 /* 0xcd */ { NULL, NULL, 0 },
1282 /* 0xce */ { NULL, NULL, 0 },
1283 /* 0xcf */ { NULL, NULL, 0 },
1284 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1285 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1286 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1287 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1288 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1289 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1290 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1291 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1292 /* 0xd8 */ { NULL, NULL, 0 },
1293 /* 0xd9 */ { NULL, NULL, 0 },
1294 /* 0xda */ { NULL, NULL, 0 },
1295 /* 0xdb */ { NULL, NULL, 0 },
1296 /* 0xdc */ { NULL, NULL, 0 },
1297 /* 0xdd */ { NULL, NULL, 0 },
1298 /* 0xde */ { NULL, NULL, 0 },
1299 /* 0xdf */ { NULL, NULL, 0 },
1300 /* 0xe0 */ { NULL, NULL, 0 },
1301 /* 0xe1 */ { NULL, NULL, 0 },
1302 /* 0xe2 */ { NULL, NULL, 0 },
1303 /* 0xe3 */ { NULL, NULL, 0 },
1304 /* 0xe4 */ { NULL, NULL, 0 },
1305 /* 0xe5 */ { NULL, NULL, 0 },
1306 /* 0xe6 */ { NULL, NULL, 0 },
1307 /* 0xe7 */ { NULL, NULL, 0 },
1308 /* 0xe8 */ { NULL, NULL, 0 },
1309 /* 0xe9 */ { NULL, NULL, 0 },
1310 /* 0xea */ { NULL, NULL, 0 },
1311 /* 0xeb */ { NULL, NULL, 0 },
1312 /* 0xec */ { NULL, NULL, 0 },
1313 /* 0xed */ { NULL, NULL, 0 },
1314 /* 0xee */ { NULL, NULL, 0 },
1315 /* 0xef */ { NULL, NULL, 0 },
1316 /* 0xf0 */ { NULL, NULL, 0 },
1317 /* 0xf1 */ { NULL, NULL, 0 },
1318 /* 0xf2 */ { NULL, NULL, 0 },
1319 /* 0xf3 */ { NULL, NULL, 0 },
1320 /* 0xf4 */ { NULL, NULL, 0 },
1321 /* 0xf5 */ { NULL, NULL, 0 },
1322 /* 0xf6 */ { NULL, NULL, 0 },
1323 /* 0xf7 */ { NULL, NULL, 0 },
1324 /* 0xf8 */ { NULL, NULL, 0 },
1325 /* 0xf9 */ { NULL, NULL, 0 },
1326 /* 0xfa */ { NULL, NULL, 0 },
1327 /* 0xfb */ { NULL, NULL, 0 },
1328 /* 0xfc */ { NULL, NULL, 0 },
1329 /* 0xfd */ { NULL, NULL, 0 },
1330 /* 0xfe */ { NULL, NULL, 0 },
1331 /* 0xff */ { NULL, NULL, 0 }
1335 /*******************************************************************
1336 allocate and initialize a reply packet
1337 ********************************************************************/
1339 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1340 const uint8_t *inbuf, char **outbuf,
1341 uint8_t num_words, uint32_t num_bytes)
1343 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1346 * Protect against integer wrap.
1347 * The SMB layer reply can be up to 0xFFFFFF bytes.
1349 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1350 char *msg;
1351 if (asprintf(&msg, "num_bytes too large: %u",
1352 (unsigned)num_bytes) == -1) {
1353 msg = discard_const_p(char, "num_bytes too large");
1355 smb_panic(msg);
1359 * Here we include the NBT header for now.
1361 *outbuf = talloc_array(mem_ctx, char,
1362 NBT_HDR_SIZE + smb_len);
1363 if (*outbuf == NULL) {
1364 return false;
1367 construct_reply_common(req->cmd, inbuf, *outbuf);
1368 srv_set_message(*outbuf, num_words, num_bytes, false);
1370 * Zero out the word area, the caller has to take care of the bcc area
1371 * himself
1373 if (num_words != 0) {
1374 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1377 return true;
1380 void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1382 char *outbuf;
1383 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1384 num_bytes)) {
1385 smb_panic("could not allocate output buffer\n");
1387 req->outbuf = (uint8_t *)outbuf;
1391 /*******************************************************************
1392 Dump a packet to a file.
1393 ********************************************************************/
1395 static void smb_dump(const char *name, int type, const char *data)
1397 size_t len;
1398 int fd, i;
1399 char *fname = NULL;
1400 if (DEBUGLEVEL < 50) {
1401 return;
1404 len = smb_len_tcp(data)+4;
1405 for (i=1;i<100;i++) {
1406 fname = talloc_asprintf(talloc_tos(),
1407 "/tmp/%s.%d.%s",
1408 name,
1410 type ? "req" : "resp");
1411 if (fname == NULL) {
1412 return;
1414 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1415 if (fd != -1 || errno != EEXIST) break;
1416 TALLOC_FREE(fname);
1418 if (fd != -1) {
1419 ssize_t ret = write(fd, data, len);
1420 if (ret != len)
1421 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1422 close(fd);
1423 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1425 TALLOC_FREE(fname);
1428 static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
1429 struct smb_request *req,
1430 uint8_t type,
1431 bool *update_session_globalp,
1432 bool *update_tcon_globalp)
1434 connection_struct *conn = req->conn;
1435 struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
1436 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
1437 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1438 bool update_session = false;
1439 bool update_tcon = false;
1441 if (req->encrypted) {
1442 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
1445 if (srv_is_signing_active(req->xconn)) {
1446 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
1447 } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
1449 * echo can be unsigned. Sesssion setup except final
1450 * session setup response too
1452 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1455 update_session |= smbXsrv_set_crypto_flag(
1456 &session->global->encryption_flags, encrypt_flag);
1457 update_session |= smbXsrv_set_crypto_flag(
1458 &session->global->signing_flags, sign_flag);
1460 if (tcon) {
1461 update_tcon |= smbXsrv_set_crypto_flag(
1462 &tcon->global->encryption_flags, encrypt_flag);
1463 update_tcon |= smbXsrv_set_crypto_flag(
1464 &tcon->global->signing_flags, sign_flag);
1467 if (update_session) {
1468 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1471 *update_session_globalp = update_session;
1472 *update_tcon_globalp = update_tcon;
1473 return;
1476 /****************************************************************************
1477 Prepare everything for calling the actual request function, and potentially
1478 call the request function via the "new" interface.
1480 Return False if the "legacy" function needs to be called, everything is
1481 prepared.
1483 Return True if we're done.
1485 I know this API sucks, but it is the one with the least code change I could
1486 find.
1487 ****************************************************************************/
1489 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1491 int flags;
1492 uint64_t session_tag;
1493 connection_struct *conn = NULL;
1494 struct smbXsrv_connection *xconn = req->xconn;
1495 NTTIME now = timeval_to_nttime(&req->request_time);
1496 struct smbXsrv_session *session = NULL;
1497 NTSTATUS status;
1499 errno = 0;
1501 if (!xconn->smb1.negprot.done) {
1502 switch (type) {
1504 * Without a negprot the request must
1505 * either be a negprot, or one of the
1506 * evil old SMB mailslot messaging types.
1508 case SMBnegprot:
1509 case SMBsendstrt:
1510 case SMBsendend:
1511 case SMBsendtxt:
1512 break;
1513 default:
1514 exit_server_cleanly("The first request "
1515 "should be a negprot");
1519 if (smb_messages[type].fn == NULL) {
1520 DEBUG(0,("Unknown message type %d!\n",type));
1521 smb_dump("Unknown", 1, (const char *)req->inbuf);
1522 reply_unknown_new(req, type);
1523 return NULL;
1526 flags = smb_messages[type].flags;
1528 /* In share mode security we must ignore the vuid. */
1529 session_tag = req->vuid;
1530 conn = req->conn;
1532 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1533 (int)getpid(), (unsigned long)conn));
1535 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1537 /* Ensure this value is replaced in the incoming packet. */
1538 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1541 * Ensure the correct username is in current_user_info. This is a
1542 * really ugly bugfix for problems with multiple session_setup_and_X's
1543 * being done and allowing %U and %G substitutions to work correctly.
1544 * There is a reason this code is done here, don't move it unless you
1545 * know what you're doing... :-).
1546 * JRA.
1550 * lookup an existing session
1552 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1553 * here, the main check is still in change_to_user()
1555 status = smb1srv_session_lookup(xconn,
1556 session_tag,
1557 now,
1558 &session);
1559 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1560 switch (type) {
1561 case SMBsesssetupX:
1562 status = NT_STATUS_OK;
1563 break;
1564 default:
1565 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1566 (unsigned long long)session_tag,
1567 (unsigned long long)req->mid));
1568 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1569 return conn;
1573 if (session_tag != xconn->client->last_session_id) {
1574 struct user_struct *vuser = NULL;
1576 xconn->client->last_session_id = session_tag;
1577 if (session) {
1578 vuser = session->compat;
1580 if (vuser) {
1581 set_current_user_info(
1582 vuser->session_info->unix_info->sanitized_username,
1583 vuser->session_info->unix_info->unix_name,
1584 vuser->session_info->info->domain_name);
1588 /* Does this call need to be run as the connected user? */
1589 if (flags & AS_USER) {
1591 /* Does this call need a valid tree connection? */
1592 if (!conn) {
1594 * Amazingly, the error code depends on the command
1595 * (from Samba4).
1597 if (type == SMBntcreateX) {
1598 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1599 } else {
1600 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1602 return NULL;
1605 if (!change_to_user(conn,session_tag)) {
1606 DEBUG(0, ("Error: Could not change to user. Removing "
1607 "deferred open, mid=%llu.\n",
1608 (unsigned long long)req->mid));
1609 reply_force_doserror(req, ERRSRV, ERRbaduid);
1610 return conn;
1613 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1615 /* Does it need write permission? */
1616 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1617 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1618 return conn;
1621 /* IPC services are limited */
1622 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1623 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1624 return conn;
1626 } else {
1627 /* This call needs to be run as root */
1628 change_to_root_user();
1631 /* load service specific parameters */
1632 if (conn) {
1633 if (req->encrypted) {
1634 conn->encrypted_tid = true;
1635 /* encrypted required from now on. */
1636 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1637 } else if (ENCRYPTION_REQUIRED(conn)) {
1638 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1639 DEBUG(1,("service[%s] requires encryption"
1640 "%s ACCESS_DENIED. mid=%llu\n",
1641 lp_servicename(talloc_tos(), SNUM(conn)),
1642 smb_fn_name(type),
1643 (unsigned long long)req->mid));
1644 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1645 return conn;
1649 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1650 (flags & (AS_USER|DO_CHDIR)
1651 ?True:False))) {
1652 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1653 return conn;
1655 conn->num_smb_operations++;
1659 * Does this protocol need to be run as guest? (Only archane
1660 * messenger service requests have this...)
1662 if (flags & AS_GUEST) {
1663 char *raddr;
1664 bool ok;
1666 if (!change_to_guest()) {
1667 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1668 return conn;
1671 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1672 talloc_tos());
1673 if (raddr == NULL) {
1674 reply_nterror(req, NT_STATUS_NO_MEMORY);
1675 return conn;
1679 * Haven't we checked this in smbd_process already???
1682 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1683 xconn->remote_hostname, raddr);
1684 TALLOC_FREE(raddr);
1686 if (!ok) {
1687 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1688 return conn;
1693 * Update encryption and signing state tracking flags that are
1694 * used by smbstatus to display signing and encryption status.
1696 if (session != NULL) {
1697 bool update_session_global = false;
1698 bool update_tcon_global = false;
1700 smb1srv_update_crypto_flags(session, req, type,
1701 &update_session_global,
1702 &update_tcon_global);
1704 if (update_session_global) {
1705 status = smbXsrv_session_update(session);
1706 if (!NT_STATUS_IS_OK(status)) {
1707 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1708 return conn;
1712 if (update_tcon_global) {
1713 status = smbXsrv_tcon_update(req->conn->tcon);
1714 if (!NT_STATUS_IS_OK(status)) {
1715 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1716 return conn;
1721 smb_messages[type].fn(req);
1722 return req->conn;
1725 /****************************************************************************
1726 Construct a reply to the incoming packet.
1727 ****************************************************************************/
1729 static void construct_reply(struct smbXsrv_connection *xconn,
1730 char *inbuf, int size, size_t unread_bytes,
1731 uint32_t seqnum, bool encrypted,
1732 struct smb_perfcount_data *deferred_pcd)
1734 struct smbd_server_connection *sconn = xconn->client->sconn;
1735 struct smb_request *req;
1737 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1738 smb_panic("could not allocate smb_request");
1741 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1742 encrypted, seqnum)) {
1743 exit_server_cleanly("Invalid SMB request");
1746 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1748 /* we popped this message off the queue - keep original perf data */
1749 if (deferred_pcd)
1750 req->pcd = *deferred_pcd;
1751 else {
1752 SMB_PERFCOUNT_START(&req->pcd);
1753 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1754 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1757 req->conn = switch_message(req->cmd, req);
1759 if (req->outbuf == NULL) {
1761 * Request has suspended itself, will come
1762 * back here.
1764 return;
1766 if (CVAL(req->outbuf,0) == 0) {
1767 show_msg((char *)req->outbuf);
1769 smb_request_done(req);
1772 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1773 char *inbuf, int size, uint32_t seqnum,
1774 bool encrypted,
1775 struct smb_perfcount_data *deferred_pcd)
1777 struct smb_request **reqs = NULL;
1778 struct smb_request *req;
1779 unsigned num_reqs;
1780 bool ok;
1782 ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
1783 seqnum, &reqs, &num_reqs);
1784 if (!ok) {
1785 char errbuf[smb_size];
1786 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1787 __LINE__, __FILE__);
1788 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1789 NULL)) {
1790 exit_server_cleanly("construct_reply_chain: "
1791 "srv_send_smb failed.");
1793 return;
1796 req = reqs[0];
1797 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1799 req->conn = switch_message(req->cmd, req);
1801 if (req->outbuf == NULL) {
1803 * Request has suspended itself, will come
1804 * back here.
1806 return;
1808 smb_request_done(req);
1812 * To be called from an async SMB handler that is potentially chained
1813 * when it is finished for shipping.
1816 void smb_request_done(struct smb_request *req)
1818 struct smb_request **reqs = NULL;
1819 struct smb_request *first_req;
1820 size_t i, num_reqs, next_index;
1821 NTSTATUS status;
1823 if (req->chain == NULL) {
1824 first_req = req;
1825 goto shipit;
1828 reqs = req->chain;
1829 num_reqs = talloc_array_length(reqs);
1831 for (i=0; i<num_reqs; i++) {
1832 if (reqs[i] == req) {
1833 break;
1836 if (i == num_reqs) {
1838 * Invalid chain, should not happen
1840 status = NT_STATUS_INTERNAL_ERROR;
1841 goto error;
1843 next_index = i+1;
1845 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1846 struct smb_request *next = reqs[next_index];
1847 struct smbXsrv_tcon *tcon;
1848 NTTIME now = timeval_to_nttime(&req->request_time);
1850 next->vuid = SVAL(req->outbuf, smb_uid);
1851 next->tid = SVAL(req->outbuf, smb_tid);
1852 status = smb1srv_tcon_lookup(req->xconn, next->tid,
1853 now, &tcon);
1855 if (NT_STATUS_IS_OK(status)) {
1856 next->conn = tcon->compat;
1857 } else {
1858 next->conn = NULL;
1860 next->chain_fsp = req->chain_fsp;
1861 next->inbuf = req->inbuf;
1863 req = next;
1864 req->conn = switch_message(req->cmd, req);
1866 if (req->outbuf == NULL) {
1868 * Request has suspended itself, will come
1869 * back here.
1871 return;
1873 next_index += 1;
1876 first_req = reqs[0];
1878 for (i=1; i<next_index; i++) {
1879 bool ok;
1881 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1882 if (!ok) {
1883 status = NT_STATUS_INTERNAL_ERROR;
1884 goto error;
1888 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1889 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1892 * This scary statement intends to set the
1893 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1894 * to the value last_req->outbuf carries
1896 SSVAL(first_req->outbuf, smb_flg2,
1897 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1898 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1901 * Transfer the error codes from the subrequest to the main one
1903 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1904 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1906 _smb_setlen_large(
1907 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1909 shipit:
1910 if (!srv_send_smb(first_req->xconn,
1911 (char *)first_req->outbuf,
1912 true, first_req->seqnum+1,
1913 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1914 &first_req->pcd)) {
1915 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1916 "failed.");
1918 TALLOC_FREE(req); /* non-chained case */
1919 TALLOC_FREE(reqs); /* chained case */
1920 return;
1922 error:
1924 char errbuf[smb_size];
1925 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1926 if (!srv_send_smb(req->xconn, errbuf, true,
1927 req->seqnum+1, req->encrypted,
1928 NULL)) {
1929 exit_server_cleanly("construct_reply_chain: "
1930 "srv_send_smb failed.");
1933 TALLOC_FREE(req); /* non-chained case */
1934 TALLOC_FREE(reqs); /* chained case */
1937 /****************************************************************************
1938 Process an smb from the client
1939 ****************************************************************************/
1940 static void process_smb(struct smbXsrv_connection *xconn,
1941 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1942 uint32_t seqnum, bool encrypted,
1943 struct smb_perfcount_data *deferred_pcd)
1945 struct smbd_server_connection *sconn = xconn->client->sconn;
1946 int msg_type = CVAL(inbuf,0);
1948 DO_PROFILE_INC(request);
1950 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1951 smb_len(inbuf) ) );
1952 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1953 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1955 if (msg_type != NBSSmessage) {
1957 * NetBIOS session request, keepalive, etc.
1959 reply_special(xconn, (char *)inbuf, nread);
1960 goto done;
1963 if (sconn->using_smb2) {
1964 /* At this point we're not really using smb2,
1965 * we make the decision here.. */
1966 if (smbd_is_smb2_header(inbuf, nread)) {
1967 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1968 size_t pdulen = nread - NBT_HDR_SIZE;
1969 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1970 return;
1972 if (nread >= smb_size && valid_smb_header(inbuf)
1973 && CVAL(inbuf, smb_com) != 0x72) {
1974 /* This is a non-negprot SMB1 packet.
1975 Disable SMB2 from now on. */
1976 sconn->using_smb2 = false;
1980 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1981 * so subtract 4 from it. */
1982 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1983 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1984 smb_len(inbuf)));
1986 /* special magic for immediate exit */
1987 if ((nread == 9) &&
1988 (IVAL(inbuf, 4) == 0x74697865) &&
1989 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1990 uint8_t exitcode = CVAL(inbuf, 8);
1991 DEBUG(1, ("Exiting immediately with code %d\n",
1992 (int)exitcode));
1993 exit(exitcode);
1996 exit_server_cleanly("Non-SMB packet");
1999 show_msg((char *)inbuf);
2001 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
2002 construct_reply_chain(xconn, (char *)inbuf, nread,
2003 seqnum, encrypted, deferred_pcd);
2004 } else {
2005 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
2006 seqnum, encrypted, deferred_pcd);
2009 sconn->trans_num++;
2011 done:
2012 sconn->num_requests++;
2014 /* The timeout_processing function isn't run nearly
2015 often enough to implement 'max log size' without
2016 overrunning the size of the file by many megabytes.
2017 This is especially true if we are running at debug
2018 level 10. Checking every 50 SMBs is a nice
2019 tradeoff of performance vs log file size overrun. */
2021 if ((sconn->num_requests % 50) == 0 &&
2022 need_to_check_log_size()) {
2023 change_to_root_user();
2024 check_log_size();
2028 /****************************************************************************
2029 Return a string containing the function name of a SMB command.
2030 ****************************************************************************/
2032 const char *smb_fn_name(int type)
2034 const char *unknown_name = "SMBunknown";
2036 if (smb_messages[type].name == NULL)
2037 return(unknown_name);
2039 return(smb_messages[type].name);
2042 /****************************************************************************
2043 Helper functions for contruct_reply.
2044 ****************************************************************************/
2046 void add_to_common_flags2(uint32_t v)
2048 common_flags2 |= v;
2051 void remove_from_common_flags2(uint32_t v)
2053 common_flags2 &= ~v;
2056 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
2057 char *outbuf)
2059 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
2060 uint16_t out_flags2 = common_flags2;
2062 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
2063 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
2064 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
2066 srv_set_message(outbuf,0,0,false);
2068 SCVAL(outbuf, smb_com, cmd);
2069 SIVAL(outbuf,smb_rcls,0);
2070 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
2071 SSVAL(outbuf,smb_flg2, out_flags2);
2072 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
2073 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2075 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2076 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2077 SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
2078 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2079 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2082 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2084 construct_reply_common(req->cmd, req->inbuf, outbuf);
2088 * @brief Find the smb_cmd offset of the last command pushed
2089 * @param[in] buf The buffer we're building up
2090 * @retval Where can we put our next andx cmd?
2092 * While chaining requests, the "next" request we're looking at needs to put
2093 * its SMB_Command before the data the previous request already built up added
2094 * to the chain. Find the offset to the place where we have to put our cmd.
2097 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2099 uint8_t cmd;
2100 size_t ofs;
2102 cmd = CVAL(buf, smb_com);
2104 if (!is_andx_req(cmd)) {
2105 return false;
2108 ofs = smb_vwv0;
2110 while (CVAL(buf, ofs) != 0xff) {
2112 if (!is_andx_req(CVAL(buf, ofs))) {
2113 return false;
2117 * ofs is from start of smb header, so add the 4 length
2118 * bytes. The next cmd is right after the wct field.
2120 ofs = SVAL(buf, ofs+2) + 4 + 1;
2122 if (ofs+4 >= talloc_get_size(buf)) {
2123 return false;
2127 *pofs = ofs;
2128 return true;
2132 * @brief Do the smb chaining at a buffer level
2133 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2134 * @param[in] andx_buf Buffer to be appended
2137 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2139 uint8_t smb_command = CVAL(andx_buf, smb_com);
2140 uint8_t wct = CVAL(andx_buf, smb_wct);
2141 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2142 uint32_t num_bytes = smb_buflen(andx_buf);
2143 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2145 uint8_t *outbuf;
2146 size_t old_size, new_size;
2147 size_t ofs;
2148 size_t chain_padding = 0;
2149 size_t andx_cmd_ofs;
2152 old_size = talloc_get_size(*poutbuf);
2154 if ((old_size % 4) != 0) {
2156 * Align the wct field of subsequent requests to a 4-byte
2157 * boundary
2159 chain_padding = 4 - (old_size % 4);
2163 * After the old request comes the new wct field (1 byte), the vwv's
2164 * and the num_bytes field.
2167 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2168 new_size += num_bytes;
2170 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2171 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2172 (unsigned)new_size));
2173 return false;
2176 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2177 if (outbuf == NULL) {
2178 DEBUG(0, ("talloc failed\n"));
2179 return false;
2181 *poutbuf = outbuf;
2183 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2184 DEBUG(1, ("invalid command chain\n"));
2185 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2186 return false;
2189 if (chain_padding != 0) {
2190 memset(outbuf + old_size, 0, chain_padding);
2191 old_size += chain_padding;
2194 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2195 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2197 ofs = old_size;
2200 * Push the chained request:
2202 * wct field
2205 SCVAL(outbuf, ofs, wct);
2206 ofs += 1;
2209 * vwv array
2212 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2215 * HACK ALERT
2217 * Read&X has an offset into its data buffer at
2218 * vwv[6]. reply_read_andx has no idea anymore that it's
2219 * running from within a chain, so we have to fix up the
2220 * offset here.
2222 * Although it looks disgusting at this place, I want to keep
2223 * it here. The alternative would be to push knowledge about
2224 * the andx chain down into read&x again.
2227 if (smb_command == SMBreadX) {
2228 uint8_t *bytes_addr;
2230 if (wct < 7) {
2232 * Invalid read&x response
2234 return false;
2237 bytes_addr = outbuf + ofs /* vwv start */
2238 + sizeof(uint16_t) * wct /* vwv array */
2239 + sizeof(uint16_t) /* bcc */
2240 + 1; /* padding byte */
2242 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2243 bytes_addr - outbuf - 4);
2246 ofs += sizeof(uint16_t) * wct;
2249 * bcc (byte count)
2252 SSVAL(outbuf, ofs, num_bytes);
2253 ofs += sizeof(uint16_t);
2256 * The bytes field
2259 memcpy(outbuf + ofs, bytes, num_bytes);
2261 return true;
2264 bool smb1_is_chain(const uint8_t *buf)
2266 uint8_t cmd, wct, andx_cmd;
2268 cmd = CVAL(buf, smb_com);
2269 if (!is_andx_req(cmd)) {
2270 return false;
2272 wct = CVAL(buf, smb_wct);
2273 if (wct < 2) {
2274 return false;
2276 andx_cmd = CVAL(buf, smb_vwv);
2277 return (andx_cmd != 0xFF);
2280 bool smb1_walk_chain(const uint8_t *buf,
2281 bool (*fn)(uint8_t cmd,
2282 uint8_t wct, const uint16_t *vwv,
2283 uint16_t num_bytes, const uint8_t *bytes,
2284 void *private_data),
2285 void *private_data)
2287 size_t smblen = smb_len(buf);
2288 const char *smb_buf = smb_base(buf);
2289 uint8_t cmd, chain_cmd;
2290 uint8_t wct;
2291 const uint16_t *vwv;
2292 uint16_t num_bytes;
2293 const uint8_t *bytes;
2295 cmd = CVAL(buf, smb_com);
2296 wct = CVAL(buf, smb_wct);
2297 vwv = (const uint16_t *)(buf + smb_vwv);
2298 num_bytes = smb_buflen(buf);
2299 bytes = (const uint8_t *)smb_buf_const(buf);
2301 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2302 return false;
2305 if (!is_andx_req(cmd)) {
2306 return true;
2308 if (wct < 2) {
2309 return false;
2312 chain_cmd = CVAL(vwv, 0);
2314 while (chain_cmd != 0xff) {
2315 uint32_t chain_offset; /* uint32_t to avoid overflow */
2316 size_t length_needed;
2317 ptrdiff_t vwv_offset;
2319 chain_offset = SVAL(vwv+1, 0);
2322 * Check if the client tries to fool us. The chain
2323 * offset needs to point beyond the current request in
2324 * the chain, it needs to strictly grow. Otherwise we
2325 * might be tricked into an endless loop always
2326 * processing the same request over and over again. We
2327 * used to assume that vwv and the byte buffer array
2328 * in a chain are always attached, but OS/2 the
2329 * Write&X/Read&X chain puts the Read&X vwv array
2330 * right behind the Write&X vwv chain. The Write&X bcc
2331 * array is put behind the Read&X vwv array. So now we
2332 * check whether the chain offset points strictly
2333 * behind the previous vwv array. req->buf points
2334 * right after the vwv array of the previous
2335 * request. See
2336 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2337 * more information.
2340 vwv_offset = ((const char *)vwv - smb_buf);
2341 if (chain_offset <= vwv_offset) {
2342 return false;
2346 * Next check: Make sure the chain offset does not
2347 * point beyond the overall smb request length.
2350 length_needed = chain_offset+1; /* wct */
2351 if (length_needed > smblen) {
2352 return false;
2356 * Now comes the pointer magic. Goal here is to set up
2357 * vwv and buf correctly again. The chain offset (the
2358 * former vwv[1]) points at the new wct field.
2361 wct = CVAL(smb_buf, chain_offset);
2363 if (is_andx_req(chain_cmd) && (wct < 2)) {
2364 return false;
2368 * Next consistency check: Make the new vwv array fits
2369 * in the overall smb request.
2372 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2373 if (length_needed > smblen) {
2374 return false;
2376 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2379 * Now grab the new byte buffer....
2382 num_bytes = SVAL(vwv+wct, 0);
2385 * .. and check that it fits.
2388 length_needed += num_bytes;
2389 if (length_needed > smblen) {
2390 return false;
2392 bytes = (const uint8_t *)(vwv+wct+1);
2394 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2395 return false;
2398 if (!is_andx_req(chain_cmd)) {
2399 return true;
2401 chain_cmd = CVAL(vwv, 0);
2403 return true;
2406 static bool smb1_chain_length_cb(uint8_t cmd,
2407 uint8_t wct, const uint16_t *vwv,
2408 uint16_t num_bytes, const uint8_t *bytes,
2409 void *private_data)
2411 unsigned *count = (unsigned *)private_data;
2412 *count += 1;
2413 return true;
2416 unsigned smb1_chain_length(const uint8_t *buf)
2418 unsigned count = 0;
2420 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2421 return 0;
2423 return count;
2426 struct smb1_parse_chain_state {
2427 TALLOC_CTX *mem_ctx;
2428 const uint8_t *buf;
2429 struct smbd_server_connection *sconn;
2430 struct smbXsrv_connection *xconn;
2431 bool encrypted;
2432 uint32_t seqnum;
2434 struct smb_request **reqs;
2435 unsigned num_reqs;
2438 static bool smb1_parse_chain_cb(uint8_t cmd,
2439 uint8_t wct, const uint16_t *vwv,
2440 uint16_t num_bytes, const uint8_t *bytes,
2441 void *private_data)
2443 struct smb1_parse_chain_state *state =
2444 (struct smb1_parse_chain_state *)private_data;
2445 struct smb_request **reqs;
2446 struct smb_request *req;
2447 bool ok;
2449 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2450 struct smb_request *, state->num_reqs+1);
2451 if (reqs == NULL) {
2452 return false;
2454 state->reqs = reqs;
2456 req = talloc(reqs, struct smb_request);
2457 if (req == NULL) {
2458 return false;
2461 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2462 state->encrypted, state->seqnum);
2463 if (!ok) {
2464 return false;
2466 req->cmd = cmd;
2467 req->wct = wct;
2468 req->vwv = vwv;
2469 req->buflen = num_bytes;
2470 req->buf = bytes;
2472 reqs[state->num_reqs] = req;
2473 state->num_reqs += 1;
2474 return true;
2477 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2478 struct smbXsrv_connection *xconn,
2479 bool encrypted, uint32_t seqnum,
2480 struct smb_request ***reqs, unsigned *num_reqs)
2482 struct smbd_server_connection *sconn = NULL;
2483 struct smb1_parse_chain_state state;
2484 unsigned i;
2486 if (xconn != NULL) {
2487 sconn = xconn->client->sconn;
2490 state.mem_ctx = mem_ctx;
2491 state.buf = buf;
2492 state.sconn = sconn;
2493 state.xconn = xconn;
2494 state.encrypted = encrypted;
2495 state.seqnum = seqnum;
2496 state.reqs = NULL;
2497 state.num_reqs = 0;
2499 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2500 TALLOC_FREE(state.reqs);
2501 return false;
2503 for (i=0; i<state.num_reqs; i++) {
2504 state.reqs[i]->chain = state.reqs;
2506 *reqs = state.reqs;
2507 *num_reqs = state.num_reqs;
2508 return true;
2511 /****************************************************************************
2512 Check if services need reloading.
2513 ****************************************************************************/
2515 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2518 if (last_smb_conf_reload_time == 0) {
2519 last_smb_conf_reload_time = t;
2522 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2523 reload_services(sconn, conn_snum_used, true);
2524 last_smb_conf_reload_time = t;
2528 static bool fd_is_readable(int fd)
2530 int ret, revents;
2532 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2534 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2538 static void smbd_server_connection_write_handler(
2539 struct smbXsrv_connection *xconn)
2541 /* TODO: make write nonblocking */
2544 static void smbd_server_connection_read_handler(
2545 struct smbXsrv_connection *xconn, int fd)
2547 uint8_t *inbuf = NULL;
2548 size_t inbuf_len = 0;
2549 size_t unread_bytes = 0;
2550 bool encrypted = false;
2551 TALLOC_CTX *mem_ctx = talloc_tos();
2552 NTSTATUS status;
2553 uint32_t seqnum;
2555 bool async_echo = lp_async_smb_echo_handler();
2556 bool from_client = false;
2558 if (async_echo) {
2559 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2561 * This is the super-ugly hack to prefer the packets
2562 * forwarded by the echo handler over the ones by the
2563 * client directly
2565 fd = xconn->smb1.echo_handler.trusted_fd;
2569 from_client = (xconn->transport.sock == fd);
2571 if (async_echo && from_client) {
2572 smbd_lock_socket(xconn);
2574 if (!fd_is_readable(fd)) {
2575 DEBUG(10,("the echo listener was faster\n"));
2576 smbd_unlock_socket(xconn);
2577 return;
2581 /* TODO: make this completely nonblocking */
2582 status = receive_smb_talloc(mem_ctx, xconn, fd,
2583 (char **)(void *)&inbuf,
2584 0, /* timeout */
2585 &unread_bytes,
2586 &encrypted,
2587 &inbuf_len, &seqnum,
2588 !from_client /* trusted channel */);
2590 if (async_echo && from_client) {
2591 smbd_unlock_socket(xconn);
2594 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2595 goto process;
2597 if (NT_STATUS_IS_ERR(status)) {
2598 exit_server_cleanly("failed to receive smb request");
2600 if (!NT_STATUS_IS_OK(status)) {
2601 return;
2604 process:
2605 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2606 seqnum, encrypted, NULL);
2609 static void smbd_server_connection_handler(struct tevent_context *ev,
2610 struct tevent_fd *fde,
2611 uint16_t flags,
2612 void *private_data)
2614 struct smbXsrv_connection *xconn =
2615 talloc_get_type_abort(private_data,
2616 struct smbXsrv_connection);
2618 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2620 * we're not supposed to do any io
2622 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2623 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2624 return;
2627 if (flags & TEVENT_FD_WRITE) {
2628 smbd_server_connection_write_handler(xconn);
2629 return;
2631 if (flags & TEVENT_FD_READ) {
2632 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2633 return;
2637 static void smbd_server_echo_handler(struct tevent_context *ev,
2638 struct tevent_fd *fde,
2639 uint16_t flags,
2640 void *private_data)
2642 struct smbXsrv_connection *xconn =
2643 talloc_get_type_abort(private_data,
2644 struct smbXsrv_connection);
2646 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2648 * we're not supposed to do any io
2650 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2651 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2652 return;
2655 if (flags & TEVENT_FD_WRITE) {
2656 smbd_server_connection_write_handler(xconn);
2657 return;
2659 if (flags & TEVENT_FD_READ) {
2660 smbd_server_connection_read_handler(
2661 xconn, xconn->smb1.echo_handler.trusted_fd);
2662 return;
2666 struct smbd_release_ip_state {
2667 struct smbXsrv_connection *xconn;
2668 struct tevent_immediate *im;
2669 char addr[INET6_ADDRSTRLEN];
2672 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2673 struct tevent_immediate *im,
2674 void *private_data)
2676 struct smbd_release_ip_state *state =
2677 talloc_get_type_abort(private_data,
2678 struct smbd_release_ip_state);
2679 struct smbXsrv_connection *xconn = state->xconn;
2681 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2683 * smbd_server_connection_terminate() already triggered ?
2685 return;
2688 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2691 /****************************************************************************
2692 received when we should release a specific IP
2693 ****************************************************************************/
2694 static int release_ip(struct tevent_context *ev,
2695 uint32_t src_vnn, uint32_t dst_vnn,
2696 uint64_t dst_srvid,
2697 const uint8_t *msg, size_t msglen,
2698 void *private_data)
2700 struct smbd_release_ip_state *state =
2701 talloc_get_type_abort(private_data,
2702 struct smbd_release_ip_state);
2703 struct smbXsrv_connection *xconn = state->xconn;
2704 const char *ip;
2705 const char *addr = state->addr;
2706 const char *p = addr;
2708 if (msglen == 0) {
2709 return 0;
2711 if (msg[msglen-1] != '\0') {
2712 return 0;
2715 ip = (const char *)msg;
2717 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2718 /* avoid recursion */
2719 return 0;
2722 if (strncmp("::ffff:", addr, 7) == 0) {
2723 p = addr + 7;
2726 DEBUG(10, ("Got release IP message for %s, "
2727 "our address is %s\n", ip, p));
2729 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2730 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2731 ip));
2733 * With SMB2 we should do a clean disconnect,
2734 * the previous_session_id in the session setup
2735 * will cleanup the old session, tcons and opens.
2737 * A clean disconnect is needed in order to support
2738 * durable handles.
2740 * Note: typically this is never triggered
2741 * as we got a TCP RST (triggered by ctdb event scripts)
2742 * before we get CTDB_SRVID_RELEASE_IP.
2744 * We used to call _exit(1) here, but as this was mostly never
2745 * triggered and has implication on our process model,
2746 * we can just use smbd_server_connection_terminate()
2747 * (also for SMB1).
2749 * We don't call smbd_server_connection_terminate() directly
2750 * as we might be called from within ctdbd_migrate(),
2751 * we need to defer our action to the next event loop
2753 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2754 smbd_release_ip_immediate, state);
2757 * Make sure we don't get any io on the connection.
2759 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2760 return EADDRNOTAVAIL;
2763 return 0;
2766 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2767 struct sockaddr_storage *srv,
2768 struct sockaddr_storage *clnt)
2770 struct smbd_release_ip_state *state;
2771 struct ctdbd_connection *cconn;
2772 int ret;
2774 cconn = messaging_ctdb_connection();
2775 if (cconn == NULL) {
2776 return NT_STATUS_NO_MEMORY;
2779 state = talloc_zero(xconn, struct smbd_release_ip_state);
2780 if (state == NULL) {
2781 return NT_STATUS_NO_MEMORY;
2783 state->xconn = xconn;
2784 state->im = tevent_create_immediate(state);
2785 if (state->im == NULL) {
2786 return NT_STATUS_NO_MEMORY;
2788 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2789 return NT_STATUS_NO_MEMORY;
2792 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2793 if (ret != 0) {
2794 return map_nt_error_from_unix(ret);
2796 return NT_STATUS_OK;
2799 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2800 void *private_data, uint32_t msg_type,
2801 struct server_id server_id, DATA_BLOB *data)
2803 struct smbd_server_connection *sconn = talloc_get_type_abort(
2804 private_data, struct smbd_server_connection);
2805 const char *ip = (char *) data->data;
2806 char *client_ip;
2808 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2810 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2811 talloc_tos());
2812 if (client_ip == NULL) {
2813 return;
2816 if (strequal(ip, client_ip)) {
2817 DBG_WARNING("Got kill client message for %s - "
2818 "exiting immediately\n", ip);
2819 exit_server_cleanly("Forced disconnect for client");
2822 TALLOC_FREE(client_ip);
2826 * Send keepalive packets to our client
2828 static bool keepalive_fn(const struct timeval *now, void *private_data)
2830 struct smbd_server_connection *sconn = talloc_get_type_abort(
2831 private_data, struct smbd_server_connection);
2832 struct smbXsrv_connection *xconn = NULL;
2833 bool ret;
2835 if (sconn->using_smb2) {
2836 /* Don't do keepalives on an SMB2 connection. */
2837 return false;
2841 * With SMB1 we only have 1 connection
2843 xconn = sconn->client->connections;
2844 smbd_lock_socket(xconn);
2845 ret = send_keepalive(xconn->transport.sock);
2846 smbd_unlock_socket(xconn);
2848 if (!ret) {
2849 int saved_errno = errno;
2851 * Try and give an error message saying what
2852 * client failed.
2854 DEBUG(0, ("send_keepalive failed for client %s. "
2855 "Error %s - exiting\n",
2856 smbXsrv_connection_dbg(xconn),
2857 strerror(saved_errno)));
2858 errno = saved_errno;
2859 return False;
2861 return True;
2865 * Do the recurring check if we're idle
2867 static bool deadtime_fn(const struct timeval *now, void *private_data)
2869 struct smbd_server_connection *sconn =
2870 (struct smbd_server_connection *)private_data;
2872 if ((conn_num_open(sconn) == 0)
2873 || (conn_idle_all(sconn, now->tv_sec))) {
2874 DEBUG( 2, ( "Closing idle connection\n" ) );
2875 messaging_send(sconn->msg_ctx,
2876 messaging_server_id(sconn->msg_ctx),
2877 MSG_SHUTDOWN, &data_blob_null);
2878 return False;
2881 return True;
2885 * Do the recurring log file and smb.conf reload checks.
2888 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2890 struct smbd_server_connection *sconn = talloc_get_type_abort(
2891 private_data, struct smbd_server_connection);
2893 DEBUG(5, ("housekeeping\n"));
2895 change_to_root_user();
2897 /* update printer queue caches if necessary */
2898 update_monitored_printq_cache(sconn->msg_ctx);
2900 /* check if we need to reload services */
2901 check_reload(sconn, time_mono(NULL));
2904 * Force a log file check.
2906 force_check_log_size();
2907 check_log_size();
2908 return true;
2912 * Read an smb packet in the echo handler child, giving the parent
2913 * smbd one second to react once the socket becomes readable.
2916 struct smbd_echo_read_state {
2917 struct tevent_context *ev;
2918 struct smbXsrv_connection *xconn;
2920 char *buf;
2921 size_t buflen;
2922 uint32_t seqnum;
2925 static void smbd_echo_read_readable(struct tevent_req *subreq);
2926 static void smbd_echo_read_waited(struct tevent_req *subreq);
2928 static struct tevent_req *smbd_echo_read_send(
2929 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2930 struct smbXsrv_connection *xconn)
2932 struct tevent_req *req, *subreq;
2933 struct smbd_echo_read_state *state;
2935 req = tevent_req_create(mem_ctx, &state,
2936 struct smbd_echo_read_state);
2937 if (req == NULL) {
2938 return NULL;
2940 state->ev = ev;
2941 state->xconn = xconn;
2943 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2944 if (tevent_req_nomem(subreq, req)) {
2945 return tevent_req_post(req, ev);
2947 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2948 return req;
2951 static void smbd_echo_read_readable(struct tevent_req *subreq)
2953 struct tevent_req *req = tevent_req_callback_data(
2954 subreq, struct tevent_req);
2955 struct smbd_echo_read_state *state = tevent_req_data(
2956 req, struct smbd_echo_read_state);
2957 bool ok;
2958 int err;
2960 ok = wait_for_read_recv(subreq, &err);
2961 TALLOC_FREE(subreq);
2962 if (!ok) {
2963 tevent_req_nterror(req, map_nt_error_from_unix(err));
2964 return;
2968 * Give the parent smbd one second to step in
2971 subreq = tevent_wakeup_send(
2972 state, state->ev, timeval_current_ofs(1, 0));
2973 if (tevent_req_nomem(subreq, req)) {
2974 return;
2976 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2979 static void smbd_echo_read_waited(struct tevent_req *subreq)
2981 struct tevent_req *req = tevent_req_callback_data(
2982 subreq, struct tevent_req);
2983 struct smbd_echo_read_state *state = tevent_req_data(
2984 req, struct smbd_echo_read_state);
2985 struct smbXsrv_connection *xconn = state->xconn;
2986 bool ok;
2987 NTSTATUS status;
2988 size_t unread = 0;
2989 bool encrypted;
2991 ok = tevent_wakeup_recv(subreq);
2992 TALLOC_FREE(subreq);
2993 if (!ok) {
2994 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2995 return;
2998 ok = smbd_lock_socket_internal(xconn);
2999 if (!ok) {
3000 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3001 DEBUG(0, ("%s: failed to lock socket\n", __location__));
3002 return;
3005 if (!fd_is_readable(xconn->transport.sock)) {
3006 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3007 (int)getpid()));
3009 ok = smbd_unlock_socket_internal(xconn);
3010 if (!ok) {
3011 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3012 DEBUG(1, ("%s: failed to unlock socket\n",
3013 __location__));
3014 return;
3017 subreq = wait_for_read_send(state, state->ev,
3018 xconn->transport.sock, false);
3019 if (tevent_req_nomem(subreq, req)) {
3020 return;
3022 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
3023 return;
3026 status = receive_smb_talloc(state, xconn,
3027 xconn->transport.sock,
3028 &state->buf,
3029 0 /* timeout */,
3030 &unread,
3031 &encrypted,
3032 &state->buflen,
3033 &state->seqnum,
3034 false /* trusted_channel*/);
3036 if (tevent_req_nterror(req, status)) {
3037 tevent_req_nterror(req, status);
3038 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3039 (int)getpid(), nt_errstr(status)));
3040 return;
3043 ok = smbd_unlock_socket_internal(xconn);
3044 if (!ok) {
3045 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3046 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
3047 return;
3049 tevent_req_done(req);
3052 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3053 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
3055 struct smbd_echo_read_state *state = tevent_req_data(
3056 req, struct smbd_echo_read_state);
3057 NTSTATUS status;
3059 if (tevent_req_is_nterror(req, &status)) {
3060 return status;
3062 *pbuf = talloc_move(mem_ctx, &state->buf);
3063 *pbuflen = state->buflen;
3064 *pseqnum = state->seqnum;
3065 return NT_STATUS_OK;
3068 struct smbd_echo_state {
3069 struct tevent_context *ev;
3070 struct iovec *pending;
3071 struct smbd_server_connection *sconn;
3072 struct smbXsrv_connection *xconn;
3073 int parent_pipe;
3075 struct tevent_fd *parent_fde;
3077 struct tevent_req *write_req;
3080 static void smbd_echo_writer_done(struct tevent_req *req);
3082 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3084 int num_pending;
3086 if (state->write_req != NULL) {
3087 return;
3090 num_pending = talloc_array_length(state->pending);
3091 if (num_pending == 0) {
3092 return;
3095 state->write_req = writev_send(state, state->ev, NULL,
3096 state->parent_pipe, false,
3097 state->pending, num_pending);
3098 if (state->write_req == NULL) {
3099 DEBUG(1, ("writev_send failed\n"));
3100 exit(1);
3103 talloc_steal(state->write_req, state->pending);
3104 state->pending = NULL;
3106 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3107 state);
3110 static void smbd_echo_writer_done(struct tevent_req *req)
3112 struct smbd_echo_state *state = tevent_req_callback_data(
3113 req, struct smbd_echo_state);
3114 ssize_t written;
3115 int err;
3117 written = writev_recv(req, &err);
3118 TALLOC_FREE(req);
3119 state->write_req = NULL;
3120 if (written == -1) {
3121 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3122 exit(1);
3124 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3125 smbd_echo_activate_writer(state);
3128 static bool smbd_echo_reply(struct smbd_echo_state *state,
3129 uint8_t *inbuf, size_t inbuf_len,
3130 uint32_t seqnum)
3132 struct smb_request req;
3133 uint16_t num_replies;
3134 char *outbuf;
3135 bool ok;
3137 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3138 DEBUG(10, ("Got netbios keepalive\n"));
3140 * Just swallow it
3142 return true;
3145 if (inbuf_len < smb_size) {
3146 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3147 return false;
3149 if (!valid_smb_header(inbuf)) {
3150 DEBUG(10, ("Got invalid SMB header\n"));
3151 return false;
3154 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3155 seqnum)) {
3156 return false;
3158 req.inbuf = inbuf;
3160 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3161 smb_messages[req.cmd].name
3162 ? smb_messages[req.cmd].name : "unknown"));
3164 if (req.cmd != SMBecho) {
3165 return false;
3167 if (req.wct < 1) {
3168 return false;
3171 num_replies = SVAL(req.vwv+0, 0);
3172 if (num_replies != 1) {
3173 /* Not a Windows "Hey, you're still there?" request */
3174 return false;
3177 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3178 1, req.buflen)) {
3179 DEBUG(10, ("create_outbuf failed\n"));
3180 return false;
3182 req.outbuf = (uint8_t *)outbuf;
3184 SSVAL(req.outbuf, smb_vwv0, num_replies);
3186 if (req.buflen > 0) {
3187 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3190 ok = srv_send_smb(req.xconn,
3191 (char *)outbuf,
3192 true, seqnum+1,
3193 false, &req.pcd);
3194 TALLOC_FREE(outbuf);
3195 if (!ok) {
3196 exit(1);
3199 return true;
3202 static void smbd_echo_exit(struct tevent_context *ev,
3203 struct tevent_fd *fde, uint16_t flags,
3204 void *private_data)
3206 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3207 exit(0);
3210 static void smbd_echo_got_packet(struct tevent_req *req);
3212 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3213 int parent_pipe)
3215 struct smbd_echo_state *state;
3216 struct tevent_req *read_req;
3218 state = talloc_zero(xconn, struct smbd_echo_state);
3219 if (state == NULL) {
3220 DEBUG(1, ("talloc failed\n"));
3221 return;
3223 state->xconn = xconn;
3224 state->parent_pipe = parent_pipe;
3225 state->ev = samba_tevent_context_init(state);
3226 if (state->ev == NULL) {
3227 DEBUG(1, ("samba_tevent_context_init failed\n"));
3228 TALLOC_FREE(state);
3229 return;
3231 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3232 TEVENT_FD_READ, smbd_echo_exit,
3233 state);
3234 if (state->parent_fde == NULL) {
3235 DEBUG(1, ("tevent_add_fd failed\n"));
3236 TALLOC_FREE(state);
3237 return;
3240 read_req = smbd_echo_read_send(state, state->ev, xconn);
3241 if (read_req == NULL) {
3242 DEBUG(1, ("smbd_echo_read_send failed\n"));
3243 TALLOC_FREE(state);
3244 return;
3246 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3248 while (true) {
3249 if (tevent_loop_once(state->ev) == -1) {
3250 DEBUG(1, ("tevent_loop_once failed: %s\n",
3251 strerror(errno)));
3252 break;
3255 TALLOC_FREE(state);
3258 static void smbd_echo_got_packet(struct tevent_req *req)
3260 struct smbd_echo_state *state = tevent_req_callback_data(
3261 req, struct smbd_echo_state);
3262 NTSTATUS status;
3263 char *buf = NULL;
3264 size_t buflen = 0;
3265 uint32_t seqnum = 0;
3266 bool reply;
3268 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3269 TALLOC_FREE(req);
3270 if (!NT_STATUS_IS_OK(status)) {
3271 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3272 nt_errstr(status)));
3273 exit(1);
3276 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3277 if (!reply) {
3278 size_t num_pending;
3279 struct iovec *tmp;
3280 struct iovec *iov;
3282 num_pending = talloc_array_length(state->pending);
3283 tmp = talloc_realloc(state, state->pending, struct iovec,
3284 num_pending+1);
3285 if (tmp == NULL) {
3286 DEBUG(1, ("talloc_realloc failed\n"));
3287 exit(1);
3289 state->pending = tmp;
3291 if (buflen >= smb_size) {
3293 * place the seqnum in the packet so that the main process
3294 * can reply with signing
3296 SIVAL(buf, smb_ss_field, seqnum);
3297 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3300 iov = &state->pending[num_pending];
3301 iov->iov_base = talloc_move(state->pending, &buf);
3302 iov->iov_len = buflen;
3304 DEBUG(10,("echo_handler[%d]: forward to main\n",
3305 (int)getpid()));
3306 smbd_echo_activate_writer(state);
3309 req = smbd_echo_read_send(state, state->ev, state->xconn);
3310 if (req == NULL) {
3311 DEBUG(1, ("smbd_echo_read_send failed\n"));
3312 exit(1);
3314 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3319 * Handle SMBecho requests in a forked child process
3321 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3323 int listener_pipe[2];
3324 int res;
3325 pid_t child;
3326 bool use_mutex = false;
3328 res = pipe(listener_pipe);
3329 if (res == -1) {
3330 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3331 return false;
3334 #ifdef HAVE_ROBUST_MUTEXES
3335 use_mutex = tdb_runtime_check_for_robust_mutexes();
3337 if (use_mutex) {
3338 pthread_mutexattr_t a;
3340 xconn->smb1.echo_handler.socket_mutex =
3341 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3342 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3343 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3344 strerror(errno)));
3345 goto fail;
3348 res = pthread_mutexattr_init(&a);
3349 if (res != 0) {
3350 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3351 strerror(res)));
3352 goto fail;
3354 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3355 if (res != 0) {
3356 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3357 strerror(res)));
3358 pthread_mutexattr_destroy(&a);
3359 goto fail;
3361 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3362 if (res != 0) {
3363 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3364 strerror(res)));
3365 pthread_mutexattr_destroy(&a);
3366 goto fail;
3368 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3369 if (res != 0) {
3370 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3371 "%s\n", strerror(res)));
3372 pthread_mutexattr_destroy(&a);
3373 goto fail;
3375 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3376 &a);
3377 pthread_mutexattr_destroy(&a);
3378 if (res != 0) {
3379 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3380 strerror(res)));
3381 goto fail;
3384 #endif
3386 if (!use_mutex) {
3387 xconn->smb1.echo_handler.socket_lock_fd =
3388 create_unlink_tmp(lp_lock_directory());
3389 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3390 DEBUG(1, ("Could not create lock fd: %s\n",
3391 strerror(errno)));
3392 goto fail;
3396 child = fork();
3397 if (child == 0) {
3398 NTSTATUS status;
3400 close(listener_pipe[0]);
3401 set_blocking(listener_pipe[1], false);
3403 status = smbd_reinit_after_fork(xconn->msg_ctx, xconn->ev_ctx,
3404 true, "smbd-echo");
3405 if (!NT_STATUS_IS_OK(status)) {
3406 DEBUG(1, ("reinit_after_fork failed: %s\n",
3407 nt_errstr(status)));
3408 exit(1);
3410 initialize_password_db(true, xconn->ev_ctx);
3411 smbd_echo_loop(xconn, listener_pipe[1]);
3412 exit(0);
3414 close(listener_pipe[1]);
3415 listener_pipe[1] = -1;
3416 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3418 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3421 * Without smb signing this is the same as the normal smbd
3422 * listener. This needs to change once signing comes in.
3424 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3425 xconn,
3426 xconn->smb1.echo_handler.trusted_fd,
3427 TEVENT_FD_READ,
3428 smbd_server_echo_handler,
3429 xconn);
3430 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3431 DEBUG(1, ("event_add_fd failed\n"));
3432 goto fail;
3435 return true;
3437 fail:
3438 if (listener_pipe[0] != -1) {
3439 close(listener_pipe[0]);
3441 if (listener_pipe[1] != -1) {
3442 close(listener_pipe[1]);
3444 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3445 close(xconn->smb1.echo_handler.socket_lock_fd);
3447 #ifdef HAVE_ROBUST_MUTEXES
3448 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3449 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3450 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3452 #endif
3453 smbd_echo_init(xconn);
3455 return false;
3458 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3460 while (user) {
3461 if (user->session_info &&
3462 (user->session_info->unix_token->uid == uid)) {
3463 return true;
3465 user = user->next;
3467 return false;
3470 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3472 while (user) {
3473 if (user->session_info != NULL) {
3474 int i;
3475 struct security_unix_token *utok;
3477 utok = user->session_info->unix_token;
3478 if (utok->gid == gid) {
3479 return true;
3481 for(i=0; i<utok->ngroups; i++) {
3482 if (utok->groups[i] == gid) {
3483 return true;
3487 user = user->next;
3489 return false;
3492 static bool sid_in_use(const struct user_struct *user,
3493 const struct dom_sid *psid)
3495 while (user) {
3496 struct security_token *tok;
3498 if (user->session_info == NULL) {
3499 continue;
3501 tok = user->session_info->security_token;
3502 if (tok == NULL) {
3504 * Not sure session_info->security_token can
3505 * ever be NULL. This check might be not
3506 * necessary.
3508 continue;
3510 if (security_token_has_sid(tok, psid)) {
3511 return true;
3513 user = user->next;
3515 return false;
3518 static bool id_in_use(const struct user_struct *user,
3519 const struct id_cache_ref *id)
3521 switch(id->type) {
3522 case UID:
3523 return uid_in_use(user, id->id.uid);
3524 case GID:
3525 return gid_in_use(user, id->id.gid);
3526 case SID:
3527 return sid_in_use(user, &id->id.sid);
3528 default:
3529 break;
3531 return false;
3534 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3535 void *private_data,
3536 uint32_t msg_type,
3537 struct server_id server_id,
3538 DATA_BLOB* data)
3540 const char *msg = (data && data->data)
3541 ? (const char *)data->data : "<NULL>";
3542 struct id_cache_ref id;
3543 struct smbd_server_connection *sconn =
3544 talloc_get_type_abort(private_data,
3545 struct smbd_server_connection);
3547 if (!id_cache_ref_parse(msg, &id)) {
3548 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3549 return;
3552 if (id_in_use(sconn->users, &id)) {
3553 exit_server_cleanly(msg);
3555 id_cache_delete_from_cache(&id);
3558 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3559 enum protocol_types protocol)
3561 NTSTATUS status;
3563 conn->protocol = protocol;
3565 if (conn->client->session_table != NULL) {
3566 return NT_STATUS_OK;
3569 if (protocol >= PROTOCOL_SMB2_02) {
3570 status = smb2srv_session_table_init(conn);
3571 if (!NT_STATUS_IS_OK(status)) {
3572 conn->protocol = PROTOCOL_NONE;
3573 return status;
3576 status = smb2srv_open_table_init(conn);
3577 if (!NT_STATUS_IS_OK(status)) {
3578 conn->protocol = PROTOCOL_NONE;
3579 return status;
3581 } else {
3582 status = smb1srv_session_table_init(conn);
3583 if (!NT_STATUS_IS_OK(status)) {
3584 conn->protocol = PROTOCOL_NONE;
3585 return status;
3588 status = smb1srv_tcon_table_init(conn);
3589 if (!NT_STATUS_IS_OK(status)) {
3590 conn->protocol = PROTOCOL_NONE;
3591 return status;
3594 status = smb1srv_open_table_init(conn);
3595 if (!NT_STATUS_IS_OK(status)) {
3596 conn->protocol = PROTOCOL_NONE;
3597 return status;
3601 set_Protocol(protocol);
3602 return NT_STATUS_OK;
3605 struct smbd_tevent_trace_state {
3606 struct tevent_context *ev;
3607 TALLOC_CTX *frame;
3608 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3611 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3612 void *private_data)
3614 struct smbd_tevent_trace_state *state =
3615 (struct smbd_tevent_trace_state *)private_data;
3617 switch (point) {
3618 case TEVENT_TRACE_BEFORE_WAIT:
3619 if (!smbprofile_dump_pending()) {
3621 * If there's no dump pending
3622 * we don't want to schedule a new 1 sec timer.
3624 * Instead we want to sleep as long as nothing happens.
3626 smbprofile_dump_setup(NULL);
3628 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3629 break;
3630 case TEVENT_TRACE_AFTER_WAIT:
3631 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3632 if (!smbprofile_dump_pending()) {
3634 * We need to flush our state after sleeping
3635 * (hopefully a long time).
3637 smbprofile_dump();
3639 * future profiling events should trigger timers
3640 * on our main event context.
3642 smbprofile_dump_setup(state->ev);
3644 break;
3645 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3646 TALLOC_FREE(state->frame);
3647 state->frame = talloc_stackframe_pool(8192);
3648 break;
3649 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3650 TALLOC_FREE(state->frame);
3651 break;
3654 errno = 0;
3658 * Create a debug string for the connection
3660 * This is allocated to talloc_tos() or a string constant
3661 * in certain corner cases. The returned string should
3662 * hence not be free'd directly but only via the talloc stack.
3664 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3666 const char *ret;
3669 * TODO: this can be improved later
3670 * maybe including the client guid or more
3672 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3673 if (ret == NULL) {
3674 return "<tsocket_address_string() failed>";
3677 return ret;
3680 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3681 struct smbXsrv_connection **_xconn)
3683 TALLOC_CTX *frame = talloc_stackframe();
3684 struct smbXsrv_connection *xconn;
3685 struct sockaddr_storage ss_srv;
3686 void *sp_srv = (void *)&ss_srv;
3687 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3688 struct sockaddr_storage ss_clnt;
3689 void *sp_clnt = (void *)&ss_clnt;
3690 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3691 socklen_t sa_socklen;
3692 struct tsocket_address *local_address = NULL;
3693 struct tsocket_address *remote_address = NULL;
3694 const char *remaddr = NULL;
3695 char *p;
3696 const char *rhost = NULL;
3697 int ret;
3698 int tmp;
3700 *_xconn = NULL;
3702 DO_PROFILE_INC(connect);
3704 xconn = talloc_zero(client, struct smbXsrv_connection);
3705 if (xconn == NULL) {
3706 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3707 TALLOC_FREE(frame);
3708 return NT_STATUS_NO_MEMORY;
3710 talloc_steal(frame, xconn);
3712 xconn->ev_ctx = client->ev_ctx;
3713 xconn->msg_ctx = client->msg_ctx;
3714 xconn->transport.sock = sock_fd;
3715 smbd_echo_init(xconn);
3716 xconn->protocol = PROTOCOL_NONE;
3718 /* Ensure child is set to blocking mode */
3719 set_blocking(sock_fd,True);
3721 set_socket_options(sock_fd, "SO_KEEPALIVE");
3722 set_socket_options(sock_fd, lp_socket_options());
3724 sa_socklen = sizeof(ss_clnt);
3725 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3726 if (ret != 0) {
3727 int saved_errno = errno;
3728 int level = (errno == ENOTCONN)?2:0;
3729 DEBUG(level,("getpeername() failed - %s\n",
3730 strerror(saved_errno)));
3731 TALLOC_FREE(frame);
3732 return map_nt_error_from_unix_common(saved_errno);
3734 ret = tsocket_address_bsd_from_sockaddr(xconn,
3735 sa_clnt, sa_socklen,
3736 &remote_address);
3737 if (ret != 0) {
3738 int saved_errno = errno;
3739 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3740 __location__, strerror(saved_errno)));
3741 TALLOC_FREE(frame);
3742 return map_nt_error_from_unix_common(saved_errno);
3745 sa_socklen = sizeof(ss_srv);
3746 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3747 if (ret != 0) {
3748 int saved_errno = errno;
3749 int level = (errno == ENOTCONN)?2:0;
3750 DEBUG(level,("getsockname() failed - %s\n",
3751 strerror(saved_errno)));
3752 TALLOC_FREE(frame);
3753 return map_nt_error_from_unix_common(saved_errno);
3755 ret = tsocket_address_bsd_from_sockaddr(xconn,
3756 sa_srv, sa_socklen,
3757 &local_address);
3758 if (ret != 0) {
3759 int saved_errno = errno;
3760 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3761 __location__, strerror(saved_errno)));
3762 TALLOC_FREE(frame);
3763 return map_nt_error_from_unix_common(saved_errno);
3766 if (tsocket_address_is_inet(remote_address, "ip")) {
3767 remaddr = tsocket_address_inet_addr_string(remote_address,
3768 talloc_tos());
3769 if (remaddr == NULL) {
3770 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3771 __location__, strerror(errno)));
3772 TALLOC_FREE(frame);
3773 return NT_STATUS_NO_MEMORY;
3775 } else {
3776 remaddr = "0.0.0.0";
3780 * Before the first packet, check the global hosts allow/ hosts deny
3781 * parameters before doing any parsing of packets passed to us by the
3782 * client. This prevents attacks on our parsing code from hosts not in
3783 * the hosts allow list.
3786 ret = get_remote_hostname(remote_address,
3787 &p, talloc_tos());
3788 if (ret < 0) {
3789 int saved_errno = errno;
3790 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3791 __location__, strerror(saved_errno)));
3792 TALLOC_FREE(frame);
3793 return map_nt_error_from_unix_common(saved_errno);
3795 rhost = p;
3796 if (strequal(rhost, "UNKNOWN")) {
3797 rhost = remaddr;
3800 xconn->local_address = local_address;
3801 xconn->remote_address = remote_address;
3802 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3803 if (xconn->remote_hostname == NULL) {
3804 return NT_STATUS_NO_MEMORY;
3807 if (!srv_init_signing(xconn)) {
3808 DEBUG(0, ("Failed to init smb_signing\n"));
3809 TALLOC_FREE(frame);
3810 return NT_STATUS_INTERNAL_ERROR;
3813 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3814 xconn->remote_hostname,
3815 remaddr)) {
3816 DEBUG( 1, ("Connection denied from %s to %s\n",
3817 tsocket_address_string(remote_address, talloc_tos()),
3818 tsocket_address_string(local_address, talloc_tos())));
3821 * We return a valid xconn
3822 * so that the caller can return an error message
3823 * to the client
3825 client->connections = xconn;
3826 xconn->client = client;
3827 talloc_steal(client, xconn);
3829 *_xconn = xconn;
3830 TALLOC_FREE(frame);
3831 return NT_STATUS_NETWORK_ACCESS_DENIED;
3834 DEBUG(10, ("Connection allowed from %s to %s\n",
3835 tsocket_address_string(remote_address, talloc_tos()),
3836 tsocket_address_string(local_address, talloc_tos())));
3838 if (lp_clustering()) {
3840 * We need to tell ctdb about our client's TCP
3841 * connection, so that for failover ctdbd can send
3842 * tickle acks, triggering a reconnection by the
3843 * client.
3845 NTSTATUS status;
3847 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3848 if (!NT_STATUS_IS_OK(status)) {
3849 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3850 nt_errstr(status)));
3854 tmp = lp_max_xmit();
3855 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3856 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3858 xconn->smb1.negprot.max_recv = tmp;
3860 xconn->smb1.sessions.done_sesssetup = false;
3861 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3863 xconn->transport.fde = tevent_add_fd(client->ev_ctx,
3864 xconn,
3865 sock_fd,
3866 TEVENT_FD_READ,
3867 smbd_server_connection_handler,
3868 xconn);
3869 if (!xconn->transport.fde) {
3870 TALLOC_FREE(frame);
3871 return NT_STATUS_NO_MEMORY;
3874 /* for now we only have one connection */
3875 DLIST_ADD_END(client->connections, xconn);
3876 xconn->client = client;
3877 talloc_steal(client, xconn);
3879 *_xconn = xconn;
3880 TALLOC_FREE(frame);
3881 return NT_STATUS_OK;
3884 /****************************************************************************
3885 Process commands from the client
3886 ****************************************************************************/
3888 void smbd_process(struct tevent_context *ev_ctx,
3889 struct messaging_context *msg_ctx,
3890 int sock_fd,
3891 bool interactive)
3893 struct smbd_tevent_trace_state trace_state = {
3894 .ev = ev_ctx,
3895 .frame = talloc_stackframe(),
3897 struct smbXsrv_client *client = NULL;
3898 struct smbd_server_connection *sconn = NULL;
3899 struct smbXsrv_connection *xconn = NULL;
3900 const char *locaddr = NULL;
3901 const char *remaddr = NULL;
3902 int ret;
3903 NTSTATUS status;
3904 struct timeval tv = timeval_current();
3905 NTTIME now = timeval_to_nttime(&tv);
3906 char *chroot_dir = NULL;
3907 int rc;
3909 status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
3910 if (!NT_STATUS_IS_OK(status)) {
3911 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
3912 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3916 * TODO: remove this...:-)
3918 global_smbXsrv_client = client;
3920 sconn = talloc_zero(client, struct smbd_server_connection);
3921 if (sconn == NULL) {
3922 exit_server("failed to create smbd_server_connection");
3925 client->sconn = sconn;
3926 sconn->client = client;
3928 sconn->ev_ctx = ev_ctx;
3929 sconn->msg_ctx = msg_ctx;
3931 ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
3932 &sconn->pool);
3933 if (ret != 0) {
3934 exit_server("pthreadpool_tevent_init() failed.");
3937 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3939 * We're not making the decision here,
3940 * we're just allowing the client
3941 * to decide between SMB1 and SMB2
3942 * with the first negprot
3943 * packet.
3945 sconn->using_smb2 = true;
3948 if (!interactive) {
3949 smbd_setup_sig_term_handler(sconn);
3950 smbd_setup_sig_hup_handler(sconn);
3953 status = smbd_add_connection(client, sock_fd, &xconn);
3954 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3956 * send a negative session response "not listening on calling
3957 * name"
3959 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3960 (void)srv_send_smb(xconn,(char *)buf, false,
3961 0, false, NULL);
3962 exit_server_cleanly("connection denied");
3963 } else if (!NT_STATUS_IS_OK(status)) {
3964 exit_server_cleanly(nt_errstr(status));
3967 sconn->local_address =
3968 tsocket_address_copy(xconn->local_address, sconn);
3969 if (sconn->local_address == NULL) {
3970 exit_server_cleanly("tsocket_address_copy() failed");
3972 sconn->remote_address =
3973 tsocket_address_copy(xconn->remote_address, sconn);
3974 if (sconn->remote_address == NULL) {
3975 exit_server_cleanly("tsocket_address_copy() failed");
3977 sconn->remote_hostname =
3978 talloc_strdup(sconn, xconn->remote_hostname);
3979 if (sconn->remote_hostname == NULL) {
3980 exit_server_cleanly("tsocket_strdup() failed");
3983 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3984 locaddr = tsocket_address_inet_addr_string(
3985 sconn->local_address,
3986 talloc_tos());
3987 if (locaddr == NULL) {
3988 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3989 __location__, strerror(errno)));
3990 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3992 } else {
3993 locaddr = "0.0.0.0";
3996 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
3997 remaddr = tsocket_address_inet_addr_string(
3998 sconn->remote_address,
3999 talloc_tos());
4000 if (remaddr == NULL) {
4001 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4002 __location__, strerror(errno)));
4003 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4005 } else {
4006 remaddr = "0.0.0.0";
4009 /* this is needed so that we get decent entries
4010 in smbstatus for port 445 connects */
4011 set_remote_machine_name(remaddr, false);
4012 reload_services(sconn, conn_snum_used, true);
4013 sub_set_socket_ids(remaddr,
4014 sconn->remote_hostname,
4015 locaddr);
4017 if (lp_preload_modules()) {
4018 smb_load_all_modules_absoute_path(lp_preload_modules());
4021 smb_perfcount_init();
4023 if (!init_account_policy()) {
4024 exit_server("Could not open account policy tdb.\n");
4027 chroot_dir = lp_root_directory(talloc_tos());
4028 if (chroot_dir[0] != '\0') {
4029 rc = chdir(chroot_dir);
4030 if (rc != 0) {
4031 DBG_ERR("Failed to chdir to %s\n", chroot_dir);
4032 exit_server("Failed to chdir()");
4035 rc = chroot(chroot_dir);
4036 if (rc != 0) {
4037 DBG_ERR("Failed to change root to %s\n", chroot_dir);
4038 exit_server("Failed to chroot()");
4040 DBG_WARNING("Changed root to %s\n", chroot_dir);
4042 TALLOC_FREE(chroot_dir);
4045 if (!file_init(sconn)) {
4046 exit_server("file_init() failed");
4049 /* Setup oplocks */
4050 if (!init_oplocks(sconn))
4051 exit_server("Failed to init oplocks");
4053 /* register our message handlers */
4054 messaging_register(sconn->msg_ctx, sconn,
4055 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4056 messaging_register(sconn->msg_ctx, sconn,
4057 MSG_SMB_CLOSE_FILE, msg_close_file);
4058 messaging_register(sconn->msg_ctx, sconn,
4059 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
4061 id_cache_register_msgs(sconn->msg_ctx);
4062 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
4063 messaging_register(sconn->msg_ctx, sconn,
4064 ID_CACHE_KILL, smbd_id_cache_kill);
4066 messaging_deregister(sconn->msg_ctx,
4067 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
4068 messaging_register(sconn->msg_ctx, sconn,
4069 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
4071 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
4072 NULL);
4073 messaging_register(sconn->msg_ctx, sconn,
4074 MSG_SMB_KILL_CLIENT_IP,
4075 msg_kill_client_ip);
4077 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
4080 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4081 * MSGs to all child processes
4083 messaging_deregister(sconn->msg_ctx,
4084 MSG_DEBUG, NULL);
4085 messaging_register(sconn->msg_ctx, NULL,
4086 MSG_DEBUG, debug_message);
4088 if ((lp_keepalive() != 0)
4089 && !(event_add_idle(ev_ctx, NULL,
4090 timeval_set(lp_keepalive(), 0),
4091 "keepalive", keepalive_fn,
4092 sconn))) {
4093 DEBUG(0, ("Could not add keepalive event\n"));
4094 exit(1);
4097 if (!(event_add_idle(ev_ctx, NULL,
4098 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4099 "deadtime", deadtime_fn, sconn))) {
4100 DEBUG(0, ("Could not add deadtime event\n"));
4101 exit(1);
4104 if (!(event_add_idle(ev_ctx, NULL,
4105 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4106 "housekeeping", housekeeping_fn, sconn))) {
4107 DEBUG(0, ("Could not add housekeeping event\n"));
4108 exit(1);
4111 smbprofile_dump_setup(ev_ctx);
4113 if (!init_dptrs(sconn)) {
4114 exit_server("init_dptrs() failed");
4117 TALLOC_FREE(trace_state.frame);
4119 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4120 &trace_state);
4122 ret = tevent_loop_wait(ev_ctx);
4123 if (ret != 0) {
4124 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4125 " exiting\n", ret, strerror(errno)));
4128 TALLOC_FREE(trace_state.frame);
4130 exit_server_cleanly(NULL);
4133 bool req_is_in_chain(const struct smb_request *req)
4135 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4137 * We're right now handling a subsequent request, so we must
4138 * be in a chain
4140 return true;
4143 if (!is_andx_req(req->cmd)) {
4144 return false;
4147 if (req->wct < 2) {
4149 * Okay, an illegal request, but definitely not chained :-)
4151 return false;
4154 return (CVAL(req->vwv+0, 0) != 0xFF);