smbd: Restructure brl_conflict_other
[Samba.git] / source3 / smbd / process.c
blobdd931e022506ab7602613ba24ed3c435258a6d91
1 /*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
42 #include "serverid.h"
43 #include "system/threads.h"
45 /* Internal message queue for deferred opens. */
46 struct pending_message_list {
47 struct pending_message_list *next, *prev;
48 struct timeval request_time; /* When was this first issued? */
49 struct smbd_server_connection *sconn;
50 struct tevent_timer *te;
51 struct smb_perfcount_data pcd;
52 uint32_t seqnum;
53 bool encrypted;
54 bool processed;
55 DATA_BLOB buf;
56 struct deferred_open_record *open_rec;
59 static void construct_reply_common(struct smb_request *req, const char *inbuf,
60 char *outbuf);
61 static struct pending_message_list *get_deferred_open_message_smb(
62 struct smbd_server_connection *sconn, uint64_t mid);
63 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
65 void smbd_echo_init(struct smbd_server_connection *sconn)
67 sconn->smb1.echo_handler.trusted_fd = -1;
68 sconn->smb1.echo_handler.socket_lock_fd = -1;
69 #ifdef HAVE_ROBUST_MUTEXES
70 sconn->smb1.echo_handler.socket_mutex = NULL;
71 #endif
74 static bool smbd_echo_active(struct smbd_server_connection *sconn)
76 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
77 return true;
80 #ifdef HAVE_ROBUST_MUTEXES
81 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
82 return true;
84 #endif
86 return false;
89 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
91 if (!smbd_echo_active(sconn)) {
92 return true;
95 sconn->smb1.echo_handler.ref_count++;
97 if (sconn->smb1.echo_handler.ref_count > 1) {
98 return true;
101 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
103 #ifdef HAVE_ROBUST_MUTEXES
104 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
105 int ret = EINTR;
107 while (ret == EINTR) {
108 ret = pthread_mutex_lock(
109 sconn->smb1.echo_handler.socket_mutex);
110 if (ret == 0) {
111 break;
114 if (ret != 0) {
115 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
116 strerror(ret)));
117 return false;
120 #endif
122 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
123 bool ok;
125 do {
126 ok = fcntl_lock(
127 sconn->smb1.echo_handler.socket_lock_fd,
128 F_SETLKW, 0, 0, F_WRLCK);
129 } while (!ok && (errno == EINTR));
131 if (!ok) {
132 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
133 return false;
137 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
139 return true;
142 void smbd_lock_socket(struct smbd_server_connection *sconn)
144 if (!smbd_lock_socket_internal(sconn)) {
145 exit_server_cleanly("failed to lock socket");
149 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
151 if (!smbd_echo_active(sconn)) {
152 return true;
155 sconn->smb1.echo_handler.ref_count--;
157 if (sconn->smb1.echo_handler.ref_count > 0) {
158 return true;
161 #ifdef HAVE_ROBUST_MUTEXES
162 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
163 int ret = EINTR;
165 while (ret == EINTR) {
166 ret = pthread_mutex_unlock(
167 sconn->smb1.echo_handler.socket_mutex);
168 if (ret == 0) {
169 break;
172 if (ret != 0) {
173 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
174 strerror(ret)));
175 return false;
178 #endif
180 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
181 bool ok;
183 do {
184 ok = fcntl_lock(
185 sconn->smb1.echo_handler.socket_lock_fd,
186 F_SETLKW, 0, 0, F_UNLCK);
187 } while (!ok && (errno == EINTR));
189 if (!ok) {
190 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
191 return false;
195 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
197 return true;
200 void smbd_unlock_socket(struct smbd_server_connection *sconn)
202 if (!smbd_unlock_socket_internal(sconn)) {
203 exit_server_cleanly("failed to unlock socket");
207 /* Accessor function for smb_read_error for smbd functions. */
209 /****************************************************************************
210 Send an smb to a fd.
211 ****************************************************************************/
213 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
214 bool do_signing, uint32_t seqnum,
215 bool do_encrypt,
216 struct smb_perfcount_data *pcd)
218 size_t len = 0;
219 ssize_t ret;
220 char *buf_out = buffer;
222 if (!NT_STATUS_IS_OK(sconn->status)) {
224 * we're not supposed to do any io
226 return true;
229 smbd_lock_socket(sconn);
231 if (do_signing) {
232 /* Sign the outgoing packet if required. */
233 srv_calculate_sign_mac(sconn, buf_out, seqnum);
236 if (do_encrypt) {
237 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
238 if (!NT_STATUS_IS_OK(status)) {
239 DEBUG(0, ("send_smb: SMB encryption failed "
240 "on outgoing packet! Error %s\n",
241 nt_errstr(status) ));
242 ret = -1;
243 goto out;
247 len = smb_len_large(buf_out) + 4;
249 ret = write_data(sconn->sock, buf_out, len);
250 if (ret <= 0) {
252 char addr[INET6_ADDRSTRLEN];
254 * Try and give an error message saying what
255 * client failed.
257 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
258 (int)getpid(), (int)len,
259 get_peer_addr(sconn->sock, addr, sizeof(addr)),
260 (int)ret, strerror(errno) ));
262 srv_free_enc_buffer(sconn, buf_out);
263 goto out;
266 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
267 srv_free_enc_buffer(sconn, buf_out);
268 out:
269 SMB_PERFCOUNT_END(pcd);
271 smbd_unlock_socket(sconn);
272 return (ret > 0);
275 /*******************************************************************
276 Setup the word count and byte count for a smb message.
277 ********************************************************************/
279 int srv_set_message(char *buf,
280 int num_words,
281 int num_bytes,
282 bool zero)
284 if (zero && (num_words || num_bytes)) {
285 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
287 SCVAL(buf,smb_wct,num_words);
288 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
289 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
290 return (smb_size + num_words*2 + num_bytes);
293 static bool valid_smb_header(struct smbd_server_connection *sconn,
294 const uint8_t *inbuf)
296 if (is_encrypted_packet(sconn, inbuf)) {
297 return true;
300 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
301 * but it just looks weird to call strncmp for this one.
303 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
306 /* Socket functions for smbd packet processing. */
308 static bool valid_packet_size(size_t len)
311 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
312 * of header. Don't print the error if this fits.... JRA.
315 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
316 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
317 (unsigned long)len));
318 return false;
320 return true;
323 static NTSTATUS read_packet_remainder(int fd, char *buffer,
324 unsigned int timeout, ssize_t len)
326 NTSTATUS status;
328 if (len <= 0) {
329 return NT_STATUS_OK;
332 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
333 if (!NT_STATUS_IS_OK(status)) {
334 char addr[INET6_ADDRSTRLEN];
335 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
336 "error = %s.\n",
337 get_peer_addr(fd, addr, sizeof(addr)),
338 nt_errstr(status)));
340 return status;
343 /****************************************************************************
344 Attempt a zerocopy writeX read. We know here that len > smb_size-4
345 ****************************************************************************/
348 * Unfortunately, earlier versions of smbclient/libsmbclient
349 * don't send this "standard" writeX header. I've fixed this
350 * for 3.2 but we'll use the old method with earlier versions.
351 * Windows and CIFSFS at least use this standard size. Not
352 * sure about MacOSX.
355 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
356 (2*14) + /* word count (including bcc) */ \
357 1 /* pad byte */)
359 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
360 const char lenbuf[4],
361 struct smbd_server_connection *sconn,
362 int sock,
363 char **buffer,
364 unsigned int timeout,
365 size_t *p_unread,
366 size_t *len_ret)
368 /* Size of a WRITEX call (+4 byte len). */
369 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
370 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
371 ssize_t toread;
372 NTSTATUS status;
374 memcpy(writeX_header, lenbuf, 4);
376 status = read_fd_with_timeout(
377 sock, writeX_header + 4,
378 STANDARD_WRITE_AND_X_HEADER_SIZE,
379 STANDARD_WRITE_AND_X_HEADER_SIZE,
380 timeout, NULL);
382 if (!NT_STATUS_IS_OK(status)) {
383 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
384 "error = %s.\n",
385 tsocket_address_string(sconn->remote_address,
386 talloc_tos()),
387 nt_errstr(status)));
388 return status;
392 * Ok - now try and see if this is a possible
393 * valid writeX call.
396 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
398 * If the data offset is beyond what
399 * we've read, drain the extra bytes.
401 uint16_t doff = SVAL(writeX_header,smb_vwv11);
402 ssize_t newlen;
404 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
405 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
406 if (drain_socket(sock, drain) != drain) {
407 smb_panic("receive_smb_raw_talloc_partial_read:"
408 " failed to drain pending bytes");
410 } else {
411 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
414 /* Spoof down the length and null out the bcc. */
415 set_message_bcc(writeX_header, 0);
416 newlen = smb_len(writeX_header);
418 /* Copy the header we've written. */
420 *buffer = (char *)talloc_memdup(mem_ctx,
421 writeX_header,
422 sizeof(writeX_header));
424 if (*buffer == NULL) {
425 DEBUG(0, ("Could not allocate inbuf of length %d\n",
426 (int)sizeof(writeX_header)));
427 return NT_STATUS_NO_MEMORY;
430 /* Work out the remaining bytes. */
431 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
432 *len_ret = newlen + 4;
433 return NT_STATUS_OK;
436 if (!valid_packet_size(len)) {
437 return NT_STATUS_INVALID_PARAMETER;
441 * Not a valid writeX call. Just do the standard
442 * talloc and return.
445 *buffer = talloc_array(mem_ctx, char, len+4);
447 if (*buffer == NULL) {
448 DEBUG(0, ("Could not allocate inbuf of length %d\n",
449 (int)len+4));
450 return NT_STATUS_NO_MEMORY;
453 /* Copy in what we already read. */
454 memcpy(*buffer,
455 writeX_header,
456 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
457 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
459 if(toread > 0) {
460 status = read_packet_remainder(
461 sock,
462 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
463 timeout, toread);
465 if (!NT_STATUS_IS_OK(status)) {
466 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
467 nt_errstr(status)));
468 return status;
472 *len_ret = len + 4;
473 return NT_STATUS_OK;
476 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
477 struct smbd_server_connection *sconn,
478 int sock,
479 char **buffer, unsigned int timeout,
480 size_t *p_unread, size_t *plen)
482 char lenbuf[4];
483 size_t len;
484 int min_recv_size = lp_min_receive_file_size();
485 NTSTATUS status;
487 *p_unread = 0;
489 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
490 &len);
491 if (!NT_STATUS_IS_OK(status)) {
492 return status;
495 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
496 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
497 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
498 !srv_is_signing_active(sconn) &&
499 sconn->smb1.echo_handler.trusted_fde == NULL) {
501 return receive_smb_raw_talloc_partial_read(
502 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
503 p_unread, plen);
506 if (!valid_packet_size(len)) {
507 return NT_STATUS_INVALID_PARAMETER;
511 * The +4 here can't wrap, we've checked the length above already.
514 *buffer = talloc_array(mem_ctx, char, len+4);
516 if (*buffer == NULL) {
517 DEBUG(0, ("Could not allocate inbuf of length %d\n",
518 (int)len+4));
519 return NT_STATUS_NO_MEMORY;
522 memcpy(*buffer, lenbuf, sizeof(lenbuf));
524 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
525 if (!NT_STATUS_IS_OK(status)) {
526 return status;
529 *plen = len + 4;
530 return NT_STATUS_OK;
533 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
534 struct smbd_server_connection *sconn,
535 int sock,
536 char **buffer, unsigned int timeout,
537 size_t *p_unread, bool *p_encrypted,
538 size_t *p_len,
539 uint32_t *seqnum,
540 bool trusted_channel)
542 size_t len = 0;
543 NTSTATUS status;
545 *p_encrypted = false;
547 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
548 p_unread, &len);
549 if (!NT_STATUS_IS_OK(status)) {
550 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
551 ("receive_smb_raw_talloc failed for client %s "
552 "read error = %s.\n",
553 tsocket_address_string(sconn->remote_address,
554 talloc_tos()),
555 nt_errstr(status)) );
556 return status;
559 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
560 status = srv_decrypt_buffer(sconn, *buffer);
561 if (!NT_STATUS_IS_OK(status)) {
562 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
563 "incoming packet! Error %s\n",
564 nt_errstr(status) ));
565 return status;
567 *p_encrypted = true;
570 /* Check the incoming SMB signature. */
571 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
572 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
573 "incoming packet!\n"));
574 return NT_STATUS_INVALID_NETWORK_RESPONSE;
577 *p_len = len;
578 return NT_STATUS_OK;
582 * Initialize a struct smb_request from an inbuf
585 static bool init_smb_request(struct smb_request *req,
586 struct smbd_server_connection *sconn,
587 const uint8 *inbuf,
588 size_t unread_bytes, bool encrypted,
589 uint32_t seqnum)
591 struct smbXsrv_tcon *tcon;
592 NTSTATUS status;
593 NTTIME now;
594 size_t req_size = smb_len(inbuf) + 4;
596 /* Ensure we have at least smb_size bytes. */
597 if (req_size < smb_size) {
598 DEBUG(0,("init_smb_request: invalid request size %u\n",
599 (unsigned int)req_size ));
600 return false;
603 req->request_time = timeval_current();
604 now = timeval_to_nttime(&req->request_time);
606 req->cmd = CVAL(inbuf, smb_com);
607 req->flags2 = SVAL(inbuf, smb_flg2);
608 req->smbpid = SVAL(inbuf, smb_pid);
609 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
610 req->seqnum = seqnum;
611 req->vuid = SVAL(inbuf, smb_uid);
612 req->tid = SVAL(inbuf, smb_tid);
613 req->wct = CVAL(inbuf, smb_wct);
614 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
615 req->buflen = smb_buflen(inbuf);
616 req->buf = (const uint8_t *)smb_buf_const(inbuf);
617 req->unread_bytes = unread_bytes;
618 req->encrypted = encrypted;
619 req->sconn = sconn;
620 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
621 if (NT_STATUS_IS_OK(status)) {
622 req->conn = tcon->compat;
623 } else {
624 req->conn = NULL;
626 req->chain_fsp = NULL;
627 req->smb2req = NULL;
628 req->priv_paths = NULL;
629 req->chain = NULL;
630 smb_init_perfcount_data(&req->pcd);
632 /* Ensure we have at least wct words and 2 bytes of bcc. */
633 if (smb_size + req->wct*2 > req_size) {
634 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
635 (unsigned int)req->wct,
636 (unsigned int)req_size));
637 return false;
639 /* Ensure bcc is correct. */
640 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
641 DEBUG(0,("init_smb_request: invalid bcc number %u "
642 "(wct = %u, size %u)\n",
643 (unsigned int)req->buflen,
644 (unsigned int)req->wct,
645 (unsigned int)req_size));
646 return false;
649 req->outbuf = NULL;
650 return true;
653 static void process_smb(struct smbd_server_connection *conn,
654 uint8_t *inbuf, size_t nread, size_t unread_bytes,
655 uint32_t seqnum, bool encrypted,
656 struct smb_perfcount_data *deferred_pcd);
658 static void smbd_deferred_open_timer(struct tevent_context *ev,
659 struct tevent_timer *te,
660 struct timeval _tval,
661 void *private_data)
663 struct pending_message_list *msg = talloc_get_type(private_data,
664 struct pending_message_list);
665 struct smbd_server_connection *sconn = msg->sconn;
666 TALLOC_CTX *mem_ctx = talloc_tos();
667 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
668 uint8_t *inbuf;
670 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
671 msg->buf.length);
672 if (inbuf == NULL) {
673 exit_server("smbd_deferred_open_timer: talloc failed\n");
674 return;
677 /* We leave this message on the queue so the open code can
678 know this is a retry. */
679 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
680 (unsigned long long)mid ));
682 /* Mark the message as processed so this is not
683 * re-processed in error. */
684 msg->processed = true;
686 process_smb(sconn, inbuf,
687 msg->buf.length, 0,
688 msg->seqnum, msg->encrypted, &msg->pcd);
690 /* If it's still there and was processed, remove it. */
691 msg = get_deferred_open_message_smb(sconn, mid);
692 if (msg && msg->processed) {
693 remove_deferred_open_message_smb(sconn, mid);
697 /****************************************************************************
698 Function to push a message onto the tail of a linked list of smb messages ready
699 for processing.
700 ****************************************************************************/
702 static bool push_queued_message(struct smb_request *req,
703 struct timeval request_time,
704 struct timeval end_time,
705 struct deferred_open_record *open_rec)
707 int msg_len = smb_len(req->inbuf) + 4;
708 struct pending_message_list *msg;
710 msg = talloc_zero(NULL, struct pending_message_list);
712 if(msg == NULL) {
713 DEBUG(0,("push_message: malloc fail (1)\n"));
714 return False;
716 msg->sconn = req->sconn;
718 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
719 if(msg->buf.data == NULL) {
720 DEBUG(0,("push_message: malloc fail (2)\n"));
721 TALLOC_FREE(msg);
722 return False;
725 msg->request_time = request_time;
726 msg->seqnum = req->seqnum;
727 msg->encrypted = req->encrypted;
728 msg->processed = false;
729 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
731 if (open_rec) {
732 msg->open_rec = talloc_move(msg, &open_rec);
735 #if 0
736 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
737 msg,
738 end_time,
739 smbd_deferred_open_timer,
740 msg);
741 if (!msg->te) {
742 DEBUG(0,("push_message: event_add_timed failed\n"));
743 TALLOC_FREE(msg);
744 return false;
746 #endif
748 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
749 struct pending_message_list *);
751 DEBUG(10,("push_message: pushed message length %u on "
752 "deferred_open_queue\n", (unsigned int)msg_len));
754 return True;
757 /****************************************************************************
758 Function to delete a sharing violation open message by mid.
759 ****************************************************************************/
761 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
762 uint64_t mid)
764 struct pending_message_list *pml;
766 if (sconn->using_smb2) {
767 remove_deferred_open_message_smb2(sconn, mid);
768 return;
771 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
772 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
773 DEBUG(10,("remove_deferred_open_message_smb: "
774 "deleting mid %llu len %u\n",
775 (unsigned long long)mid,
776 (unsigned int)pml->buf.length ));
777 DLIST_REMOVE(sconn->deferred_open_queue, pml);
778 TALLOC_FREE(pml);
779 return;
784 /****************************************************************************
785 Move a sharing violation open retry message to the front of the list and
786 schedule it for immediate processing.
787 ****************************************************************************/
789 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
790 uint64_t mid)
792 struct pending_message_list *pml;
793 int i = 0;
795 if (sconn->using_smb2) {
796 return schedule_deferred_open_message_smb2(sconn, mid);
799 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
800 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
802 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
803 "msg_mid = %llu\n",
804 i++,
805 (unsigned long long)msg_mid ));
807 if (mid == msg_mid) {
808 struct tevent_timer *te;
810 if (pml->processed) {
811 /* A processed message should not be
812 * rescheduled. */
813 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
814 "message mid %llu was already processed\n",
815 (unsigned long long)msg_mid ));
816 continue;
819 DEBUG(10,("schedule_deferred_open_message_smb: "
820 "scheduling mid %llu\n",
821 (unsigned long long)mid ));
823 te = tevent_add_timer(pml->sconn->ev_ctx,
824 pml,
825 timeval_zero(),
826 smbd_deferred_open_timer,
827 pml);
828 if (!te) {
829 DEBUG(10,("schedule_deferred_open_message_smb: "
830 "event_add_timed() failed, "
831 "skipping mid %llu\n",
832 (unsigned long long)msg_mid ));
835 TALLOC_FREE(pml->te);
836 pml->te = te;
837 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
838 return true;
842 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
843 "find message mid %llu\n",
844 (unsigned long long)mid ));
846 return false;
849 /****************************************************************************
850 Return true if this mid is on the deferred queue and was not yet processed.
851 ****************************************************************************/
853 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
855 struct pending_message_list *pml;
857 if (sconn->using_smb2) {
858 return open_was_deferred_smb2(sconn, mid);
861 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
862 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
863 return True;
866 return False;
869 /****************************************************************************
870 Return the message queued by this mid.
871 ****************************************************************************/
873 static struct pending_message_list *get_deferred_open_message_smb(
874 struct smbd_server_connection *sconn, uint64_t mid)
876 struct pending_message_list *pml;
878 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
879 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
880 return pml;
883 return NULL;
886 /****************************************************************************
887 Get the state data queued by this mid.
888 ****************************************************************************/
890 bool get_deferred_open_message_state(struct smb_request *smbreq,
891 struct timeval *p_request_time,
892 struct deferred_open_record **open_rec)
894 struct pending_message_list *pml;
896 if (smbreq->sconn->using_smb2) {
897 return get_deferred_open_message_state_smb2(smbreq->smb2req,
898 p_request_time,
899 open_rec);
902 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
903 if (!pml) {
904 return false;
906 if (p_request_time) {
907 *p_request_time = pml->request_time;
909 if (open_rec != NULL) {
910 *open_rec = pml->open_rec;
912 return true;
915 /****************************************************************************
916 Function to push a deferred open smb message onto a linked list of local smb
917 messages ready for processing.
918 ****************************************************************************/
920 bool push_deferred_open_message_smb(struct smb_request *req,
921 struct timeval request_time,
922 struct timeval timeout,
923 struct file_id id,
924 struct deferred_open_record *open_rec)
926 struct timeval end_time;
928 if (req->smb2req) {
929 return push_deferred_open_message_smb2(req->smb2req,
930 request_time,
931 timeout,
933 open_rec);
936 if (req->unread_bytes) {
937 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
938 "unread_bytes = %u\n",
939 (unsigned int)req->unread_bytes ));
940 smb_panic("push_deferred_open_message_smb: "
941 "logic error unread_bytes != 0" );
944 end_time = timeval_sum(&request_time, &timeout);
946 DEBUG(10,("push_deferred_open_message_smb: pushing message "
947 "len %u mid %llu timeout time [%u.%06u]\n",
948 (unsigned int) smb_len(req->inbuf)+4,
949 (unsigned long long)req->mid,
950 (unsigned int)end_time.tv_sec,
951 (unsigned int)end_time.tv_usec));
953 return push_queued_message(req, request_time, end_time, open_rec);
956 static void smbd_sig_term_handler(struct tevent_context *ev,
957 struct tevent_signal *se,
958 int signum,
959 int count,
960 void *siginfo,
961 void *private_data)
963 exit_server_cleanly("termination signal");
966 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
968 struct tevent_signal *se;
970 se = tevent_add_signal(sconn->ev_ctx,
971 sconn,
972 SIGTERM, 0,
973 smbd_sig_term_handler,
974 sconn);
975 if (!se) {
976 exit_server("failed to setup SIGTERM handler");
980 static void smbd_sig_hup_handler(struct tevent_context *ev,
981 struct tevent_signal *se,
982 int signum,
983 int count,
984 void *siginfo,
985 void *private_data)
987 struct smbd_server_connection *sconn =
988 talloc_get_type_abort(private_data,
989 struct smbd_server_connection);
991 change_to_root_user();
992 DEBUG(1,("Reloading services after SIGHUP\n"));
993 reload_services(sconn, conn_snum_used, false);
996 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
998 struct tevent_signal *se;
1000 se = tevent_add_signal(sconn->ev_ctx,
1001 sconn,
1002 SIGHUP, 0,
1003 smbd_sig_hup_handler,
1004 sconn);
1005 if (!se) {
1006 exit_server("failed to setup SIGHUP handler");
1010 static void smbd_conf_updated(struct messaging_context *msg,
1011 void *private_data,
1012 uint32_t msg_type,
1013 struct server_id server_id,
1014 DATA_BLOB *data)
1016 struct smbd_server_connection *sconn =
1017 talloc_get_type_abort(private_data,
1018 struct smbd_server_connection);
1020 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1021 "updated. Reloading.\n"));
1022 change_to_root_user();
1023 reload_services(sconn, conn_snum_used, false);
1027 * Only allow 5 outstanding trans requests. We're allocating memory, so
1028 * prevent a DoS.
1031 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1033 int count = 0;
1034 for (; list != NULL; list = list->next) {
1036 if (list->mid == mid) {
1037 return NT_STATUS_INVALID_PARAMETER;
1040 count += 1;
1042 if (count > 5) {
1043 return NT_STATUS_INSUFFICIENT_RESOURCES;
1046 return NT_STATUS_OK;
1050 These flags determine some of the permissions required to do an operation
1052 Note that I don't set NEED_WRITE on some write operations because they
1053 are used by some brain-dead clients when printing, and I don't want to
1054 force write permissions on print services.
1056 #define AS_USER (1<<0)
1057 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1058 #define TIME_INIT (1<<2)
1059 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1060 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1061 #define DO_CHDIR (1<<6)
1064 define a list of possible SMB messages and their corresponding
1065 functions. Any message that has a NULL function is unimplemented -
1066 please feel free to contribute implementations!
1068 static const struct smb_message_struct {
1069 const char *name;
1070 void (*fn)(struct smb_request *req);
1071 int flags;
1072 } smb_messages[256] = {
1074 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1075 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1076 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1077 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1078 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1079 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1080 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1081 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1082 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1083 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1084 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1085 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1086 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1087 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1088 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1089 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1090 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1091 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1092 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1093 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1094 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1095 /* 0x15 */ { NULL, NULL, 0 },
1096 /* 0x16 */ { NULL, NULL, 0 },
1097 /* 0x17 */ { NULL, NULL, 0 },
1098 /* 0x18 */ { NULL, NULL, 0 },
1099 /* 0x19 */ { NULL, NULL, 0 },
1100 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1101 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1102 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1103 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1104 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1105 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1106 /* 0x20 */ { "SMBwritec", NULL,0},
1107 /* 0x21 */ { NULL, NULL, 0 },
1108 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1109 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1110 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1111 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1112 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1113 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1114 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1115 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1116 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1117 /* 0x2b */ { "SMBecho",reply_echo,0},
1118 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1119 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1120 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1121 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1122 /* 0x30 */ { NULL, NULL, 0 },
1123 /* 0x31 */ { NULL, NULL, 0 },
1124 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1125 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1126 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1127 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1128 /* 0x36 */ { NULL, NULL, 0 },
1129 /* 0x37 */ { NULL, NULL, 0 },
1130 /* 0x38 */ { NULL, NULL, 0 },
1131 /* 0x39 */ { NULL, NULL, 0 },
1132 /* 0x3a */ { NULL, NULL, 0 },
1133 /* 0x3b */ { NULL, NULL, 0 },
1134 /* 0x3c */ { NULL, NULL, 0 },
1135 /* 0x3d */ { NULL, NULL, 0 },
1136 /* 0x3e */ { NULL, NULL, 0 },
1137 /* 0x3f */ { NULL, NULL, 0 },
1138 /* 0x40 */ { NULL, NULL, 0 },
1139 /* 0x41 */ { NULL, NULL, 0 },
1140 /* 0x42 */ { NULL, NULL, 0 },
1141 /* 0x43 */ { NULL, NULL, 0 },
1142 /* 0x44 */ { NULL, NULL, 0 },
1143 /* 0x45 */ { NULL, NULL, 0 },
1144 /* 0x46 */ { NULL, NULL, 0 },
1145 /* 0x47 */ { NULL, NULL, 0 },
1146 /* 0x48 */ { NULL, NULL, 0 },
1147 /* 0x49 */ { NULL, NULL, 0 },
1148 /* 0x4a */ { NULL, NULL, 0 },
1149 /* 0x4b */ { NULL, NULL, 0 },
1150 /* 0x4c */ { NULL, NULL, 0 },
1151 /* 0x4d */ { NULL, NULL, 0 },
1152 /* 0x4e */ { NULL, NULL, 0 },
1153 /* 0x4f */ { NULL, NULL, 0 },
1154 /* 0x50 */ { NULL, NULL, 0 },
1155 /* 0x51 */ { NULL, NULL, 0 },
1156 /* 0x52 */ { NULL, NULL, 0 },
1157 /* 0x53 */ { NULL, NULL, 0 },
1158 /* 0x54 */ { NULL, NULL, 0 },
1159 /* 0x55 */ { NULL, NULL, 0 },
1160 /* 0x56 */ { NULL, NULL, 0 },
1161 /* 0x57 */ { NULL, NULL, 0 },
1162 /* 0x58 */ { NULL, NULL, 0 },
1163 /* 0x59 */ { NULL, NULL, 0 },
1164 /* 0x5a */ { NULL, NULL, 0 },
1165 /* 0x5b */ { NULL, NULL, 0 },
1166 /* 0x5c */ { NULL, NULL, 0 },
1167 /* 0x5d */ { NULL, NULL, 0 },
1168 /* 0x5e */ { NULL, NULL, 0 },
1169 /* 0x5f */ { NULL, NULL, 0 },
1170 /* 0x60 */ { NULL, NULL, 0 },
1171 /* 0x61 */ { NULL, NULL, 0 },
1172 /* 0x62 */ { NULL, NULL, 0 },
1173 /* 0x63 */ { NULL, NULL, 0 },
1174 /* 0x64 */ { NULL, NULL, 0 },
1175 /* 0x65 */ { NULL, NULL, 0 },
1176 /* 0x66 */ { NULL, NULL, 0 },
1177 /* 0x67 */ { NULL, NULL, 0 },
1178 /* 0x68 */ { NULL, NULL, 0 },
1179 /* 0x69 */ { NULL, NULL, 0 },
1180 /* 0x6a */ { NULL, NULL, 0 },
1181 /* 0x6b */ { NULL, NULL, 0 },
1182 /* 0x6c */ { NULL, NULL, 0 },
1183 /* 0x6d */ { NULL, NULL, 0 },
1184 /* 0x6e */ { NULL, NULL, 0 },
1185 /* 0x6f */ { NULL, NULL, 0 },
1186 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1187 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1188 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1189 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1190 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1191 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1192 /* 0x76 */ { NULL, NULL, 0 },
1193 /* 0x77 */ { NULL, NULL, 0 },
1194 /* 0x78 */ { NULL, NULL, 0 },
1195 /* 0x79 */ { NULL, NULL, 0 },
1196 /* 0x7a */ { NULL, NULL, 0 },
1197 /* 0x7b */ { NULL, NULL, 0 },
1198 /* 0x7c */ { NULL, NULL, 0 },
1199 /* 0x7d */ { NULL, NULL, 0 },
1200 /* 0x7e */ { NULL, NULL, 0 },
1201 /* 0x7f */ { NULL, NULL, 0 },
1202 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1203 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1204 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1205 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1206 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1207 /* 0x85 */ { NULL, NULL, 0 },
1208 /* 0x86 */ { NULL, NULL, 0 },
1209 /* 0x87 */ { NULL, NULL, 0 },
1210 /* 0x88 */ { NULL, NULL, 0 },
1211 /* 0x89 */ { NULL, NULL, 0 },
1212 /* 0x8a */ { NULL, NULL, 0 },
1213 /* 0x8b */ { NULL, NULL, 0 },
1214 /* 0x8c */ { NULL, NULL, 0 },
1215 /* 0x8d */ { NULL, NULL, 0 },
1216 /* 0x8e */ { NULL, NULL, 0 },
1217 /* 0x8f */ { NULL, NULL, 0 },
1218 /* 0x90 */ { NULL, NULL, 0 },
1219 /* 0x91 */ { NULL, NULL, 0 },
1220 /* 0x92 */ { NULL, NULL, 0 },
1221 /* 0x93 */ { NULL, NULL, 0 },
1222 /* 0x94 */ { NULL, NULL, 0 },
1223 /* 0x95 */ { NULL, NULL, 0 },
1224 /* 0x96 */ { NULL, NULL, 0 },
1225 /* 0x97 */ { NULL, NULL, 0 },
1226 /* 0x98 */ { NULL, NULL, 0 },
1227 /* 0x99 */ { NULL, NULL, 0 },
1228 /* 0x9a */ { NULL, NULL, 0 },
1229 /* 0x9b */ { NULL, NULL, 0 },
1230 /* 0x9c */ { NULL, NULL, 0 },
1231 /* 0x9d */ { NULL, NULL, 0 },
1232 /* 0x9e */ { NULL, NULL, 0 },
1233 /* 0x9f */ { NULL, NULL, 0 },
1234 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1235 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1236 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1237 /* 0xa3 */ { NULL, NULL, 0 },
1238 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1239 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1240 /* 0xa6 */ { NULL, NULL, 0 },
1241 /* 0xa7 */ { NULL, NULL, 0 },
1242 /* 0xa8 */ { NULL, NULL, 0 },
1243 /* 0xa9 */ { NULL, NULL, 0 },
1244 /* 0xaa */ { NULL, NULL, 0 },
1245 /* 0xab */ { NULL, NULL, 0 },
1246 /* 0xac */ { NULL, NULL, 0 },
1247 /* 0xad */ { NULL, NULL, 0 },
1248 /* 0xae */ { NULL, NULL, 0 },
1249 /* 0xaf */ { NULL, NULL, 0 },
1250 /* 0xb0 */ { NULL, NULL, 0 },
1251 /* 0xb1 */ { NULL, NULL, 0 },
1252 /* 0xb2 */ { NULL, NULL, 0 },
1253 /* 0xb3 */ { NULL, NULL, 0 },
1254 /* 0xb4 */ { NULL, NULL, 0 },
1255 /* 0xb5 */ { NULL, NULL, 0 },
1256 /* 0xb6 */ { NULL, NULL, 0 },
1257 /* 0xb7 */ { NULL, NULL, 0 },
1258 /* 0xb8 */ { NULL, NULL, 0 },
1259 /* 0xb9 */ { NULL, NULL, 0 },
1260 /* 0xba */ { NULL, NULL, 0 },
1261 /* 0xbb */ { NULL, NULL, 0 },
1262 /* 0xbc */ { NULL, NULL, 0 },
1263 /* 0xbd */ { NULL, NULL, 0 },
1264 /* 0xbe */ { NULL, NULL, 0 },
1265 /* 0xbf */ { NULL, NULL, 0 },
1266 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1267 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1268 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1269 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1270 /* 0xc4 */ { NULL, NULL, 0 },
1271 /* 0xc5 */ { NULL, NULL, 0 },
1272 /* 0xc6 */ { NULL, NULL, 0 },
1273 /* 0xc7 */ { NULL, NULL, 0 },
1274 /* 0xc8 */ { NULL, NULL, 0 },
1275 /* 0xc9 */ { NULL, NULL, 0 },
1276 /* 0xca */ { NULL, NULL, 0 },
1277 /* 0xcb */ { NULL, NULL, 0 },
1278 /* 0xcc */ { NULL, NULL, 0 },
1279 /* 0xcd */ { NULL, NULL, 0 },
1280 /* 0xce */ { NULL, NULL, 0 },
1281 /* 0xcf */ { NULL, NULL, 0 },
1282 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1283 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1284 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1285 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1286 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1287 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1288 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1289 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1290 /* 0xd8 */ { NULL, NULL, 0 },
1291 /* 0xd9 */ { NULL, NULL, 0 },
1292 /* 0xda */ { NULL, NULL, 0 },
1293 /* 0xdb */ { NULL, NULL, 0 },
1294 /* 0xdc */ { NULL, NULL, 0 },
1295 /* 0xdd */ { NULL, NULL, 0 },
1296 /* 0xde */ { NULL, NULL, 0 },
1297 /* 0xdf */ { NULL, NULL, 0 },
1298 /* 0xe0 */ { NULL, NULL, 0 },
1299 /* 0xe1 */ { NULL, NULL, 0 },
1300 /* 0xe2 */ { NULL, NULL, 0 },
1301 /* 0xe3 */ { NULL, NULL, 0 },
1302 /* 0xe4 */ { NULL, NULL, 0 },
1303 /* 0xe5 */ { NULL, NULL, 0 },
1304 /* 0xe6 */ { NULL, NULL, 0 },
1305 /* 0xe7 */ { NULL, NULL, 0 },
1306 /* 0xe8 */ { NULL, NULL, 0 },
1307 /* 0xe9 */ { NULL, NULL, 0 },
1308 /* 0xea */ { NULL, NULL, 0 },
1309 /* 0xeb */ { NULL, NULL, 0 },
1310 /* 0xec */ { NULL, NULL, 0 },
1311 /* 0xed */ { NULL, NULL, 0 },
1312 /* 0xee */ { NULL, NULL, 0 },
1313 /* 0xef */ { NULL, NULL, 0 },
1314 /* 0xf0 */ { NULL, NULL, 0 },
1315 /* 0xf1 */ { NULL, NULL, 0 },
1316 /* 0xf2 */ { NULL, NULL, 0 },
1317 /* 0xf3 */ { NULL, NULL, 0 },
1318 /* 0xf4 */ { NULL, NULL, 0 },
1319 /* 0xf5 */ { NULL, NULL, 0 },
1320 /* 0xf6 */ { NULL, NULL, 0 },
1321 /* 0xf7 */ { NULL, NULL, 0 },
1322 /* 0xf8 */ { NULL, NULL, 0 },
1323 /* 0xf9 */ { NULL, NULL, 0 },
1324 /* 0xfa */ { NULL, NULL, 0 },
1325 /* 0xfb */ { NULL, NULL, 0 },
1326 /* 0xfc */ { NULL, NULL, 0 },
1327 /* 0xfd */ { NULL, NULL, 0 },
1328 /* 0xfe */ { NULL, NULL, 0 },
1329 /* 0xff */ { NULL, NULL, 0 }
1333 /*******************************************************************
1334 allocate and initialize a reply packet
1335 ********************************************************************/
1337 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1338 const char *inbuf, char **outbuf, uint8_t num_words,
1339 uint32_t num_bytes)
1341 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1344 * Protect against integer wrap.
1345 * The SMB layer reply can be up to 0xFFFFFF bytes.
1347 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1348 char *msg;
1349 if (asprintf(&msg, "num_bytes too large: %u",
1350 (unsigned)num_bytes) == -1) {
1351 msg = discard_const_p(char, "num_bytes too large");
1353 smb_panic(msg);
1357 * Here we include the NBT header for now.
1359 *outbuf = talloc_array(mem_ctx, char,
1360 NBT_HDR_SIZE + smb_len);
1361 if (*outbuf == NULL) {
1362 return false;
1365 construct_reply_common(req, inbuf, *outbuf);
1366 srv_set_message(*outbuf, num_words, num_bytes, false);
1368 * Zero out the word area, the caller has to take care of the bcc area
1369 * himself
1371 if (num_words != 0) {
1372 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1375 return true;
1378 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1380 char *outbuf;
1381 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1382 num_bytes)) {
1383 smb_panic("could not allocate output buffer\n");
1385 req->outbuf = (uint8_t *)outbuf;
1389 /*******************************************************************
1390 Dump a packet to a file.
1391 ********************************************************************/
1393 static void smb_dump(const char *name, int type, const char *data)
1395 size_t len;
1396 int fd, i;
1397 char *fname = NULL;
1398 if (DEBUGLEVEL < 50) {
1399 return;
1402 len = smb_len_tcp(data)+4;
1403 for (i=1;i<100;i++) {
1404 fname = talloc_asprintf(talloc_tos(),
1405 "/tmp/%s.%d.%s",
1406 name,
1408 type ? "req" : "resp");
1409 if (fname == NULL) {
1410 return;
1412 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1413 if (fd != -1 || errno != EEXIST) break;
1414 TALLOC_FREE(fname);
1416 if (fd != -1) {
1417 ssize_t ret = write(fd, data, len);
1418 if (ret != len)
1419 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1420 close(fd);
1421 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1423 TALLOC_FREE(fname);
1426 /****************************************************************************
1427 Prepare everything for calling the actual request function, and potentially
1428 call the request function via the "new" interface.
1430 Return False if the "legacy" function needs to be called, everything is
1431 prepared.
1433 Return True if we're done.
1435 I know this API sucks, but it is the one with the least code change I could
1436 find.
1437 ****************************************************************************/
1439 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1441 int flags;
1442 uint64_t session_tag;
1443 connection_struct *conn = NULL;
1444 struct smbd_server_connection *sconn = req->sconn;
1445 NTTIME now = timeval_to_nttime(&req->request_time);
1446 struct smbXsrv_session *session = NULL;
1447 NTSTATUS status;
1449 errno = 0;
1451 if (smb_messages[type].fn == NULL) {
1452 DEBUG(0,("Unknown message type %d!\n",type));
1453 smb_dump("Unknown", 1, (const char *)req->inbuf);
1454 reply_unknown_new(req, type);
1455 return NULL;
1458 flags = smb_messages[type].flags;
1460 /* In share mode security we must ignore the vuid. */
1461 session_tag = req->vuid;
1462 conn = req->conn;
1464 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1465 (int)getpid(), (unsigned long)conn));
1467 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1469 /* Ensure this value is replaced in the incoming packet. */
1470 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1473 * Ensure the correct username is in current_user_info. This is a
1474 * really ugly bugfix for problems with multiple session_setup_and_X's
1475 * being done and allowing %U and %G substitutions to work correctly.
1476 * There is a reason this code is done here, don't move it unless you
1477 * know what you're doing... :-).
1478 * JRA.
1482 * lookup an existing session
1484 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1485 * here, the main check is still in change_to_user()
1487 status = smb1srv_session_lookup(sconn->conn,
1488 session_tag,
1489 now,
1490 &session);
1491 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1492 switch (type) {
1493 case SMBsesssetupX:
1494 status = NT_STATUS_OK;
1495 break;
1496 default:
1497 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1498 (unsigned long long)session_tag,
1499 (unsigned long long)req->mid));
1500 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1501 return conn;
1505 if (session_tag != sconn->conn->last_session_id) {
1506 struct user_struct *vuser = NULL;
1508 sconn->conn->last_session_id = session_tag;
1509 if (session) {
1510 vuser = session->compat;
1512 if (vuser) {
1513 set_current_user_info(
1514 vuser->session_info->unix_info->sanitized_username,
1515 vuser->session_info->unix_info->unix_name,
1516 vuser->session_info->info->domain_name);
1520 /* Does this call need to be run as the connected user? */
1521 if (flags & AS_USER) {
1523 /* Does this call need a valid tree connection? */
1524 if (!conn) {
1526 * Amazingly, the error code depends on the command
1527 * (from Samba4).
1529 if (type == SMBntcreateX) {
1530 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1531 } else {
1532 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1534 return NULL;
1537 if (!change_to_user(conn,session_tag)) {
1538 DEBUG(0, ("Error: Could not change to user. Removing "
1539 "deferred open, mid=%llu.\n",
1540 (unsigned long long)req->mid));
1541 reply_force_doserror(req, ERRSRV, ERRbaduid);
1542 return conn;
1545 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1547 /* Does it need write permission? */
1548 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1549 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1550 return conn;
1553 /* IPC services are limited */
1554 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1555 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1556 return conn;
1558 } else {
1559 /* This call needs to be run as root */
1560 change_to_root_user();
1563 /* load service specific parameters */
1564 if (conn) {
1565 if (req->encrypted) {
1566 conn->encrypted_tid = true;
1567 /* encrypted required from now on. */
1568 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1569 } else if (ENCRYPTION_REQUIRED(conn)) {
1570 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1571 DEBUG(1,("service[%s] requires encryption"
1572 "%s ACCESS_DENIED. mid=%llu\n",
1573 lp_servicename(talloc_tos(), SNUM(conn)),
1574 smb_fn_name(type),
1575 (unsigned long long)req->mid));
1576 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1577 return conn;
1581 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1582 (flags & (AS_USER|DO_CHDIR)
1583 ?True:False))) {
1584 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1585 return conn;
1587 conn->num_smb_operations++;
1591 * Does this protocol need to be run as guest? (Only archane
1592 * messenger service requests have this...)
1594 if (flags & AS_GUEST) {
1595 char *raddr;
1596 bool ok;
1598 if (!change_to_guest()) {
1599 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1600 return conn;
1603 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1604 talloc_tos());
1605 if (raddr == NULL) {
1606 reply_nterror(req, NT_STATUS_NO_MEMORY);
1607 return conn;
1611 * Haven't we checked this in smbd_process already???
1614 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1615 sconn->remote_hostname, raddr);
1616 TALLOC_FREE(raddr);
1618 if (!ok) {
1619 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1620 return conn;
1624 smb_messages[type].fn(req);
1625 return req->conn;
1628 /****************************************************************************
1629 Construct a reply to the incoming packet.
1630 ****************************************************************************/
1632 static void construct_reply(struct smbd_server_connection *sconn,
1633 char *inbuf, int size, size_t unread_bytes,
1634 uint32_t seqnum, bool encrypted,
1635 struct smb_perfcount_data *deferred_pcd)
1637 connection_struct *conn;
1638 struct smb_request *req;
1640 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1641 smb_panic("could not allocate smb_request");
1644 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1645 encrypted, seqnum)) {
1646 exit_server_cleanly("Invalid SMB request");
1649 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1651 /* we popped this message off the queue - keep original perf data */
1652 if (deferred_pcd)
1653 req->pcd = *deferred_pcd;
1654 else {
1655 SMB_PERFCOUNT_START(&req->pcd);
1656 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1657 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1660 conn = switch_message(req->cmd, req);
1662 if (req->outbuf == NULL) {
1663 return;
1666 if (CVAL(req->outbuf,0) == 0) {
1667 show_msg((char *)req->outbuf);
1670 if (!srv_send_smb(req->sconn,
1671 (char *)req->outbuf,
1672 true, req->seqnum+1,
1673 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1674 &req->pcd)) {
1675 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1678 TALLOC_FREE(req);
1680 return;
1683 static void construct_reply_chain(struct smbd_server_connection *sconn,
1684 char *inbuf, int size, uint32_t seqnum,
1685 bool encrypted,
1686 struct smb_perfcount_data *deferred_pcd)
1688 struct smb_request **reqs = NULL;
1689 struct smb_request *req;
1690 unsigned num_reqs;
1691 bool ok;
1693 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1694 seqnum, &reqs, &num_reqs);
1695 if (!ok) {
1696 char errbuf[smb_size];
1697 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1698 __LINE__, __FILE__);
1699 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1700 NULL)) {
1701 exit_server_cleanly("construct_reply_chain: "
1702 "srv_send_smb failed.");
1704 return;
1707 req = reqs[0];
1708 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1710 req->conn = switch_message(req->cmd, req);
1712 if (req->outbuf == NULL) {
1714 * Request has suspended itself, will come
1715 * back here.
1717 return;
1719 smb_request_done(req);
1723 * To be called from an async SMB handler that is potentially chained
1724 * when it is finished for shipping.
1727 void smb_request_done(struct smb_request *req)
1729 struct smb_request **reqs = NULL;
1730 struct smb_request *first_req;
1731 size_t i, num_reqs, next_index;
1732 NTSTATUS status;
1734 if (req->chain == NULL) {
1735 first_req = req;
1736 goto shipit;
1739 reqs = req->chain;
1740 num_reqs = talloc_array_length(reqs);
1742 for (i=0; i<num_reqs; i++) {
1743 if (reqs[i] == req) {
1744 break;
1747 if (i == num_reqs) {
1749 * Invalid chain, should not happen
1751 status = NT_STATUS_INTERNAL_ERROR;
1752 goto error;
1754 next_index = i+1;
1756 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1757 struct smb_request *next = reqs[next_index];
1758 struct smbXsrv_tcon *tcon;
1759 NTTIME now = timeval_to_nttime(&req->request_time);
1761 next->vuid = SVAL(req->outbuf, smb_uid);
1762 next->tid = SVAL(req->outbuf, smb_tid);
1763 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1764 now, &tcon);
1765 if (NT_STATUS_IS_OK(status)) {
1766 req->conn = tcon->compat;
1767 } else {
1768 req->conn = NULL;
1770 next->chain_fsp = req->chain_fsp;
1771 next->inbuf = req->inbuf;
1773 req = next;
1774 req->conn = switch_message(req->cmd, req);
1776 if (req->outbuf == NULL) {
1778 * Request has suspended itself, will come
1779 * back here.
1781 return;
1783 next_index += 1;
1786 first_req = reqs[0];
1788 for (i=1; i<next_index; i++) {
1789 bool ok;
1791 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1792 if (!ok) {
1793 status = NT_STATUS_INTERNAL_ERROR;
1794 goto error;
1798 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1799 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1802 * This scary statement intends to set the
1803 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1804 * to the value last_req->outbuf carries
1806 SSVAL(first_req->outbuf, smb_flg2,
1807 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1808 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1811 * Transfer the error codes from the subrequest to the main one
1813 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1814 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1816 _smb_setlen_large(
1817 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1819 shipit:
1820 if (!srv_send_smb(first_req->sconn,
1821 (char *)first_req->outbuf,
1822 true, first_req->seqnum+1,
1823 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1824 &first_req->pcd)) {
1825 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1826 "failed.");
1828 TALLOC_FREE(req); /* non-chained case */
1829 TALLOC_FREE(reqs); /* chained case */
1830 return;
1832 error:
1834 char errbuf[smb_size];
1835 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1836 if (!srv_send_smb(req->sconn, errbuf, true,
1837 req->seqnum+1, req->encrypted,
1838 NULL)) {
1839 exit_server_cleanly("construct_reply_chain: "
1840 "srv_send_smb failed.");
1843 TALLOC_FREE(req); /* non-chained case */
1844 TALLOC_FREE(reqs); /* chained case */
1847 /****************************************************************************
1848 Process an smb from the client
1849 ****************************************************************************/
1850 static void process_smb(struct smbd_server_connection *sconn,
1851 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1852 uint32_t seqnum, bool encrypted,
1853 struct smb_perfcount_data *deferred_pcd)
1855 int msg_type = CVAL(inbuf,0);
1857 DO_PROFILE_INC(smb_count);
1859 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1860 smb_len(inbuf) ) );
1861 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1862 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1864 if (msg_type != NBSSmessage) {
1866 * NetBIOS session request, keepalive, etc.
1868 reply_special(sconn, (char *)inbuf, nread);
1869 goto done;
1872 if (sconn->using_smb2) {
1873 /* At this point we're not really using smb2,
1874 * we make the decision here.. */
1875 if (smbd_is_smb2_header(inbuf, nread)) {
1876 smbd_smb2_first_negprot(sconn, inbuf, nread);
1877 return;
1878 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1879 && CVAL(inbuf, smb_com) != 0x72) {
1880 /* This is a non-negprot SMB1 packet.
1881 Disable SMB2 from now on. */
1882 sconn->using_smb2 = false;
1886 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1887 * so subtract 4 from it. */
1888 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1889 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1890 smb_len(inbuf)));
1892 /* special magic for immediate exit */
1893 if ((nread == 9) &&
1894 (IVAL(inbuf, 4) == 0x74697865) &&
1895 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1896 uint8_t exitcode = CVAL(inbuf, 8);
1897 DEBUG(1, ("Exiting immediately with code %d\n",
1898 (int)exitcode));
1899 exit(exitcode);
1902 exit_server_cleanly("Non-SMB packet");
1905 show_msg((char *)inbuf);
1907 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1908 construct_reply_chain(sconn, (char *)inbuf, nread,
1909 seqnum, encrypted, deferred_pcd);
1910 } else {
1911 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1912 seqnum, encrypted, deferred_pcd);
1915 sconn->trans_num++;
1917 done:
1918 sconn->num_requests++;
1920 /* The timeout_processing function isn't run nearly
1921 often enough to implement 'max log size' without
1922 overrunning the size of the file by many megabytes.
1923 This is especially true if we are running at debug
1924 level 10. Checking every 50 SMBs is a nice
1925 tradeoff of performance vs log file size overrun. */
1927 if ((sconn->num_requests % 50) == 0 &&
1928 need_to_check_log_size()) {
1929 change_to_root_user();
1930 check_log_size();
1934 /****************************************************************************
1935 Return a string containing the function name of a SMB command.
1936 ****************************************************************************/
1938 const char *smb_fn_name(int type)
1940 const char *unknown_name = "SMBunknown";
1942 if (smb_messages[type].name == NULL)
1943 return(unknown_name);
1945 return(smb_messages[type].name);
1948 /****************************************************************************
1949 Helper functions for contruct_reply.
1950 ****************************************************************************/
1952 void add_to_common_flags2(uint32 v)
1954 common_flags2 |= v;
1957 void remove_from_common_flags2(uint32 v)
1959 common_flags2 &= ~v;
1962 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1963 char *outbuf)
1965 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1966 uint16_t out_flags2 = common_flags2;
1968 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1969 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1970 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1972 srv_set_message(outbuf,0,0,false);
1974 SCVAL(outbuf, smb_com, req->cmd);
1975 SIVAL(outbuf,smb_rcls,0);
1976 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1977 SSVAL(outbuf,smb_flg2, out_flags2);
1978 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1979 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1981 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1982 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1983 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1984 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1987 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1989 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1993 * @brief Find the smb_cmd offset of the last command pushed
1994 * @param[in] buf The buffer we're building up
1995 * @retval Where can we put our next andx cmd?
1997 * While chaining requests, the "next" request we're looking at needs to put
1998 * its SMB_Command before the data the previous request already built up added
1999 * to the chain. Find the offset to the place where we have to put our cmd.
2002 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2004 uint8_t cmd;
2005 size_t ofs;
2007 cmd = CVAL(buf, smb_com);
2009 if (!is_andx_req(cmd)) {
2010 return false;
2013 ofs = smb_vwv0;
2015 while (CVAL(buf, ofs) != 0xff) {
2017 if (!is_andx_req(CVAL(buf, ofs))) {
2018 return false;
2022 * ofs is from start of smb header, so add the 4 length
2023 * bytes. The next cmd is right after the wct field.
2025 ofs = SVAL(buf, ofs+2) + 4 + 1;
2027 if (ofs+4 >= talloc_get_size(buf)) {
2028 return false;
2032 *pofs = ofs;
2033 return true;
2037 * @brief Do the smb chaining at a buffer level
2038 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2039 * @param[in] andx_buf Buffer to be appended
2042 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2044 uint8_t smb_command = CVAL(andx_buf, smb_com);
2045 uint8_t wct = CVAL(andx_buf, smb_wct);
2046 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2047 uint32_t num_bytes = smb_buflen(andx_buf);
2048 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2050 uint8_t *outbuf;
2051 size_t old_size, new_size;
2052 size_t ofs;
2053 size_t chain_padding = 0;
2054 size_t andx_cmd_ofs;
2057 old_size = talloc_get_size(*poutbuf);
2059 if ((old_size % 4) != 0) {
2061 * Align the wct field of subsequent requests to a 4-byte
2062 * boundary
2064 chain_padding = 4 - (old_size % 4);
2068 * After the old request comes the new wct field (1 byte), the vwv's
2069 * and the num_bytes field.
2072 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2073 new_size += num_bytes;
2075 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2076 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2077 (unsigned)new_size));
2078 return false;
2081 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2082 if (outbuf == NULL) {
2083 DEBUG(0, ("talloc failed\n"));
2084 return false;
2086 *poutbuf = outbuf;
2088 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2089 DEBUG(1, ("invalid command chain\n"));
2090 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2091 return false;
2094 if (chain_padding != 0) {
2095 memset(outbuf + old_size, 0, chain_padding);
2096 old_size += chain_padding;
2099 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2100 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2102 ofs = old_size;
2105 * Push the chained request:
2107 * wct field
2110 SCVAL(outbuf, ofs, wct);
2111 ofs += 1;
2114 * vwv array
2117 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2120 * HACK ALERT
2122 * Read&X has an offset into its data buffer at
2123 * vwv[6]. reply_read_andx has no idea anymore that it's
2124 * running from within a chain, so we have to fix up the
2125 * offset here.
2127 * Although it looks disgusting at this place, I want to keep
2128 * it here. The alternative would be to push knowledge about
2129 * the andx chain down into read&x again.
2132 if (smb_command == SMBreadX) {
2133 uint8_t *bytes_addr;
2135 if (wct < 7) {
2137 * Invalid read&x response
2139 return false;
2142 bytes_addr = outbuf + ofs /* vwv start */
2143 + sizeof(uint16_t) * wct /* vwv array */
2144 + sizeof(uint16_t); /* bcc */
2146 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2147 bytes_addr - outbuf - 4);
2150 ofs += sizeof(uint16_t) * wct;
2153 * bcc (byte count)
2156 SSVAL(outbuf, ofs, num_bytes);
2157 ofs += sizeof(uint16_t);
2160 * The bytes field
2163 memcpy(outbuf + ofs, bytes, num_bytes);
2165 return true;
2168 bool smb1_is_chain(const uint8_t *buf)
2170 uint8_t cmd, wct, andx_cmd;
2172 cmd = CVAL(buf, smb_com);
2173 if (!is_andx_req(cmd)) {
2174 return false;
2176 wct = CVAL(buf, smb_wct);
2177 if (wct < 2) {
2178 return false;
2180 andx_cmd = CVAL(buf, smb_vwv);
2181 return (andx_cmd != 0xFF);
2184 bool smb1_walk_chain(const uint8_t *buf,
2185 bool (*fn)(uint8_t cmd,
2186 uint8_t wct, const uint16_t *vwv,
2187 uint16_t num_bytes, const uint8_t *bytes,
2188 void *private_data),
2189 void *private_data)
2191 size_t smblen = smb_len(buf);
2192 const char *smb_buf = smb_base(buf);
2193 uint8_t cmd, chain_cmd;
2194 uint8_t wct;
2195 const uint16_t *vwv;
2196 uint16_t num_bytes;
2197 const uint8_t *bytes;
2199 cmd = CVAL(buf, smb_com);
2200 wct = CVAL(buf, smb_wct);
2201 vwv = (const uint16_t *)(buf + smb_vwv);
2202 num_bytes = smb_buflen(buf);
2203 bytes = (const uint8_t *)smb_buf_const(buf);
2205 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2206 return false;
2209 if (!is_andx_req(cmd)) {
2210 return true;
2212 if (wct < 2) {
2213 return false;
2216 chain_cmd = CVAL(vwv, 0);
2218 while (chain_cmd != 0xff) {
2219 uint32_t chain_offset; /* uint32_t to avoid overflow */
2220 size_t length_needed;
2221 ptrdiff_t vwv_offset;
2223 chain_offset = SVAL(vwv+1, 0);
2226 * Check if the client tries to fool us. The chain
2227 * offset needs to point beyond the current request in
2228 * the chain, it needs to strictly grow. Otherwise we
2229 * might be tricked into an endless loop always
2230 * processing the same request over and over again. We
2231 * used to assume that vwv and the byte buffer array
2232 * in a chain are always attached, but OS/2 the
2233 * Write&X/Read&X chain puts the Read&X vwv array
2234 * right behind the Write&X vwv chain. The Write&X bcc
2235 * array is put behind the Read&X vwv array. So now we
2236 * check whether the chain offset points strictly
2237 * behind the previous vwv array. req->buf points
2238 * right after the vwv array of the previous
2239 * request. See
2240 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2241 * more information.
2244 vwv_offset = ((const char *)vwv - smb_buf);
2245 if (chain_offset <= vwv_offset) {
2246 return false;
2250 * Next check: Make sure the chain offset does not
2251 * point beyond the overall smb request length.
2254 length_needed = chain_offset+1; /* wct */
2255 if (length_needed > smblen) {
2256 return false;
2260 * Now comes the pointer magic. Goal here is to set up
2261 * vwv and buf correctly again. The chain offset (the
2262 * former vwv[1]) points at the new wct field.
2265 wct = CVAL(smb_buf, chain_offset);
2267 if (is_andx_req(chain_cmd) && (wct < 2)) {
2268 return false;
2272 * Next consistency check: Make the new vwv array fits
2273 * in the overall smb request.
2276 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2277 if (length_needed > smblen) {
2278 return false;
2280 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2283 * Now grab the new byte buffer....
2286 num_bytes = SVAL(vwv+wct, 0);
2289 * .. and check that it fits.
2292 length_needed += num_bytes;
2293 if (length_needed > smblen) {
2294 return false;
2296 bytes = (const uint8_t *)(vwv+wct+1);
2298 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2299 return false;
2302 if (!is_andx_req(chain_cmd)) {
2303 return true;
2305 chain_cmd = CVAL(vwv, 0);
2307 return true;
2310 static bool smb1_chain_length_cb(uint8_t cmd,
2311 uint8_t wct, const uint16_t *vwv,
2312 uint16_t num_bytes, const uint8_t *bytes,
2313 void *private_data)
2315 unsigned *count = (unsigned *)private_data;
2316 *count += 1;
2317 return true;
2320 unsigned smb1_chain_length(const uint8_t *buf)
2322 unsigned count = 0;
2324 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2325 return 0;
2327 return count;
2330 struct smb1_parse_chain_state {
2331 TALLOC_CTX *mem_ctx;
2332 const uint8_t *buf;
2333 struct smbd_server_connection *sconn;
2334 bool encrypted;
2335 uint32_t seqnum;
2337 struct smb_request **reqs;
2338 unsigned num_reqs;
2341 static bool smb1_parse_chain_cb(uint8_t cmd,
2342 uint8_t wct, const uint16_t *vwv,
2343 uint16_t num_bytes, const uint8_t *bytes,
2344 void *private_data)
2346 struct smb1_parse_chain_state *state =
2347 (struct smb1_parse_chain_state *)private_data;
2348 struct smb_request **reqs;
2349 struct smb_request *req;
2350 bool ok;
2352 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2353 struct smb_request *, state->num_reqs+1);
2354 if (reqs == NULL) {
2355 return false;
2357 state->reqs = reqs;
2359 req = talloc(reqs, struct smb_request);
2360 if (req == NULL) {
2361 return false;
2364 ok = init_smb_request(req, state->sconn, state->buf, 0,
2365 state->encrypted, state->seqnum);
2366 if (!ok) {
2367 return false;
2369 req->cmd = cmd;
2370 req->wct = wct;
2371 req->vwv = vwv;
2372 req->buflen = num_bytes;
2373 req->buf = bytes;
2375 reqs[state->num_reqs] = req;
2376 state->num_reqs += 1;
2377 return true;
2380 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2381 struct smbd_server_connection *sconn,
2382 bool encrypted, uint32_t seqnum,
2383 struct smb_request ***reqs, unsigned *num_reqs)
2385 struct smb1_parse_chain_state state;
2386 unsigned i;
2388 state.mem_ctx = mem_ctx;
2389 state.buf = buf;
2390 state.sconn = sconn;
2391 state.encrypted = encrypted;
2392 state.seqnum = seqnum;
2393 state.reqs = NULL;
2394 state.num_reqs = 0;
2396 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2397 TALLOC_FREE(state.reqs);
2398 return false;
2400 for (i=0; i<state.num_reqs; i++) {
2401 state.reqs[i]->chain = state.reqs;
2403 *reqs = state.reqs;
2404 *num_reqs = state.num_reqs;
2405 return true;
2408 /****************************************************************************
2409 Check if services need reloading.
2410 ****************************************************************************/
2412 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2415 if (last_smb_conf_reload_time == 0) {
2416 last_smb_conf_reload_time = t;
2419 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2420 reload_services(sconn, conn_snum_used, true);
2421 last_smb_conf_reload_time = t;
2425 static bool fd_is_readable(int fd)
2427 int ret, revents;
2429 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2431 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2435 static void smbd_server_connection_write_handler(
2436 struct smbd_server_connection *sconn)
2438 /* TODO: make write nonblocking */
2441 static void smbd_server_connection_read_handler(
2442 struct smbd_server_connection *sconn, int fd)
2444 uint8_t *inbuf = NULL;
2445 size_t inbuf_len = 0;
2446 size_t unread_bytes = 0;
2447 bool encrypted = false;
2448 TALLOC_CTX *mem_ctx = talloc_tos();
2449 NTSTATUS status;
2450 uint32_t seqnum;
2452 bool async_echo = lp_async_smb_echo_handler();
2453 bool from_client = false;
2455 if (async_echo) {
2456 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2458 * This is the super-ugly hack to prefer the packets
2459 * forwarded by the echo handler over the ones by the
2460 * client directly
2462 fd = sconn->smb1.echo_handler.trusted_fd;
2466 from_client = (sconn->sock == fd);
2468 if (async_echo && from_client) {
2469 smbd_lock_socket(sconn);
2471 if (!fd_is_readable(fd)) {
2472 DEBUG(10,("the echo listener was faster\n"));
2473 smbd_unlock_socket(sconn);
2474 return;
2478 /* TODO: make this completely nonblocking */
2479 status = receive_smb_talloc(mem_ctx, sconn, fd,
2480 (char **)(void *)&inbuf,
2481 0, /* timeout */
2482 &unread_bytes,
2483 &encrypted,
2484 &inbuf_len, &seqnum,
2485 !from_client /* trusted channel */);
2487 if (async_echo && from_client) {
2488 smbd_unlock_socket(sconn);
2491 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2492 goto process;
2494 if (NT_STATUS_IS_ERR(status)) {
2495 exit_server_cleanly("failed to receive smb request");
2497 if (!NT_STATUS_IS_OK(status)) {
2498 return;
2501 process:
2502 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2503 seqnum, encrypted, NULL);
2506 static void smbd_server_connection_handler(struct tevent_context *ev,
2507 struct tevent_fd *fde,
2508 uint16_t flags,
2509 void *private_data)
2511 struct smbd_server_connection *conn = talloc_get_type(private_data,
2512 struct smbd_server_connection);
2514 if (!NT_STATUS_IS_OK(conn->status)) {
2516 * we're not supposed to do any io
2518 TEVENT_FD_NOT_READABLE(conn->smb1.fde);
2519 TEVENT_FD_NOT_WRITEABLE(conn->smb1.fde);
2520 return;
2523 if (flags & TEVENT_FD_WRITE) {
2524 smbd_server_connection_write_handler(conn);
2525 return;
2527 if (flags & TEVENT_FD_READ) {
2528 smbd_server_connection_read_handler(conn, conn->sock);
2529 return;
2533 static void smbd_server_echo_handler(struct tevent_context *ev,
2534 struct tevent_fd *fde,
2535 uint16_t flags,
2536 void *private_data)
2538 struct smbd_server_connection *conn = talloc_get_type(private_data,
2539 struct smbd_server_connection);
2541 if (!NT_STATUS_IS_OK(conn->status)) {
2543 * we're not supposed to do any io
2545 TEVENT_FD_NOT_READABLE(conn->smb1.echo_handler.trusted_fde);
2546 TEVENT_FD_NOT_WRITEABLE(conn->smb1.echo_handler.trusted_fde);
2547 return;
2550 if (flags & TEVENT_FD_WRITE) {
2551 smbd_server_connection_write_handler(conn);
2552 return;
2554 if (flags & TEVENT_FD_READ) {
2555 smbd_server_connection_read_handler(
2556 conn, conn->smb1.echo_handler.trusted_fd);
2557 return;
2561 struct smbd_release_ip_state {
2562 struct smbd_server_connection *sconn;
2563 struct tevent_immediate *im;
2564 char addr[INET6_ADDRSTRLEN];
2567 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2568 struct tevent_immediate *im,
2569 void *private_data)
2571 struct smbd_release_ip_state *state =
2572 talloc_get_type_abort(private_data,
2573 struct smbd_release_ip_state);
2575 if (!NT_STATUS_EQUAL(state->sconn->status, NT_STATUS_ADDRESS_CLOSED)) {
2577 * smbd_server_connection_terminate() already triggered ?
2579 return;
2582 smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
2585 /****************************************************************************
2586 received when we should release a specific IP
2587 ****************************************************************************/
2588 static bool release_ip(const char *ip, void *priv)
2590 struct smbd_release_ip_state *state =
2591 talloc_get_type_abort(priv,
2592 struct smbd_release_ip_state);
2593 const char *addr = state->addr;
2594 const char *p = addr;
2596 if (!NT_STATUS_IS_OK(state->sconn->status)) {
2597 /* avoid recursion */
2598 return false;
2601 if (strncmp("::ffff:", addr, 7) == 0) {
2602 p = addr + 7;
2605 DEBUG(10, ("Got release IP message for %s, "
2606 "our address is %s\n", ip, p));
2608 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2609 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2610 ip));
2612 * With SMB2 we should do a clean disconnect,
2613 * the previous_session_id in the session setup
2614 * will cleanup the old session, tcons and opens.
2616 * A clean disconnect is needed in order to support
2617 * durable handles.
2619 * Note: typically this is never triggered
2620 * as we got a TCP RST (triggered by ctdb event scripts)
2621 * before we get CTDB_SRVID_RELEASE_IP.
2623 * We used to call _exit(1) here, but as this was mostly never
2624 * triggered and has implication on our process model,
2625 * we can just use smbd_server_connection_terminate()
2626 * (also for SMB1).
2628 * We don't call smbd_server_connection_terminate() directly
2629 * as we might be called from within ctdbd_migrate(),
2630 * we need to defer our action to the next event loop
2632 tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
2633 smbd_release_ip_immediate, state);
2636 * Make sure we don't get any io on the connection.
2638 state->sconn->status = NT_STATUS_ADDRESS_CLOSED;
2639 return true;
2642 return false;
2645 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2646 struct sockaddr_storage *srv,
2647 struct sockaddr_storage *clnt)
2649 struct smbd_release_ip_state *state;
2650 struct ctdbd_connection *cconn;
2652 cconn = messaging_ctdbd_connection();
2653 if (cconn == NULL) {
2654 return NT_STATUS_NO_MEMORY;
2657 state = talloc_zero(sconn, struct smbd_release_ip_state);
2658 if (state == NULL) {
2659 return NT_STATUS_NO_MEMORY;
2661 state->sconn = sconn;
2662 state->im = tevent_create_immediate(state);
2663 if (state->im == NULL) {
2664 return NT_STATUS_NO_MEMORY;
2666 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2667 return NT_STATUS_NO_MEMORY;
2670 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2673 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2674 struct sockaddr_storage *client)
2676 socklen_t length;
2677 length = sizeof(*server);
2678 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2679 return -1;
2681 length = sizeof(*client);
2682 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2683 return -1;
2685 return 0;
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 bool ret;
2723 if (sconn->using_smb2) {
2724 /* Don't do keepalives on an SMB2 connection. */
2725 return false;
2728 smbd_lock_socket(sconn);
2729 ret = send_keepalive(sconn->sock);
2730 smbd_unlock_socket(sconn);
2732 if (!ret) {
2733 char addr[INET6_ADDRSTRLEN];
2735 * Try and give an error message saying what
2736 * client failed.
2738 DEBUG(0, ("send_keepalive failed for client %s. "
2739 "Error %s - exiting\n",
2740 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2741 strerror(errno)));
2742 return False;
2744 return True;
2748 * Do the recurring check if we're idle
2750 static bool deadtime_fn(const struct timeval *now, void *private_data)
2752 struct smbd_server_connection *sconn =
2753 (struct smbd_server_connection *)private_data;
2755 if ((conn_num_open(sconn) == 0)
2756 || (conn_idle_all(sconn, now->tv_sec))) {
2757 DEBUG( 2, ( "Closing idle connection\n" ) );
2758 messaging_send(sconn->msg_ctx,
2759 messaging_server_id(sconn->msg_ctx),
2760 MSG_SHUTDOWN, &data_blob_null);
2761 return False;
2764 return True;
2768 * Do the recurring log file and smb.conf reload checks.
2771 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2773 struct smbd_server_connection *sconn = talloc_get_type_abort(
2774 private_data, struct smbd_server_connection);
2776 DEBUG(5, ("housekeeping\n"));
2778 change_to_root_user();
2780 /* update printer queue caches if necessary */
2781 update_monitored_printq_cache(sconn->msg_ctx);
2783 /* check if we need to reload services */
2784 check_reload(sconn, time_mono(NULL));
2787 * Force a log file check.
2789 force_check_log_size();
2790 check_log_size();
2791 return true;
2795 * Read an smb packet in the echo handler child, giving the parent
2796 * smbd one second to react once the socket becomes readable.
2799 struct smbd_echo_read_state {
2800 struct tevent_context *ev;
2801 struct smbd_server_connection *sconn;
2803 char *buf;
2804 size_t buflen;
2805 uint32_t seqnum;
2808 static void smbd_echo_read_readable(struct tevent_req *subreq);
2809 static void smbd_echo_read_waited(struct tevent_req *subreq);
2811 static struct tevent_req *smbd_echo_read_send(
2812 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2813 struct smbd_server_connection *sconn)
2815 struct tevent_req *req, *subreq;
2816 struct smbd_echo_read_state *state;
2818 req = tevent_req_create(mem_ctx, &state,
2819 struct smbd_echo_read_state);
2820 if (req == NULL) {
2821 return NULL;
2823 state->ev = ev;
2824 state->sconn = sconn;
2826 subreq = wait_for_read_send(state, ev, sconn->sock);
2827 if (tevent_req_nomem(subreq, req)) {
2828 return tevent_req_post(req, ev);
2830 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2831 return req;
2834 static void smbd_echo_read_readable(struct tevent_req *subreq)
2836 struct tevent_req *req = tevent_req_callback_data(
2837 subreq, struct tevent_req);
2838 struct smbd_echo_read_state *state = tevent_req_data(
2839 req, struct smbd_echo_read_state);
2840 bool ok;
2841 int err;
2843 ok = wait_for_read_recv(subreq, &err);
2844 TALLOC_FREE(subreq);
2845 if (!ok) {
2846 tevent_req_nterror(req, map_nt_error_from_unix(err));
2847 return;
2851 * Give the parent smbd one second to step in
2854 subreq = tevent_wakeup_send(
2855 state, state->ev, timeval_current_ofs(1, 0));
2856 if (tevent_req_nomem(subreq, req)) {
2857 return;
2859 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2862 static void smbd_echo_read_waited(struct tevent_req *subreq)
2864 struct tevent_req *req = tevent_req_callback_data(
2865 subreq, struct tevent_req);
2866 struct smbd_echo_read_state *state = tevent_req_data(
2867 req, struct smbd_echo_read_state);
2868 struct smbd_server_connection *sconn = state->sconn;
2869 bool ok;
2870 NTSTATUS status;
2871 size_t unread = 0;
2872 bool encrypted;
2874 ok = tevent_wakeup_recv(subreq);
2875 TALLOC_FREE(subreq);
2876 if (!ok) {
2877 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2878 return;
2881 ok = smbd_lock_socket_internal(sconn);
2882 if (!ok) {
2883 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2884 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2885 return;
2888 if (!fd_is_readable(sconn->sock)) {
2889 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2890 (int)getpid()));
2892 ok = smbd_unlock_socket_internal(sconn);
2893 if (!ok) {
2894 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2895 DEBUG(1, ("%s: failed to unlock socket\n",
2896 __location__));
2897 return;
2900 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2901 if (tevent_req_nomem(subreq, req)) {
2902 return;
2904 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2905 return;
2908 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2909 0 /* timeout */,
2910 &unread,
2911 &encrypted,
2912 &state->buflen,
2913 &state->seqnum,
2914 false /* trusted_channel*/);
2916 if (tevent_req_nterror(req, status)) {
2917 tevent_req_nterror(req, status);
2918 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2919 (int)getpid(), nt_errstr(status)));
2920 return;
2923 ok = smbd_unlock_socket_internal(sconn);
2924 if (!ok) {
2925 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2926 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2927 return;
2929 tevent_req_done(req);
2932 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2933 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2935 struct smbd_echo_read_state *state = tevent_req_data(
2936 req, struct smbd_echo_read_state);
2937 NTSTATUS status;
2939 if (tevent_req_is_nterror(req, &status)) {
2940 return status;
2942 *pbuf = talloc_move(mem_ctx, &state->buf);
2943 *pbuflen = state->buflen;
2944 *pseqnum = state->seqnum;
2945 return NT_STATUS_OK;
2948 struct smbd_echo_state {
2949 struct tevent_context *ev;
2950 struct iovec *pending;
2951 struct smbd_server_connection *sconn;
2952 int parent_pipe;
2954 struct tevent_fd *parent_fde;
2956 struct tevent_req *write_req;
2959 static void smbd_echo_writer_done(struct tevent_req *req);
2961 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2963 int num_pending;
2965 if (state->write_req != NULL) {
2966 return;
2969 num_pending = talloc_array_length(state->pending);
2970 if (num_pending == 0) {
2971 return;
2974 state->write_req = writev_send(state, state->ev, NULL,
2975 state->parent_pipe, false,
2976 state->pending, num_pending);
2977 if (state->write_req == NULL) {
2978 DEBUG(1, ("writev_send failed\n"));
2979 exit(1);
2982 talloc_steal(state->write_req, state->pending);
2983 state->pending = NULL;
2985 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2986 state);
2989 static void smbd_echo_writer_done(struct tevent_req *req)
2991 struct smbd_echo_state *state = tevent_req_callback_data(
2992 req, struct smbd_echo_state);
2993 ssize_t written;
2994 int err;
2996 written = writev_recv(req, &err);
2997 TALLOC_FREE(req);
2998 state->write_req = NULL;
2999 if (written == -1) {
3000 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3001 exit(1);
3003 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3004 smbd_echo_activate_writer(state);
3007 static bool smbd_echo_reply(struct smbd_echo_state *state,
3008 uint8_t *inbuf, size_t inbuf_len,
3009 uint32_t seqnum)
3011 struct smb_request req;
3012 uint16_t num_replies;
3013 char *outbuf;
3014 bool ok;
3016 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3017 DEBUG(10, ("Got netbios keepalive\n"));
3019 * Just swallow it
3021 return true;
3024 if (inbuf_len < smb_size) {
3025 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3026 return false;
3028 if (!valid_smb_header(state->sconn, inbuf)) {
3029 DEBUG(10, ("Got invalid SMB header\n"));
3030 return false;
3033 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
3034 seqnum)) {
3035 return false;
3037 req.inbuf = inbuf;
3039 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3040 smb_messages[req.cmd].name
3041 ? smb_messages[req.cmd].name : "unknown"));
3043 if (req.cmd != SMBecho) {
3044 return false;
3046 if (req.wct < 1) {
3047 return false;
3050 num_replies = SVAL(req.vwv+0, 0);
3051 if (num_replies != 1) {
3052 /* Not a Windows "Hey, you're still there?" request */
3053 return false;
3056 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3057 1, req.buflen)) {
3058 DEBUG(10, ("create_outbuf failed\n"));
3059 return false;
3061 req.outbuf = (uint8_t *)outbuf;
3063 SSVAL(req.outbuf, smb_vwv0, num_replies);
3065 if (req.buflen > 0) {
3066 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3069 ok = srv_send_smb(req.sconn,
3070 (char *)outbuf,
3071 true, seqnum+1,
3072 false, &req.pcd);
3073 TALLOC_FREE(outbuf);
3074 if (!ok) {
3075 exit(1);
3078 return true;
3081 static void smbd_echo_exit(struct tevent_context *ev,
3082 struct tevent_fd *fde, uint16_t flags,
3083 void *private_data)
3085 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3086 exit(0);
3089 static void smbd_echo_got_packet(struct tevent_req *req);
3091 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3092 int parent_pipe)
3094 struct smbd_echo_state *state;
3095 struct tevent_req *read_req;
3097 state = talloc_zero(sconn, struct smbd_echo_state);
3098 if (state == NULL) {
3099 DEBUG(1, ("talloc failed\n"));
3100 return;
3102 state->sconn = sconn;
3103 state->parent_pipe = parent_pipe;
3104 state->ev = s3_tevent_context_init(state);
3105 if (state->ev == NULL) {
3106 DEBUG(1, ("tevent_context_init failed\n"));
3107 TALLOC_FREE(state);
3108 return;
3110 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3111 TEVENT_FD_READ, smbd_echo_exit,
3112 state);
3113 if (state->parent_fde == NULL) {
3114 DEBUG(1, ("tevent_add_fd failed\n"));
3115 TALLOC_FREE(state);
3116 return;
3119 read_req = smbd_echo_read_send(state, state->ev, sconn);
3120 if (read_req == NULL) {
3121 DEBUG(1, ("smbd_echo_read_send failed\n"));
3122 TALLOC_FREE(state);
3123 return;
3125 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3127 while (true) {
3128 if (tevent_loop_once(state->ev) == -1) {
3129 DEBUG(1, ("tevent_loop_once failed: %s\n",
3130 strerror(errno)));
3131 break;
3134 TALLOC_FREE(state);
3137 static void smbd_echo_got_packet(struct tevent_req *req)
3139 struct smbd_echo_state *state = tevent_req_callback_data(
3140 req, struct smbd_echo_state);
3141 NTSTATUS status;
3142 char *buf = NULL;
3143 size_t buflen = 0;
3144 uint32_t seqnum = 0;
3145 bool reply;
3147 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3148 TALLOC_FREE(req);
3149 if (!NT_STATUS_IS_OK(status)) {
3150 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3151 nt_errstr(status)));
3152 exit(1);
3155 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3156 if (!reply) {
3157 size_t num_pending;
3158 struct iovec *tmp;
3159 struct iovec *iov;
3161 num_pending = talloc_array_length(state->pending);
3162 tmp = talloc_realloc(state, state->pending, struct iovec,
3163 num_pending+1);
3164 if (tmp == NULL) {
3165 DEBUG(1, ("talloc_realloc failed\n"));
3166 exit(1);
3168 state->pending = tmp;
3170 if (buflen >= smb_size) {
3172 * place the seqnum in the packet so that the main process
3173 * can reply with signing
3175 SIVAL(buf, smb_ss_field, seqnum);
3176 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3179 iov = &state->pending[num_pending];
3180 iov->iov_base = talloc_move(state->pending, &buf);
3181 iov->iov_len = buflen;
3183 DEBUG(10,("echo_handler[%d]: forward to main\n",
3184 (int)getpid()));
3185 smbd_echo_activate_writer(state);
3188 req = smbd_echo_read_send(state, state->ev, state->sconn);
3189 if (req == NULL) {
3190 DEBUG(1, ("smbd_echo_read_send failed\n"));
3191 exit(1);
3193 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3198 * Handle SMBecho requests in a forked child process
3200 bool fork_echo_handler(struct smbd_server_connection *sconn)
3202 int listener_pipe[2];
3203 int res;
3204 pid_t child;
3205 bool use_mutex = false;
3207 res = pipe(listener_pipe);
3208 if (res == -1) {
3209 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3210 return false;
3213 #ifdef HAVE_ROBUST_MUTEXES
3214 use_mutex = tdb_runtime_check_for_robust_mutexes();
3216 if (use_mutex) {
3217 pthread_mutexattr_t a;
3219 sconn->smb1.echo_handler.socket_mutex =
3220 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3221 if (sconn->smb1.echo_handler.socket_mutex == NULL) {
3222 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3223 strerror(errno)));
3224 goto fail;
3227 res = pthread_mutexattr_init(&a);
3228 if (res != 0) {
3229 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3230 strerror(res)));
3231 goto fail;
3233 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3234 if (res != 0) {
3235 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3236 strerror(res)));
3237 pthread_mutexattr_destroy(&a);
3238 goto fail;
3240 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3241 if (res != 0) {
3242 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3243 strerror(res)));
3244 pthread_mutexattr_destroy(&a);
3245 goto fail;
3247 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3248 if (res != 0) {
3249 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3250 "%s\n", strerror(res)));
3251 pthread_mutexattr_destroy(&a);
3252 goto fail;
3254 res = pthread_mutex_init(sconn->smb1.echo_handler.socket_mutex,
3255 &a);
3256 pthread_mutexattr_destroy(&a);
3257 if (res != 0) {
3258 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3259 strerror(res)));
3260 goto fail;
3263 #endif
3265 if (!use_mutex) {
3266 sconn->smb1.echo_handler.socket_lock_fd =
3267 create_unlink_tmp(lp_lock_directory());
3268 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3269 DEBUG(1, ("Could not create lock fd: %s\n",
3270 strerror(errno)));
3271 goto fail;
3275 child = fork();
3276 if (child == 0) {
3277 NTSTATUS status;
3279 close(listener_pipe[0]);
3280 set_blocking(listener_pipe[1], false);
3282 status = reinit_after_fork(sconn->msg_ctx,
3283 sconn->ev_ctx,
3284 true);
3285 if (!NT_STATUS_IS_OK(status)) {
3286 DEBUG(1, ("reinit_after_fork failed: %s\n",
3287 nt_errstr(status)));
3288 exit(1);
3290 smbd_echo_loop(sconn, listener_pipe[1]);
3291 exit(0);
3293 close(listener_pipe[1]);
3294 listener_pipe[1] = -1;
3295 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3297 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3300 * Without smb signing this is the same as the normal smbd
3301 * listener. This needs to change once signing comes in.
3303 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3304 sconn,
3305 sconn->smb1.echo_handler.trusted_fd,
3306 TEVENT_FD_READ,
3307 smbd_server_echo_handler,
3308 sconn);
3309 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3310 DEBUG(1, ("event_add_fd failed\n"));
3311 goto fail;
3314 return true;
3316 fail:
3317 if (listener_pipe[0] != -1) {
3318 close(listener_pipe[0]);
3320 if (listener_pipe[1] != -1) {
3321 close(listener_pipe[1]);
3323 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3324 close(sconn->smb1.echo_handler.socket_lock_fd);
3327 #ifdef HAVE_ROBUST_MUTEXES
3328 if (sconn->smb1.echo_handler.socket_mutex != NULL) {
3329 pthread_mutex_destroy(sconn->smb1.echo_handler.socket_mutex);
3330 anonymous_shared_free(sconn->smb1.echo_handler.socket_mutex);
3332 #endif
3333 smbd_echo_init(sconn);
3335 return false;
3338 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3340 while (user) {
3341 if (user->session_info &&
3342 (user->session_info->unix_token->uid == uid)) {
3343 return true;
3345 user = user->next;
3347 return false;
3350 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3352 while (user) {
3353 if (user->session_info != NULL) {
3354 int i;
3355 struct security_unix_token *utok;
3357 utok = user->session_info->unix_token;
3358 if (utok->gid == gid) {
3359 return true;
3361 for(i=0; i<utok->ngroups; i++) {
3362 if (utok->groups[i] == gid) {
3363 return true;
3367 user = user->next;
3369 return false;
3372 static bool sid_in_use(const struct user_struct *user,
3373 const struct dom_sid *psid)
3375 while (user) {
3376 struct security_token *tok;
3378 if (user->session_info == NULL) {
3379 continue;
3381 tok = user->session_info->security_token;
3382 if (tok == NULL) {
3384 * Not sure session_info->security_token can
3385 * ever be NULL. This check might be not
3386 * necessary.
3388 continue;
3390 if (security_token_has_sid(tok, psid)) {
3391 return true;
3393 user = user->next;
3395 return false;
3398 static bool id_in_use(const struct user_struct *user,
3399 const struct id_cache_ref *id)
3401 switch(id->type) {
3402 case UID:
3403 return uid_in_use(user, id->id.uid);
3404 case GID:
3405 return gid_in_use(user, id->id.gid);
3406 case SID:
3407 return sid_in_use(user, &id->id.sid);
3408 default:
3409 break;
3411 return false;
3414 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3415 void *private_data,
3416 uint32_t msg_type,
3417 struct server_id server_id,
3418 DATA_BLOB* data)
3420 const char *msg = (data && data->data)
3421 ? (const char *)data->data : "<NULL>";
3422 struct id_cache_ref id;
3423 struct smbd_server_connection *sconn =
3424 talloc_get_type_abort(private_data,
3425 struct smbd_server_connection);
3427 if (!id_cache_ref_parse(msg, &id)) {
3428 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3429 return;
3432 if (id_in_use(sconn->users, &id)) {
3433 exit_server_cleanly(msg);
3435 id_cache_delete_from_cache(&id);
3438 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3439 enum protocol_types protocol)
3441 NTSTATUS status;
3443 set_Protocol(protocol);
3444 conn->protocol = protocol;
3446 if (protocol >= PROTOCOL_SMB2_02) {
3447 status = smb2srv_session_table_init(conn);
3448 if (!NT_STATUS_IS_OK(status)) {
3449 return status;
3452 status = smb2srv_open_table_init(conn);
3453 if (!NT_STATUS_IS_OK(status)) {
3454 return status;
3456 } else {
3457 status = smb1srv_session_table_init(conn);
3458 if (!NT_STATUS_IS_OK(status)) {
3459 return status;
3462 status = smb1srv_tcon_table_init(conn);
3463 if (!NT_STATUS_IS_OK(status)) {
3464 return status;
3467 status = smb1srv_open_table_init(conn);
3468 if (!NT_STATUS_IS_OK(status)) {
3469 return status;
3473 return NT_STATUS_OK;
3476 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3477 void *private_data)
3479 struct smbXsrv_connection *conn =
3480 talloc_get_type_abort(private_data,
3481 struct smbXsrv_connection);
3483 switch (point) {
3484 case TEVENT_TRACE_BEFORE_WAIT:
3486 * This just removes compiler warning
3487 * without profile support
3489 conn->smbd_idle_profstamp = 0;
3490 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3491 break;
3492 case TEVENT_TRACE_AFTER_WAIT:
3493 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3494 break;
3495 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3496 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3497 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3498 break;
3499 #endif
3503 /****************************************************************************
3504 Process commands from the client
3505 ****************************************************************************/
3507 void smbd_process(struct tevent_context *ev_ctx,
3508 struct messaging_context *msg_ctx,
3509 int sock_fd,
3510 bool interactive)
3512 TALLOC_CTX *frame = talloc_stackframe();
3513 struct smbXsrv_connection *conn;
3514 struct smbd_server_connection *sconn;
3515 struct sockaddr_storage ss;
3516 struct sockaddr *sa = NULL;
3517 socklen_t sa_socklen;
3518 struct tsocket_address *local_address = NULL;
3519 struct tsocket_address *remote_address = NULL;
3520 const char *locaddr = NULL;
3521 const char *remaddr = NULL;
3522 char *rhost;
3523 int ret;
3524 int tmp;
3526 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3527 if (conn == NULL) {
3528 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3529 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3532 conn->ev_ctx = ev_ctx;
3533 conn->msg_ctx = msg_ctx;
3535 sconn = talloc_zero(conn, struct smbd_server_connection);
3536 if (!sconn) {
3537 exit_server("failed to create smbd_server_connection");
3540 conn->sconn = sconn;
3541 sconn->conn = conn;
3544 * TODO: remove this...:-)
3546 global_smbXsrv_connection = conn;
3548 sconn->ev_ctx = ev_ctx;
3549 sconn->msg_ctx = msg_ctx;
3550 sconn->sock = sock_fd;
3551 smbd_echo_init(sconn);
3553 if (!interactive) {
3554 smbd_setup_sig_term_handler(sconn);
3555 smbd_setup_sig_hup_handler(sconn);
3557 if (!serverid_register(messaging_server_id(msg_ctx),
3558 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3559 |FLAG_MSG_DBWRAP
3560 |FLAG_MSG_PRINT_GENERAL)) {
3561 exit_server_cleanly("Could not register myself in "
3562 "serverid.tdb");
3566 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3568 * We're not making the decision here,
3569 * we're just allowing the client
3570 * to decide between SMB1 and SMB2
3571 * with the first negprot
3572 * packet.
3574 sconn->using_smb2 = true;
3577 /* Ensure child is set to blocking mode */
3578 set_blocking(sconn->sock,True);
3580 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3581 set_socket_options(sconn->sock, lp_socket_options());
3583 sa = (struct sockaddr *)(void *)&ss;
3584 sa_socklen = sizeof(ss);
3585 ret = getpeername(sconn->sock, sa, &sa_socklen);
3586 if (ret != 0) {
3587 int level = (errno == ENOTCONN)?2:0;
3588 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3589 exit_server_cleanly("getpeername() failed.\n");
3591 ret = tsocket_address_bsd_from_sockaddr(sconn,
3592 sa, sa_socklen,
3593 &remote_address);
3594 if (ret != 0) {
3595 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3596 __location__, strerror(errno)));
3597 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3600 sa = (struct sockaddr *)(void *)&ss;
3601 sa_socklen = sizeof(ss);
3602 ret = getsockname(sconn->sock, sa, &sa_socklen);
3603 if (ret != 0) {
3604 int level = (errno == ENOTCONN)?2:0;
3605 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3606 exit_server_cleanly("getsockname() failed.\n");
3608 ret = tsocket_address_bsd_from_sockaddr(sconn,
3609 sa, sa_socklen,
3610 &local_address);
3611 if (ret != 0) {
3612 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3613 __location__, strerror(errno)));
3614 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3617 sconn->local_address = local_address;
3618 sconn->remote_address = remote_address;
3620 if (tsocket_address_is_inet(local_address, "ip")) {
3621 locaddr = tsocket_address_inet_addr_string(
3622 sconn->local_address,
3623 talloc_tos());
3624 if (locaddr == NULL) {
3625 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3626 __location__, strerror(errno)));
3627 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3629 } else {
3630 locaddr = "0.0.0.0";
3633 if (tsocket_address_is_inet(remote_address, "ip")) {
3634 remaddr = tsocket_address_inet_addr_string(
3635 sconn->remote_address,
3636 talloc_tos());
3637 if (remaddr == NULL) {
3638 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3639 __location__, strerror(errno)));
3640 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3642 } else {
3643 remaddr = "0.0.0.0";
3646 /* this is needed so that we get decent entries
3647 in smbstatus for port 445 connects */
3648 set_remote_machine_name(remaddr, false);
3649 reload_services(sconn, conn_snum_used, true);
3652 * Before the first packet, check the global hosts allow/ hosts deny
3653 * parameters before doing any parsing of packets passed to us by the
3654 * client. This prevents attacks on our parsing code from hosts not in
3655 * the hosts allow list.
3658 ret = get_remote_hostname(remote_address,
3659 &rhost,
3660 talloc_tos());
3661 if (ret < 0) {
3662 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3663 __location__, strerror(errno)));
3664 exit_server_cleanly("get_remote_hostname failed.\n");
3666 if (strequal(rhost, "UNKNOWN")) {
3667 rhost = talloc_strdup(talloc_tos(), remaddr);
3669 sconn->remote_hostname = talloc_move(sconn, &rhost);
3671 sub_set_socket_ids(remaddr,
3672 sconn->remote_hostname,
3673 locaddr);
3675 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3676 sconn->remote_hostname,
3677 remaddr)) {
3679 * send a negative session response "not listening on calling
3680 * name"
3682 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3683 DEBUG( 1, ("Connection denied from %s to %s\n",
3684 tsocket_address_string(remote_address, talloc_tos()),
3685 tsocket_address_string(local_address, talloc_tos())));
3686 (void)srv_send_smb(sconn,(char *)buf, false,
3687 0, false, NULL);
3688 exit_server_cleanly("connection denied");
3691 DEBUG(10, ("Connection allowed from %s to %s\n",
3692 tsocket_address_string(remote_address, talloc_tos()),
3693 tsocket_address_string(local_address, talloc_tos())));
3695 if (lp_preload_modules()) {
3696 smb_load_modules(lp_preload_modules());
3699 smb_perfcount_init();
3701 if (!init_account_policy()) {
3702 exit_server("Could not open account policy tdb.\n");
3705 if (*lp_root_directory(talloc_tos())) {
3706 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3707 DEBUG(0,("Failed to change root to %s\n",
3708 lp_root_directory(talloc_tos())));
3709 exit_server("Failed to chroot()");
3711 if (chdir("/") == -1) {
3712 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3713 exit_server("Failed to chroot()");
3715 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3718 if (!srv_init_signing(sconn)) {
3719 exit_server("Failed to init smb_signing");
3722 if (!file_init(sconn)) {
3723 exit_server("file_init() failed");
3726 /* Setup oplocks */
3727 if (!init_oplocks(sconn))
3728 exit_server("Failed to init oplocks");
3730 /* register our message handlers */
3731 messaging_register(sconn->msg_ctx, sconn,
3732 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3733 messaging_register(sconn->msg_ctx, sconn,
3734 MSG_SMB_CLOSE_FILE, msg_close_file);
3735 messaging_register(sconn->msg_ctx, sconn,
3736 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3738 id_cache_register_msgs(sconn->msg_ctx);
3739 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3740 messaging_register(sconn->msg_ctx, sconn,
3741 ID_CACHE_KILL, smbd_id_cache_kill);
3743 messaging_deregister(sconn->msg_ctx,
3744 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3745 messaging_register(sconn->msg_ctx, sconn,
3746 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3748 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3749 NULL);
3750 messaging_register(sconn->msg_ctx, sconn,
3751 MSG_SMB_KILL_CLIENT_IP,
3752 msg_kill_client_ip);
3754 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3757 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3758 * MSGs to all child processes
3760 messaging_deregister(sconn->msg_ctx,
3761 MSG_DEBUG, NULL);
3762 messaging_register(sconn->msg_ctx, NULL,
3763 MSG_DEBUG, debug_message);
3765 if ((lp_keepalive() != 0)
3766 && !(event_add_idle(ev_ctx, NULL,
3767 timeval_set(lp_keepalive(), 0),
3768 "keepalive", keepalive_fn,
3769 sconn))) {
3770 DEBUG(0, ("Could not add keepalive event\n"));
3771 exit(1);
3774 if (!(event_add_idle(ev_ctx, NULL,
3775 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3776 "deadtime", deadtime_fn, sconn))) {
3777 DEBUG(0, ("Could not add deadtime event\n"));
3778 exit(1);
3781 if (!(event_add_idle(ev_ctx, NULL,
3782 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3783 "housekeeping", housekeeping_fn, sconn))) {
3784 DEBUG(0, ("Could not add housekeeping event\n"));
3785 exit(1);
3788 if (lp_clustering()) {
3790 * We need to tell ctdb about our client's TCP
3791 * connection, so that for failover ctdbd can send
3792 * tickle acks, triggering a reconnection by the
3793 * client.
3796 struct sockaddr_storage srv, clnt;
3798 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3799 NTSTATUS status;
3800 status = smbd_register_ips(sconn, &srv, &clnt);
3801 if (!NT_STATUS_IS_OK(status)) {
3802 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3803 nt_errstr(status)));
3805 } else {
3806 int level = (errno == ENOTCONN)?2:0;
3807 DEBUG(level,("Unable to get tcp info for "
3808 "smbd_register_ips: %s\n",
3809 strerror(errno)));
3810 exit_server_cleanly("client_get_tcp_info() failed.\n");
3814 sconn->nbt.got_session = false;
3816 tmp = lp_max_xmit();
3817 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3818 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3820 sconn->smb1.negprot.max_recv = tmp;
3822 sconn->smb1.sessions.done_sesssetup = false;
3823 sconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3825 if (!init_dptrs(sconn)) {
3826 exit_server("init_dptrs() failed");
3829 sconn->smb1.fde = tevent_add_fd(ev_ctx,
3830 sconn,
3831 sconn->sock,
3832 TEVENT_FD_READ,
3833 smbd_server_connection_handler,
3834 sconn);
3835 if (!sconn->smb1.fde) {
3836 exit_server("failed to create smbd_server_connection fde");
3839 sconn->conn->local_address = sconn->local_address;
3840 sconn->conn->remote_address = sconn->remote_address;
3841 sconn->conn->remote_hostname = sconn->remote_hostname;
3842 sconn->conn->protocol = PROTOCOL_NONE;
3844 TALLOC_FREE(frame);
3846 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3848 while (True) {
3849 frame = talloc_stackframe_pool(8192);
3851 errno = 0;
3852 if (tevent_loop_once(ev_ctx) == -1) {
3853 if (errno != EINTR) {
3854 DEBUG(3, ("tevent_loop_once failed: %s,"
3855 " exiting\n", strerror(errno) ));
3856 break;
3860 TALLOC_FREE(frame);
3863 exit_server_cleanly(NULL);
3866 bool req_is_in_chain(const struct smb_request *req)
3868 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3870 * We're right now handling a subsequent request, so we must
3871 * be in a chain
3873 return true;
3876 if (!is_andx_req(req->cmd)) {
3877 return false;
3880 if (req->wct < 2) {
3882 * Okay, an illegal request, but definitely not chained :-)
3884 return false;
3887 return (CVAL(req->vwv+0, 0) != 0xFF);