s3:smbd: remove unused 'sconn' from is_encrypted_packet()
[Samba.git] / source3 / smbd / process.c
blob8caa7d2a7de430b267bd7bd79881c69523edb6ec
1 /*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
42 #include "serverid.h"
43 #include "system/threads.h"
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list {
47 struct pending_message_list *next, *prev;
48 struct timeval request_time; /* When was this first issued? */
49 struct smbd_server_connection *sconn;
50 struct smbXsrv_connection *xconn;
51 struct tevent_timer *te;
52 struct smb_perfcount_data pcd;
53 uint32_t seqnum;
54 bool encrypted;
55 bool processed;
56 DATA_BLOB buf;
57 struct deferred_open_record *open_rec;
60 static void construct_reply_common(struct smb_request *req, const char *inbuf,
61 char *outbuf);
62 static struct pending_message_list *get_deferred_open_message_smb(
63 struct smbd_server_connection *sconn, uint64_t mid);
64 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
66 static void smbd_echo_init(struct smbXsrv_connection *xconn)
68 xconn->smb1.echo_handler.trusted_fd = -1;
69 xconn->smb1.echo_handler.socket_lock_fd = -1;
70 #ifdef HAVE_ROBUST_MUTEXES
71 xconn->smb1.echo_handler.socket_mutex = NULL;
72 #endif
75 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
77 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
78 return true;
81 #ifdef HAVE_ROBUST_MUTEXES
82 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
83 return true;
85 #endif
87 return false;
90 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
92 struct smbXsrv_connection *xconn = sconn->conn;
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 smbd_server_connection *sconn)
147 if (!smbd_lock_socket_internal(sconn)) {
148 exit_server_cleanly("failed to lock socket");
152 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
154 struct smbXsrv_connection *xconn = sconn->conn;
156 if (!smbd_echo_active(xconn)) {
157 return true;
160 xconn->smb1.echo_handler.ref_count--;
162 if (xconn->smb1.echo_handler.ref_count > 0) {
163 return true;
166 #ifdef HAVE_ROBUST_MUTEXES
167 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
168 int ret = EINTR;
170 while (ret == EINTR) {
171 ret = pthread_mutex_unlock(
172 xconn->smb1.echo_handler.socket_mutex);
173 if (ret == 0) {
174 break;
177 if (ret != 0) {
178 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
179 strerror(ret)));
180 return false;
183 #endif
185 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
186 bool ok;
188 do {
189 ok = fcntl_lock(
190 xconn->smb1.echo_handler.socket_lock_fd,
191 F_SETLKW, 0, 0, F_UNLCK);
192 } while (!ok && (errno == EINTR));
194 if (!ok) {
195 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
196 return false;
200 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
202 return true;
205 void smbd_unlock_socket(struct smbd_server_connection *sconn)
207 if (!smbd_unlock_socket_internal(sconn)) {
208 exit_server_cleanly("failed to unlock socket");
212 /* Accessor function for smb_read_error for smbd functions. */
214 /****************************************************************************
215 Send an smb to a fd.
216 ****************************************************************************/
218 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
219 bool do_signing, uint32_t seqnum,
220 bool do_encrypt,
221 struct smb_perfcount_data *pcd)
223 struct smbXsrv_connection *xconn = sconn->conn;
224 size_t len = 0;
225 ssize_t ret;
226 char *buf_out = buffer;
228 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
230 * we're not supposed to do any io
232 return true;
235 smbd_lock_socket(sconn);
237 if (do_signing) {
238 /* Sign the outgoing packet if required. */
239 srv_calculate_sign_mac(xconn, buf_out, seqnum);
242 if (do_encrypt) {
243 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
244 if (!NT_STATUS_IS_OK(status)) {
245 DEBUG(0, ("send_smb: SMB encryption failed "
246 "on outgoing packet! Error %s\n",
247 nt_errstr(status) ));
248 ret = -1;
249 goto out;
253 len = smb_len_large(buf_out) + 4;
255 ret = write_data(xconn->transport.sock, buf_out, len);
256 if (ret <= 0) {
257 int saved_errno = errno;
259 * Try and give an error message saying what
260 * client failed.
262 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
263 (int)getpid(), (int)len,
264 smbXsrv_connection_dbg(xconn),
265 (int)ret, strerror(saved_errno)));
266 errno = saved_errno;
268 srv_free_enc_buffer(sconn, buf_out);
269 goto out;
272 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
273 srv_free_enc_buffer(sconn, buf_out);
274 out:
275 SMB_PERFCOUNT_END(pcd);
277 smbd_unlock_socket(sconn);
278 return (ret > 0);
281 /*******************************************************************
282 Setup the word count and byte count for a smb message.
283 ********************************************************************/
285 int srv_set_message(char *buf,
286 int num_words,
287 int num_bytes,
288 bool zero)
290 if (zero && (num_words || num_bytes)) {
291 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
293 SCVAL(buf,smb_wct,num_words);
294 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
295 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
296 return (smb_size + num_words*2 + num_bytes);
299 static bool valid_smb_header(struct smbd_server_connection *sconn,
300 const uint8_t *inbuf)
302 if (is_encrypted_packet(inbuf)) {
303 return true;
306 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
307 * but it just looks weird to call strncmp for this one.
309 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
312 /* Socket functions for smbd packet processing. */
314 static bool valid_packet_size(size_t len)
317 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
318 * of header. Don't print the error if this fits.... JRA.
321 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
322 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
323 (unsigned long)len));
324 return false;
326 return true;
329 static NTSTATUS read_packet_remainder(int fd, char *buffer,
330 unsigned int timeout, ssize_t len)
332 NTSTATUS status;
334 if (len <= 0) {
335 return NT_STATUS_OK;
338 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
339 if (!NT_STATUS_IS_OK(status)) {
340 char addr[INET6_ADDRSTRLEN];
341 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
342 "error = %s.\n",
343 get_peer_addr(fd, addr, sizeof(addr)),
344 nt_errstr(status)));
346 return status;
349 /****************************************************************************
350 Attempt a zerocopy writeX read. We know here that len > smb_size-4
351 ****************************************************************************/
354 * Unfortunately, earlier versions of smbclient/libsmbclient
355 * don't send this "standard" writeX header. I've fixed this
356 * for 3.2 but we'll use the old method with earlier versions.
357 * Windows and CIFSFS at least use this standard size. Not
358 * sure about MacOSX.
361 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
362 (2*14) + /* word count (including bcc) */ \
363 1 /* pad byte */)
365 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
366 const char lenbuf[4],
367 struct smbd_server_connection *sconn,
368 int sock,
369 char **buffer,
370 unsigned int timeout,
371 size_t *p_unread,
372 size_t *len_ret)
374 /* Size of a WRITEX call (+4 byte len). */
375 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
376 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
377 ssize_t toread;
378 NTSTATUS status;
380 memcpy(writeX_header, lenbuf, 4);
382 status = read_fd_with_timeout(
383 sock, writeX_header + 4,
384 STANDARD_WRITE_AND_X_HEADER_SIZE,
385 STANDARD_WRITE_AND_X_HEADER_SIZE,
386 timeout, NULL);
388 if (!NT_STATUS_IS_OK(status)) {
389 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
390 "error = %s.\n",
391 tsocket_address_string(sconn->remote_address,
392 talloc_tos()),
393 nt_errstr(status)));
394 return status;
398 * Ok - now try and see if this is a possible
399 * valid writeX call.
402 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
404 * If the data offset is beyond what
405 * we've read, drain the extra bytes.
407 uint16_t doff = SVAL(writeX_header,smb_vwv11);
408 ssize_t newlen;
410 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
411 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
412 if (drain_socket(sock, drain) != drain) {
413 smb_panic("receive_smb_raw_talloc_partial_read:"
414 " failed to drain pending bytes");
416 } else {
417 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
420 /* Spoof down the length and null out the bcc. */
421 set_message_bcc(writeX_header, 0);
422 newlen = smb_len(writeX_header);
424 /* Copy the header we've written. */
426 *buffer = (char *)talloc_memdup(mem_ctx,
427 writeX_header,
428 sizeof(writeX_header));
430 if (*buffer == NULL) {
431 DEBUG(0, ("Could not allocate inbuf of length %d\n",
432 (int)sizeof(writeX_header)));
433 return NT_STATUS_NO_MEMORY;
436 /* Work out the remaining bytes. */
437 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
438 *len_ret = newlen + 4;
439 return NT_STATUS_OK;
442 if (!valid_packet_size(len)) {
443 return NT_STATUS_INVALID_PARAMETER;
447 * Not a valid writeX call. Just do the standard
448 * talloc and return.
451 *buffer = talloc_array(mem_ctx, char, len+4);
453 if (*buffer == NULL) {
454 DEBUG(0, ("Could not allocate inbuf of length %d\n",
455 (int)len+4));
456 return NT_STATUS_NO_MEMORY;
459 /* Copy in what we already read. */
460 memcpy(*buffer,
461 writeX_header,
462 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
463 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
465 if(toread > 0) {
466 status = read_packet_remainder(
467 sock,
468 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
469 timeout, toread);
471 if (!NT_STATUS_IS_OK(status)) {
472 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
473 nt_errstr(status)));
474 return status;
478 *len_ret = len + 4;
479 return NT_STATUS_OK;
482 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
483 struct smbd_server_connection *sconn,
484 int sock,
485 char **buffer, unsigned int timeout,
486 size_t *p_unread, size_t *plen)
488 struct smbXsrv_connection *xconn = sconn->conn;
489 char lenbuf[4];
490 size_t len;
491 int min_recv_size = lp_min_receive_file_size();
492 NTSTATUS status;
494 *p_unread = 0;
496 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
497 &len);
498 if (!NT_STATUS_IS_OK(status)) {
499 return status;
502 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
503 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
504 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
505 !srv_is_signing_active(xconn) &&
506 xconn->smb1.echo_handler.trusted_fde == NULL) {
508 return receive_smb_raw_talloc_partial_read(
509 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
510 p_unread, plen);
513 if (!valid_packet_size(len)) {
514 return NT_STATUS_INVALID_PARAMETER;
518 * The +4 here can't wrap, we've checked the length above already.
521 *buffer = talloc_array(mem_ctx, char, len+4);
523 if (*buffer == NULL) {
524 DEBUG(0, ("Could not allocate inbuf of length %d\n",
525 (int)len+4));
526 return NT_STATUS_NO_MEMORY;
529 memcpy(*buffer, lenbuf, sizeof(lenbuf));
531 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
532 if (!NT_STATUS_IS_OK(status)) {
533 return status;
536 *plen = len + 4;
537 return NT_STATUS_OK;
540 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
541 struct smbd_server_connection *sconn,
542 int sock,
543 char **buffer, unsigned int timeout,
544 size_t *p_unread, bool *p_encrypted,
545 size_t *p_len,
546 uint32_t *seqnum,
547 bool trusted_channel)
549 struct smbXsrv_connection *xconn = sconn->conn;
550 size_t len = 0;
551 NTSTATUS status;
553 *p_encrypted = false;
555 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
556 p_unread, &len);
557 if (!NT_STATUS_IS_OK(status)) {
558 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
559 ("receive_smb_raw_talloc failed for client %s "
560 "read error = %s.\n",
561 tsocket_address_string(sconn->remote_address,
562 talloc_tos()),
563 nt_errstr(status)) );
564 return status;
567 if (is_encrypted_packet((uint8_t *)*buffer)) {
568 status = srv_decrypt_buffer(sconn, *buffer);
569 if (!NT_STATUS_IS_OK(status)) {
570 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
571 "incoming packet! Error %s\n",
572 nt_errstr(status) ));
573 return status;
575 *p_encrypted = true;
578 /* Check the incoming SMB signature. */
579 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
580 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
581 "incoming packet!\n"));
582 return NT_STATUS_INVALID_NETWORK_RESPONSE;
585 *p_len = len;
586 return NT_STATUS_OK;
590 * Initialize a struct smb_request from an inbuf
593 static bool init_smb_request(struct smb_request *req,
594 struct smbd_server_connection *sconn,
595 struct smbXsrv_connection *xconn,
596 const uint8 *inbuf,
597 size_t unread_bytes, bool encrypted,
598 uint32_t seqnum)
600 struct smbXsrv_tcon *tcon;
601 NTSTATUS status;
602 NTTIME now;
603 size_t req_size = smb_len(inbuf) + 4;
605 /* Ensure we have at least smb_size bytes. */
606 if (req_size < smb_size) {
607 DEBUG(0,("init_smb_request: invalid request size %u\n",
608 (unsigned int)req_size ));
609 return false;
612 req->request_time = timeval_current();
613 now = timeval_to_nttime(&req->request_time);
615 req->cmd = CVAL(inbuf, smb_com);
616 req->flags2 = SVAL(inbuf, smb_flg2);
617 req->smbpid = SVAL(inbuf, smb_pid);
618 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
619 req->seqnum = seqnum;
620 req->vuid = SVAL(inbuf, smb_uid);
621 req->tid = SVAL(inbuf, smb_tid);
622 req->wct = CVAL(inbuf, smb_wct);
623 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
624 req->buflen = smb_buflen(inbuf);
625 req->buf = (const uint8_t *)smb_buf_const(inbuf);
626 req->unread_bytes = unread_bytes;
627 req->encrypted = encrypted;
628 req->sconn = sconn;
629 req->xconn = xconn;
630 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
631 if (NT_STATUS_IS_OK(status)) {
632 req->conn = tcon->compat;
633 } else {
634 req->conn = NULL;
636 req->chain_fsp = NULL;
637 req->smb2req = NULL;
638 req->priv_paths = NULL;
639 req->chain = NULL;
640 smb_init_perfcount_data(&req->pcd);
642 /* Ensure we have at least wct words and 2 bytes of bcc. */
643 if (smb_size + req->wct*2 > req_size) {
644 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
645 (unsigned int)req->wct,
646 (unsigned int)req_size));
647 return false;
649 /* Ensure bcc is correct. */
650 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
651 DEBUG(0,("init_smb_request: invalid bcc number %u "
652 "(wct = %u, size %u)\n",
653 (unsigned int)req->buflen,
654 (unsigned int)req->wct,
655 (unsigned int)req_size));
656 return false;
659 req->outbuf = NULL;
660 return true;
663 static void process_smb(struct smbXsrv_connection *xconn,
664 uint8_t *inbuf, size_t nread, size_t unread_bytes,
665 uint32_t seqnum, bool encrypted,
666 struct smb_perfcount_data *deferred_pcd);
668 static void smbd_deferred_open_timer(struct tevent_context *ev,
669 struct tevent_timer *te,
670 struct timeval _tval,
671 void *private_data)
673 struct pending_message_list *msg = talloc_get_type(private_data,
674 struct pending_message_list);
675 struct smbd_server_connection *sconn = msg->sconn;
676 struct smbXsrv_connection *xconn = msg->xconn;
677 TALLOC_CTX *mem_ctx = talloc_tos();
678 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
679 uint8_t *inbuf;
681 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
682 msg->buf.length);
683 if (inbuf == NULL) {
684 exit_server("smbd_deferred_open_timer: talloc failed\n");
685 return;
688 /* We leave this message on the queue so the open code can
689 know this is a retry. */
690 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
691 (unsigned long long)mid ));
693 /* Mark the message as processed so this is not
694 * re-processed in error. */
695 msg->processed = true;
697 process_smb(xconn, inbuf,
698 msg->buf.length, 0,
699 msg->seqnum, msg->encrypted, &msg->pcd);
701 /* If it's still there and was processed, remove it. */
702 msg = get_deferred_open_message_smb(sconn, mid);
703 if (msg && msg->processed) {
704 remove_deferred_open_message_smb(sconn, mid);
708 /****************************************************************************
709 Function to push a message onto the tail of a linked list of smb messages ready
710 for processing.
711 ****************************************************************************/
713 static bool push_queued_message(struct smb_request *req,
714 struct timeval request_time,
715 struct timeval end_time,
716 struct deferred_open_record *open_rec)
718 int msg_len = smb_len(req->inbuf) + 4;
719 struct pending_message_list *msg;
721 msg = talloc_zero(NULL, struct pending_message_list);
723 if(msg == NULL) {
724 DEBUG(0,("push_message: malloc fail (1)\n"));
725 return False;
727 msg->sconn = req->sconn;
728 msg->xconn = req->xconn;
730 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
731 if(msg->buf.data == NULL) {
732 DEBUG(0,("push_message: malloc fail (2)\n"));
733 TALLOC_FREE(msg);
734 return False;
737 msg->request_time = request_time;
738 msg->seqnum = req->seqnum;
739 msg->encrypted = req->encrypted;
740 msg->processed = false;
741 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
743 if (open_rec) {
744 msg->open_rec = talloc_move(msg, &open_rec);
747 #if 0
748 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
749 msg,
750 end_time,
751 smbd_deferred_open_timer,
752 msg);
753 if (!msg->te) {
754 DEBUG(0,("push_message: event_add_timed failed\n"));
755 TALLOC_FREE(msg);
756 return false;
758 #endif
760 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
761 struct pending_message_list *);
763 DEBUG(10,("push_message: pushed message length %u on "
764 "deferred_open_queue\n", (unsigned int)msg_len));
766 return True;
769 /****************************************************************************
770 Function to delete a sharing violation open message by mid.
771 ****************************************************************************/
773 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
774 uint64_t mid)
776 struct pending_message_list *pml;
778 if (sconn->using_smb2) {
779 remove_deferred_open_message_smb2(sconn, mid);
780 return;
783 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
784 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
785 DEBUG(10,("remove_deferred_open_message_smb: "
786 "deleting mid %llu len %u\n",
787 (unsigned long long)mid,
788 (unsigned int)pml->buf.length ));
789 DLIST_REMOVE(sconn->deferred_open_queue, pml);
790 TALLOC_FREE(pml);
791 return;
796 /****************************************************************************
797 Move a sharing violation open retry message to the front of the list and
798 schedule it for immediate processing.
799 ****************************************************************************/
801 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
802 uint64_t mid)
804 struct pending_message_list *pml;
805 int i = 0;
807 if (sconn->using_smb2) {
808 return schedule_deferred_open_message_smb2(sconn, mid);
811 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
812 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
814 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
815 "msg_mid = %llu\n",
816 i++,
817 (unsigned long long)msg_mid ));
819 if (mid == msg_mid) {
820 struct tevent_timer *te;
822 if (pml->processed) {
823 /* A processed message should not be
824 * rescheduled. */
825 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
826 "message mid %llu was already processed\n",
827 (unsigned long long)msg_mid ));
828 continue;
831 DEBUG(10,("schedule_deferred_open_message_smb: "
832 "scheduling mid %llu\n",
833 (unsigned long long)mid ));
835 te = tevent_add_timer(pml->sconn->ev_ctx,
836 pml,
837 timeval_zero(),
838 smbd_deferred_open_timer,
839 pml);
840 if (!te) {
841 DEBUG(10,("schedule_deferred_open_message_smb: "
842 "event_add_timed() failed, "
843 "skipping mid %llu\n",
844 (unsigned long long)msg_mid ));
847 TALLOC_FREE(pml->te);
848 pml->te = te;
849 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
850 return true;
854 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
855 "find message mid %llu\n",
856 (unsigned long long)mid ));
858 return false;
861 /****************************************************************************
862 Return true if this mid is on the deferred queue and was not yet processed.
863 ****************************************************************************/
865 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
867 struct pending_message_list *pml;
869 if (sconn->using_smb2) {
870 return open_was_deferred_smb2(sconn, mid);
873 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
874 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
875 return True;
878 return False;
881 /****************************************************************************
882 Return the message queued by this mid.
883 ****************************************************************************/
885 static struct pending_message_list *get_deferred_open_message_smb(
886 struct smbd_server_connection *sconn, uint64_t mid)
888 struct pending_message_list *pml;
890 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
891 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
892 return pml;
895 return NULL;
898 /****************************************************************************
899 Get the state data queued by this mid.
900 ****************************************************************************/
902 bool get_deferred_open_message_state(struct smb_request *smbreq,
903 struct timeval *p_request_time,
904 struct deferred_open_record **open_rec)
906 struct pending_message_list *pml;
908 if (smbreq->sconn->using_smb2) {
909 return get_deferred_open_message_state_smb2(smbreq->smb2req,
910 p_request_time,
911 open_rec);
914 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
915 if (!pml) {
916 return false;
918 if (p_request_time) {
919 *p_request_time = pml->request_time;
921 if (open_rec != NULL) {
922 *open_rec = pml->open_rec;
924 return true;
927 /****************************************************************************
928 Function to push a deferred open smb message onto a linked list of local smb
929 messages ready for processing.
930 ****************************************************************************/
932 bool push_deferred_open_message_smb(struct smb_request *req,
933 struct timeval request_time,
934 struct timeval timeout,
935 struct file_id id,
936 struct deferred_open_record *open_rec)
938 struct timeval end_time;
940 if (req->smb2req) {
941 return push_deferred_open_message_smb2(req->smb2req,
942 request_time,
943 timeout,
945 open_rec);
948 if (req->unread_bytes) {
949 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
950 "unread_bytes = %u\n",
951 (unsigned int)req->unread_bytes ));
952 smb_panic("push_deferred_open_message_smb: "
953 "logic error unread_bytes != 0" );
956 end_time = timeval_sum(&request_time, &timeout);
958 DEBUG(10,("push_deferred_open_message_smb: pushing message "
959 "len %u mid %llu timeout time [%u.%06u]\n",
960 (unsigned int) smb_len(req->inbuf)+4,
961 (unsigned long long)req->mid,
962 (unsigned int)end_time.tv_sec,
963 (unsigned int)end_time.tv_usec));
965 return push_queued_message(req, request_time, end_time, open_rec);
968 static void smbd_sig_term_handler(struct tevent_context *ev,
969 struct tevent_signal *se,
970 int signum,
971 int count,
972 void *siginfo,
973 void *private_data)
975 exit_server_cleanly("termination signal");
978 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
980 struct tevent_signal *se;
982 se = tevent_add_signal(sconn->ev_ctx,
983 sconn,
984 SIGTERM, 0,
985 smbd_sig_term_handler,
986 sconn);
987 if (!se) {
988 exit_server("failed to setup SIGTERM handler");
992 static void smbd_sig_hup_handler(struct tevent_context *ev,
993 struct tevent_signal *se,
994 int signum,
995 int count,
996 void *siginfo,
997 void *private_data)
999 struct smbd_server_connection *sconn =
1000 talloc_get_type_abort(private_data,
1001 struct smbd_server_connection);
1003 change_to_root_user();
1004 DEBUG(1,("Reloading services after SIGHUP\n"));
1005 reload_services(sconn, conn_snum_used, false);
1008 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1010 struct tevent_signal *se;
1012 se = tevent_add_signal(sconn->ev_ctx,
1013 sconn,
1014 SIGHUP, 0,
1015 smbd_sig_hup_handler,
1016 sconn);
1017 if (!se) {
1018 exit_server("failed to setup SIGHUP handler");
1022 static void smbd_conf_updated(struct messaging_context *msg,
1023 void *private_data,
1024 uint32_t msg_type,
1025 struct server_id server_id,
1026 DATA_BLOB *data)
1028 struct smbd_server_connection *sconn =
1029 talloc_get_type_abort(private_data,
1030 struct smbd_server_connection);
1032 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1033 "updated. Reloading.\n"));
1034 change_to_root_user();
1035 reload_services(sconn, conn_snum_used, false);
1039 * Only allow 5 outstanding trans requests. We're allocating memory, so
1040 * prevent a DoS.
1043 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1045 int count = 0;
1046 for (; list != NULL; list = list->next) {
1048 if (list->mid == mid) {
1049 return NT_STATUS_INVALID_PARAMETER;
1052 count += 1;
1054 if (count > 5) {
1055 return NT_STATUS_INSUFFICIENT_RESOURCES;
1058 return NT_STATUS_OK;
1062 These flags determine some of the permissions required to do an operation
1064 Note that I don't set NEED_WRITE on some write operations because they
1065 are used by some brain-dead clients when printing, and I don't want to
1066 force write permissions on print services.
1068 #define AS_USER (1<<0)
1069 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1070 #define TIME_INIT (1<<2)
1071 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1072 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1073 #define DO_CHDIR (1<<6)
1076 define a list of possible SMB messages and their corresponding
1077 functions. Any message that has a NULL function is unimplemented -
1078 please feel free to contribute implementations!
1080 static const struct smb_message_struct {
1081 const char *name;
1082 void (*fn)(struct smb_request *req);
1083 int flags;
1084 } smb_messages[256] = {
1086 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1087 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1088 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1089 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1090 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1091 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1092 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1093 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1094 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1095 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1096 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1097 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1098 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1099 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1100 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1101 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1102 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1103 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1104 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1105 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1106 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1107 /* 0x15 */ { NULL, NULL, 0 },
1108 /* 0x16 */ { NULL, NULL, 0 },
1109 /* 0x17 */ { NULL, NULL, 0 },
1110 /* 0x18 */ { NULL, NULL, 0 },
1111 /* 0x19 */ { NULL, NULL, 0 },
1112 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1113 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1114 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1115 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1116 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1117 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1118 /* 0x20 */ { "SMBwritec", NULL,0},
1119 /* 0x21 */ { NULL, NULL, 0 },
1120 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1121 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1122 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1123 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1124 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1125 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1126 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1127 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1128 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1129 /* 0x2b */ { "SMBecho",reply_echo,0},
1130 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1131 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1132 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1133 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1134 /* 0x30 */ { NULL, NULL, 0 },
1135 /* 0x31 */ { NULL, NULL, 0 },
1136 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1137 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1138 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1139 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1140 /* 0x36 */ { NULL, NULL, 0 },
1141 /* 0x37 */ { NULL, NULL, 0 },
1142 /* 0x38 */ { NULL, NULL, 0 },
1143 /* 0x39 */ { NULL, NULL, 0 },
1144 /* 0x3a */ { NULL, NULL, 0 },
1145 /* 0x3b */ { NULL, NULL, 0 },
1146 /* 0x3c */ { NULL, NULL, 0 },
1147 /* 0x3d */ { NULL, NULL, 0 },
1148 /* 0x3e */ { NULL, NULL, 0 },
1149 /* 0x3f */ { NULL, NULL, 0 },
1150 /* 0x40 */ { NULL, NULL, 0 },
1151 /* 0x41 */ { NULL, NULL, 0 },
1152 /* 0x42 */ { NULL, NULL, 0 },
1153 /* 0x43 */ { NULL, NULL, 0 },
1154 /* 0x44 */ { NULL, NULL, 0 },
1155 /* 0x45 */ { NULL, NULL, 0 },
1156 /* 0x46 */ { NULL, NULL, 0 },
1157 /* 0x47 */ { NULL, NULL, 0 },
1158 /* 0x48 */ { NULL, NULL, 0 },
1159 /* 0x49 */ { NULL, NULL, 0 },
1160 /* 0x4a */ { NULL, NULL, 0 },
1161 /* 0x4b */ { NULL, NULL, 0 },
1162 /* 0x4c */ { NULL, NULL, 0 },
1163 /* 0x4d */ { NULL, NULL, 0 },
1164 /* 0x4e */ { NULL, NULL, 0 },
1165 /* 0x4f */ { NULL, NULL, 0 },
1166 /* 0x50 */ { NULL, NULL, 0 },
1167 /* 0x51 */ { NULL, NULL, 0 },
1168 /* 0x52 */ { NULL, NULL, 0 },
1169 /* 0x53 */ { NULL, NULL, 0 },
1170 /* 0x54 */ { NULL, NULL, 0 },
1171 /* 0x55 */ { NULL, NULL, 0 },
1172 /* 0x56 */ { NULL, NULL, 0 },
1173 /* 0x57 */ { NULL, NULL, 0 },
1174 /* 0x58 */ { NULL, NULL, 0 },
1175 /* 0x59 */ { NULL, NULL, 0 },
1176 /* 0x5a */ { NULL, NULL, 0 },
1177 /* 0x5b */ { NULL, NULL, 0 },
1178 /* 0x5c */ { NULL, NULL, 0 },
1179 /* 0x5d */ { NULL, NULL, 0 },
1180 /* 0x5e */ { NULL, NULL, 0 },
1181 /* 0x5f */ { NULL, NULL, 0 },
1182 /* 0x60 */ { NULL, NULL, 0 },
1183 /* 0x61 */ { NULL, NULL, 0 },
1184 /* 0x62 */ { NULL, NULL, 0 },
1185 /* 0x63 */ { NULL, NULL, 0 },
1186 /* 0x64 */ { NULL, NULL, 0 },
1187 /* 0x65 */ { NULL, NULL, 0 },
1188 /* 0x66 */ { NULL, NULL, 0 },
1189 /* 0x67 */ { NULL, NULL, 0 },
1190 /* 0x68 */ { NULL, NULL, 0 },
1191 /* 0x69 */ { NULL, NULL, 0 },
1192 /* 0x6a */ { NULL, NULL, 0 },
1193 /* 0x6b */ { NULL, NULL, 0 },
1194 /* 0x6c */ { NULL, NULL, 0 },
1195 /* 0x6d */ { NULL, NULL, 0 },
1196 /* 0x6e */ { NULL, NULL, 0 },
1197 /* 0x6f */ { NULL, NULL, 0 },
1198 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1199 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1200 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1201 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1202 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1203 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1204 /* 0x76 */ { NULL, NULL, 0 },
1205 /* 0x77 */ { NULL, NULL, 0 },
1206 /* 0x78 */ { NULL, NULL, 0 },
1207 /* 0x79 */ { NULL, NULL, 0 },
1208 /* 0x7a */ { NULL, NULL, 0 },
1209 /* 0x7b */ { NULL, NULL, 0 },
1210 /* 0x7c */ { NULL, NULL, 0 },
1211 /* 0x7d */ { NULL, NULL, 0 },
1212 /* 0x7e */ { NULL, NULL, 0 },
1213 /* 0x7f */ { NULL, NULL, 0 },
1214 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1215 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1216 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1217 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1218 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1219 /* 0x85 */ { NULL, NULL, 0 },
1220 /* 0x86 */ { NULL, NULL, 0 },
1221 /* 0x87 */ { NULL, NULL, 0 },
1222 /* 0x88 */ { NULL, NULL, 0 },
1223 /* 0x89 */ { NULL, NULL, 0 },
1224 /* 0x8a */ { NULL, NULL, 0 },
1225 /* 0x8b */ { NULL, NULL, 0 },
1226 /* 0x8c */ { NULL, NULL, 0 },
1227 /* 0x8d */ { NULL, NULL, 0 },
1228 /* 0x8e */ { NULL, NULL, 0 },
1229 /* 0x8f */ { NULL, NULL, 0 },
1230 /* 0x90 */ { NULL, NULL, 0 },
1231 /* 0x91 */ { NULL, NULL, 0 },
1232 /* 0x92 */ { NULL, NULL, 0 },
1233 /* 0x93 */ { NULL, NULL, 0 },
1234 /* 0x94 */ { NULL, NULL, 0 },
1235 /* 0x95 */ { NULL, NULL, 0 },
1236 /* 0x96 */ { NULL, NULL, 0 },
1237 /* 0x97 */ { NULL, NULL, 0 },
1238 /* 0x98 */ { NULL, NULL, 0 },
1239 /* 0x99 */ { NULL, NULL, 0 },
1240 /* 0x9a */ { NULL, NULL, 0 },
1241 /* 0x9b */ { NULL, NULL, 0 },
1242 /* 0x9c */ { NULL, NULL, 0 },
1243 /* 0x9d */ { NULL, NULL, 0 },
1244 /* 0x9e */ { NULL, NULL, 0 },
1245 /* 0x9f */ { NULL, NULL, 0 },
1246 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1247 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1248 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1249 /* 0xa3 */ { NULL, NULL, 0 },
1250 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1251 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1252 /* 0xa6 */ { NULL, NULL, 0 },
1253 /* 0xa7 */ { NULL, NULL, 0 },
1254 /* 0xa8 */ { NULL, NULL, 0 },
1255 /* 0xa9 */ { NULL, NULL, 0 },
1256 /* 0xaa */ { NULL, NULL, 0 },
1257 /* 0xab */ { NULL, NULL, 0 },
1258 /* 0xac */ { NULL, NULL, 0 },
1259 /* 0xad */ { NULL, NULL, 0 },
1260 /* 0xae */ { NULL, NULL, 0 },
1261 /* 0xaf */ { NULL, NULL, 0 },
1262 /* 0xb0 */ { NULL, NULL, 0 },
1263 /* 0xb1 */ { NULL, NULL, 0 },
1264 /* 0xb2 */ { NULL, NULL, 0 },
1265 /* 0xb3 */ { NULL, NULL, 0 },
1266 /* 0xb4 */ { NULL, NULL, 0 },
1267 /* 0xb5 */ { NULL, NULL, 0 },
1268 /* 0xb6 */ { NULL, NULL, 0 },
1269 /* 0xb7 */ { NULL, NULL, 0 },
1270 /* 0xb8 */ { NULL, NULL, 0 },
1271 /* 0xb9 */ { NULL, NULL, 0 },
1272 /* 0xba */ { NULL, NULL, 0 },
1273 /* 0xbb */ { NULL, NULL, 0 },
1274 /* 0xbc */ { NULL, NULL, 0 },
1275 /* 0xbd */ { NULL, NULL, 0 },
1276 /* 0xbe */ { NULL, NULL, 0 },
1277 /* 0xbf */ { NULL, NULL, 0 },
1278 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1279 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1280 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1281 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1282 /* 0xc4 */ { NULL, NULL, 0 },
1283 /* 0xc5 */ { NULL, NULL, 0 },
1284 /* 0xc6 */ { NULL, NULL, 0 },
1285 /* 0xc7 */ { NULL, NULL, 0 },
1286 /* 0xc8 */ { NULL, NULL, 0 },
1287 /* 0xc9 */ { NULL, NULL, 0 },
1288 /* 0xca */ { NULL, NULL, 0 },
1289 /* 0xcb */ { NULL, NULL, 0 },
1290 /* 0xcc */ { NULL, NULL, 0 },
1291 /* 0xcd */ { NULL, NULL, 0 },
1292 /* 0xce */ { NULL, NULL, 0 },
1293 /* 0xcf */ { NULL, NULL, 0 },
1294 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1295 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1296 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1297 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1298 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1299 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1300 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1301 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1302 /* 0xd8 */ { NULL, NULL, 0 },
1303 /* 0xd9 */ { NULL, NULL, 0 },
1304 /* 0xda */ { NULL, NULL, 0 },
1305 /* 0xdb */ { NULL, NULL, 0 },
1306 /* 0xdc */ { NULL, NULL, 0 },
1307 /* 0xdd */ { NULL, NULL, 0 },
1308 /* 0xde */ { NULL, NULL, 0 },
1309 /* 0xdf */ { NULL, NULL, 0 },
1310 /* 0xe0 */ { NULL, NULL, 0 },
1311 /* 0xe1 */ { NULL, NULL, 0 },
1312 /* 0xe2 */ { NULL, NULL, 0 },
1313 /* 0xe3 */ { NULL, NULL, 0 },
1314 /* 0xe4 */ { NULL, NULL, 0 },
1315 /* 0xe5 */ { NULL, NULL, 0 },
1316 /* 0xe6 */ { NULL, NULL, 0 },
1317 /* 0xe7 */ { NULL, NULL, 0 },
1318 /* 0xe8 */ { NULL, NULL, 0 },
1319 /* 0xe9 */ { NULL, NULL, 0 },
1320 /* 0xea */ { NULL, NULL, 0 },
1321 /* 0xeb */ { NULL, NULL, 0 },
1322 /* 0xec */ { NULL, NULL, 0 },
1323 /* 0xed */ { NULL, NULL, 0 },
1324 /* 0xee */ { NULL, NULL, 0 },
1325 /* 0xef */ { NULL, NULL, 0 },
1326 /* 0xf0 */ { NULL, NULL, 0 },
1327 /* 0xf1 */ { NULL, NULL, 0 },
1328 /* 0xf2 */ { NULL, NULL, 0 },
1329 /* 0xf3 */ { NULL, NULL, 0 },
1330 /* 0xf4 */ { NULL, NULL, 0 },
1331 /* 0xf5 */ { NULL, NULL, 0 },
1332 /* 0xf6 */ { NULL, NULL, 0 },
1333 /* 0xf7 */ { NULL, NULL, 0 },
1334 /* 0xf8 */ { NULL, NULL, 0 },
1335 /* 0xf9 */ { NULL, NULL, 0 },
1336 /* 0xfa */ { NULL, NULL, 0 },
1337 /* 0xfb */ { NULL, NULL, 0 },
1338 /* 0xfc */ { NULL, NULL, 0 },
1339 /* 0xfd */ { NULL, NULL, 0 },
1340 /* 0xfe */ { NULL, NULL, 0 },
1341 /* 0xff */ { NULL, NULL, 0 }
1345 /*******************************************************************
1346 allocate and initialize a reply packet
1347 ********************************************************************/
1349 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1350 const char *inbuf, char **outbuf, uint8_t num_words,
1351 uint32_t num_bytes)
1353 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1356 * Protect against integer wrap.
1357 * The SMB layer reply can be up to 0xFFFFFF bytes.
1359 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1360 char *msg;
1361 if (asprintf(&msg, "num_bytes too large: %u",
1362 (unsigned)num_bytes) == -1) {
1363 msg = discard_const_p(char, "num_bytes too large");
1365 smb_panic(msg);
1369 * Here we include the NBT header for now.
1371 *outbuf = talloc_array(mem_ctx, char,
1372 NBT_HDR_SIZE + smb_len);
1373 if (*outbuf == NULL) {
1374 return false;
1377 construct_reply_common(req, inbuf, *outbuf);
1378 srv_set_message(*outbuf, num_words, num_bytes, false);
1380 * Zero out the word area, the caller has to take care of the bcc area
1381 * himself
1383 if (num_words != 0) {
1384 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1387 return true;
1390 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1392 char *outbuf;
1393 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1394 num_bytes)) {
1395 smb_panic("could not allocate output buffer\n");
1397 req->outbuf = (uint8_t *)outbuf;
1401 /*******************************************************************
1402 Dump a packet to a file.
1403 ********************************************************************/
1405 static void smb_dump(const char *name, int type, const char *data)
1407 size_t len;
1408 int fd, i;
1409 char *fname = NULL;
1410 if (DEBUGLEVEL < 50) {
1411 return;
1414 len = smb_len_tcp(data)+4;
1415 for (i=1;i<100;i++) {
1416 fname = talloc_asprintf(talloc_tos(),
1417 "/tmp/%s.%d.%s",
1418 name,
1420 type ? "req" : "resp");
1421 if (fname == NULL) {
1422 return;
1424 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1425 if (fd != -1 || errno != EEXIST) break;
1426 TALLOC_FREE(fname);
1428 if (fd != -1) {
1429 ssize_t ret = write(fd, data, len);
1430 if (ret != len)
1431 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1432 close(fd);
1433 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1435 TALLOC_FREE(fname);
1438 /****************************************************************************
1439 Prepare everything for calling the actual request function, and potentially
1440 call the request function via the "new" interface.
1442 Return False if the "legacy" function needs to be called, everything is
1443 prepared.
1445 Return True if we're done.
1447 I know this API sucks, but it is the one with the least code change I could
1448 find.
1449 ****************************************************************************/
1451 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1453 int flags;
1454 uint64_t session_tag;
1455 connection_struct *conn = NULL;
1456 struct smbXsrv_connection *xconn = req->xconn;
1457 NTTIME now = timeval_to_nttime(&req->request_time);
1458 struct smbXsrv_session *session = NULL;
1459 NTSTATUS status;
1461 errno = 0;
1463 if (smb_messages[type].fn == NULL) {
1464 DEBUG(0,("Unknown message type %d!\n",type));
1465 smb_dump("Unknown", 1, (const char *)req->inbuf);
1466 reply_unknown_new(req, type);
1467 return NULL;
1470 flags = smb_messages[type].flags;
1472 /* In share mode security we must ignore the vuid. */
1473 session_tag = req->vuid;
1474 conn = req->conn;
1476 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1477 (int)getpid(), (unsigned long)conn));
1479 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1481 /* Ensure this value is replaced in the incoming packet. */
1482 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1485 * Ensure the correct username is in current_user_info. This is a
1486 * really ugly bugfix for problems with multiple session_setup_and_X's
1487 * being done and allowing %U and %G substitutions to work correctly.
1488 * There is a reason this code is done here, don't move it unless you
1489 * know what you're doing... :-).
1490 * JRA.
1494 * lookup an existing session
1496 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1497 * here, the main check is still in change_to_user()
1499 status = smb1srv_session_lookup(xconn,
1500 session_tag,
1501 now,
1502 &session);
1503 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1504 switch (type) {
1505 case SMBsesssetupX:
1506 status = NT_STATUS_OK;
1507 break;
1508 default:
1509 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1510 (unsigned long long)session_tag,
1511 (unsigned long long)req->mid));
1512 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1513 return conn;
1517 if (session_tag != xconn->last_session_id) {
1518 struct user_struct *vuser = NULL;
1520 xconn->last_session_id = session_tag;
1521 if (session) {
1522 vuser = session->compat;
1524 if (vuser) {
1525 set_current_user_info(
1526 vuser->session_info->unix_info->sanitized_username,
1527 vuser->session_info->unix_info->unix_name,
1528 vuser->session_info->info->domain_name);
1532 /* Does this call need to be run as the connected user? */
1533 if (flags & AS_USER) {
1535 /* Does this call need a valid tree connection? */
1536 if (!conn) {
1538 * Amazingly, the error code depends on the command
1539 * (from Samba4).
1541 if (type == SMBntcreateX) {
1542 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1543 } else {
1544 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1546 return NULL;
1549 if (!change_to_user(conn,session_tag)) {
1550 DEBUG(0, ("Error: Could not change to user. Removing "
1551 "deferred open, mid=%llu.\n",
1552 (unsigned long long)req->mid));
1553 reply_force_doserror(req, ERRSRV, ERRbaduid);
1554 return conn;
1557 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1559 /* Does it need write permission? */
1560 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1561 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1562 return conn;
1565 /* IPC services are limited */
1566 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1567 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1568 return conn;
1570 } else {
1571 /* This call needs to be run as root */
1572 change_to_root_user();
1575 /* load service specific parameters */
1576 if (conn) {
1577 if (req->encrypted) {
1578 conn->encrypted_tid = true;
1579 /* encrypted required from now on. */
1580 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1581 } else if (ENCRYPTION_REQUIRED(conn)) {
1582 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1583 DEBUG(1,("service[%s] requires encryption"
1584 "%s ACCESS_DENIED. mid=%llu\n",
1585 lp_servicename(talloc_tos(), SNUM(conn)),
1586 smb_fn_name(type),
1587 (unsigned long long)req->mid));
1588 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1589 return conn;
1593 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1594 (flags & (AS_USER|DO_CHDIR)
1595 ?True:False))) {
1596 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1597 return conn;
1599 conn->num_smb_operations++;
1603 * Does this protocol need to be run as guest? (Only archane
1604 * messenger service requests have this...)
1606 if (flags & AS_GUEST) {
1607 char *raddr;
1608 bool ok;
1610 if (!change_to_guest()) {
1611 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1612 return conn;
1615 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1616 talloc_tos());
1617 if (raddr == NULL) {
1618 reply_nterror(req, NT_STATUS_NO_MEMORY);
1619 return conn;
1623 * Haven't we checked this in smbd_process already???
1626 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1627 xconn->remote_hostname, raddr);
1628 TALLOC_FREE(raddr);
1630 if (!ok) {
1631 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1632 return conn;
1636 smb_messages[type].fn(req);
1637 return req->conn;
1640 /****************************************************************************
1641 Construct a reply to the incoming packet.
1642 ****************************************************************************/
1644 static void construct_reply(struct smbd_server_connection *sconn,
1645 char *inbuf, int size, size_t unread_bytes,
1646 uint32_t seqnum, bool encrypted,
1647 struct smb_perfcount_data *deferred_pcd)
1649 struct smbXsrv_connection *xconn = sconn->conn;
1650 struct smb_request *req;
1652 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1653 smb_panic("could not allocate smb_request");
1656 if (!init_smb_request(req, sconn, xconn, (uint8 *)inbuf, unread_bytes,
1657 encrypted, seqnum)) {
1658 exit_server_cleanly("Invalid SMB request");
1661 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1663 /* we popped this message off the queue - keep original perf data */
1664 if (deferred_pcd)
1665 req->pcd = *deferred_pcd;
1666 else {
1667 SMB_PERFCOUNT_START(&req->pcd);
1668 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1669 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1672 req->conn = switch_message(req->cmd, req);
1674 if (req->outbuf == NULL) {
1676 * Request has suspended itself, will come
1677 * back here.
1679 return;
1681 if (CVAL(req->outbuf,0) == 0) {
1682 show_msg((char *)req->outbuf);
1684 smb_request_done(req);
1687 static void construct_reply_chain(struct smbd_server_connection *sconn,
1688 char *inbuf, int size, uint32_t seqnum,
1689 bool encrypted,
1690 struct smb_perfcount_data *deferred_pcd)
1692 struct smb_request **reqs = NULL;
1693 struct smb_request *req;
1694 unsigned num_reqs;
1695 bool ok;
1697 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1698 seqnum, &reqs, &num_reqs);
1699 if (!ok) {
1700 char errbuf[smb_size];
1701 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1702 __LINE__, __FILE__);
1703 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1704 NULL)) {
1705 exit_server_cleanly("construct_reply_chain: "
1706 "srv_send_smb failed.");
1708 return;
1711 req = reqs[0];
1712 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1714 req->conn = switch_message(req->cmd, req);
1716 if (req->outbuf == NULL) {
1718 * Request has suspended itself, will come
1719 * back here.
1721 return;
1723 smb_request_done(req);
1727 * To be called from an async SMB handler that is potentially chained
1728 * when it is finished for shipping.
1731 void smb_request_done(struct smb_request *req)
1733 struct smb_request **reqs = NULL;
1734 struct smb_request *first_req;
1735 size_t i, num_reqs, next_index;
1736 NTSTATUS status;
1738 if (req->chain == NULL) {
1739 first_req = req;
1740 goto shipit;
1743 reqs = req->chain;
1744 num_reqs = talloc_array_length(reqs);
1746 for (i=0; i<num_reqs; i++) {
1747 if (reqs[i] == req) {
1748 break;
1751 if (i == num_reqs) {
1753 * Invalid chain, should not happen
1755 status = NT_STATUS_INTERNAL_ERROR;
1756 goto error;
1758 next_index = i+1;
1760 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1761 struct smb_request *next = reqs[next_index];
1762 struct smbXsrv_tcon *tcon;
1763 NTTIME now = timeval_to_nttime(&req->request_time);
1765 next->vuid = SVAL(req->outbuf, smb_uid);
1766 next->tid = SVAL(req->outbuf, smb_tid);
1767 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1768 now, &tcon);
1769 if (NT_STATUS_IS_OK(status)) {
1770 req->conn = tcon->compat;
1771 } else {
1772 req->conn = NULL;
1774 next->chain_fsp = req->chain_fsp;
1775 next->inbuf = req->inbuf;
1777 req = next;
1778 req->conn = switch_message(req->cmd, req);
1780 if (req->outbuf == NULL) {
1782 * Request has suspended itself, will come
1783 * back here.
1785 return;
1787 next_index += 1;
1790 first_req = reqs[0];
1792 for (i=1; i<next_index; i++) {
1793 bool ok;
1795 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1796 if (!ok) {
1797 status = NT_STATUS_INTERNAL_ERROR;
1798 goto error;
1802 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1803 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1806 * This scary statement intends to set the
1807 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1808 * to the value last_req->outbuf carries
1810 SSVAL(first_req->outbuf, smb_flg2,
1811 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1812 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1815 * Transfer the error codes from the subrequest to the main one
1817 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1818 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1820 _smb_setlen_large(
1821 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1823 shipit:
1824 if (!srv_send_smb(first_req->sconn,
1825 (char *)first_req->outbuf,
1826 true, first_req->seqnum+1,
1827 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1828 &first_req->pcd)) {
1829 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1830 "failed.");
1832 TALLOC_FREE(req); /* non-chained case */
1833 TALLOC_FREE(reqs); /* chained case */
1834 return;
1836 error:
1838 char errbuf[smb_size];
1839 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1840 if (!srv_send_smb(req->sconn, errbuf, true,
1841 req->seqnum+1, req->encrypted,
1842 NULL)) {
1843 exit_server_cleanly("construct_reply_chain: "
1844 "srv_send_smb failed.");
1847 TALLOC_FREE(req); /* non-chained case */
1848 TALLOC_FREE(reqs); /* chained case */
1851 /****************************************************************************
1852 Process an smb from the client
1853 ****************************************************************************/
1854 static void process_smb(struct smbXsrv_connection *xconn,
1855 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1856 uint32_t seqnum, bool encrypted,
1857 struct smb_perfcount_data *deferred_pcd)
1859 struct smbd_server_connection *sconn = xconn->sconn;
1860 int msg_type = CVAL(inbuf,0);
1862 DO_PROFILE_INC(smb_count);
1864 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1865 smb_len(inbuf) ) );
1866 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1867 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1869 if (msg_type != NBSSmessage) {
1871 * NetBIOS session request, keepalive, etc.
1873 reply_special(xconn, (char *)inbuf, nread);
1874 goto done;
1877 if (sconn->using_smb2) {
1878 /* At this point we're not really using smb2,
1879 * we make the decision here.. */
1880 if (smbd_is_smb2_header(inbuf, nread)) {
1881 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1882 size_t pdulen = nread - NBT_HDR_SIZE;
1883 smbd_smb2_first_negprot(xconn, inpdu, pdulen);
1884 return;
1885 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1886 && CVAL(inbuf, smb_com) != 0x72) {
1887 /* This is a non-negprot SMB1 packet.
1888 Disable SMB2 from now on. */
1889 sconn->using_smb2 = false;
1893 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1894 * so subtract 4 from it. */
1895 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1896 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1897 smb_len(inbuf)));
1899 /* special magic for immediate exit */
1900 if ((nread == 9) &&
1901 (IVAL(inbuf, 4) == 0x74697865) &&
1902 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1903 uint8_t exitcode = CVAL(inbuf, 8);
1904 DEBUG(1, ("Exiting immediately with code %d\n",
1905 (int)exitcode));
1906 exit(exitcode);
1909 exit_server_cleanly("Non-SMB packet");
1912 show_msg((char *)inbuf);
1914 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1915 construct_reply_chain(sconn, (char *)inbuf, nread,
1916 seqnum, encrypted, deferred_pcd);
1917 } else {
1918 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1919 seqnum, encrypted, deferred_pcd);
1922 sconn->trans_num++;
1924 done:
1925 sconn->num_requests++;
1927 /* The timeout_processing function isn't run nearly
1928 often enough to implement 'max log size' without
1929 overrunning the size of the file by many megabytes.
1930 This is especially true if we are running at debug
1931 level 10. Checking every 50 SMBs is a nice
1932 tradeoff of performance vs log file size overrun. */
1934 if ((sconn->num_requests % 50) == 0 &&
1935 need_to_check_log_size()) {
1936 change_to_root_user();
1937 check_log_size();
1941 /****************************************************************************
1942 Return a string containing the function name of a SMB command.
1943 ****************************************************************************/
1945 const char *smb_fn_name(int type)
1947 const char *unknown_name = "SMBunknown";
1949 if (smb_messages[type].name == NULL)
1950 return(unknown_name);
1952 return(smb_messages[type].name);
1955 /****************************************************************************
1956 Helper functions for contruct_reply.
1957 ****************************************************************************/
1959 void add_to_common_flags2(uint32 v)
1961 common_flags2 |= v;
1964 void remove_from_common_flags2(uint32 v)
1966 common_flags2 &= ~v;
1969 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1970 char *outbuf)
1972 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1973 uint16_t out_flags2 = common_flags2;
1975 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1976 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1977 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1979 srv_set_message(outbuf,0,0,false);
1981 SCVAL(outbuf, smb_com, req->cmd);
1982 SIVAL(outbuf,smb_rcls,0);
1983 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1984 SSVAL(outbuf,smb_flg2, out_flags2);
1985 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1986 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1988 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1989 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1990 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1991 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1994 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1996 construct_reply_common(req, (const char *)req->inbuf, outbuf);
2000 * @brief Find the smb_cmd offset of the last command pushed
2001 * @param[in] buf The buffer we're building up
2002 * @retval Where can we put our next andx cmd?
2004 * While chaining requests, the "next" request we're looking at needs to put
2005 * its SMB_Command before the data the previous request already built up added
2006 * to the chain. Find the offset to the place where we have to put our cmd.
2009 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2011 uint8_t cmd;
2012 size_t ofs;
2014 cmd = CVAL(buf, smb_com);
2016 if (!is_andx_req(cmd)) {
2017 return false;
2020 ofs = smb_vwv0;
2022 while (CVAL(buf, ofs) != 0xff) {
2024 if (!is_andx_req(CVAL(buf, ofs))) {
2025 return false;
2029 * ofs is from start of smb header, so add the 4 length
2030 * bytes. The next cmd is right after the wct field.
2032 ofs = SVAL(buf, ofs+2) + 4 + 1;
2034 if (ofs+4 >= talloc_get_size(buf)) {
2035 return false;
2039 *pofs = ofs;
2040 return true;
2044 * @brief Do the smb chaining at a buffer level
2045 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2046 * @param[in] andx_buf Buffer to be appended
2049 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2051 uint8_t smb_command = CVAL(andx_buf, smb_com);
2052 uint8_t wct = CVAL(andx_buf, smb_wct);
2053 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2054 uint32_t num_bytes = smb_buflen(andx_buf);
2055 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2057 uint8_t *outbuf;
2058 size_t old_size, new_size;
2059 size_t ofs;
2060 size_t chain_padding = 0;
2061 size_t andx_cmd_ofs;
2064 old_size = talloc_get_size(*poutbuf);
2066 if ((old_size % 4) != 0) {
2068 * Align the wct field of subsequent requests to a 4-byte
2069 * boundary
2071 chain_padding = 4 - (old_size % 4);
2075 * After the old request comes the new wct field (1 byte), the vwv's
2076 * and the num_bytes field.
2079 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2080 new_size += num_bytes;
2082 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2083 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2084 (unsigned)new_size));
2085 return false;
2088 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2089 if (outbuf == NULL) {
2090 DEBUG(0, ("talloc failed\n"));
2091 return false;
2093 *poutbuf = outbuf;
2095 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2096 DEBUG(1, ("invalid command chain\n"));
2097 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2098 return false;
2101 if (chain_padding != 0) {
2102 memset(outbuf + old_size, 0, chain_padding);
2103 old_size += chain_padding;
2106 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2107 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2109 ofs = old_size;
2112 * Push the chained request:
2114 * wct field
2117 SCVAL(outbuf, ofs, wct);
2118 ofs += 1;
2121 * vwv array
2124 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2127 * HACK ALERT
2129 * Read&X has an offset into its data buffer at
2130 * vwv[6]. reply_read_andx has no idea anymore that it's
2131 * running from within a chain, so we have to fix up the
2132 * offset here.
2134 * Although it looks disgusting at this place, I want to keep
2135 * it here. The alternative would be to push knowledge about
2136 * the andx chain down into read&x again.
2139 if (smb_command == SMBreadX) {
2140 uint8_t *bytes_addr;
2142 if (wct < 7) {
2144 * Invalid read&x response
2146 return false;
2149 bytes_addr = outbuf + ofs /* vwv start */
2150 + sizeof(uint16_t) * wct /* vwv array */
2151 + sizeof(uint16_t); /* bcc */
2153 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2154 bytes_addr - outbuf - 4);
2157 ofs += sizeof(uint16_t) * wct;
2160 * bcc (byte count)
2163 SSVAL(outbuf, ofs, num_bytes);
2164 ofs += sizeof(uint16_t);
2167 * The bytes field
2170 memcpy(outbuf + ofs, bytes, num_bytes);
2172 return true;
2175 bool smb1_is_chain(const uint8_t *buf)
2177 uint8_t cmd, wct, andx_cmd;
2179 cmd = CVAL(buf, smb_com);
2180 if (!is_andx_req(cmd)) {
2181 return false;
2183 wct = CVAL(buf, smb_wct);
2184 if (wct < 2) {
2185 return false;
2187 andx_cmd = CVAL(buf, smb_vwv);
2188 return (andx_cmd != 0xFF);
2191 bool smb1_walk_chain(const uint8_t *buf,
2192 bool (*fn)(uint8_t cmd,
2193 uint8_t wct, const uint16_t *vwv,
2194 uint16_t num_bytes, const uint8_t *bytes,
2195 void *private_data),
2196 void *private_data)
2198 size_t smblen = smb_len(buf);
2199 const char *smb_buf = smb_base(buf);
2200 uint8_t cmd, chain_cmd;
2201 uint8_t wct;
2202 const uint16_t *vwv;
2203 uint16_t num_bytes;
2204 const uint8_t *bytes;
2206 cmd = CVAL(buf, smb_com);
2207 wct = CVAL(buf, smb_wct);
2208 vwv = (const uint16_t *)(buf + smb_vwv);
2209 num_bytes = smb_buflen(buf);
2210 bytes = (const uint8_t *)smb_buf_const(buf);
2212 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2213 return false;
2216 if (!is_andx_req(cmd)) {
2217 return true;
2219 if (wct < 2) {
2220 return false;
2223 chain_cmd = CVAL(vwv, 0);
2225 while (chain_cmd != 0xff) {
2226 uint32_t chain_offset; /* uint32_t to avoid overflow */
2227 size_t length_needed;
2228 ptrdiff_t vwv_offset;
2230 chain_offset = SVAL(vwv+1, 0);
2233 * Check if the client tries to fool us. The chain
2234 * offset needs to point beyond the current request in
2235 * the chain, it needs to strictly grow. Otherwise we
2236 * might be tricked into an endless loop always
2237 * processing the same request over and over again. We
2238 * used to assume that vwv and the byte buffer array
2239 * in a chain are always attached, but OS/2 the
2240 * Write&X/Read&X chain puts the Read&X vwv array
2241 * right behind the Write&X vwv chain. The Write&X bcc
2242 * array is put behind the Read&X vwv array. So now we
2243 * check whether the chain offset points strictly
2244 * behind the previous vwv array. req->buf points
2245 * right after the vwv array of the previous
2246 * request. See
2247 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2248 * more information.
2251 vwv_offset = ((const char *)vwv - smb_buf);
2252 if (chain_offset <= vwv_offset) {
2253 return false;
2257 * Next check: Make sure the chain offset does not
2258 * point beyond the overall smb request length.
2261 length_needed = chain_offset+1; /* wct */
2262 if (length_needed > smblen) {
2263 return false;
2267 * Now comes the pointer magic. Goal here is to set up
2268 * vwv and buf correctly again. The chain offset (the
2269 * former vwv[1]) points at the new wct field.
2272 wct = CVAL(smb_buf, chain_offset);
2274 if (is_andx_req(chain_cmd) && (wct < 2)) {
2275 return false;
2279 * Next consistency check: Make the new vwv array fits
2280 * in the overall smb request.
2283 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2284 if (length_needed > smblen) {
2285 return false;
2287 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2290 * Now grab the new byte buffer....
2293 num_bytes = SVAL(vwv+wct, 0);
2296 * .. and check that it fits.
2299 length_needed += num_bytes;
2300 if (length_needed > smblen) {
2301 return false;
2303 bytes = (const uint8_t *)(vwv+wct+1);
2305 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2306 return false;
2309 if (!is_andx_req(chain_cmd)) {
2310 return true;
2312 chain_cmd = CVAL(vwv, 0);
2314 return true;
2317 static bool smb1_chain_length_cb(uint8_t cmd,
2318 uint8_t wct, const uint16_t *vwv,
2319 uint16_t num_bytes, const uint8_t *bytes,
2320 void *private_data)
2322 unsigned *count = (unsigned *)private_data;
2323 *count += 1;
2324 return true;
2327 unsigned smb1_chain_length(const uint8_t *buf)
2329 unsigned count = 0;
2331 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2332 return 0;
2334 return count;
2337 struct smb1_parse_chain_state {
2338 TALLOC_CTX *mem_ctx;
2339 const uint8_t *buf;
2340 struct smbd_server_connection *sconn;
2341 struct smbXsrv_connection *xconn;
2342 bool encrypted;
2343 uint32_t seqnum;
2345 struct smb_request **reqs;
2346 unsigned num_reqs;
2349 static bool smb1_parse_chain_cb(uint8_t cmd,
2350 uint8_t wct, const uint16_t *vwv,
2351 uint16_t num_bytes, const uint8_t *bytes,
2352 void *private_data)
2354 struct smb1_parse_chain_state *state =
2355 (struct smb1_parse_chain_state *)private_data;
2356 struct smb_request **reqs;
2357 struct smb_request *req;
2358 bool ok;
2360 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2361 struct smb_request *, state->num_reqs+1);
2362 if (reqs == NULL) {
2363 return false;
2365 state->reqs = reqs;
2367 req = talloc(reqs, struct smb_request);
2368 if (req == NULL) {
2369 return false;
2372 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2373 state->encrypted, state->seqnum);
2374 if (!ok) {
2375 return false;
2377 req->cmd = cmd;
2378 req->wct = wct;
2379 req->vwv = vwv;
2380 req->buflen = num_bytes;
2381 req->buf = bytes;
2383 reqs[state->num_reqs] = req;
2384 state->num_reqs += 1;
2385 return true;
2388 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2389 struct smbd_server_connection *sconn,
2390 bool encrypted, uint32_t seqnum,
2391 struct smb_request ***reqs, unsigned *num_reqs)
2393 struct smbXsrv_connection *xconn = sconn->conn;
2394 struct smb1_parse_chain_state state;
2395 unsigned i;
2397 state.mem_ctx = mem_ctx;
2398 state.buf = buf;
2399 state.sconn = sconn;
2400 state.xconn = xconn;
2401 state.encrypted = encrypted;
2402 state.seqnum = seqnum;
2403 state.reqs = NULL;
2404 state.num_reqs = 0;
2406 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2407 TALLOC_FREE(state.reqs);
2408 return false;
2410 for (i=0; i<state.num_reqs; i++) {
2411 state.reqs[i]->chain = state.reqs;
2413 *reqs = state.reqs;
2414 *num_reqs = state.num_reqs;
2415 return true;
2418 /****************************************************************************
2419 Check if services need reloading.
2420 ****************************************************************************/
2422 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2425 if (last_smb_conf_reload_time == 0) {
2426 last_smb_conf_reload_time = t;
2429 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2430 reload_services(sconn, conn_snum_used, true);
2431 last_smb_conf_reload_time = t;
2435 static bool fd_is_readable(int fd)
2437 int ret, revents;
2439 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2441 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2445 static void smbd_server_connection_write_handler(
2446 struct smbXsrv_connection *xconn)
2448 /* TODO: make write nonblocking */
2451 static void smbd_server_connection_read_handler(
2452 struct smbXsrv_connection *xconn, int fd)
2454 struct smbd_server_connection *sconn = xconn->sconn;
2455 uint8_t *inbuf = NULL;
2456 size_t inbuf_len = 0;
2457 size_t unread_bytes = 0;
2458 bool encrypted = false;
2459 TALLOC_CTX *mem_ctx = talloc_tos();
2460 NTSTATUS status;
2461 uint32_t seqnum;
2463 bool async_echo = lp_async_smb_echo_handler();
2464 bool from_client = false;
2466 if (async_echo) {
2467 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2469 * This is the super-ugly hack to prefer the packets
2470 * forwarded by the echo handler over the ones by the
2471 * client directly
2473 fd = xconn->smb1.echo_handler.trusted_fd;
2477 from_client = (xconn->transport.sock == fd);
2479 if (async_echo && from_client) {
2480 smbd_lock_socket(sconn);
2482 if (!fd_is_readable(fd)) {
2483 DEBUG(10,("the echo listener was faster\n"));
2484 smbd_unlock_socket(sconn);
2485 return;
2489 /* TODO: make this completely nonblocking */
2490 status = receive_smb_talloc(mem_ctx, sconn, fd,
2491 (char **)(void *)&inbuf,
2492 0, /* timeout */
2493 &unread_bytes,
2494 &encrypted,
2495 &inbuf_len, &seqnum,
2496 !from_client /* trusted channel */);
2498 if (async_echo && from_client) {
2499 smbd_unlock_socket(sconn);
2502 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2503 goto process;
2505 if (NT_STATUS_IS_ERR(status)) {
2506 exit_server_cleanly("failed to receive smb request");
2508 if (!NT_STATUS_IS_OK(status)) {
2509 return;
2512 process:
2513 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2514 seqnum, encrypted, NULL);
2517 static void smbd_server_connection_handler(struct tevent_context *ev,
2518 struct tevent_fd *fde,
2519 uint16_t flags,
2520 void *private_data)
2522 struct smbXsrv_connection *xconn =
2523 talloc_get_type_abort(private_data,
2524 struct smbXsrv_connection);
2526 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2528 * we're not supposed to do any io
2530 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2531 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2532 return;
2535 if (flags & TEVENT_FD_WRITE) {
2536 smbd_server_connection_write_handler(xconn);
2537 return;
2539 if (flags & TEVENT_FD_READ) {
2540 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2541 return;
2545 static void smbd_server_echo_handler(struct tevent_context *ev,
2546 struct tevent_fd *fde,
2547 uint16_t flags,
2548 void *private_data)
2550 struct smbXsrv_connection *xconn =
2551 talloc_get_type_abort(private_data,
2552 struct smbXsrv_connection);
2554 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2556 * we're not supposed to do any io
2558 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2559 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2560 return;
2563 if (flags & TEVENT_FD_WRITE) {
2564 smbd_server_connection_write_handler(xconn);
2565 return;
2567 if (flags & TEVENT_FD_READ) {
2568 smbd_server_connection_read_handler(
2569 xconn, xconn->smb1.echo_handler.trusted_fd);
2570 return;
2574 struct smbd_release_ip_state {
2575 struct smbXsrv_connection *xconn;
2576 struct tevent_immediate *im;
2577 char addr[INET6_ADDRSTRLEN];
2580 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2581 struct tevent_immediate *im,
2582 void *private_data)
2584 struct smbd_release_ip_state *state =
2585 talloc_get_type_abort(private_data,
2586 struct smbd_release_ip_state);
2587 struct smbXsrv_connection *xconn = state->xconn;
2589 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2591 * smbd_server_connection_terminate() already triggered ?
2593 return;
2596 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2599 /****************************************************************************
2600 received when we should release a specific IP
2601 ****************************************************************************/
2602 static bool release_ip(const char *ip, void *priv)
2604 struct smbd_release_ip_state *state =
2605 talloc_get_type_abort(priv,
2606 struct smbd_release_ip_state);
2607 struct smbXsrv_connection *xconn = state->xconn;
2608 const char *addr = state->addr;
2609 const char *p = addr;
2611 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2612 /* avoid recursion */
2613 return false;
2616 if (strncmp("::ffff:", addr, 7) == 0) {
2617 p = addr + 7;
2620 DEBUG(10, ("Got release IP message for %s, "
2621 "our address is %s\n", ip, p));
2623 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2624 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2625 ip));
2627 * With SMB2 we should do a clean disconnect,
2628 * the previous_session_id in the session setup
2629 * will cleanup the old session, tcons and opens.
2631 * A clean disconnect is needed in order to support
2632 * durable handles.
2634 * Note: typically this is never triggered
2635 * as we got a TCP RST (triggered by ctdb event scripts)
2636 * before we get CTDB_SRVID_RELEASE_IP.
2638 * We used to call _exit(1) here, but as this was mostly never
2639 * triggered and has implication on our process model,
2640 * we can just use smbd_server_connection_terminate()
2641 * (also for SMB1).
2643 * We don't call smbd_server_connection_terminate() directly
2644 * as we might be called from within ctdbd_migrate(),
2645 * we need to defer our action to the next event loop
2647 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2648 smbd_release_ip_immediate, state);
2651 * Make sure we don't get any io on the connection.
2653 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2654 return true;
2657 return false;
2660 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2661 struct sockaddr_storage *srv,
2662 struct sockaddr_storage *clnt)
2664 struct smbd_release_ip_state *state;
2665 struct ctdbd_connection *cconn;
2667 cconn = messaging_ctdbd_connection();
2668 if (cconn == NULL) {
2669 return NT_STATUS_NO_MEMORY;
2672 state = talloc_zero(xconn, struct smbd_release_ip_state);
2673 if (state == NULL) {
2674 return NT_STATUS_NO_MEMORY;
2676 state->xconn = xconn;
2677 state->im = tevent_create_immediate(state);
2678 if (state->im == NULL) {
2679 return NT_STATUS_NO_MEMORY;
2681 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2682 return NT_STATUS_NO_MEMORY;
2685 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2688 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2689 void *private_data, uint32_t msg_type,
2690 struct server_id server_id, DATA_BLOB *data)
2692 struct smbd_server_connection *sconn = talloc_get_type_abort(
2693 private_data, struct smbd_server_connection);
2694 const char *ip = (char *) data->data;
2695 char *client_ip;
2697 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2699 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2700 talloc_tos());
2701 if (client_ip == NULL) {
2702 return;
2705 if (strequal(ip, client_ip)) {
2706 DEBUG(1, ("Got kill client message for %s - "
2707 "exiting immediately\n", ip));
2708 exit_server_cleanly("Forced disconnect for client");
2711 TALLOC_FREE(client_ip);
2715 * Send keepalive packets to our client
2717 static bool keepalive_fn(const struct timeval *now, void *private_data)
2719 struct smbd_server_connection *sconn = talloc_get_type_abort(
2720 private_data, struct smbd_server_connection);
2721 struct smbXsrv_connection *xconn = sconn->conn;
2722 bool ret;
2724 if (sconn->using_smb2) {
2725 /* Don't do keepalives on an SMB2 connection. */
2726 return false;
2729 smbd_lock_socket(sconn);
2730 ret = send_keepalive(xconn->transport.sock);
2731 smbd_unlock_socket(sconn);
2733 if (!ret) {
2734 int saved_errno = errno;
2736 * Try and give an error message saying what
2737 * client failed.
2739 DEBUG(0, ("send_keepalive failed for client %s. "
2740 "Error %s - exiting\n",
2741 smbXsrv_connection_dbg(xconn),
2742 strerror(saved_errno)));
2743 errno = saved_errno;
2744 return False;
2746 return True;
2750 * Do the recurring check if we're idle
2752 static bool deadtime_fn(const struct timeval *now, void *private_data)
2754 struct smbd_server_connection *sconn =
2755 (struct smbd_server_connection *)private_data;
2757 if ((conn_num_open(sconn) == 0)
2758 || (conn_idle_all(sconn, now->tv_sec))) {
2759 DEBUG( 2, ( "Closing idle connection\n" ) );
2760 messaging_send(sconn->msg_ctx,
2761 messaging_server_id(sconn->msg_ctx),
2762 MSG_SHUTDOWN, &data_blob_null);
2763 return False;
2766 return True;
2770 * Do the recurring log file and smb.conf reload checks.
2773 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2775 struct smbd_server_connection *sconn = talloc_get_type_abort(
2776 private_data, struct smbd_server_connection);
2778 DEBUG(5, ("housekeeping\n"));
2780 change_to_root_user();
2782 /* update printer queue caches if necessary */
2783 update_monitored_printq_cache(sconn->msg_ctx);
2785 /* check if we need to reload services */
2786 check_reload(sconn, time_mono(NULL));
2789 * Force a log file check.
2791 force_check_log_size();
2792 check_log_size();
2793 return true;
2797 * Read an smb packet in the echo handler child, giving the parent
2798 * smbd one second to react once the socket becomes readable.
2801 struct smbd_echo_read_state {
2802 struct tevent_context *ev;
2803 struct smbd_server_connection *sconn;
2805 char *buf;
2806 size_t buflen;
2807 uint32_t seqnum;
2810 static void smbd_echo_read_readable(struct tevent_req *subreq);
2811 static void smbd_echo_read_waited(struct tevent_req *subreq);
2813 static struct tevent_req *smbd_echo_read_send(
2814 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2815 struct smbd_server_connection *sconn)
2817 struct tevent_req *req, *subreq;
2818 struct smbd_echo_read_state *state;
2819 struct smbXsrv_connection *xconn = sconn->conn;
2821 req = tevent_req_create(mem_ctx, &state,
2822 struct smbd_echo_read_state);
2823 if (req == NULL) {
2824 return NULL;
2826 state->ev = ev;
2827 state->sconn = sconn;
2829 subreq = wait_for_read_send(state, ev, xconn->transport.sock);
2830 if (tevent_req_nomem(subreq, req)) {
2831 return tevent_req_post(req, ev);
2833 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2834 return req;
2837 static void smbd_echo_read_readable(struct tevent_req *subreq)
2839 struct tevent_req *req = tevent_req_callback_data(
2840 subreq, struct tevent_req);
2841 struct smbd_echo_read_state *state = tevent_req_data(
2842 req, struct smbd_echo_read_state);
2843 bool ok;
2844 int err;
2846 ok = wait_for_read_recv(subreq, &err);
2847 TALLOC_FREE(subreq);
2848 if (!ok) {
2849 tevent_req_nterror(req, map_nt_error_from_unix(err));
2850 return;
2854 * Give the parent smbd one second to step in
2857 subreq = tevent_wakeup_send(
2858 state, state->ev, timeval_current_ofs(1, 0));
2859 if (tevent_req_nomem(subreq, req)) {
2860 return;
2862 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2865 static void smbd_echo_read_waited(struct tevent_req *subreq)
2867 struct tevent_req *req = tevent_req_callback_data(
2868 subreq, struct tevent_req);
2869 struct smbd_echo_read_state *state = tevent_req_data(
2870 req, struct smbd_echo_read_state);
2871 struct smbd_server_connection *sconn = state->sconn;
2872 struct smbXsrv_connection *xconn = sconn->conn;
2873 bool ok;
2874 NTSTATUS status;
2875 size_t unread = 0;
2876 bool encrypted;
2878 ok = tevent_wakeup_recv(subreq);
2879 TALLOC_FREE(subreq);
2880 if (!ok) {
2881 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2882 return;
2885 ok = smbd_lock_socket_internal(sconn);
2886 if (!ok) {
2887 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2888 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2889 return;
2892 if (!fd_is_readable(xconn->transport.sock)) {
2893 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2894 (int)getpid()));
2896 ok = smbd_unlock_socket_internal(sconn);
2897 if (!ok) {
2898 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2899 DEBUG(1, ("%s: failed to unlock socket\n",
2900 __location__));
2901 return;
2904 subreq = wait_for_read_send(state, state->ev,
2905 xconn->transport.sock);
2906 if (tevent_req_nomem(subreq, req)) {
2907 return;
2909 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2910 return;
2913 status = receive_smb_talloc(state, sconn,
2914 xconn->transport.sock,
2915 &state->buf,
2916 0 /* timeout */,
2917 &unread,
2918 &encrypted,
2919 &state->buflen,
2920 &state->seqnum,
2921 false /* trusted_channel*/);
2923 if (tevent_req_nterror(req, status)) {
2924 tevent_req_nterror(req, status);
2925 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2926 (int)getpid(), nt_errstr(status)));
2927 return;
2930 ok = smbd_unlock_socket_internal(sconn);
2931 if (!ok) {
2932 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2933 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2934 return;
2936 tevent_req_done(req);
2939 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2940 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2942 struct smbd_echo_read_state *state = tevent_req_data(
2943 req, struct smbd_echo_read_state);
2944 NTSTATUS status;
2946 if (tevent_req_is_nterror(req, &status)) {
2947 return status;
2949 *pbuf = talloc_move(mem_ctx, &state->buf);
2950 *pbuflen = state->buflen;
2951 *pseqnum = state->seqnum;
2952 return NT_STATUS_OK;
2955 struct smbd_echo_state {
2956 struct tevent_context *ev;
2957 struct iovec *pending;
2958 struct smbd_server_connection *sconn;
2959 struct smbXsrv_connection *xconn;
2960 int parent_pipe;
2962 struct tevent_fd *parent_fde;
2964 struct tevent_req *write_req;
2967 static void smbd_echo_writer_done(struct tevent_req *req);
2969 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2971 int num_pending;
2973 if (state->write_req != NULL) {
2974 return;
2977 num_pending = talloc_array_length(state->pending);
2978 if (num_pending == 0) {
2979 return;
2982 state->write_req = writev_send(state, state->ev, NULL,
2983 state->parent_pipe, false,
2984 state->pending, num_pending);
2985 if (state->write_req == NULL) {
2986 DEBUG(1, ("writev_send failed\n"));
2987 exit(1);
2990 talloc_steal(state->write_req, state->pending);
2991 state->pending = NULL;
2993 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2994 state);
2997 static void smbd_echo_writer_done(struct tevent_req *req)
2999 struct smbd_echo_state *state = tevent_req_callback_data(
3000 req, struct smbd_echo_state);
3001 ssize_t written;
3002 int err;
3004 written = writev_recv(req, &err);
3005 TALLOC_FREE(req);
3006 state->write_req = NULL;
3007 if (written == -1) {
3008 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3009 exit(1);
3011 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3012 smbd_echo_activate_writer(state);
3015 static bool smbd_echo_reply(struct smbd_echo_state *state,
3016 uint8_t *inbuf, size_t inbuf_len,
3017 uint32_t seqnum)
3019 struct smb_request req;
3020 uint16_t num_replies;
3021 char *outbuf;
3022 bool ok;
3024 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3025 DEBUG(10, ("Got netbios keepalive\n"));
3027 * Just swallow it
3029 return true;
3032 if (inbuf_len < smb_size) {
3033 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3034 return false;
3036 if (!valid_smb_header(state->sconn, inbuf)) {
3037 DEBUG(10, ("Got invalid SMB header\n"));
3038 return false;
3041 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3042 seqnum)) {
3043 return false;
3045 req.inbuf = inbuf;
3047 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3048 smb_messages[req.cmd].name
3049 ? smb_messages[req.cmd].name : "unknown"));
3051 if (req.cmd != SMBecho) {
3052 return false;
3054 if (req.wct < 1) {
3055 return false;
3058 num_replies = SVAL(req.vwv+0, 0);
3059 if (num_replies != 1) {
3060 /* Not a Windows "Hey, you're still there?" request */
3061 return false;
3064 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3065 1, req.buflen)) {
3066 DEBUG(10, ("create_outbuf failed\n"));
3067 return false;
3069 req.outbuf = (uint8_t *)outbuf;
3071 SSVAL(req.outbuf, smb_vwv0, num_replies);
3073 if (req.buflen > 0) {
3074 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3077 ok = srv_send_smb(req.sconn,
3078 (char *)outbuf,
3079 true, seqnum+1,
3080 false, &req.pcd);
3081 TALLOC_FREE(outbuf);
3082 if (!ok) {
3083 exit(1);
3086 return true;
3089 static void smbd_echo_exit(struct tevent_context *ev,
3090 struct tevent_fd *fde, uint16_t flags,
3091 void *private_data)
3093 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3094 exit(0);
3097 static void smbd_echo_got_packet(struct tevent_req *req);
3099 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3100 int parent_pipe)
3102 struct smbXsrv_connection *xconn = sconn->conn;
3103 struct smbd_echo_state *state;
3104 struct tevent_req *read_req;
3106 state = talloc_zero(sconn, struct smbd_echo_state);
3107 if (state == NULL) {
3108 DEBUG(1, ("talloc failed\n"));
3109 return;
3111 state->sconn = sconn;
3112 state->xconn = xconn;
3113 state->parent_pipe = parent_pipe;
3114 state->ev = s3_tevent_context_init(state);
3115 if (state->ev == NULL) {
3116 DEBUG(1, ("tevent_context_init failed\n"));
3117 TALLOC_FREE(state);
3118 return;
3120 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3121 TEVENT_FD_READ, smbd_echo_exit,
3122 state);
3123 if (state->parent_fde == NULL) {
3124 DEBUG(1, ("tevent_add_fd failed\n"));
3125 TALLOC_FREE(state);
3126 return;
3129 read_req = smbd_echo_read_send(state, state->ev, sconn);
3130 if (read_req == NULL) {
3131 DEBUG(1, ("smbd_echo_read_send failed\n"));
3132 TALLOC_FREE(state);
3133 return;
3135 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3137 while (true) {
3138 if (tevent_loop_once(state->ev) == -1) {
3139 DEBUG(1, ("tevent_loop_once failed: %s\n",
3140 strerror(errno)));
3141 break;
3144 TALLOC_FREE(state);
3147 static void smbd_echo_got_packet(struct tevent_req *req)
3149 struct smbd_echo_state *state = tevent_req_callback_data(
3150 req, struct smbd_echo_state);
3151 NTSTATUS status;
3152 char *buf = NULL;
3153 size_t buflen = 0;
3154 uint32_t seqnum = 0;
3155 bool reply;
3157 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3158 TALLOC_FREE(req);
3159 if (!NT_STATUS_IS_OK(status)) {
3160 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3161 nt_errstr(status)));
3162 exit(1);
3165 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3166 if (!reply) {
3167 size_t num_pending;
3168 struct iovec *tmp;
3169 struct iovec *iov;
3171 num_pending = talloc_array_length(state->pending);
3172 tmp = talloc_realloc(state, state->pending, struct iovec,
3173 num_pending+1);
3174 if (tmp == NULL) {
3175 DEBUG(1, ("talloc_realloc failed\n"));
3176 exit(1);
3178 state->pending = tmp;
3180 if (buflen >= smb_size) {
3182 * place the seqnum in the packet so that the main process
3183 * can reply with signing
3185 SIVAL(buf, smb_ss_field, seqnum);
3186 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3189 iov = &state->pending[num_pending];
3190 iov->iov_base = talloc_move(state->pending, &buf);
3191 iov->iov_len = buflen;
3193 DEBUG(10,("echo_handler[%d]: forward to main\n",
3194 (int)getpid()));
3195 smbd_echo_activate_writer(state);
3198 req = smbd_echo_read_send(state, state->ev, state->sconn);
3199 if (req == NULL) {
3200 DEBUG(1, ("smbd_echo_read_send failed\n"));
3201 exit(1);
3203 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3208 * Handle SMBecho requests in a forked child process
3210 bool fork_echo_handler(struct smbd_server_connection *sconn)
3212 struct smbXsrv_connection *xconn = sconn->conn;
3213 int listener_pipe[2];
3214 int res;
3215 pid_t child;
3216 bool use_mutex = false;
3218 res = pipe(listener_pipe);
3219 if (res == -1) {
3220 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3221 return false;
3224 #ifdef HAVE_ROBUST_MUTEXES
3225 use_mutex = tdb_runtime_check_for_robust_mutexes();
3227 if (use_mutex) {
3228 pthread_mutexattr_t a;
3230 xconn->smb1.echo_handler.socket_mutex =
3231 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3232 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3233 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3234 strerror(errno)));
3235 goto fail;
3238 res = pthread_mutexattr_init(&a);
3239 if (res != 0) {
3240 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3241 strerror(res)));
3242 goto fail;
3244 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3245 if (res != 0) {
3246 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3247 strerror(res)));
3248 pthread_mutexattr_destroy(&a);
3249 goto fail;
3251 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3252 if (res != 0) {
3253 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3254 strerror(res)));
3255 pthread_mutexattr_destroy(&a);
3256 goto fail;
3258 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3259 if (res != 0) {
3260 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3261 "%s\n", strerror(res)));
3262 pthread_mutexattr_destroy(&a);
3263 goto fail;
3265 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3266 &a);
3267 pthread_mutexattr_destroy(&a);
3268 if (res != 0) {
3269 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3270 strerror(res)));
3271 goto fail;
3274 #endif
3276 if (!use_mutex) {
3277 xconn->smb1.echo_handler.socket_lock_fd =
3278 create_unlink_tmp(lp_lock_directory());
3279 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3280 DEBUG(1, ("Could not create lock fd: %s\n",
3281 strerror(errno)));
3282 goto fail;
3286 child = fork();
3287 if (child == 0) {
3288 NTSTATUS status;
3290 close(listener_pipe[0]);
3291 set_blocking(listener_pipe[1], false);
3293 status = reinit_after_fork(sconn->msg_ctx,
3294 sconn->ev_ctx,
3295 true);
3296 if (!NT_STATUS_IS_OK(status)) {
3297 DEBUG(1, ("reinit_after_fork failed: %s\n",
3298 nt_errstr(status)));
3299 exit(1);
3301 smbd_echo_loop(sconn, listener_pipe[1]);
3302 exit(0);
3304 close(listener_pipe[1]);
3305 listener_pipe[1] = -1;
3306 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3308 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3311 * Without smb signing this is the same as the normal smbd
3312 * listener. This needs to change once signing comes in.
3314 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3315 xconn,
3316 xconn->smb1.echo_handler.trusted_fd,
3317 TEVENT_FD_READ,
3318 smbd_server_echo_handler,
3319 xconn);
3320 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3321 DEBUG(1, ("event_add_fd failed\n"));
3322 goto fail;
3325 return true;
3327 fail:
3328 if (listener_pipe[0] != -1) {
3329 close(listener_pipe[0]);
3331 if (listener_pipe[1] != -1) {
3332 close(listener_pipe[1]);
3334 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3335 close(xconn->smb1.echo_handler.socket_lock_fd);
3337 #ifdef HAVE_ROBUST_MUTEXES
3338 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3339 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3340 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3342 #endif
3343 smbd_echo_init(xconn);
3345 return false;
3348 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3350 while (user) {
3351 if (user->session_info &&
3352 (user->session_info->unix_token->uid == uid)) {
3353 return true;
3355 user = user->next;
3357 return false;
3360 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3362 while (user) {
3363 if (user->session_info != NULL) {
3364 int i;
3365 struct security_unix_token *utok;
3367 utok = user->session_info->unix_token;
3368 if (utok->gid == gid) {
3369 return true;
3371 for(i=0; i<utok->ngroups; i++) {
3372 if (utok->groups[i] == gid) {
3373 return true;
3377 user = user->next;
3379 return false;
3382 static bool sid_in_use(const struct user_struct *user,
3383 const struct dom_sid *psid)
3385 while (user) {
3386 struct security_token *tok;
3388 if (user->session_info == NULL) {
3389 continue;
3391 tok = user->session_info->security_token;
3392 if (tok == NULL) {
3394 * Not sure session_info->security_token can
3395 * ever be NULL. This check might be not
3396 * necessary.
3398 continue;
3400 if (security_token_has_sid(tok, psid)) {
3401 return true;
3403 user = user->next;
3405 return false;
3408 static bool id_in_use(const struct user_struct *user,
3409 const struct id_cache_ref *id)
3411 switch(id->type) {
3412 case UID:
3413 return uid_in_use(user, id->id.uid);
3414 case GID:
3415 return gid_in_use(user, id->id.gid);
3416 case SID:
3417 return sid_in_use(user, &id->id.sid);
3418 default:
3419 break;
3421 return false;
3424 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3425 void *private_data,
3426 uint32_t msg_type,
3427 struct server_id server_id,
3428 DATA_BLOB* data)
3430 const char *msg = (data && data->data)
3431 ? (const char *)data->data : "<NULL>";
3432 struct id_cache_ref id;
3433 struct smbd_server_connection *sconn =
3434 talloc_get_type_abort(private_data,
3435 struct smbd_server_connection);
3437 if (!id_cache_ref_parse(msg, &id)) {
3438 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3439 return;
3442 if (id_in_use(sconn->users, &id)) {
3443 exit_server_cleanly(msg);
3445 id_cache_delete_from_cache(&id);
3448 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3449 enum protocol_types protocol)
3451 NTSTATUS status;
3453 set_Protocol(protocol);
3454 conn->protocol = protocol;
3456 if (protocol >= PROTOCOL_SMB2_02) {
3457 status = smb2srv_session_table_init(conn);
3458 if (!NT_STATUS_IS_OK(status)) {
3459 return status;
3462 status = smb2srv_open_table_init(conn);
3463 if (!NT_STATUS_IS_OK(status)) {
3464 return status;
3466 } else {
3467 status = smb1srv_session_table_init(conn);
3468 if (!NT_STATUS_IS_OK(status)) {
3469 return status;
3472 status = smb1srv_tcon_table_init(conn);
3473 if (!NT_STATUS_IS_OK(status)) {
3474 return status;
3477 status = smb1srv_open_table_init(conn);
3478 if (!NT_STATUS_IS_OK(status)) {
3479 return status;
3483 return NT_STATUS_OK;
3486 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3487 void *private_data)
3489 struct smbXsrv_connection *conn =
3490 talloc_get_type_abort(private_data,
3491 struct smbXsrv_connection);
3493 switch (point) {
3494 case TEVENT_TRACE_BEFORE_WAIT:
3496 * This just removes compiler warning
3497 * without profile support
3499 conn->smbd_idle_profstamp = 0;
3500 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3501 break;
3502 case TEVENT_TRACE_AFTER_WAIT:
3503 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3504 break;
3505 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3506 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3507 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3508 break;
3509 #endif
3514 * Create a debug string for the connection
3516 * This is allocated to talloc_tos() or a string constant
3517 * in certain corner cases. The returned string should
3518 * hence not be free'd directly but only via the talloc stack.
3520 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3522 const char *ret;
3525 * TODO: this can be improved later
3526 * maybe including the client guid or more
3528 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3529 if (ret == NULL) {
3530 return "<tsocket_address_string() failed>";
3533 return ret;
3536 /****************************************************************************
3537 Process commands from the client
3538 ****************************************************************************/
3540 void smbd_process(struct tevent_context *ev_ctx,
3541 struct messaging_context *msg_ctx,
3542 int sock_fd,
3543 bool interactive)
3545 TALLOC_CTX *frame = talloc_stackframe();
3546 struct smbXsrv_connection *xconn;
3547 struct smbd_server_connection *sconn;
3548 struct sockaddr_storage ss_srv;
3549 void *sp_srv = (void *)&ss_srv;
3550 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3551 struct sockaddr_storage ss_clnt;
3552 void *sp_clnt = (void *)&ss_clnt;
3553 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3554 socklen_t sa_socklen;
3555 struct tsocket_address *local_address = NULL;
3556 struct tsocket_address *remote_address = NULL;
3557 const char *locaddr = NULL;
3558 const char *remaddr = NULL;
3559 char *rhost;
3560 int ret;
3561 int tmp;
3563 xconn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3564 if (xconn == NULL) {
3565 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3566 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3569 xconn->ev_ctx = ev_ctx;
3570 xconn->msg_ctx = msg_ctx;
3571 xconn->transport.sock = sock_fd;
3572 smbd_echo_init(xconn);
3574 sconn = talloc_zero(xconn, struct smbd_server_connection);
3575 if (!sconn) {
3576 exit_server("failed to create smbd_server_connection");
3579 xconn->sconn = sconn;
3580 sconn->conn = xconn;
3583 * TODO: remove this...:-)
3585 global_smbXsrv_connection = xconn;
3587 sconn->ev_ctx = ev_ctx;
3588 sconn->msg_ctx = msg_ctx;
3590 if (!interactive) {
3591 smbd_setup_sig_term_handler(sconn);
3592 smbd_setup_sig_hup_handler(sconn);
3594 if (!serverid_register(messaging_server_id(msg_ctx),
3595 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3596 |FLAG_MSG_DBWRAP
3597 |FLAG_MSG_PRINT_GENERAL)) {
3598 exit_server_cleanly("Could not register myself in "
3599 "serverid.tdb");
3603 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3605 * We're not making the decision here,
3606 * we're just allowing the client
3607 * to decide between SMB1 and SMB2
3608 * with the first negprot
3609 * packet.
3611 sconn->using_smb2 = true;
3614 /* Ensure child is set to blocking mode */
3615 set_blocking(sock_fd,True);
3617 set_socket_options(sock_fd, "SO_KEEPALIVE");
3618 set_socket_options(sock_fd, lp_socket_options());
3620 sa_socklen = sizeof(ss_clnt);
3621 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3622 if (ret != 0) {
3623 int level = (errno == ENOTCONN)?2:0;
3624 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3625 exit_server_cleanly("getpeername() failed.\n");
3627 ret = tsocket_address_bsd_from_sockaddr(sconn,
3628 sa_clnt, sa_socklen,
3629 &remote_address);
3630 if (ret != 0) {
3631 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3632 __location__, strerror(errno)));
3633 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3636 sa_socklen = sizeof(ss_srv);
3637 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3638 if (ret != 0) {
3639 int level = (errno == ENOTCONN)?2:0;
3640 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3641 exit_server_cleanly("getsockname() failed.\n");
3643 ret = tsocket_address_bsd_from_sockaddr(sconn,
3644 sa_srv, sa_socklen,
3645 &local_address);
3646 if (ret != 0) {
3647 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3648 __location__, strerror(errno)));
3649 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3652 sconn->local_address = local_address;
3653 sconn->remote_address = remote_address;
3655 if (tsocket_address_is_inet(local_address, "ip")) {
3656 locaddr = tsocket_address_inet_addr_string(
3657 sconn->local_address,
3658 talloc_tos());
3659 if (locaddr == NULL) {
3660 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3661 __location__, strerror(errno)));
3662 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3664 } else {
3665 locaddr = "0.0.0.0";
3668 if (tsocket_address_is_inet(remote_address, "ip")) {
3669 remaddr = tsocket_address_inet_addr_string(
3670 sconn->remote_address,
3671 talloc_tos());
3672 if (remaddr == NULL) {
3673 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3674 __location__, strerror(errno)));
3675 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3677 } else {
3678 remaddr = "0.0.0.0";
3681 /* this is needed so that we get decent entries
3682 in smbstatus for port 445 connects */
3683 set_remote_machine_name(remaddr, false);
3684 reload_services(sconn, conn_snum_used, true);
3687 * Before the first packet, check the global hosts allow/ hosts deny
3688 * parameters before doing any parsing of packets passed to us by the
3689 * client. This prevents attacks on our parsing code from hosts not in
3690 * the hosts allow list.
3693 ret = get_remote_hostname(remote_address,
3694 &rhost,
3695 talloc_tos());
3696 if (ret < 0) {
3697 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3698 __location__, strerror(errno)));
3699 exit_server_cleanly("get_remote_hostname failed.\n");
3701 if (strequal(rhost, "UNKNOWN")) {
3702 rhost = talloc_strdup(talloc_tos(), remaddr);
3704 sconn->remote_hostname = talloc_move(sconn, &rhost);
3706 sub_set_socket_ids(remaddr,
3707 sconn->remote_hostname,
3708 locaddr);
3710 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3711 sconn->remote_hostname,
3712 remaddr)) {
3714 * send a negative session response "not listening on calling
3715 * name"
3717 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3718 DEBUG( 1, ("Connection denied from %s to %s\n",
3719 tsocket_address_string(remote_address, talloc_tos()),
3720 tsocket_address_string(local_address, talloc_tos())));
3721 (void)srv_send_smb(sconn,(char *)buf, false,
3722 0, false, NULL);
3723 exit_server_cleanly("connection denied");
3726 DEBUG(10, ("Connection allowed from %s to %s\n",
3727 tsocket_address_string(remote_address, talloc_tos()),
3728 tsocket_address_string(local_address, talloc_tos())));
3730 if (lp_preload_modules()) {
3731 smb_load_modules(lp_preload_modules());
3734 smb_perfcount_init();
3736 if (!init_account_policy()) {
3737 exit_server("Could not open account policy tdb.\n");
3740 if (*lp_root_directory(talloc_tos())) {
3741 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3742 DEBUG(0,("Failed to change root to %s\n",
3743 lp_root_directory(talloc_tos())));
3744 exit_server("Failed to chroot()");
3746 if (chdir("/") == -1) {
3747 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3748 exit_server("Failed to chroot()");
3750 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3753 if (!srv_init_signing(xconn)) {
3754 exit_server("Failed to init smb_signing");
3757 if (!file_init(sconn)) {
3758 exit_server("file_init() failed");
3761 /* Setup oplocks */
3762 if (!init_oplocks(sconn))
3763 exit_server("Failed to init oplocks");
3765 /* register our message handlers */
3766 messaging_register(sconn->msg_ctx, sconn,
3767 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3768 messaging_register(sconn->msg_ctx, sconn,
3769 MSG_SMB_CLOSE_FILE, msg_close_file);
3770 messaging_register(sconn->msg_ctx, sconn,
3771 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3773 id_cache_register_msgs(sconn->msg_ctx);
3774 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3775 messaging_register(sconn->msg_ctx, sconn,
3776 ID_CACHE_KILL, smbd_id_cache_kill);
3778 messaging_deregister(sconn->msg_ctx,
3779 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3780 messaging_register(sconn->msg_ctx, sconn,
3781 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3783 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3784 NULL);
3785 messaging_register(sconn->msg_ctx, sconn,
3786 MSG_SMB_KILL_CLIENT_IP,
3787 msg_kill_client_ip);
3789 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3792 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3793 * MSGs to all child processes
3795 messaging_deregister(sconn->msg_ctx,
3796 MSG_DEBUG, NULL);
3797 messaging_register(sconn->msg_ctx, NULL,
3798 MSG_DEBUG, debug_message);
3800 if ((lp_keepalive() != 0)
3801 && !(event_add_idle(ev_ctx, NULL,
3802 timeval_set(lp_keepalive(), 0),
3803 "keepalive", keepalive_fn,
3804 sconn))) {
3805 DEBUG(0, ("Could not add keepalive event\n"));
3806 exit(1);
3809 if (!(event_add_idle(ev_ctx, NULL,
3810 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3811 "deadtime", deadtime_fn, sconn))) {
3812 DEBUG(0, ("Could not add deadtime event\n"));
3813 exit(1);
3816 if (!(event_add_idle(ev_ctx, NULL,
3817 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3818 "housekeeping", housekeeping_fn, sconn))) {
3819 DEBUG(0, ("Could not add housekeeping event\n"));
3820 exit(1);
3823 if (lp_clustering()) {
3825 * We need to tell ctdb about our client's TCP
3826 * connection, so that for failover ctdbd can send
3827 * tickle acks, triggering a reconnection by the
3828 * client.
3830 NTSTATUS status;
3832 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3833 if (!NT_STATUS_IS_OK(status)) {
3834 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3835 nt_errstr(status)));
3839 tmp = lp_max_xmit();
3840 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3841 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3843 xconn->smb1.negprot.max_recv = tmp;
3845 xconn->smb1.sessions.done_sesssetup = false;
3846 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3848 if (!init_dptrs(sconn)) {
3849 exit_server("init_dptrs() failed");
3852 xconn->transport.fde = tevent_add_fd(ev_ctx,
3853 xconn,
3854 sock_fd,
3855 TEVENT_FD_READ,
3856 smbd_server_connection_handler,
3857 xconn);
3858 if (!xconn->transport.fde) {
3859 exit_server("failed to create smbd_server_connection fde");
3862 sconn->conn->local_address = sconn->local_address;
3863 sconn->conn->remote_address = sconn->remote_address;
3864 sconn->conn->remote_hostname = sconn->remote_hostname;
3865 sconn->conn->protocol = PROTOCOL_NONE;
3867 TALLOC_FREE(frame);
3869 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, xconn);
3871 while (True) {
3872 frame = talloc_stackframe_pool(8192);
3874 errno = 0;
3875 if (tevent_loop_once(ev_ctx) == -1) {
3876 if (errno != EINTR) {
3877 DEBUG(3, ("tevent_loop_once failed: %s,"
3878 " exiting\n", strerror(errno) ));
3879 break;
3883 TALLOC_FREE(frame);
3886 exit_server_cleanly(NULL);
3889 bool req_is_in_chain(const struct smb_request *req)
3891 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3893 * We're right now handling a subsequent request, so we must
3894 * be in a chain
3896 return true;
3899 if (!is_andx_req(req->cmd)) {
3900 return false;
3903 if (req->wct < 2) {
3905 * Okay, an illegal request, but definitely not chained :-)
3907 return false;
3910 return (CVAL(req->vwv+0, 0) != 0xFF);