s3:smbd: use SMB_BUFFER_SIZE_MIN/MAX to limit lp_max_xmit()
[Samba.git] / source3 / smbd / process.c
blob938ee4ca490929b4143561a0472e1282967f6938
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"
44 /* Internal message queue for deferred opens. */
45 struct pending_message_list {
46 struct pending_message_list *next, *prev;
47 struct timeval request_time; /* When was this first issued? */
48 struct smbd_server_connection *sconn;
49 struct tevent_timer *te;
50 struct smb_perfcount_data pcd;
51 uint32_t seqnum;
52 bool encrypted;
53 bool processed;
54 DATA_BLOB buf;
55 DATA_BLOB private_data;
58 static void construct_reply_common(struct smb_request *req, const char *inbuf,
59 char *outbuf);
60 static struct pending_message_list *get_deferred_open_message_smb(
61 struct smbd_server_connection *sconn, uint64_t mid);
62 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
64 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
66 bool ok;
68 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
69 return true;
72 sconn->smb1.echo_handler.ref_count++;
74 if (sconn->smb1.echo_handler.ref_count > 1) {
75 return true;
78 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
80 do {
81 ok = fcntl_lock(
82 sconn->smb1.echo_handler.socket_lock_fd,
83 F_SETLKW, 0, 0, F_WRLCK);
84 } while (!ok && (errno == EINTR));
86 if (!ok) {
87 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
88 return false;
91 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
93 return true;
96 void smbd_lock_socket(struct smbd_server_connection *sconn)
98 if (!smbd_lock_socket_internal(sconn)) {
99 exit_server_cleanly("failed to lock socket");
103 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
105 bool ok;
107 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
108 return true;
111 sconn->smb1.echo_handler.ref_count--;
113 if (sconn->smb1.echo_handler.ref_count > 0) {
114 return true;
117 do {
118 ok = fcntl_lock(
119 sconn->smb1.echo_handler.socket_lock_fd,
120 F_SETLKW, 0, 0, F_UNLCK);
121 } while (!ok && (errno == EINTR));
123 if (!ok) {
124 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
125 return false;
128 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
130 return true;
133 void smbd_unlock_socket(struct smbd_server_connection *sconn)
135 if (!smbd_unlock_socket_internal(sconn)) {
136 exit_server_cleanly("failed to unlock socket");
140 /* Accessor function for smb_read_error for smbd functions. */
142 /****************************************************************************
143 Send an smb to a fd.
144 ****************************************************************************/
146 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
147 bool do_signing, uint32_t seqnum,
148 bool do_encrypt,
149 struct smb_perfcount_data *pcd)
151 size_t len = 0;
152 ssize_t ret;
153 char *buf_out = buffer;
155 if (!NT_STATUS_IS_OK(sconn->status)) {
157 * we're not supposed to do any io
159 return true;
162 smbd_lock_socket(sconn);
164 if (do_signing) {
165 /* Sign the outgoing packet if required. */
166 srv_calculate_sign_mac(sconn, buf_out, seqnum);
169 if (do_encrypt) {
170 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
171 if (!NT_STATUS_IS_OK(status)) {
172 DEBUG(0, ("send_smb: SMB encryption failed "
173 "on outgoing packet! Error %s\n",
174 nt_errstr(status) ));
175 ret = -1;
176 goto out;
180 len = smb_len_large(buf_out) + 4;
182 ret = write_data(sconn->sock, buf_out, len);
183 if (ret <= 0) {
185 char addr[INET6_ADDRSTRLEN];
187 * Try and give an error message saying what
188 * client failed.
190 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
191 (int)getpid(), (int)len,
192 get_peer_addr(sconn->sock, addr, sizeof(addr)),
193 (int)ret, strerror(errno) ));
195 srv_free_enc_buffer(sconn, buf_out);
196 goto out;
199 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
200 srv_free_enc_buffer(sconn, buf_out);
201 out:
202 SMB_PERFCOUNT_END(pcd);
204 smbd_unlock_socket(sconn);
205 return (ret > 0);
208 /*******************************************************************
209 Setup the word count and byte count for a smb message.
210 ********************************************************************/
212 int srv_set_message(char *buf,
213 int num_words,
214 int num_bytes,
215 bool zero)
217 if (zero && (num_words || num_bytes)) {
218 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
220 SCVAL(buf,smb_wct,num_words);
221 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
222 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
223 return (smb_size + num_words*2 + num_bytes);
226 static bool valid_smb_header(struct smbd_server_connection *sconn,
227 const uint8_t *inbuf)
229 if (is_encrypted_packet(sconn, inbuf)) {
230 return true;
233 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
234 * but it just looks weird to call strncmp for this one.
236 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
239 /* Socket functions for smbd packet processing. */
241 static bool valid_packet_size(size_t len)
244 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
245 * of header. Don't print the error if this fits.... JRA.
248 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
249 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
250 (unsigned long)len));
251 return false;
253 return true;
256 static NTSTATUS read_packet_remainder(int fd, char *buffer,
257 unsigned int timeout, ssize_t len)
259 NTSTATUS status;
261 if (len <= 0) {
262 return NT_STATUS_OK;
265 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
266 if (!NT_STATUS_IS_OK(status)) {
267 char addr[INET6_ADDRSTRLEN];
268 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
269 "error = %s.\n",
270 get_peer_addr(fd, addr, sizeof(addr)),
271 nt_errstr(status)));
273 return status;
276 /****************************************************************************
277 Attempt a zerocopy writeX read. We know here that len > smb_size-4
278 ****************************************************************************/
281 * Unfortunately, earlier versions of smbclient/libsmbclient
282 * don't send this "standard" writeX header. I've fixed this
283 * for 3.2 but we'll use the old method with earlier versions.
284 * Windows and CIFSFS at least use this standard size. Not
285 * sure about MacOSX.
288 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
289 (2*14) + /* word count (including bcc) */ \
290 1 /* pad byte */)
292 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
293 const char lenbuf[4],
294 struct smbd_server_connection *sconn,
295 int sock,
296 char **buffer,
297 unsigned int timeout,
298 size_t *p_unread,
299 size_t *len_ret)
301 /* Size of a WRITEX call (+4 byte len). */
302 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
303 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
304 ssize_t toread;
305 NTSTATUS status;
307 memcpy(writeX_header, lenbuf, 4);
309 status = read_fd_with_timeout(
310 sock, writeX_header + 4,
311 STANDARD_WRITE_AND_X_HEADER_SIZE,
312 STANDARD_WRITE_AND_X_HEADER_SIZE,
313 timeout, NULL);
315 if (!NT_STATUS_IS_OK(status)) {
316 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
317 "error = %s.\n",
318 tsocket_address_string(sconn->remote_address,
319 talloc_tos()),
320 nt_errstr(status)));
321 return status;
325 * Ok - now try and see if this is a possible
326 * valid writeX call.
329 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
331 * If the data offset is beyond what
332 * we've read, drain the extra bytes.
334 uint16_t doff = SVAL(writeX_header,smb_vwv11);
335 ssize_t newlen;
337 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
338 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
339 if (drain_socket(sock, drain) != drain) {
340 smb_panic("receive_smb_raw_talloc_partial_read:"
341 " failed to drain pending bytes");
343 } else {
344 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
347 /* Spoof down the length and null out the bcc. */
348 set_message_bcc(writeX_header, 0);
349 newlen = smb_len(writeX_header);
351 /* Copy the header we've written. */
353 *buffer = (char *)talloc_memdup(mem_ctx,
354 writeX_header,
355 sizeof(writeX_header));
357 if (*buffer == NULL) {
358 DEBUG(0, ("Could not allocate inbuf of length %d\n",
359 (int)sizeof(writeX_header)));
360 return NT_STATUS_NO_MEMORY;
363 /* Work out the remaining bytes. */
364 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
365 *len_ret = newlen + 4;
366 return NT_STATUS_OK;
369 if (!valid_packet_size(len)) {
370 return NT_STATUS_INVALID_PARAMETER;
374 * Not a valid writeX call. Just do the standard
375 * talloc and return.
378 *buffer = talloc_array(mem_ctx, char, len+4);
380 if (*buffer == NULL) {
381 DEBUG(0, ("Could not allocate inbuf of length %d\n",
382 (int)len+4));
383 return NT_STATUS_NO_MEMORY;
386 /* Copy in what we already read. */
387 memcpy(*buffer,
388 writeX_header,
389 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
390 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
392 if(toread > 0) {
393 status = read_packet_remainder(
394 sock,
395 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
396 timeout, toread);
398 if (!NT_STATUS_IS_OK(status)) {
399 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
400 nt_errstr(status)));
401 return status;
405 *len_ret = len + 4;
406 return NT_STATUS_OK;
409 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
410 struct smbd_server_connection *sconn,
411 int sock,
412 char **buffer, unsigned int timeout,
413 size_t *p_unread, size_t *plen)
415 char lenbuf[4];
416 size_t len;
417 int min_recv_size = lp_min_receive_file_size();
418 NTSTATUS status;
420 *p_unread = 0;
422 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
423 &len);
424 if (!NT_STATUS_IS_OK(status)) {
425 return status;
428 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
429 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
430 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
431 !srv_is_signing_active(sconn) &&
432 sconn->smb1.echo_handler.trusted_fde == NULL) {
434 return receive_smb_raw_talloc_partial_read(
435 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
436 p_unread, plen);
439 if (!valid_packet_size(len)) {
440 return NT_STATUS_INVALID_PARAMETER;
444 * The +4 here can't wrap, we've checked the length above already.
447 *buffer = talloc_array(mem_ctx, char, len+4);
449 if (*buffer == NULL) {
450 DEBUG(0, ("Could not allocate inbuf of length %d\n",
451 (int)len+4));
452 return NT_STATUS_NO_MEMORY;
455 memcpy(*buffer, lenbuf, sizeof(lenbuf));
457 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
458 if (!NT_STATUS_IS_OK(status)) {
459 return status;
462 *plen = len + 4;
463 return NT_STATUS_OK;
466 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
467 struct smbd_server_connection *sconn,
468 int sock,
469 char **buffer, unsigned int timeout,
470 size_t *p_unread, bool *p_encrypted,
471 size_t *p_len,
472 uint32_t *seqnum,
473 bool trusted_channel)
475 size_t len = 0;
476 NTSTATUS status;
478 *p_encrypted = false;
480 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
481 p_unread, &len);
482 if (!NT_STATUS_IS_OK(status)) {
483 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
484 ("receive_smb_raw_talloc failed for client %s "
485 "read error = %s.\n",
486 tsocket_address_string(sconn->remote_address,
487 talloc_tos()),
488 nt_errstr(status)) );
489 return status;
492 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
493 status = srv_decrypt_buffer(sconn, *buffer);
494 if (!NT_STATUS_IS_OK(status)) {
495 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
496 "incoming packet! Error %s\n",
497 nt_errstr(status) ));
498 return status;
500 *p_encrypted = true;
503 /* Check the incoming SMB signature. */
504 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
505 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
506 "incoming packet!\n"));
507 return NT_STATUS_INVALID_NETWORK_RESPONSE;
510 *p_len = len;
511 return NT_STATUS_OK;
515 * Initialize a struct smb_request from an inbuf
518 static bool init_smb_request(struct smb_request *req,
519 struct smbd_server_connection *sconn,
520 const uint8 *inbuf,
521 size_t unread_bytes, bool encrypted,
522 uint32_t seqnum)
524 struct smbXsrv_tcon *tcon;
525 NTSTATUS status;
526 NTTIME now;
527 size_t req_size = smb_len(inbuf) + 4;
529 /* Ensure we have at least smb_size bytes. */
530 if (req_size < smb_size) {
531 DEBUG(0,("init_smb_request: invalid request size %u\n",
532 (unsigned int)req_size ));
533 return false;
536 req->request_time = timeval_current();
537 now = timeval_to_nttime(&req->request_time);
539 req->cmd = CVAL(inbuf, smb_com);
540 req->flags2 = SVAL(inbuf, smb_flg2);
541 req->smbpid = SVAL(inbuf, smb_pid);
542 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
543 req->seqnum = seqnum;
544 req->vuid = SVAL(inbuf, smb_uid);
545 req->tid = SVAL(inbuf, smb_tid);
546 req->wct = CVAL(inbuf, smb_wct);
547 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
548 req->buflen = smb_buflen(inbuf);
549 req->buf = (const uint8_t *)smb_buf_const(inbuf);
550 req->unread_bytes = unread_bytes;
551 req->encrypted = encrypted;
552 req->sconn = sconn;
553 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
554 if (NT_STATUS_IS_OK(status)) {
555 req->conn = tcon->compat;
556 } else {
557 req->conn = NULL;
559 req->chain_fsp = NULL;
560 req->smb2req = NULL;
561 req->priv_paths = NULL;
562 req->chain = NULL;
563 smb_init_perfcount_data(&req->pcd);
565 /* Ensure we have at least wct words and 2 bytes of bcc. */
566 if (smb_size + req->wct*2 > req_size) {
567 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
568 (unsigned int)req->wct,
569 (unsigned int)req_size));
570 return false;
572 /* Ensure bcc is correct. */
573 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
574 DEBUG(0,("init_smb_request: invalid bcc number %u "
575 "(wct = %u, size %u)\n",
576 (unsigned int)req->buflen,
577 (unsigned int)req->wct,
578 (unsigned int)req_size));
579 return false;
582 req->outbuf = NULL;
583 return true;
586 static void process_smb(struct smbd_server_connection *conn,
587 uint8_t *inbuf, size_t nread, size_t unread_bytes,
588 uint32_t seqnum, bool encrypted,
589 struct smb_perfcount_data *deferred_pcd);
591 static void smbd_deferred_open_timer(struct tevent_context *ev,
592 struct tevent_timer *te,
593 struct timeval _tval,
594 void *private_data)
596 struct pending_message_list *msg = talloc_get_type(private_data,
597 struct pending_message_list);
598 struct smbd_server_connection *sconn = msg->sconn;
599 TALLOC_CTX *mem_ctx = talloc_tos();
600 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
601 uint8_t *inbuf;
603 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
604 msg->buf.length);
605 if (inbuf == NULL) {
606 exit_server("smbd_deferred_open_timer: talloc failed\n");
607 return;
610 /* We leave this message on the queue so the open code can
611 know this is a retry. */
612 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
613 (unsigned long long)mid ));
615 /* Mark the message as processed so this is not
616 * re-processed in error. */
617 msg->processed = true;
619 process_smb(sconn, inbuf,
620 msg->buf.length, 0,
621 msg->seqnum, msg->encrypted, &msg->pcd);
623 /* If it's still there and was processed, remove it. */
624 msg = get_deferred_open_message_smb(sconn, mid);
625 if (msg && msg->processed) {
626 remove_deferred_open_message_smb(sconn, mid);
630 /****************************************************************************
631 Function to push a message onto the tail of a linked list of smb messages ready
632 for processing.
633 ****************************************************************************/
635 static bool push_queued_message(struct smb_request *req,
636 struct timeval request_time,
637 struct timeval end_time,
638 char *private_data, size_t private_len)
640 int msg_len = smb_len(req->inbuf) + 4;
641 struct pending_message_list *msg;
643 msg = talloc_zero(NULL, struct pending_message_list);
645 if(msg == NULL) {
646 DEBUG(0,("push_message: malloc fail (1)\n"));
647 return False;
649 msg->sconn = req->sconn;
651 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
652 if(msg->buf.data == NULL) {
653 DEBUG(0,("push_message: malloc fail (2)\n"));
654 TALLOC_FREE(msg);
655 return False;
658 msg->request_time = request_time;
659 msg->seqnum = req->seqnum;
660 msg->encrypted = req->encrypted;
661 msg->processed = false;
662 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
664 if (private_data) {
665 msg->private_data = data_blob_talloc(msg, private_data,
666 private_len);
667 if (msg->private_data.data == NULL) {
668 DEBUG(0,("push_message: malloc fail (3)\n"));
669 TALLOC_FREE(msg);
670 return False;
674 #if 0
675 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
676 msg,
677 end_time,
678 smbd_deferred_open_timer,
679 msg);
680 if (!msg->te) {
681 DEBUG(0,("push_message: event_add_timed failed\n"));
682 TALLOC_FREE(msg);
683 return false;
685 #endif
687 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
688 struct pending_message_list *);
690 DEBUG(10,("push_message: pushed message length %u on "
691 "deferred_open_queue\n", (unsigned int)msg_len));
693 return True;
696 /****************************************************************************
697 Function to delete a sharing violation open message by mid.
698 ****************************************************************************/
700 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
701 uint64_t mid)
703 struct pending_message_list *pml;
705 if (sconn->using_smb2) {
706 remove_deferred_open_message_smb2(sconn, mid);
707 return;
710 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
711 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
712 DEBUG(10,("remove_deferred_open_message_smb: "
713 "deleting mid %llu len %u\n",
714 (unsigned long long)mid,
715 (unsigned int)pml->buf.length ));
716 DLIST_REMOVE(sconn->deferred_open_queue, pml);
717 TALLOC_FREE(pml);
718 return;
723 /****************************************************************************
724 Move a sharing violation open retry message to the front of the list and
725 schedule it for immediate processing.
726 ****************************************************************************/
728 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
729 uint64_t mid)
731 struct pending_message_list *pml;
732 int i = 0;
734 if (sconn->using_smb2) {
735 return schedule_deferred_open_message_smb2(sconn, mid);
738 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
739 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
741 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
742 "msg_mid = %llu\n",
743 i++,
744 (unsigned long long)msg_mid ));
746 if (mid == msg_mid) {
747 struct tevent_timer *te;
749 if (pml->processed) {
750 /* A processed message should not be
751 * rescheduled. */
752 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
753 "message mid %llu was already processed\n",
754 (unsigned long long)msg_mid ));
755 continue;
758 DEBUG(10,("schedule_deferred_open_message_smb: "
759 "scheduling mid %llu\n",
760 (unsigned long long)mid ));
762 te = tevent_add_timer(pml->sconn->ev_ctx,
763 pml,
764 timeval_zero(),
765 smbd_deferred_open_timer,
766 pml);
767 if (!te) {
768 DEBUG(10,("schedule_deferred_open_message_smb: "
769 "event_add_timed() failed, "
770 "skipping mid %llu\n",
771 (unsigned long long)msg_mid ));
774 TALLOC_FREE(pml->te);
775 pml->te = te;
776 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
777 return true;
781 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
782 "find message mid %llu\n",
783 (unsigned long long)mid ));
785 return false;
788 /****************************************************************************
789 Return true if this mid is on the deferred queue and was not yet processed.
790 ****************************************************************************/
792 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
794 struct pending_message_list *pml;
796 if (sconn->using_smb2) {
797 return open_was_deferred_smb2(sconn, mid);
800 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
801 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
802 return True;
805 return False;
808 /****************************************************************************
809 Return the message queued by this mid.
810 ****************************************************************************/
812 static struct pending_message_list *get_deferred_open_message_smb(
813 struct smbd_server_connection *sconn, uint64_t mid)
815 struct pending_message_list *pml;
817 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
818 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
819 return pml;
822 return NULL;
825 /****************************************************************************
826 Get the state data queued by this mid.
827 ****************************************************************************/
829 bool get_deferred_open_message_state(struct smb_request *smbreq,
830 struct timeval *p_request_time,
831 void **pp_state)
833 struct pending_message_list *pml;
835 if (smbreq->sconn->using_smb2) {
836 return get_deferred_open_message_state_smb2(smbreq->smb2req,
837 p_request_time,
838 pp_state);
841 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
842 if (!pml) {
843 return false;
845 if (p_request_time) {
846 *p_request_time = pml->request_time;
848 if (pp_state) {
849 *pp_state = (void *)pml->private_data.data;
851 return true;
854 /****************************************************************************
855 Function to push a deferred open smb message onto a linked list of local smb
856 messages ready for processing.
857 ****************************************************************************/
859 bool push_deferred_open_message_smb(struct smb_request *req,
860 struct timeval request_time,
861 struct timeval timeout,
862 struct file_id id,
863 char *private_data, size_t priv_len)
865 struct timeval end_time;
867 if (req->smb2req) {
868 return push_deferred_open_message_smb2(req->smb2req,
869 request_time,
870 timeout,
872 private_data,
873 priv_len);
876 if (req->unread_bytes) {
877 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
878 "unread_bytes = %u\n",
879 (unsigned int)req->unread_bytes ));
880 smb_panic("push_deferred_open_message_smb: "
881 "logic error unread_bytes != 0" );
884 end_time = timeval_sum(&request_time, &timeout);
886 DEBUG(10,("push_deferred_open_message_smb: pushing message "
887 "len %u mid %llu timeout time [%u.%06u]\n",
888 (unsigned int) smb_len(req->inbuf)+4,
889 (unsigned long long)req->mid,
890 (unsigned int)end_time.tv_sec,
891 (unsigned int)end_time.tv_usec));
893 return push_queued_message(req, request_time, end_time,
894 private_data, priv_len);
897 static void smbd_sig_term_handler(struct tevent_context *ev,
898 struct tevent_signal *se,
899 int signum,
900 int count,
901 void *siginfo,
902 void *private_data)
904 exit_server_cleanly("termination signal");
907 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
909 struct tevent_signal *se;
911 se = tevent_add_signal(sconn->ev_ctx,
912 sconn,
913 SIGTERM, 0,
914 smbd_sig_term_handler,
915 sconn);
916 if (!se) {
917 exit_server("failed to setup SIGTERM handler");
921 static void smbd_sig_hup_handler(struct tevent_context *ev,
922 struct tevent_signal *se,
923 int signum,
924 int count,
925 void *siginfo,
926 void *private_data)
928 struct smbd_server_connection *sconn =
929 talloc_get_type_abort(private_data,
930 struct smbd_server_connection);
932 change_to_root_user();
933 DEBUG(1,("Reloading services after SIGHUP\n"));
934 reload_services(sconn, conn_snum_used, false);
937 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
939 struct tevent_signal *se;
941 se = tevent_add_signal(sconn->ev_ctx,
942 sconn,
943 SIGHUP, 0,
944 smbd_sig_hup_handler,
945 sconn);
946 if (!se) {
947 exit_server("failed to setup SIGHUP handler");
951 static void smbd_conf_updated(struct messaging_context *msg,
952 void *private_data,
953 uint32_t msg_type,
954 struct server_id server_id,
955 DATA_BLOB *data)
957 struct smbd_server_connection *sconn =
958 talloc_get_type_abort(private_data,
959 struct smbd_server_connection);
961 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
962 "updated. Reloading.\n"));
963 change_to_root_user();
964 reload_services(sconn, conn_snum_used, false);
968 * Only allow 5 outstanding trans requests. We're allocating memory, so
969 * prevent a DoS.
972 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
974 int count = 0;
975 for (; list != NULL; list = list->next) {
977 if (list->mid == mid) {
978 return NT_STATUS_INVALID_PARAMETER;
981 count += 1;
983 if (count > 5) {
984 return NT_STATUS_INSUFFICIENT_RESOURCES;
987 return NT_STATUS_OK;
991 These flags determine some of the permissions required to do an operation
993 Note that I don't set NEED_WRITE on some write operations because they
994 are used by some brain-dead clients when printing, and I don't want to
995 force write permissions on print services.
997 #define AS_USER (1<<0)
998 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
999 #define TIME_INIT (1<<2)
1000 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1001 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1002 #define DO_CHDIR (1<<6)
1005 define a list of possible SMB messages and their corresponding
1006 functions. Any message that has a NULL function is unimplemented -
1007 please feel free to contribute implementations!
1009 static const struct smb_message_struct {
1010 const char *name;
1011 void (*fn)(struct smb_request *req);
1012 int flags;
1013 } smb_messages[256] = {
1015 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1016 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1017 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1018 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1019 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1020 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1021 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1022 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1023 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1024 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1025 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1026 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1027 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1028 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1029 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1030 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1031 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1032 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1033 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1034 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1035 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1036 /* 0x15 */ { NULL, NULL, 0 },
1037 /* 0x16 */ { NULL, NULL, 0 },
1038 /* 0x17 */ { NULL, NULL, 0 },
1039 /* 0x18 */ { NULL, NULL, 0 },
1040 /* 0x19 */ { NULL, NULL, 0 },
1041 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1042 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1043 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1044 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1045 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1046 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1047 /* 0x20 */ { "SMBwritec", NULL,0},
1048 /* 0x21 */ { NULL, NULL, 0 },
1049 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1050 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1051 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1052 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1053 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1054 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1055 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1056 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1057 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1058 /* 0x2b */ { "SMBecho",reply_echo,0},
1059 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1060 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1061 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1062 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1063 /* 0x30 */ { NULL, NULL, 0 },
1064 /* 0x31 */ { NULL, NULL, 0 },
1065 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1066 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1067 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1068 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1069 /* 0x36 */ { NULL, NULL, 0 },
1070 /* 0x37 */ { NULL, NULL, 0 },
1071 /* 0x38 */ { NULL, NULL, 0 },
1072 /* 0x39 */ { NULL, NULL, 0 },
1073 /* 0x3a */ { NULL, NULL, 0 },
1074 /* 0x3b */ { NULL, NULL, 0 },
1075 /* 0x3c */ { NULL, NULL, 0 },
1076 /* 0x3d */ { NULL, NULL, 0 },
1077 /* 0x3e */ { NULL, NULL, 0 },
1078 /* 0x3f */ { NULL, NULL, 0 },
1079 /* 0x40 */ { NULL, NULL, 0 },
1080 /* 0x41 */ { NULL, NULL, 0 },
1081 /* 0x42 */ { NULL, NULL, 0 },
1082 /* 0x43 */ { NULL, NULL, 0 },
1083 /* 0x44 */ { NULL, NULL, 0 },
1084 /* 0x45 */ { NULL, NULL, 0 },
1085 /* 0x46 */ { NULL, NULL, 0 },
1086 /* 0x47 */ { NULL, NULL, 0 },
1087 /* 0x48 */ { NULL, NULL, 0 },
1088 /* 0x49 */ { NULL, NULL, 0 },
1089 /* 0x4a */ { NULL, NULL, 0 },
1090 /* 0x4b */ { NULL, NULL, 0 },
1091 /* 0x4c */ { NULL, NULL, 0 },
1092 /* 0x4d */ { NULL, NULL, 0 },
1093 /* 0x4e */ { NULL, NULL, 0 },
1094 /* 0x4f */ { NULL, NULL, 0 },
1095 /* 0x50 */ { NULL, NULL, 0 },
1096 /* 0x51 */ { NULL, NULL, 0 },
1097 /* 0x52 */ { NULL, NULL, 0 },
1098 /* 0x53 */ { NULL, NULL, 0 },
1099 /* 0x54 */ { NULL, NULL, 0 },
1100 /* 0x55 */ { NULL, NULL, 0 },
1101 /* 0x56 */ { NULL, NULL, 0 },
1102 /* 0x57 */ { NULL, NULL, 0 },
1103 /* 0x58 */ { NULL, NULL, 0 },
1104 /* 0x59 */ { NULL, NULL, 0 },
1105 /* 0x5a */ { NULL, NULL, 0 },
1106 /* 0x5b */ { NULL, NULL, 0 },
1107 /* 0x5c */ { NULL, NULL, 0 },
1108 /* 0x5d */ { NULL, NULL, 0 },
1109 /* 0x5e */ { NULL, NULL, 0 },
1110 /* 0x5f */ { NULL, NULL, 0 },
1111 /* 0x60 */ { NULL, NULL, 0 },
1112 /* 0x61 */ { NULL, NULL, 0 },
1113 /* 0x62 */ { NULL, NULL, 0 },
1114 /* 0x63 */ { NULL, NULL, 0 },
1115 /* 0x64 */ { NULL, NULL, 0 },
1116 /* 0x65 */ { NULL, NULL, 0 },
1117 /* 0x66 */ { NULL, NULL, 0 },
1118 /* 0x67 */ { NULL, NULL, 0 },
1119 /* 0x68 */ { NULL, NULL, 0 },
1120 /* 0x69 */ { NULL, NULL, 0 },
1121 /* 0x6a */ { NULL, NULL, 0 },
1122 /* 0x6b */ { NULL, NULL, 0 },
1123 /* 0x6c */ { NULL, NULL, 0 },
1124 /* 0x6d */ { NULL, NULL, 0 },
1125 /* 0x6e */ { NULL, NULL, 0 },
1126 /* 0x6f */ { NULL, NULL, 0 },
1127 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1128 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1129 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1130 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1131 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1132 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1133 /* 0x76 */ { NULL, NULL, 0 },
1134 /* 0x77 */ { NULL, NULL, 0 },
1135 /* 0x78 */ { NULL, NULL, 0 },
1136 /* 0x79 */ { NULL, NULL, 0 },
1137 /* 0x7a */ { NULL, NULL, 0 },
1138 /* 0x7b */ { NULL, NULL, 0 },
1139 /* 0x7c */ { NULL, NULL, 0 },
1140 /* 0x7d */ { NULL, NULL, 0 },
1141 /* 0x7e */ { NULL, NULL, 0 },
1142 /* 0x7f */ { NULL, NULL, 0 },
1143 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1144 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1145 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1146 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1147 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1148 /* 0x85 */ { NULL, NULL, 0 },
1149 /* 0x86 */ { NULL, NULL, 0 },
1150 /* 0x87 */ { NULL, NULL, 0 },
1151 /* 0x88 */ { NULL, NULL, 0 },
1152 /* 0x89 */ { NULL, NULL, 0 },
1153 /* 0x8a */ { NULL, NULL, 0 },
1154 /* 0x8b */ { NULL, NULL, 0 },
1155 /* 0x8c */ { NULL, NULL, 0 },
1156 /* 0x8d */ { NULL, NULL, 0 },
1157 /* 0x8e */ { NULL, NULL, 0 },
1158 /* 0x8f */ { NULL, NULL, 0 },
1159 /* 0x90 */ { NULL, NULL, 0 },
1160 /* 0x91 */ { NULL, NULL, 0 },
1161 /* 0x92 */ { NULL, NULL, 0 },
1162 /* 0x93 */ { NULL, NULL, 0 },
1163 /* 0x94 */ { NULL, NULL, 0 },
1164 /* 0x95 */ { NULL, NULL, 0 },
1165 /* 0x96 */ { NULL, NULL, 0 },
1166 /* 0x97 */ { NULL, NULL, 0 },
1167 /* 0x98 */ { NULL, NULL, 0 },
1168 /* 0x99 */ { NULL, NULL, 0 },
1169 /* 0x9a */ { NULL, NULL, 0 },
1170 /* 0x9b */ { NULL, NULL, 0 },
1171 /* 0x9c */ { NULL, NULL, 0 },
1172 /* 0x9d */ { NULL, NULL, 0 },
1173 /* 0x9e */ { NULL, NULL, 0 },
1174 /* 0x9f */ { NULL, NULL, 0 },
1175 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1176 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1177 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1178 /* 0xa3 */ { NULL, NULL, 0 },
1179 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1180 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1181 /* 0xa6 */ { NULL, NULL, 0 },
1182 /* 0xa7 */ { NULL, NULL, 0 },
1183 /* 0xa8 */ { NULL, NULL, 0 },
1184 /* 0xa9 */ { NULL, NULL, 0 },
1185 /* 0xaa */ { NULL, NULL, 0 },
1186 /* 0xab */ { NULL, NULL, 0 },
1187 /* 0xac */ { NULL, NULL, 0 },
1188 /* 0xad */ { NULL, NULL, 0 },
1189 /* 0xae */ { NULL, NULL, 0 },
1190 /* 0xaf */ { NULL, NULL, 0 },
1191 /* 0xb0 */ { NULL, NULL, 0 },
1192 /* 0xb1 */ { NULL, NULL, 0 },
1193 /* 0xb2 */ { NULL, NULL, 0 },
1194 /* 0xb3 */ { NULL, NULL, 0 },
1195 /* 0xb4 */ { NULL, NULL, 0 },
1196 /* 0xb5 */ { NULL, NULL, 0 },
1197 /* 0xb6 */ { NULL, NULL, 0 },
1198 /* 0xb7 */ { NULL, NULL, 0 },
1199 /* 0xb8 */ { NULL, NULL, 0 },
1200 /* 0xb9 */ { NULL, NULL, 0 },
1201 /* 0xba */ { NULL, NULL, 0 },
1202 /* 0xbb */ { NULL, NULL, 0 },
1203 /* 0xbc */ { NULL, NULL, 0 },
1204 /* 0xbd */ { NULL, NULL, 0 },
1205 /* 0xbe */ { NULL, NULL, 0 },
1206 /* 0xbf */ { NULL, NULL, 0 },
1207 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1208 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1209 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1210 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1211 /* 0xc4 */ { NULL, NULL, 0 },
1212 /* 0xc5 */ { NULL, NULL, 0 },
1213 /* 0xc6 */ { NULL, NULL, 0 },
1214 /* 0xc7 */ { NULL, NULL, 0 },
1215 /* 0xc8 */ { NULL, NULL, 0 },
1216 /* 0xc9 */ { NULL, NULL, 0 },
1217 /* 0xca */ { NULL, NULL, 0 },
1218 /* 0xcb */ { NULL, NULL, 0 },
1219 /* 0xcc */ { NULL, NULL, 0 },
1220 /* 0xcd */ { NULL, NULL, 0 },
1221 /* 0xce */ { NULL, NULL, 0 },
1222 /* 0xcf */ { NULL, NULL, 0 },
1223 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1224 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1225 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1226 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1227 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1228 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1229 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1230 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1231 /* 0xd8 */ { NULL, NULL, 0 },
1232 /* 0xd9 */ { NULL, NULL, 0 },
1233 /* 0xda */ { NULL, NULL, 0 },
1234 /* 0xdb */ { NULL, NULL, 0 },
1235 /* 0xdc */ { NULL, NULL, 0 },
1236 /* 0xdd */ { NULL, NULL, 0 },
1237 /* 0xde */ { NULL, NULL, 0 },
1238 /* 0xdf */ { NULL, NULL, 0 },
1239 /* 0xe0 */ { NULL, NULL, 0 },
1240 /* 0xe1 */ { NULL, NULL, 0 },
1241 /* 0xe2 */ { NULL, NULL, 0 },
1242 /* 0xe3 */ { NULL, NULL, 0 },
1243 /* 0xe4 */ { NULL, NULL, 0 },
1244 /* 0xe5 */ { NULL, NULL, 0 },
1245 /* 0xe6 */ { NULL, NULL, 0 },
1246 /* 0xe7 */ { NULL, NULL, 0 },
1247 /* 0xe8 */ { NULL, NULL, 0 },
1248 /* 0xe9 */ { NULL, NULL, 0 },
1249 /* 0xea */ { NULL, NULL, 0 },
1250 /* 0xeb */ { NULL, NULL, 0 },
1251 /* 0xec */ { NULL, NULL, 0 },
1252 /* 0xed */ { NULL, NULL, 0 },
1253 /* 0xee */ { NULL, NULL, 0 },
1254 /* 0xef */ { NULL, NULL, 0 },
1255 /* 0xf0 */ { NULL, NULL, 0 },
1256 /* 0xf1 */ { NULL, NULL, 0 },
1257 /* 0xf2 */ { NULL, NULL, 0 },
1258 /* 0xf3 */ { NULL, NULL, 0 },
1259 /* 0xf4 */ { NULL, NULL, 0 },
1260 /* 0xf5 */ { NULL, NULL, 0 },
1261 /* 0xf6 */ { NULL, NULL, 0 },
1262 /* 0xf7 */ { NULL, NULL, 0 },
1263 /* 0xf8 */ { NULL, NULL, 0 },
1264 /* 0xf9 */ { NULL, NULL, 0 },
1265 /* 0xfa */ { NULL, NULL, 0 },
1266 /* 0xfb */ { NULL, NULL, 0 },
1267 /* 0xfc */ { NULL, NULL, 0 },
1268 /* 0xfd */ { NULL, NULL, 0 },
1269 /* 0xfe */ { NULL, NULL, 0 },
1270 /* 0xff */ { NULL, NULL, 0 }
1274 /*******************************************************************
1275 allocate and initialize a reply packet
1276 ********************************************************************/
1278 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1279 const char *inbuf, char **outbuf, uint8_t num_words,
1280 uint32_t num_bytes)
1282 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1285 * Protect against integer wrap.
1286 * The SMB layer reply can be up to 0xFFFFFF bytes.
1288 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1289 char *msg;
1290 if (asprintf(&msg, "num_bytes too large: %u",
1291 (unsigned)num_bytes) == -1) {
1292 msg = discard_const_p(char, "num_bytes too large");
1294 smb_panic(msg);
1298 * Here we include the NBT header for now.
1300 *outbuf = talloc_array(mem_ctx, char,
1301 NBT_HDR_SIZE + smb_len);
1302 if (*outbuf == NULL) {
1303 return false;
1306 construct_reply_common(req, inbuf, *outbuf);
1307 srv_set_message(*outbuf, num_words, num_bytes, false);
1309 * Zero out the word area, the caller has to take care of the bcc area
1310 * himself
1312 if (num_words != 0) {
1313 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1316 return true;
1319 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1321 char *outbuf;
1322 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1323 num_bytes)) {
1324 smb_panic("could not allocate output buffer\n");
1326 req->outbuf = (uint8_t *)outbuf;
1330 /*******************************************************************
1331 Dump a packet to a file.
1332 ********************************************************************/
1334 static void smb_dump(const char *name, int type, const char *data)
1336 size_t len;
1337 int fd, i;
1338 char *fname = NULL;
1339 if (DEBUGLEVEL < 50) {
1340 return;
1343 len = smb_len_tcp(data)+4;
1344 for (i=1;i<100;i++) {
1345 fname = talloc_asprintf(talloc_tos(),
1346 "/tmp/%s.%d.%s",
1347 name,
1349 type ? "req" : "resp");
1350 if (fname == NULL) {
1351 return;
1353 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1354 if (fd != -1 || errno != EEXIST) break;
1355 TALLOC_FREE(fname);
1357 if (fd != -1) {
1358 ssize_t ret = write(fd, data, len);
1359 if (ret != len)
1360 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1361 close(fd);
1362 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1364 TALLOC_FREE(fname);
1367 /****************************************************************************
1368 Prepare everything for calling the actual request function, and potentially
1369 call the request function via the "new" interface.
1371 Return False if the "legacy" function needs to be called, everything is
1372 prepared.
1374 Return True if we're done.
1376 I know this API sucks, but it is the one with the least code change I could
1377 find.
1378 ****************************************************************************/
1380 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1382 int flags;
1383 uint64_t session_tag;
1384 connection_struct *conn = NULL;
1385 struct smbd_server_connection *sconn = req->sconn;
1386 NTTIME now = timeval_to_nttime(&req->request_time);
1387 struct smbXsrv_session *session = NULL;
1388 NTSTATUS status;
1390 errno = 0;
1392 if (smb_messages[type].fn == NULL) {
1393 DEBUG(0,("Unknown message type %d!\n",type));
1394 smb_dump("Unknown", 1, (const char *)req->inbuf);
1395 reply_unknown_new(req, type);
1396 return NULL;
1399 flags = smb_messages[type].flags;
1401 /* In share mode security we must ignore the vuid. */
1402 session_tag = req->vuid;
1403 conn = req->conn;
1405 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1406 (int)getpid(), (unsigned long)conn));
1408 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1410 /* Ensure this value is replaced in the incoming packet. */
1411 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1414 * Ensure the correct username is in current_user_info. This is a
1415 * really ugly bugfix for problems with multiple session_setup_and_X's
1416 * being done and allowing %U and %G substitutions to work correctly.
1417 * There is a reason this code is done here, don't move it unless you
1418 * know what you're doing... :-).
1419 * JRA.
1423 * lookup an existing session
1425 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1426 * here, the main check is still in change_to_user()
1428 status = smb1srv_session_lookup(sconn->conn,
1429 session_tag,
1430 now,
1431 &session);
1432 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1433 switch (type) {
1434 case SMBsesssetupX:
1435 status = NT_STATUS_OK;
1436 break;
1437 default:
1438 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1439 (unsigned long long)session_tag,
1440 (unsigned long long)req->mid));
1441 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1442 return conn;
1446 if (session_tag != sconn->conn->last_session_id) {
1447 struct user_struct *vuser = NULL;
1449 sconn->conn->last_session_id = session_tag;
1450 if (session) {
1451 vuser = session->compat;
1453 if (vuser) {
1454 set_current_user_info(
1455 vuser->session_info->unix_info->sanitized_username,
1456 vuser->session_info->unix_info->unix_name,
1457 vuser->session_info->info->domain_name);
1461 /* Does this call need to be run as the connected user? */
1462 if (flags & AS_USER) {
1464 /* Does this call need a valid tree connection? */
1465 if (!conn) {
1467 * Amazingly, the error code depends on the command
1468 * (from Samba4).
1470 if (type == SMBntcreateX) {
1471 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1472 } else {
1473 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1475 return NULL;
1478 if (!change_to_user(conn,session_tag)) {
1479 DEBUG(0, ("Error: Could not change to user. Removing "
1480 "deferred open, mid=%llu.\n",
1481 (unsigned long long)req->mid));
1482 reply_force_doserror(req, ERRSRV, ERRbaduid);
1483 return conn;
1486 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1488 /* Does it need write permission? */
1489 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1490 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1491 return conn;
1494 /* IPC services are limited */
1495 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1496 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1497 return conn;
1499 } else {
1500 /* This call needs to be run as root */
1501 change_to_root_user();
1504 /* load service specific parameters */
1505 if (conn) {
1506 if (req->encrypted) {
1507 conn->encrypted_tid = true;
1508 /* encrypted required from now on. */
1509 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1510 } else if (ENCRYPTION_REQUIRED(conn)) {
1511 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1512 DEBUG(1,("service[%s] requires encryption"
1513 "%s ACCESS_DENIED. mid=%llu\n",
1514 lp_servicename(talloc_tos(), SNUM(conn)),
1515 smb_fn_name(type),
1516 (unsigned long long)req->mid));
1517 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1518 return conn;
1522 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1523 (flags & (AS_USER|DO_CHDIR)
1524 ?True:False))) {
1525 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1526 return conn;
1528 conn->num_smb_operations++;
1532 * Does this protocol need to be run as guest? (Only archane
1533 * messenger service requests have this...)
1535 if (flags & AS_GUEST) {
1536 char *raddr;
1537 bool ok;
1539 if (!change_to_guest()) {
1540 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1541 return conn;
1544 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1545 talloc_tos());
1546 if (raddr == NULL) {
1547 reply_nterror(req, NT_STATUS_NO_MEMORY);
1548 return conn;
1552 * Haven't we checked this in smbd_process already???
1555 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1556 sconn->remote_hostname, raddr);
1557 TALLOC_FREE(raddr);
1559 if (!ok) {
1560 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1561 return conn;
1565 smb_messages[type].fn(req);
1566 return req->conn;
1569 /****************************************************************************
1570 Construct a reply to the incoming packet.
1571 ****************************************************************************/
1573 static void construct_reply(struct smbd_server_connection *sconn,
1574 char *inbuf, int size, size_t unread_bytes,
1575 uint32_t seqnum, bool encrypted,
1576 struct smb_perfcount_data *deferred_pcd)
1578 connection_struct *conn;
1579 struct smb_request *req;
1581 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1582 smb_panic("could not allocate smb_request");
1585 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1586 encrypted, seqnum)) {
1587 exit_server_cleanly("Invalid SMB request");
1590 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1592 /* we popped this message off the queue - keep original perf data */
1593 if (deferred_pcd)
1594 req->pcd = *deferred_pcd;
1595 else {
1596 SMB_PERFCOUNT_START(&req->pcd);
1597 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1598 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1601 conn = switch_message(req->cmd, req);
1603 if (req->outbuf == NULL) {
1604 return;
1607 if (CVAL(req->outbuf,0) == 0) {
1608 show_msg((char *)req->outbuf);
1611 if (!srv_send_smb(req->sconn,
1612 (char *)req->outbuf,
1613 true, req->seqnum+1,
1614 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1615 &req->pcd)) {
1616 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1619 TALLOC_FREE(req);
1621 return;
1624 static void construct_reply_chain(struct smbd_server_connection *sconn,
1625 char *inbuf, int size, uint32_t seqnum,
1626 bool encrypted,
1627 struct smb_perfcount_data *deferred_pcd)
1629 struct smb_request **reqs = NULL;
1630 struct smb_request *req;
1631 unsigned num_reqs;
1632 bool ok;
1634 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1635 seqnum, &reqs, &num_reqs);
1636 if (!ok) {
1637 char errbuf[smb_size];
1638 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1639 __LINE__, __FILE__);
1640 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1641 NULL)) {
1642 exit_server_cleanly("construct_reply_chain: "
1643 "srv_send_smb failed.");
1645 return;
1648 req = reqs[0];
1649 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1651 req->conn = switch_message(req->cmd, req);
1653 if (req->outbuf == NULL) {
1655 * Request has suspended itself, will come
1656 * back here.
1658 return;
1660 smb_request_done(req);
1664 * To be called from an async SMB handler that is potentially chained
1665 * when it is finished for shipping.
1668 void smb_request_done(struct smb_request *req)
1670 struct smb_request **reqs = NULL;
1671 struct smb_request *first_req;
1672 size_t i, num_reqs, next_index;
1673 NTSTATUS status;
1675 if (req->chain == NULL) {
1676 first_req = req;
1677 goto shipit;
1680 reqs = req->chain;
1681 num_reqs = talloc_array_length(reqs);
1683 for (i=0; i<num_reqs; i++) {
1684 if (reqs[i] == req) {
1685 break;
1688 if (i == num_reqs) {
1690 * Invalid chain, should not happen
1692 status = NT_STATUS_INTERNAL_ERROR;
1693 goto error;
1695 next_index = i+1;
1697 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1698 struct smb_request *next = reqs[next_index];
1699 struct smbXsrv_tcon *tcon;
1700 NTTIME now = timeval_to_nttime(&req->request_time);
1702 next->vuid = SVAL(req->outbuf, smb_uid);
1703 next->tid = SVAL(req->outbuf, smb_tid);
1704 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1705 now, &tcon);
1706 if (NT_STATUS_IS_OK(status)) {
1707 req->conn = tcon->compat;
1708 } else {
1709 req->conn = NULL;
1711 next->chain_fsp = req->chain_fsp;
1712 next->inbuf = req->inbuf;
1714 req = next;
1715 req->conn = switch_message(req->cmd, req);
1717 if (req->outbuf == NULL) {
1719 * Request has suspended itself, will come
1720 * back here.
1722 return;
1724 next_index += 1;
1727 first_req = reqs[0];
1729 for (i=1; i<next_index; i++) {
1730 bool ok;
1732 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1733 if (!ok) {
1734 status = NT_STATUS_INTERNAL_ERROR;
1735 goto error;
1739 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1740 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1743 * This scary statement intends to set the
1744 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1745 * to the value last_req->outbuf carries
1747 SSVAL(first_req->outbuf, smb_flg2,
1748 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1749 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1752 * Transfer the error codes from the subrequest to the main one
1754 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1755 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1757 _smb_setlen_large(
1758 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1760 shipit:
1761 if (!srv_send_smb(first_req->sconn,
1762 (char *)first_req->outbuf,
1763 true, first_req->seqnum+1,
1764 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1765 &first_req->pcd)) {
1766 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1767 "failed.");
1769 TALLOC_FREE(req); /* non-chained case */
1770 TALLOC_FREE(reqs); /* chained case */
1771 return;
1773 error:
1775 char errbuf[smb_size];
1776 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1777 if (!srv_send_smb(req->sconn, errbuf, true,
1778 req->seqnum+1, req->encrypted,
1779 NULL)) {
1780 exit_server_cleanly("construct_reply_chain: "
1781 "srv_send_smb failed.");
1784 TALLOC_FREE(req); /* non-chained case */
1785 TALLOC_FREE(reqs); /* chained case */
1788 /****************************************************************************
1789 Process an smb from the client
1790 ****************************************************************************/
1791 static void process_smb(struct smbd_server_connection *sconn,
1792 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1793 uint32_t seqnum, bool encrypted,
1794 struct smb_perfcount_data *deferred_pcd)
1796 int msg_type = CVAL(inbuf,0);
1798 DO_PROFILE_INC(smb_count);
1800 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1801 smb_len(inbuf) ) );
1802 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1803 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1805 if (msg_type != NBSSmessage) {
1807 * NetBIOS session request, keepalive, etc.
1809 reply_special(sconn, (char *)inbuf, nread);
1810 goto done;
1813 if (sconn->using_smb2) {
1814 /* At this point we're not really using smb2,
1815 * we make the decision here.. */
1816 if (smbd_is_smb2_header(inbuf, nread)) {
1817 smbd_smb2_first_negprot(sconn, inbuf, nread);
1818 return;
1819 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1820 && CVAL(inbuf, smb_com) != 0x72) {
1821 /* This is a non-negprot SMB1 packet.
1822 Disable SMB2 from now on. */
1823 sconn->using_smb2 = false;
1827 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1828 * so subtract 4 from it. */
1829 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1830 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1831 smb_len(inbuf)));
1833 /* special magic for immediate exit */
1834 if ((nread == 9) &&
1835 (IVAL(inbuf, 4) == 0x74697865) &&
1836 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1837 uint8_t exitcode = CVAL(inbuf, 8);
1838 DEBUG(1, ("Exiting immediately with code %d\n",
1839 (int)exitcode));
1840 exit(exitcode);
1843 exit_server_cleanly("Non-SMB packet");
1846 show_msg((char *)inbuf);
1848 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1849 construct_reply_chain(sconn, (char *)inbuf, nread,
1850 seqnum, encrypted, deferred_pcd);
1851 } else {
1852 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1853 seqnum, encrypted, deferred_pcd);
1856 sconn->trans_num++;
1858 done:
1859 sconn->num_requests++;
1861 /* The timeout_processing function isn't run nearly
1862 often enough to implement 'max log size' without
1863 overrunning the size of the file by many megabytes.
1864 This is especially true if we are running at debug
1865 level 10. Checking every 50 SMBs is a nice
1866 tradeoff of performance vs log file size overrun. */
1868 if ((sconn->num_requests % 50) == 0 &&
1869 need_to_check_log_size()) {
1870 change_to_root_user();
1871 check_log_size();
1875 /****************************************************************************
1876 Return a string containing the function name of a SMB command.
1877 ****************************************************************************/
1879 const char *smb_fn_name(int type)
1881 const char *unknown_name = "SMBunknown";
1883 if (smb_messages[type].name == NULL)
1884 return(unknown_name);
1886 return(smb_messages[type].name);
1889 /****************************************************************************
1890 Helper functions for contruct_reply.
1891 ****************************************************************************/
1893 void add_to_common_flags2(uint32 v)
1895 common_flags2 |= v;
1898 void remove_from_common_flags2(uint32 v)
1900 common_flags2 &= ~v;
1903 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1904 char *outbuf)
1906 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1907 uint16_t out_flags2 = common_flags2;
1909 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1910 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1911 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1913 srv_set_message(outbuf,0,0,false);
1915 SCVAL(outbuf, smb_com, req->cmd);
1916 SIVAL(outbuf,smb_rcls,0);
1917 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1918 SSVAL(outbuf,smb_flg2, out_flags2);
1919 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1920 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1922 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1923 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1924 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1925 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1928 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1930 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1934 * @brief Find the smb_cmd offset of the last command pushed
1935 * @param[in] buf The buffer we're building up
1936 * @retval Where can we put our next andx cmd?
1938 * While chaining requests, the "next" request we're looking at needs to put
1939 * its SMB_Command before the data the previous request already built up added
1940 * to the chain. Find the offset to the place where we have to put our cmd.
1943 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1945 uint8_t cmd;
1946 size_t ofs;
1948 cmd = CVAL(buf, smb_com);
1950 if (!is_andx_req(cmd)) {
1951 return false;
1954 ofs = smb_vwv0;
1956 while (CVAL(buf, ofs) != 0xff) {
1958 if (!is_andx_req(CVAL(buf, ofs))) {
1959 return false;
1963 * ofs is from start of smb header, so add the 4 length
1964 * bytes. The next cmd is right after the wct field.
1966 ofs = SVAL(buf, ofs+2) + 4 + 1;
1968 if (ofs+4 >= talloc_get_size(buf)) {
1969 return false;
1973 *pofs = ofs;
1974 return true;
1978 * @brief Do the smb chaining at a buffer level
1979 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1980 * @param[in] andx_buf Buffer to be appended
1983 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1985 uint8_t smb_command = CVAL(andx_buf, smb_com);
1986 uint8_t wct = CVAL(andx_buf, smb_wct);
1987 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1988 uint32_t num_bytes = smb_buflen(andx_buf);
1989 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1991 uint8_t *outbuf;
1992 size_t old_size, new_size;
1993 size_t ofs;
1994 size_t chain_padding = 0;
1995 size_t andx_cmd_ofs;
1998 old_size = talloc_get_size(*poutbuf);
2000 if ((old_size % 4) != 0) {
2002 * Align the wct field of subsequent requests to a 4-byte
2003 * boundary
2005 chain_padding = 4 - (old_size % 4);
2009 * After the old request comes the new wct field (1 byte), the vwv's
2010 * and the num_bytes field.
2013 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2014 new_size += num_bytes;
2016 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2017 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2018 (unsigned)new_size));
2019 return false;
2022 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2023 if (outbuf == NULL) {
2024 DEBUG(0, ("talloc failed\n"));
2025 return false;
2027 *poutbuf = outbuf;
2029 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2030 DEBUG(1, ("invalid command chain\n"));
2031 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2032 return false;
2035 if (chain_padding != 0) {
2036 memset(outbuf + old_size, 0, chain_padding);
2037 old_size += chain_padding;
2040 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2041 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2043 ofs = old_size;
2046 * Push the chained request:
2048 * wct field
2051 SCVAL(outbuf, ofs, wct);
2052 ofs += 1;
2055 * vwv array
2058 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2061 * HACK ALERT
2063 * Read&X has an offset into its data buffer at
2064 * vwv[6]. reply_read_andx has no idea anymore that it's
2065 * running from within a chain, so we have to fix up the
2066 * offset here.
2068 * Although it looks disgusting at this place, I want to keep
2069 * it here. The alternative would be to push knowledge about
2070 * the andx chain down into read&x again.
2073 if (smb_command == SMBreadX) {
2074 uint8_t *bytes_addr;
2076 if (wct < 7) {
2078 * Invalid read&x response
2080 return false;
2083 bytes_addr = outbuf + ofs /* vwv start */
2084 + sizeof(uint16_t) * wct /* vwv array */
2085 + sizeof(uint16_t); /* bcc */
2087 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2088 bytes_addr - outbuf - 4);
2091 ofs += sizeof(uint16_t) * wct;
2094 * bcc (byte count)
2097 SSVAL(outbuf, ofs, num_bytes);
2098 ofs += sizeof(uint16_t);
2101 * The bytes field
2104 memcpy(outbuf + ofs, bytes, num_bytes);
2106 return true;
2109 bool smb1_is_chain(const uint8_t *buf)
2111 uint8_t cmd, wct, andx_cmd;
2113 cmd = CVAL(buf, smb_com);
2114 if (!is_andx_req(cmd)) {
2115 return false;
2117 wct = CVAL(buf, smb_wct);
2118 if (wct < 2) {
2119 return false;
2121 andx_cmd = CVAL(buf, smb_vwv);
2122 return (andx_cmd != 0xFF);
2125 bool smb1_walk_chain(const uint8_t *buf,
2126 bool (*fn)(uint8_t cmd,
2127 uint8_t wct, const uint16_t *vwv,
2128 uint16_t num_bytes, const uint8_t *bytes,
2129 void *private_data),
2130 void *private_data)
2132 size_t smblen = smb_len(buf);
2133 const char *smb_buf = smb_base(buf);
2134 uint8_t cmd, chain_cmd;
2135 uint8_t wct;
2136 const uint16_t *vwv;
2137 uint16_t num_bytes;
2138 const uint8_t *bytes;
2140 cmd = CVAL(buf, smb_com);
2141 wct = CVAL(buf, smb_wct);
2142 vwv = (const uint16_t *)(buf + smb_vwv);
2143 num_bytes = smb_buflen(buf);
2144 bytes = (const uint8_t *)smb_buf_const(buf);
2146 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2147 return false;
2150 if (!is_andx_req(cmd)) {
2151 return true;
2153 if (wct < 2) {
2154 return false;
2157 chain_cmd = CVAL(vwv, 0);
2159 while (chain_cmd != 0xff) {
2160 uint32_t chain_offset; /* uint32_t to avoid overflow */
2161 size_t length_needed;
2162 ptrdiff_t vwv_offset;
2164 chain_offset = SVAL(vwv+1, 0);
2167 * Check if the client tries to fool us. The chain
2168 * offset needs to point beyond the current request in
2169 * the chain, it needs to strictly grow. Otherwise we
2170 * might be tricked into an endless loop always
2171 * processing the same request over and over again. We
2172 * used to assume that vwv and the byte buffer array
2173 * in a chain are always attached, but OS/2 the
2174 * Write&X/Read&X chain puts the Read&X vwv array
2175 * right behind the Write&X vwv chain. The Write&X bcc
2176 * array is put behind the Read&X vwv array. So now we
2177 * check whether the chain offset points strictly
2178 * behind the previous vwv array. req->buf points
2179 * right after the vwv array of the previous
2180 * request. See
2181 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2182 * more information.
2185 vwv_offset = ((const char *)vwv - smb_buf);
2186 if (chain_offset <= vwv_offset) {
2187 return false;
2191 * Next check: Make sure the chain offset does not
2192 * point beyond the overall smb request length.
2195 length_needed = chain_offset+1; /* wct */
2196 if (length_needed > smblen) {
2197 return false;
2201 * Now comes the pointer magic. Goal here is to set up
2202 * vwv and buf correctly again. The chain offset (the
2203 * former vwv[1]) points at the new wct field.
2206 wct = CVAL(smb_buf, chain_offset);
2208 if (is_andx_req(chain_cmd) && (wct < 2)) {
2209 return false;
2213 * Next consistency check: Make the new vwv array fits
2214 * in the overall smb request.
2217 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2218 if (length_needed > smblen) {
2219 return false;
2221 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2224 * Now grab the new byte buffer....
2227 num_bytes = SVAL(vwv+wct, 0);
2230 * .. and check that it fits.
2233 length_needed += num_bytes;
2234 if (length_needed > smblen) {
2235 return false;
2237 bytes = (const uint8_t *)(vwv+wct+1);
2239 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2240 return false;
2243 if (!is_andx_req(chain_cmd)) {
2244 return true;
2246 chain_cmd = CVAL(vwv, 0);
2248 return true;
2251 static bool smb1_chain_length_cb(uint8_t cmd,
2252 uint8_t wct, const uint16_t *vwv,
2253 uint16_t num_bytes, const uint8_t *bytes,
2254 void *private_data)
2256 unsigned *count = (unsigned *)private_data;
2257 *count += 1;
2258 return true;
2261 unsigned smb1_chain_length(const uint8_t *buf)
2263 unsigned count = 0;
2265 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2266 return 0;
2268 return count;
2271 struct smb1_parse_chain_state {
2272 TALLOC_CTX *mem_ctx;
2273 const uint8_t *buf;
2274 struct smbd_server_connection *sconn;
2275 bool encrypted;
2276 uint32_t seqnum;
2278 struct smb_request **reqs;
2279 unsigned num_reqs;
2282 static bool smb1_parse_chain_cb(uint8_t cmd,
2283 uint8_t wct, const uint16_t *vwv,
2284 uint16_t num_bytes, const uint8_t *bytes,
2285 void *private_data)
2287 struct smb1_parse_chain_state *state =
2288 (struct smb1_parse_chain_state *)private_data;
2289 struct smb_request **reqs;
2290 struct smb_request *req;
2291 bool ok;
2293 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2294 struct smb_request *, state->num_reqs+1);
2295 if (reqs == NULL) {
2296 return false;
2298 state->reqs = reqs;
2300 req = talloc(reqs, struct smb_request);
2301 if (req == NULL) {
2302 return false;
2305 ok = init_smb_request(req, state->sconn, state->buf, 0,
2306 state->encrypted, state->seqnum);
2307 if (!ok) {
2308 return false;
2310 req->cmd = cmd;
2311 req->wct = wct;
2312 req->vwv = vwv;
2313 req->buflen = num_bytes;
2314 req->buf = bytes;
2316 reqs[state->num_reqs] = req;
2317 state->num_reqs += 1;
2318 return true;
2321 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2322 struct smbd_server_connection *sconn,
2323 bool encrypted, uint32_t seqnum,
2324 struct smb_request ***reqs, unsigned *num_reqs)
2326 struct smb1_parse_chain_state state;
2327 unsigned i;
2329 state.mem_ctx = mem_ctx;
2330 state.buf = buf;
2331 state.sconn = sconn;
2332 state.encrypted = encrypted;
2333 state.seqnum = seqnum;
2334 state.reqs = NULL;
2335 state.num_reqs = 0;
2337 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2338 TALLOC_FREE(state.reqs);
2339 return false;
2341 for (i=0; i<state.num_reqs; i++) {
2342 state.reqs[i]->chain = state.reqs;
2344 *reqs = state.reqs;
2345 *num_reqs = state.num_reqs;
2346 return true;
2349 /****************************************************************************
2350 Check if services need reloading.
2351 ****************************************************************************/
2353 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2356 if (last_smb_conf_reload_time == 0) {
2357 last_smb_conf_reload_time = t;
2360 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2361 reload_services(sconn, conn_snum_used, true);
2362 last_smb_conf_reload_time = t;
2366 static bool fd_is_readable(int fd)
2368 int ret, revents;
2370 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2372 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2376 static void smbd_server_connection_write_handler(
2377 struct smbd_server_connection *sconn)
2379 /* TODO: make write nonblocking */
2382 static void smbd_server_connection_read_handler(
2383 struct smbd_server_connection *sconn, int fd)
2385 uint8_t *inbuf = NULL;
2386 size_t inbuf_len = 0;
2387 size_t unread_bytes = 0;
2388 bool encrypted = false;
2389 TALLOC_CTX *mem_ctx = talloc_tos();
2390 NTSTATUS status;
2391 uint32_t seqnum;
2393 bool async_echo = lp_async_smb_echo_handler();
2394 bool from_client = false;
2396 if (async_echo) {
2397 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2399 * This is the super-ugly hack to prefer the packets
2400 * forwarded by the echo handler over the ones by the
2401 * client directly
2403 fd = sconn->smb1.echo_handler.trusted_fd;
2407 from_client = (sconn->sock == fd);
2409 if (async_echo && from_client) {
2410 smbd_lock_socket(sconn);
2412 if (!fd_is_readable(fd)) {
2413 DEBUG(10,("the echo listener was faster\n"));
2414 smbd_unlock_socket(sconn);
2415 return;
2419 /* TODO: make this completely nonblocking */
2420 status = receive_smb_talloc(mem_ctx, sconn, fd,
2421 (char **)(void *)&inbuf,
2422 0, /* timeout */
2423 &unread_bytes,
2424 &encrypted,
2425 &inbuf_len, &seqnum,
2426 !from_client /* trusted channel */);
2428 if (async_echo && from_client) {
2429 smbd_unlock_socket(sconn);
2432 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2433 goto process;
2435 if (NT_STATUS_IS_ERR(status)) {
2436 exit_server_cleanly("failed to receive smb request");
2438 if (!NT_STATUS_IS_OK(status)) {
2439 return;
2442 process:
2443 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2444 seqnum, encrypted, NULL);
2447 static void smbd_server_connection_handler(struct tevent_context *ev,
2448 struct tevent_fd *fde,
2449 uint16_t flags,
2450 void *private_data)
2452 struct smbd_server_connection *conn = talloc_get_type(private_data,
2453 struct smbd_server_connection);
2455 if (!NT_STATUS_IS_OK(conn->status)) {
2457 * we're not supposed to do any io
2459 TEVENT_FD_NOT_READABLE(conn->smb1.fde);
2460 TEVENT_FD_NOT_WRITEABLE(conn->smb1.fde);
2461 return;
2464 if (flags & TEVENT_FD_WRITE) {
2465 smbd_server_connection_write_handler(conn);
2466 return;
2468 if (flags & TEVENT_FD_READ) {
2469 smbd_server_connection_read_handler(conn, conn->sock);
2470 return;
2474 static void smbd_server_echo_handler(struct tevent_context *ev,
2475 struct tevent_fd *fde,
2476 uint16_t flags,
2477 void *private_data)
2479 struct smbd_server_connection *conn = talloc_get_type(private_data,
2480 struct smbd_server_connection);
2482 if (!NT_STATUS_IS_OK(conn->status)) {
2484 * we're not supposed to do any io
2486 TEVENT_FD_NOT_READABLE(conn->smb1.echo_handler.trusted_fde);
2487 TEVENT_FD_NOT_WRITEABLE(conn->smb1.echo_handler.trusted_fde);
2488 return;
2491 if (flags & TEVENT_FD_WRITE) {
2492 smbd_server_connection_write_handler(conn);
2493 return;
2495 if (flags & TEVENT_FD_READ) {
2496 smbd_server_connection_read_handler(
2497 conn, conn->smb1.echo_handler.trusted_fd);
2498 return;
2502 #ifdef CLUSTER_SUPPORT
2504 struct smbd_release_ip_state {
2505 struct smbd_server_connection *sconn;
2506 struct tevent_immediate *im;
2507 char addr[INET6_ADDRSTRLEN];
2510 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2511 struct tevent_immediate *im,
2512 void *private_data)
2514 struct smbd_release_ip_state *state =
2515 talloc_get_type_abort(private_data,
2516 struct smbd_release_ip_state);
2518 if (!NT_STATUS_EQUAL(state->sconn->status, NT_STATUS_ADDRESS_CLOSED)) {
2520 * smbd_server_connection_terminate() already triggered ?
2522 return;
2525 smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
2528 /****************************************************************************
2529 received when we should release a specific IP
2530 ****************************************************************************/
2531 static bool release_ip(const char *ip, void *priv)
2533 struct smbd_release_ip_state *state =
2534 talloc_get_type_abort(priv,
2535 struct smbd_release_ip_state);
2536 const char *addr = state->addr;
2537 const char *p = addr;
2539 if (!NT_STATUS_IS_OK(state->sconn->status)) {
2540 /* avoid recursion */
2541 return false;
2544 if (strncmp("::ffff:", addr, 7) == 0) {
2545 p = addr + 7;
2548 DEBUG(10, ("Got release IP message for %s, "
2549 "our address is %s\n", ip, p));
2551 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2552 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2553 ip));
2555 * With SMB2 we should do a clean disconnect,
2556 * the previous_session_id in the session setup
2557 * will cleanup the old session, tcons and opens.
2559 * A clean disconnect is needed in order to support
2560 * durable handles.
2562 * Note: typically this is never triggered
2563 * as we got a TCP RST (triggered by ctdb event scripts)
2564 * before we get CTDB_SRVID_RELEASE_IP.
2566 * We used to call _exit(1) here, but as this was mostly never
2567 * triggered and has implication on our process model,
2568 * we can just use smbd_server_connection_terminate()
2569 * (also for SMB1).
2571 * We don't call smbd_server_connection_terminate() directly
2572 * as we might be called from within ctdbd_migrate(),
2573 * we need to defer our action to the next event loop
2575 tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
2576 smbd_release_ip_immediate, state);
2579 * Make sure we don't get any io on the connection.
2581 state->sconn->status = NT_STATUS_ADDRESS_CLOSED;
2582 return true;
2585 return false;
2588 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2589 struct sockaddr_storage *srv,
2590 struct sockaddr_storage *clnt)
2592 struct smbd_release_ip_state *state;
2593 struct ctdbd_connection *cconn;
2595 cconn = messaging_ctdbd_connection();
2596 if (cconn == NULL) {
2597 return NT_STATUS_NO_MEMORY;
2600 state = talloc_zero(sconn, struct smbd_release_ip_state);
2601 if (state == NULL) {
2602 return NT_STATUS_NO_MEMORY;
2604 state->sconn = sconn;
2605 state->im = tevent_create_immediate(state);
2606 if (state->im == NULL) {
2607 return NT_STATUS_NO_MEMORY;
2609 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2610 return NT_STATUS_NO_MEMORY;
2613 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2616 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2617 struct sockaddr_storage *client)
2619 socklen_t length;
2620 length = sizeof(*server);
2621 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2622 return -1;
2624 length = sizeof(*client);
2625 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2626 return -1;
2628 return 0;
2630 #endif
2632 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2633 void *private_data, uint32_t msg_type,
2634 struct server_id server_id, DATA_BLOB *data)
2636 struct smbd_server_connection *sconn = talloc_get_type_abort(
2637 private_data, struct smbd_server_connection);
2638 const char *ip = (char *) data->data;
2639 char *client_ip;
2641 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2643 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2644 talloc_tos());
2645 if (client_ip == NULL) {
2646 return;
2649 if (strequal(ip, client_ip)) {
2650 DEBUG(1, ("Got kill client message for %s - "
2651 "exiting immediately\n", ip));
2652 exit_server_cleanly("Forced disconnect for client");
2655 TALLOC_FREE(client_ip);
2659 * Send keepalive packets to our client
2661 static bool keepalive_fn(const struct timeval *now, void *private_data)
2663 struct smbd_server_connection *sconn = talloc_get_type_abort(
2664 private_data, struct smbd_server_connection);
2665 bool ret;
2667 if (sconn->using_smb2) {
2668 /* Don't do keepalives on an SMB2 connection. */
2669 return false;
2672 smbd_lock_socket(sconn);
2673 ret = send_keepalive(sconn->sock);
2674 smbd_unlock_socket(sconn);
2676 if (!ret) {
2677 char addr[INET6_ADDRSTRLEN];
2679 * Try and give an error message saying what
2680 * client failed.
2682 DEBUG(0, ("send_keepalive failed for client %s. "
2683 "Error %s - exiting\n",
2684 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2685 strerror(errno)));
2686 return False;
2688 return True;
2692 * Do the recurring check if we're idle
2694 static bool deadtime_fn(const struct timeval *now, void *private_data)
2696 struct smbd_server_connection *sconn =
2697 (struct smbd_server_connection *)private_data;
2699 if ((conn_num_open(sconn) == 0)
2700 || (conn_idle_all(sconn, now->tv_sec))) {
2701 DEBUG( 2, ( "Closing idle connection\n" ) );
2702 messaging_send(sconn->msg_ctx,
2703 messaging_server_id(sconn->msg_ctx),
2704 MSG_SHUTDOWN, &data_blob_null);
2705 return False;
2708 return True;
2712 * Do the recurring log file and smb.conf reload checks.
2715 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2717 struct smbd_server_connection *sconn = talloc_get_type_abort(
2718 private_data, struct smbd_server_connection);
2720 DEBUG(5, ("housekeeping\n"));
2722 change_to_root_user();
2724 /* update printer queue caches if necessary */
2725 update_monitored_printq_cache(sconn->msg_ctx);
2727 /* check if we need to reload services */
2728 check_reload(sconn, time_mono(NULL));
2731 * Force a log file check.
2733 force_check_log_size();
2734 check_log_size();
2735 return true;
2739 * Read an smb packet in the echo handler child, giving the parent
2740 * smbd one second to react once the socket becomes readable.
2743 struct smbd_echo_read_state {
2744 struct tevent_context *ev;
2745 struct smbd_server_connection *sconn;
2747 char *buf;
2748 size_t buflen;
2749 uint32_t seqnum;
2752 static void smbd_echo_read_readable(struct tevent_req *subreq);
2753 static void smbd_echo_read_waited(struct tevent_req *subreq);
2755 static struct tevent_req *smbd_echo_read_send(
2756 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2757 struct smbd_server_connection *sconn)
2759 struct tevent_req *req, *subreq;
2760 struct smbd_echo_read_state *state;
2762 req = tevent_req_create(mem_ctx, &state,
2763 struct smbd_echo_read_state);
2764 if (req == NULL) {
2765 return NULL;
2767 state->ev = ev;
2768 state->sconn = sconn;
2770 subreq = wait_for_read_send(state, ev, sconn->sock);
2771 if (tevent_req_nomem(subreq, req)) {
2772 return tevent_req_post(req, ev);
2774 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2775 return req;
2778 static void smbd_echo_read_readable(struct tevent_req *subreq)
2780 struct tevent_req *req = tevent_req_callback_data(
2781 subreq, struct tevent_req);
2782 struct smbd_echo_read_state *state = tevent_req_data(
2783 req, struct smbd_echo_read_state);
2784 bool ok;
2785 int err;
2787 ok = wait_for_read_recv(subreq, &err);
2788 TALLOC_FREE(subreq);
2789 if (!ok) {
2790 tevent_req_nterror(req, map_nt_error_from_unix(err));
2791 return;
2795 * Give the parent smbd one second to step in
2798 subreq = tevent_wakeup_send(
2799 state, state->ev, timeval_current_ofs(1, 0));
2800 if (tevent_req_nomem(subreq, req)) {
2801 return;
2803 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2806 static void smbd_echo_read_waited(struct tevent_req *subreq)
2808 struct tevent_req *req = tevent_req_callback_data(
2809 subreq, struct tevent_req);
2810 struct smbd_echo_read_state *state = tevent_req_data(
2811 req, struct smbd_echo_read_state);
2812 struct smbd_server_connection *sconn = state->sconn;
2813 bool ok;
2814 NTSTATUS status;
2815 size_t unread = 0;
2816 bool encrypted;
2818 ok = tevent_wakeup_recv(subreq);
2819 TALLOC_FREE(subreq);
2820 if (!ok) {
2821 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2822 return;
2825 ok = smbd_lock_socket_internal(sconn);
2826 if (!ok) {
2827 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2828 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2829 return;
2832 if (!fd_is_readable(sconn->sock)) {
2833 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2834 (int)getpid()));
2836 ok = smbd_unlock_socket_internal(sconn);
2837 if (!ok) {
2838 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2839 DEBUG(1, ("%s: failed to unlock socket\n",
2840 __location__));
2841 return;
2844 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2845 if (tevent_req_nomem(subreq, req)) {
2846 return;
2848 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2849 return;
2852 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2853 0 /* timeout */,
2854 &unread,
2855 &encrypted,
2856 &state->buflen,
2857 &state->seqnum,
2858 false /* trusted_channel*/);
2860 if (tevent_req_nterror(req, status)) {
2861 tevent_req_nterror(req, status);
2862 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2863 (int)getpid(), nt_errstr(status)));
2864 return;
2867 ok = smbd_unlock_socket_internal(sconn);
2868 if (!ok) {
2869 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2870 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2871 return;
2873 tevent_req_done(req);
2876 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2877 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2879 struct smbd_echo_read_state *state = tevent_req_data(
2880 req, struct smbd_echo_read_state);
2881 NTSTATUS status;
2883 if (tevent_req_is_nterror(req, &status)) {
2884 return status;
2886 *pbuf = talloc_move(mem_ctx, &state->buf);
2887 *pbuflen = state->buflen;
2888 *pseqnum = state->seqnum;
2889 return NT_STATUS_OK;
2892 struct smbd_echo_state {
2893 struct tevent_context *ev;
2894 struct iovec *pending;
2895 struct smbd_server_connection *sconn;
2896 int parent_pipe;
2898 struct tevent_fd *parent_fde;
2900 struct tevent_req *write_req;
2903 static void smbd_echo_writer_done(struct tevent_req *req);
2905 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2907 int num_pending;
2909 if (state->write_req != NULL) {
2910 return;
2913 num_pending = talloc_array_length(state->pending);
2914 if (num_pending == 0) {
2915 return;
2918 state->write_req = writev_send(state, state->ev, NULL,
2919 state->parent_pipe, false,
2920 state->pending, num_pending);
2921 if (state->write_req == NULL) {
2922 DEBUG(1, ("writev_send failed\n"));
2923 exit(1);
2926 talloc_steal(state->write_req, state->pending);
2927 state->pending = NULL;
2929 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2930 state);
2933 static void smbd_echo_writer_done(struct tevent_req *req)
2935 struct smbd_echo_state *state = tevent_req_callback_data(
2936 req, struct smbd_echo_state);
2937 ssize_t written;
2938 int err;
2940 written = writev_recv(req, &err);
2941 TALLOC_FREE(req);
2942 state->write_req = NULL;
2943 if (written == -1) {
2944 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2945 exit(1);
2947 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2948 smbd_echo_activate_writer(state);
2951 static bool smbd_echo_reply(struct smbd_echo_state *state,
2952 uint8_t *inbuf, size_t inbuf_len,
2953 uint32_t seqnum)
2955 struct smb_request req;
2956 uint16_t num_replies;
2957 char *outbuf;
2958 bool ok;
2960 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2961 DEBUG(10, ("Got netbios keepalive\n"));
2963 * Just swallow it
2965 return true;
2968 if (inbuf_len < smb_size) {
2969 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2970 return false;
2972 if (!valid_smb_header(state->sconn, inbuf)) {
2973 DEBUG(10, ("Got invalid SMB header\n"));
2974 return false;
2977 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2978 seqnum)) {
2979 return false;
2981 req.inbuf = inbuf;
2983 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2984 smb_messages[req.cmd].name
2985 ? smb_messages[req.cmd].name : "unknown"));
2987 if (req.cmd != SMBecho) {
2988 return false;
2990 if (req.wct < 1) {
2991 return false;
2994 num_replies = SVAL(req.vwv+0, 0);
2995 if (num_replies != 1) {
2996 /* Not a Windows "Hey, you're still there?" request */
2997 return false;
3000 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
3001 1, req.buflen)) {
3002 DEBUG(10, ("create_outbuf failed\n"));
3003 return false;
3005 req.outbuf = (uint8_t *)outbuf;
3007 SSVAL(req.outbuf, smb_vwv0, num_replies);
3009 if (req.buflen > 0) {
3010 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3013 ok = srv_send_smb(req.sconn,
3014 (char *)outbuf,
3015 true, seqnum+1,
3016 false, &req.pcd);
3017 TALLOC_FREE(outbuf);
3018 if (!ok) {
3019 exit(1);
3022 return true;
3025 static void smbd_echo_exit(struct tevent_context *ev,
3026 struct tevent_fd *fde, uint16_t flags,
3027 void *private_data)
3029 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3030 exit(0);
3033 static void smbd_echo_got_packet(struct tevent_req *req);
3035 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3036 int parent_pipe)
3038 struct smbd_echo_state *state;
3039 struct tevent_req *read_req;
3041 state = talloc_zero(sconn, struct smbd_echo_state);
3042 if (state == NULL) {
3043 DEBUG(1, ("talloc failed\n"));
3044 return;
3046 state->sconn = sconn;
3047 state->parent_pipe = parent_pipe;
3048 state->ev = s3_tevent_context_init(state);
3049 if (state->ev == NULL) {
3050 DEBUG(1, ("tevent_context_init failed\n"));
3051 TALLOC_FREE(state);
3052 return;
3054 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3055 TEVENT_FD_READ, smbd_echo_exit,
3056 state);
3057 if (state->parent_fde == NULL) {
3058 DEBUG(1, ("tevent_add_fd failed\n"));
3059 TALLOC_FREE(state);
3060 return;
3063 read_req = smbd_echo_read_send(state, state->ev, sconn);
3064 if (read_req == NULL) {
3065 DEBUG(1, ("smbd_echo_read_send failed\n"));
3066 TALLOC_FREE(state);
3067 return;
3069 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3071 while (true) {
3072 if (tevent_loop_once(state->ev) == -1) {
3073 DEBUG(1, ("tevent_loop_once failed: %s\n",
3074 strerror(errno)));
3075 break;
3078 TALLOC_FREE(state);
3081 static void smbd_echo_got_packet(struct tevent_req *req)
3083 struct smbd_echo_state *state = tevent_req_callback_data(
3084 req, struct smbd_echo_state);
3085 NTSTATUS status;
3086 char *buf = NULL;
3087 size_t buflen = 0;
3088 uint32_t seqnum = 0;
3089 bool reply;
3091 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3092 TALLOC_FREE(req);
3093 if (!NT_STATUS_IS_OK(status)) {
3094 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3095 nt_errstr(status)));
3096 exit(1);
3099 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3100 if (!reply) {
3101 size_t num_pending;
3102 struct iovec *tmp;
3103 struct iovec *iov;
3105 num_pending = talloc_array_length(state->pending);
3106 tmp = talloc_realloc(state, state->pending, struct iovec,
3107 num_pending+1);
3108 if (tmp == NULL) {
3109 DEBUG(1, ("talloc_realloc failed\n"));
3110 exit(1);
3112 state->pending = tmp;
3114 if (buflen >= smb_size) {
3116 * place the seqnum in the packet so that the main process
3117 * can reply with signing
3119 SIVAL(buf, smb_ss_field, seqnum);
3120 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3123 iov = &state->pending[num_pending];
3124 iov->iov_base = talloc_move(state->pending, &buf);
3125 iov->iov_len = buflen;
3127 DEBUG(10,("echo_handler[%d]: forward to main\n",
3128 (int)getpid()));
3129 smbd_echo_activate_writer(state);
3132 req = smbd_echo_read_send(state, state->ev, state->sconn);
3133 if (req == NULL) {
3134 DEBUG(1, ("smbd_echo_read_send failed\n"));
3135 exit(1);
3137 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3142 * Handle SMBecho requests in a forked child process
3144 bool fork_echo_handler(struct smbd_server_connection *sconn)
3146 int listener_pipe[2];
3147 int res;
3148 pid_t child;
3150 res = pipe(listener_pipe);
3151 if (res == -1) {
3152 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3153 return false;
3155 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lock_directory());
3156 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3157 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3158 goto fail;
3161 child = fork();
3162 if (child == 0) {
3163 NTSTATUS status;
3165 close(listener_pipe[0]);
3166 set_blocking(listener_pipe[1], false);
3168 status = reinit_after_fork(sconn->msg_ctx,
3169 sconn->ev_ctx,
3170 true);
3171 if (!NT_STATUS_IS_OK(status)) {
3172 DEBUG(1, ("reinit_after_fork failed: %s\n",
3173 nt_errstr(status)));
3174 exit(1);
3176 smbd_echo_loop(sconn, listener_pipe[1]);
3177 exit(0);
3179 close(listener_pipe[1]);
3180 listener_pipe[1] = -1;
3181 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3183 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3186 * Without smb signing this is the same as the normal smbd
3187 * listener. This needs to change once signing comes in.
3189 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3190 sconn,
3191 sconn->smb1.echo_handler.trusted_fd,
3192 TEVENT_FD_READ,
3193 smbd_server_echo_handler,
3194 sconn);
3195 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3196 DEBUG(1, ("event_add_fd failed\n"));
3197 goto fail;
3200 return true;
3202 fail:
3203 if (listener_pipe[0] != -1) {
3204 close(listener_pipe[0]);
3206 if (listener_pipe[1] != -1) {
3207 close(listener_pipe[1]);
3209 sconn->smb1.echo_handler.trusted_fd = -1;
3210 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3211 close(sconn->smb1.echo_handler.socket_lock_fd);
3213 sconn->smb1.echo_handler.trusted_fd = -1;
3214 sconn->smb1.echo_handler.socket_lock_fd = -1;
3215 return false;
3218 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3220 while (user) {
3221 if (user->session_info &&
3222 (user->session_info->unix_token->uid == uid)) {
3223 return true;
3225 user = user->next;
3227 return false;
3230 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3232 while (user) {
3233 if (user->session_info != NULL) {
3234 int i;
3235 struct security_unix_token *utok;
3237 utok = user->session_info->unix_token;
3238 if (utok->gid == gid) {
3239 return true;
3241 for(i=0; i<utok->ngroups; i++) {
3242 if (utok->groups[i] == gid) {
3243 return true;
3247 user = user->next;
3249 return false;
3252 static bool sid_in_use(const struct user_struct *user,
3253 const struct dom_sid *psid)
3255 while (user) {
3256 struct security_token *tok;
3258 if (user->session_info == NULL) {
3259 continue;
3261 tok = user->session_info->security_token;
3262 if (tok == NULL) {
3264 * Not sure session_info->security_token can
3265 * ever be NULL. This check might be not
3266 * necessary.
3268 continue;
3270 if (security_token_has_sid(tok, psid)) {
3271 return true;
3273 user = user->next;
3275 return false;
3278 static bool id_in_use(const struct user_struct *user,
3279 const struct id_cache_ref *id)
3281 switch(id->type) {
3282 case UID:
3283 return uid_in_use(user, id->id.uid);
3284 case GID:
3285 return gid_in_use(user, id->id.gid);
3286 case SID:
3287 return sid_in_use(user, &id->id.sid);
3288 default:
3289 break;
3291 return false;
3294 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3295 void *private_data,
3296 uint32_t msg_type,
3297 struct server_id server_id,
3298 DATA_BLOB* data)
3300 const char *msg = (data && data->data)
3301 ? (const char *)data->data : "<NULL>";
3302 struct id_cache_ref id;
3303 struct smbd_server_connection *sconn =
3304 talloc_get_type_abort(private_data,
3305 struct smbd_server_connection);
3307 if (!id_cache_ref_parse(msg, &id)) {
3308 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3309 return;
3312 if (id_in_use(sconn->users, &id)) {
3313 exit_server_cleanly(msg);
3315 id_cache_delete_from_cache(&id);
3318 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3319 enum protocol_types protocol)
3321 NTSTATUS status;
3323 set_Protocol(protocol);
3324 conn->protocol = protocol;
3326 if (protocol >= PROTOCOL_SMB2_02) {
3327 status = smb2srv_session_table_init(conn);
3328 if (!NT_STATUS_IS_OK(status)) {
3329 return status;
3332 status = smb2srv_open_table_init(conn);
3333 if (!NT_STATUS_IS_OK(status)) {
3334 return status;
3336 } else {
3337 status = smb1srv_session_table_init(conn);
3338 if (!NT_STATUS_IS_OK(status)) {
3339 return status;
3342 status = smb1srv_tcon_table_init(conn);
3343 if (!NT_STATUS_IS_OK(status)) {
3344 return status;
3347 status = smb1srv_open_table_init(conn);
3348 if (!NT_STATUS_IS_OK(status)) {
3349 return status;
3353 return NT_STATUS_OK;
3356 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3357 void *private_data)
3359 struct smbXsrv_connection *conn =
3360 talloc_get_type_abort(private_data,
3361 struct smbXsrv_connection);
3363 switch (point) {
3364 case TEVENT_TRACE_BEFORE_WAIT:
3366 * This just removes compiler warning
3367 * without profile support
3369 conn->smbd_idle_profstamp = 0;
3370 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3371 break;
3372 case TEVENT_TRACE_AFTER_WAIT:
3373 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3374 break;
3378 /****************************************************************************
3379 Process commands from the client
3380 ****************************************************************************/
3382 void smbd_process(struct tevent_context *ev_ctx,
3383 struct messaging_context *msg_ctx,
3384 int sock_fd,
3385 bool interactive)
3387 TALLOC_CTX *frame = talloc_stackframe();
3388 struct smbXsrv_connection *conn;
3389 struct smbd_server_connection *sconn;
3390 struct sockaddr_storage ss;
3391 struct sockaddr *sa = NULL;
3392 socklen_t sa_socklen;
3393 struct tsocket_address *local_address = NULL;
3394 struct tsocket_address *remote_address = NULL;
3395 const char *locaddr = NULL;
3396 const char *remaddr = NULL;
3397 char *rhost;
3398 int ret;
3399 int tmp;
3401 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3402 if (conn == NULL) {
3403 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3404 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3407 conn->ev_ctx = ev_ctx;
3408 conn->msg_ctx = msg_ctx;
3410 sconn = talloc_zero(conn, struct smbd_server_connection);
3411 if (!sconn) {
3412 exit_server("failed to create smbd_server_connection");
3415 conn->sconn = sconn;
3416 sconn->conn = conn;
3419 * TODO: remove this...:-)
3421 global_smbXsrv_connection = conn;
3423 sconn->ev_ctx = ev_ctx;
3424 sconn->msg_ctx = msg_ctx;
3425 sconn->sock = sock_fd;
3426 sconn->smb1.echo_handler.trusted_fd = -1;
3427 sconn->smb1.echo_handler.socket_lock_fd = -1;
3429 if (!interactive) {
3430 smbd_setup_sig_term_handler(sconn);
3431 smbd_setup_sig_hup_handler(sconn);
3433 if (!serverid_register(messaging_server_id(msg_ctx),
3434 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3435 |FLAG_MSG_DBWRAP
3436 |FLAG_MSG_PRINT_GENERAL)) {
3437 exit_server_cleanly("Could not register myself in "
3438 "serverid.tdb");
3442 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3444 * We're not making the decision here,
3445 * we're just allowing the client
3446 * to decide between SMB1 and SMB2
3447 * with the first negprot
3448 * packet.
3450 sconn->using_smb2 = true;
3453 /* Ensure child is set to blocking mode */
3454 set_blocking(sconn->sock,True);
3456 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3457 set_socket_options(sconn->sock, lp_socket_options());
3459 sa = (struct sockaddr *)(void *)&ss;
3460 sa_socklen = sizeof(ss);
3461 ret = getpeername(sconn->sock, sa, &sa_socklen);
3462 if (ret != 0) {
3463 int level = (errno == ENOTCONN)?2:0;
3464 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3465 exit_server_cleanly("getpeername() failed.\n");
3467 ret = tsocket_address_bsd_from_sockaddr(sconn,
3468 sa, sa_socklen,
3469 &remote_address);
3470 if (ret != 0) {
3471 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3472 __location__, strerror(errno)));
3473 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3476 sa = (struct sockaddr *)(void *)&ss;
3477 sa_socklen = sizeof(ss);
3478 ret = getsockname(sconn->sock, sa, &sa_socklen);
3479 if (ret != 0) {
3480 int level = (errno == ENOTCONN)?2:0;
3481 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3482 exit_server_cleanly("getsockname() failed.\n");
3484 ret = tsocket_address_bsd_from_sockaddr(sconn,
3485 sa, sa_socklen,
3486 &local_address);
3487 if (ret != 0) {
3488 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3489 __location__, strerror(errno)));
3490 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3493 sconn->local_address = local_address;
3494 sconn->remote_address = remote_address;
3496 if (tsocket_address_is_inet(local_address, "ip")) {
3497 locaddr = tsocket_address_inet_addr_string(
3498 sconn->local_address,
3499 talloc_tos());
3500 if (locaddr == NULL) {
3501 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3502 __location__, strerror(errno)));
3503 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3505 } else {
3506 locaddr = "0.0.0.0";
3509 if (tsocket_address_is_inet(remote_address, "ip")) {
3510 remaddr = tsocket_address_inet_addr_string(
3511 sconn->remote_address,
3512 talloc_tos());
3513 if (remaddr == NULL) {
3514 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3515 __location__, strerror(errno)));
3516 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3518 } else {
3519 remaddr = "0.0.0.0";
3522 /* this is needed so that we get decent entries
3523 in smbstatus for port 445 connects */
3524 set_remote_machine_name(remaddr, false);
3525 reload_services(sconn, conn_snum_used, true);
3528 * Before the first packet, check the global hosts allow/ hosts deny
3529 * parameters before doing any parsing of packets passed to us by the
3530 * client. This prevents attacks on our parsing code from hosts not in
3531 * the hosts allow list.
3534 ret = get_remote_hostname(remote_address,
3535 &rhost,
3536 talloc_tos());
3537 if (ret < 0) {
3538 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3539 __location__, strerror(errno)));
3540 exit_server_cleanly("get_remote_hostname failed.\n");
3542 if (strequal(rhost, "UNKNOWN")) {
3543 rhost = talloc_strdup(talloc_tos(), remaddr);
3545 sconn->remote_hostname = talloc_move(sconn, &rhost);
3547 sub_set_socket_ids(remaddr,
3548 sconn->remote_hostname,
3549 locaddr);
3551 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3552 sconn->remote_hostname,
3553 remaddr)) {
3555 * send a negative session response "not listening on calling
3556 * name"
3558 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3559 DEBUG( 1, ("Connection denied from %s to %s\n",
3560 tsocket_address_string(remote_address, talloc_tos()),
3561 tsocket_address_string(local_address, talloc_tos())));
3562 (void)srv_send_smb(sconn,(char *)buf, false,
3563 0, false, NULL);
3564 exit_server_cleanly("connection denied");
3567 DEBUG(10, ("Connection allowed from %s to %s\n",
3568 tsocket_address_string(remote_address, talloc_tos()),
3569 tsocket_address_string(local_address, talloc_tos())));
3571 if (lp_preload_modules()) {
3572 smb_load_modules(lp_preload_modules());
3575 smb_perfcount_init();
3577 if (!init_account_policy()) {
3578 exit_server("Could not open account policy tdb.\n");
3581 if (*lp_root_directory(talloc_tos())) {
3582 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3583 DEBUG(0,("Failed to change root to %s\n",
3584 lp_root_directory(talloc_tos())));
3585 exit_server("Failed to chroot()");
3587 if (chdir("/") == -1) {
3588 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3589 exit_server("Failed to chroot()");
3591 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3594 if (!srv_init_signing(sconn)) {
3595 exit_server("Failed to init smb_signing");
3598 if (!file_init(sconn)) {
3599 exit_server("file_init() failed");
3602 /* Setup oplocks */
3603 if (!init_oplocks(sconn))
3604 exit_server("Failed to init oplocks");
3606 /* register our message handlers */
3607 messaging_register(sconn->msg_ctx, sconn,
3608 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3609 messaging_register(sconn->msg_ctx, sconn,
3610 MSG_SMB_CLOSE_FILE, msg_close_file);
3611 messaging_register(sconn->msg_ctx, sconn,
3612 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3614 id_cache_register_msgs(sconn->msg_ctx);
3615 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3616 messaging_register(sconn->msg_ctx, sconn,
3617 ID_CACHE_KILL, smbd_id_cache_kill);
3619 messaging_deregister(sconn->msg_ctx,
3620 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3621 messaging_register(sconn->msg_ctx, sconn,
3622 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3624 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3625 NULL);
3626 messaging_register(sconn->msg_ctx, sconn,
3627 MSG_SMB_KILL_CLIENT_IP,
3628 msg_kill_client_ip);
3630 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3633 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3634 * MSGs to all child processes
3636 messaging_deregister(sconn->msg_ctx,
3637 MSG_DEBUG, NULL);
3638 messaging_register(sconn->msg_ctx, NULL,
3639 MSG_DEBUG, debug_message);
3641 if ((lp_keepalive() != 0)
3642 && !(event_add_idle(ev_ctx, NULL,
3643 timeval_set(lp_keepalive(), 0),
3644 "keepalive", keepalive_fn,
3645 sconn))) {
3646 DEBUG(0, ("Could not add keepalive event\n"));
3647 exit(1);
3650 if (!(event_add_idle(ev_ctx, NULL,
3651 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3652 "deadtime", deadtime_fn, sconn))) {
3653 DEBUG(0, ("Could not add deadtime event\n"));
3654 exit(1);
3657 if (!(event_add_idle(ev_ctx, NULL,
3658 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3659 "housekeeping", housekeeping_fn, sconn))) {
3660 DEBUG(0, ("Could not add housekeeping event\n"));
3661 exit(1);
3664 #ifdef CLUSTER_SUPPORT
3666 if (lp_clustering()) {
3668 * We need to tell ctdb about our client's TCP
3669 * connection, so that for failover ctdbd can send
3670 * tickle acks, triggering a reconnection by the
3671 * client.
3674 struct sockaddr_storage srv, clnt;
3676 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3677 NTSTATUS status;
3678 status = smbd_register_ips(sconn, &srv, &clnt);
3679 if (!NT_STATUS_IS_OK(status)) {
3680 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3681 nt_errstr(status)));
3683 } else {
3684 int level = (errno == ENOTCONN)?2:0;
3685 DEBUG(level,("Unable to get tcp info for "
3686 "smbd_register_ips: %s\n",
3687 strerror(errno)));
3688 exit_server_cleanly("client_get_tcp_info() failed.\n");
3692 #endif
3694 sconn->nbt.got_session = false;
3696 tmp = lp_max_xmit();
3697 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3698 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3700 sconn->smb1.negprot.max_recv = tmp;
3702 sconn->smb1.sessions.done_sesssetup = false;
3703 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3705 if (!init_dptrs(sconn)) {
3706 exit_server("init_dptrs() failed");
3709 sconn->smb1.fde = tevent_add_fd(ev_ctx,
3710 sconn,
3711 sconn->sock,
3712 TEVENT_FD_READ,
3713 smbd_server_connection_handler,
3714 sconn);
3715 if (!sconn->smb1.fde) {
3716 exit_server("failed to create smbd_server_connection fde");
3719 sconn->conn->local_address = sconn->local_address;
3720 sconn->conn->remote_address = sconn->remote_address;
3721 sconn->conn->remote_hostname = sconn->remote_hostname;
3722 sconn->conn->protocol = PROTOCOL_NONE;
3724 TALLOC_FREE(frame);
3726 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3728 while (True) {
3729 frame = talloc_stackframe_pool(8192);
3731 errno = 0;
3732 if (tevent_loop_once(ev_ctx) == -1) {
3733 if (errno != EINTR) {
3734 DEBUG(3, ("tevent_loop_once failed: %s,"
3735 " exiting\n", strerror(errno) ));
3736 break;
3740 TALLOC_FREE(frame);
3743 exit_server_cleanly(NULL);
3746 bool req_is_in_chain(const struct smb_request *req)
3748 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3750 * We're right now handling a subsequent request, so we must
3751 * be in a chain
3753 return true;
3756 if (!is_andx_req(req->cmd)) {
3757 return false;
3760 if (req->wct < 2) {
3762 * Okay, an illegal request, but definitely not chained :-)
3764 return false;
3767 return (CVAL(req->vwv+0, 0) != 0xFF);