ctdb-logging: Split ringbuffer handling code from ctdb_collect_log
[Samba/wip.git] / source3 / smbd / process.c
blob8a1d1d677046cf48e7d513e692e92793d896ee37
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 > (LARGE_WRITEX_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 struct smbd_release_ip_state {
2503 struct smbd_server_connection *sconn;
2504 struct tevent_immediate *im;
2505 char addr[INET6_ADDRSTRLEN];
2508 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2509 struct tevent_immediate *im,
2510 void *private_data)
2512 struct smbd_release_ip_state *state =
2513 talloc_get_type_abort(private_data,
2514 struct smbd_release_ip_state);
2516 if (!NT_STATUS_EQUAL(state->sconn->status, NT_STATUS_ADDRESS_CLOSED)) {
2518 * smbd_server_connection_terminate() already triggered ?
2520 return;
2523 smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
2526 /****************************************************************************
2527 received when we should release a specific IP
2528 ****************************************************************************/
2529 static bool release_ip(const char *ip, void *priv)
2531 struct smbd_release_ip_state *state =
2532 talloc_get_type_abort(priv,
2533 struct smbd_release_ip_state);
2534 const char *addr = state->addr;
2535 const char *p = addr;
2537 if (!NT_STATUS_IS_OK(state->sconn->status)) {
2538 /* avoid recursion */
2539 return false;
2542 if (strncmp("::ffff:", addr, 7) == 0) {
2543 p = addr + 7;
2546 DEBUG(10, ("Got release IP message for %s, "
2547 "our address is %s\n", ip, p));
2549 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2550 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2551 ip));
2553 * With SMB2 we should do a clean disconnect,
2554 * the previous_session_id in the session setup
2555 * will cleanup the old session, tcons and opens.
2557 * A clean disconnect is needed in order to support
2558 * durable handles.
2560 * Note: typically this is never triggered
2561 * as we got a TCP RST (triggered by ctdb event scripts)
2562 * before we get CTDB_SRVID_RELEASE_IP.
2564 * We used to call _exit(1) here, but as this was mostly never
2565 * triggered and has implication on our process model,
2566 * we can just use smbd_server_connection_terminate()
2567 * (also for SMB1).
2569 * We don't call smbd_server_connection_terminate() directly
2570 * as we might be called from within ctdbd_migrate(),
2571 * we need to defer our action to the next event loop
2573 tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
2574 smbd_release_ip_immediate, state);
2577 * Make sure we don't get any io on the connection.
2579 state->sconn->status = NT_STATUS_ADDRESS_CLOSED;
2580 return true;
2583 return false;
2586 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2587 struct sockaddr_storage *srv,
2588 struct sockaddr_storage *clnt)
2590 struct smbd_release_ip_state *state;
2591 struct ctdbd_connection *cconn;
2593 cconn = messaging_ctdbd_connection();
2594 if (cconn == NULL) {
2595 return NT_STATUS_NO_MEMORY;
2598 state = talloc_zero(sconn, struct smbd_release_ip_state);
2599 if (state == NULL) {
2600 return NT_STATUS_NO_MEMORY;
2602 state->sconn = sconn;
2603 state->im = tevent_create_immediate(state);
2604 if (state->im == NULL) {
2605 return NT_STATUS_NO_MEMORY;
2607 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2608 return NT_STATUS_NO_MEMORY;
2611 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2614 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2615 struct sockaddr_storage *client)
2617 socklen_t length;
2618 length = sizeof(*server);
2619 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2620 return -1;
2622 length = sizeof(*client);
2623 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2624 return -1;
2626 return 0;
2629 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2630 void *private_data, uint32_t msg_type,
2631 struct server_id server_id, DATA_BLOB *data)
2633 struct smbd_server_connection *sconn = talloc_get_type_abort(
2634 private_data, struct smbd_server_connection);
2635 const char *ip = (char *) data->data;
2636 char *client_ip;
2638 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2640 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2641 talloc_tos());
2642 if (client_ip == NULL) {
2643 return;
2646 if (strequal(ip, client_ip)) {
2647 DEBUG(1, ("Got kill client message for %s - "
2648 "exiting immediately\n", ip));
2649 exit_server_cleanly("Forced disconnect for client");
2652 TALLOC_FREE(client_ip);
2656 * Send keepalive packets to our client
2658 static bool keepalive_fn(const struct timeval *now, void *private_data)
2660 struct smbd_server_connection *sconn = talloc_get_type_abort(
2661 private_data, struct smbd_server_connection);
2662 bool ret;
2664 if (sconn->using_smb2) {
2665 /* Don't do keepalives on an SMB2 connection. */
2666 return false;
2669 smbd_lock_socket(sconn);
2670 ret = send_keepalive(sconn->sock);
2671 smbd_unlock_socket(sconn);
2673 if (!ret) {
2674 char addr[INET6_ADDRSTRLEN];
2676 * Try and give an error message saying what
2677 * client failed.
2679 DEBUG(0, ("send_keepalive failed for client %s. "
2680 "Error %s - exiting\n",
2681 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2682 strerror(errno)));
2683 return False;
2685 return True;
2689 * Do the recurring check if we're idle
2691 static bool deadtime_fn(const struct timeval *now, void *private_data)
2693 struct smbd_server_connection *sconn =
2694 (struct smbd_server_connection *)private_data;
2696 if ((conn_num_open(sconn) == 0)
2697 || (conn_idle_all(sconn, now->tv_sec))) {
2698 DEBUG( 2, ( "Closing idle connection\n" ) );
2699 messaging_send(sconn->msg_ctx,
2700 messaging_server_id(sconn->msg_ctx),
2701 MSG_SHUTDOWN, &data_blob_null);
2702 return False;
2705 return True;
2709 * Do the recurring log file and smb.conf reload checks.
2712 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2714 struct smbd_server_connection *sconn = talloc_get_type_abort(
2715 private_data, struct smbd_server_connection);
2717 DEBUG(5, ("housekeeping\n"));
2719 change_to_root_user();
2721 /* update printer queue caches if necessary */
2722 update_monitored_printq_cache(sconn->msg_ctx);
2724 /* check if we need to reload services */
2725 check_reload(sconn, time_mono(NULL));
2728 * Force a log file check.
2730 force_check_log_size();
2731 check_log_size();
2732 return true;
2736 * Read an smb packet in the echo handler child, giving the parent
2737 * smbd one second to react once the socket becomes readable.
2740 struct smbd_echo_read_state {
2741 struct tevent_context *ev;
2742 struct smbd_server_connection *sconn;
2744 char *buf;
2745 size_t buflen;
2746 uint32_t seqnum;
2749 static void smbd_echo_read_readable(struct tevent_req *subreq);
2750 static void smbd_echo_read_waited(struct tevent_req *subreq);
2752 static struct tevent_req *smbd_echo_read_send(
2753 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2754 struct smbd_server_connection *sconn)
2756 struct tevent_req *req, *subreq;
2757 struct smbd_echo_read_state *state;
2759 req = tevent_req_create(mem_ctx, &state,
2760 struct smbd_echo_read_state);
2761 if (req == NULL) {
2762 return NULL;
2764 state->ev = ev;
2765 state->sconn = sconn;
2767 subreq = wait_for_read_send(state, ev, sconn->sock);
2768 if (tevent_req_nomem(subreq, req)) {
2769 return tevent_req_post(req, ev);
2771 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2772 return req;
2775 static void smbd_echo_read_readable(struct tevent_req *subreq)
2777 struct tevent_req *req = tevent_req_callback_data(
2778 subreq, struct tevent_req);
2779 struct smbd_echo_read_state *state = tevent_req_data(
2780 req, struct smbd_echo_read_state);
2781 bool ok;
2782 int err;
2784 ok = wait_for_read_recv(subreq, &err);
2785 TALLOC_FREE(subreq);
2786 if (!ok) {
2787 tevent_req_nterror(req, map_nt_error_from_unix(err));
2788 return;
2792 * Give the parent smbd one second to step in
2795 subreq = tevent_wakeup_send(
2796 state, state->ev, timeval_current_ofs(1, 0));
2797 if (tevent_req_nomem(subreq, req)) {
2798 return;
2800 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2803 static void smbd_echo_read_waited(struct tevent_req *subreq)
2805 struct tevent_req *req = tevent_req_callback_data(
2806 subreq, struct tevent_req);
2807 struct smbd_echo_read_state *state = tevent_req_data(
2808 req, struct smbd_echo_read_state);
2809 struct smbd_server_connection *sconn = state->sconn;
2810 bool ok;
2811 NTSTATUS status;
2812 size_t unread = 0;
2813 bool encrypted;
2815 ok = tevent_wakeup_recv(subreq);
2816 TALLOC_FREE(subreq);
2817 if (!ok) {
2818 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2819 return;
2822 ok = smbd_lock_socket_internal(sconn);
2823 if (!ok) {
2824 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2825 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2826 return;
2829 if (!fd_is_readable(sconn->sock)) {
2830 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2831 (int)getpid()));
2833 ok = smbd_unlock_socket_internal(sconn);
2834 if (!ok) {
2835 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2836 DEBUG(1, ("%s: failed to unlock socket\n",
2837 __location__));
2838 return;
2841 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2842 if (tevent_req_nomem(subreq, req)) {
2843 return;
2845 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2846 return;
2849 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2850 0 /* timeout */,
2851 &unread,
2852 &encrypted,
2853 &state->buflen,
2854 &state->seqnum,
2855 false /* trusted_channel*/);
2857 if (tevent_req_nterror(req, status)) {
2858 tevent_req_nterror(req, status);
2859 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2860 (int)getpid(), nt_errstr(status)));
2861 return;
2864 ok = smbd_unlock_socket_internal(sconn);
2865 if (!ok) {
2866 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2867 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2868 return;
2870 tevent_req_done(req);
2873 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2874 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2876 struct smbd_echo_read_state *state = tevent_req_data(
2877 req, struct smbd_echo_read_state);
2878 NTSTATUS status;
2880 if (tevent_req_is_nterror(req, &status)) {
2881 return status;
2883 *pbuf = talloc_move(mem_ctx, &state->buf);
2884 *pbuflen = state->buflen;
2885 *pseqnum = state->seqnum;
2886 return NT_STATUS_OK;
2889 struct smbd_echo_state {
2890 struct tevent_context *ev;
2891 struct iovec *pending;
2892 struct smbd_server_connection *sconn;
2893 int parent_pipe;
2895 struct tevent_fd *parent_fde;
2897 struct tevent_req *write_req;
2900 static void smbd_echo_writer_done(struct tevent_req *req);
2902 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2904 int num_pending;
2906 if (state->write_req != NULL) {
2907 return;
2910 num_pending = talloc_array_length(state->pending);
2911 if (num_pending == 0) {
2912 return;
2915 state->write_req = writev_send(state, state->ev, NULL,
2916 state->parent_pipe, false,
2917 state->pending, num_pending);
2918 if (state->write_req == NULL) {
2919 DEBUG(1, ("writev_send failed\n"));
2920 exit(1);
2923 talloc_steal(state->write_req, state->pending);
2924 state->pending = NULL;
2926 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2927 state);
2930 static void smbd_echo_writer_done(struct tevent_req *req)
2932 struct smbd_echo_state *state = tevent_req_callback_data(
2933 req, struct smbd_echo_state);
2934 ssize_t written;
2935 int err;
2937 written = writev_recv(req, &err);
2938 TALLOC_FREE(req);
2939 state->write_req = NULL;
2940 if (written == -1) {
2941 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2942 exit(1);
2944 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2945 smbd_echo_activate_writer(state);
2948 static bool smbd_echo_reply(struct smbd_echo_state *state,
2949 uint8_t *inbuf, size_t inbuf_len,
2950 uint32_t seqnum)
2952 struct smb_request req;
2953 uint16_t num_replies;
2954 char *outbuf;
2955 bool ok;
2957 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2958 DEBUG(10, ("Got netbios keepalive\n"));
2960 * Just swallow it
2962 return true;
2965 if (inbuf_len < smb_size) {
2966 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2967 return false;
2969 if (!valid_smb_header(state->sconn, inbuf)) {
2970 DEBUG(10, ("Got invalid SMB header\n"));
2971 return false;
2974 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2975 seqnum)) {
2976 return false;
2978 req.inbuf = inbuf;
2980 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2981 smb_messages[req.cmd].name
2982 ? smb_messages[req.cmd].name : "unknown"));
2984 if (req.cmd != SMBecho) {
2985 return false;
2987 if (req.wct < 1) {
2988 return false;
2991 num_replies = SVAL(req.vwv+0, 0);
2992 if (num_replies != 1) {
2993 /* Not a Windows "Hey, you're still there?" request */
2994 return false;
2997 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2998 1, req.buflen)) {
2999 DEBUG(10, ("create_outbuf failed\n"));
3000 return false;
3002 req.outbuf = (uint8_t *)outbuf;
3004 SSVAL(req.outbuf, smb_vwv0, num_replies);
3006 if (req.buflen > 0) {
3007 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3010 ok = srv_send_smb(req.sconn,
3011 (char *)outbuf,
3012 true, seqnum+1,
3013 false, &req.pcd);
3014 TALLOC_FREE(outbuf);
3015 if (!ok) {
3016 exit(1);
3019 return true;
3022 static void smbd_echo_exit(struct tevent_context *ev,
3023 struct tevent_fd *fde, uint16_t flags,
3024 void *private_data)
3026 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3027 exit(0);
3030 static void smbd_echo_got_packet(struct tevent_req *req);
3032 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3033 int parent_pipe)
3035 struct smbd_echo_state *state;
3036 struct tevent_req *read_req;
3038 state = talloc_zero(sconn, struct smbd_echo_state);
3039 if (state == NULL) {
3040 DEBUG(1, ("talloc failed\n"));
3041 return;
3043 state->sconn = sconn;
3044 state->parent_pipe = parent_pipe;
3045 state->ev = s3_tevent_context_init(state);
3046 if (state->ev == NULL) {
3047 DEBUG(1, ("tevent_context_init failed\n"));
3048 TALLOC_FREE(state);
3049 return;
3051 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3052 TEVENT_FD_READ, smbd_echo_exit,
3053 state);
3054 if (state->parent_fde == NULL) {
3055 DEBUG(1, ("tevent_add_fd failed\n"));
3056 TALLOC_FREE(state);
3057 return;
3060 read_req = smbd_echo_read_send(state, state->ev, sconn);
3061 if (read_req == NULL) {
3062 DEBUG(1, ("smbd_echo_read_send failed\n"));
3063 TALLOC_FREE(state);
3064 return;
3066 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3068 while (true) {
3069 if (tevent_loop_once(state->ev) == -1) {
3070 DEBUG(1, ("tevent_loop_once failed: %s\n",
3071 strerror(errno)));
3072 break;
3075 TALLOC_FREE(state);
3078 static void smbd_echo_got_packet(struct tevent_req *req)
3080 struct smbd_echo_state *state = tevent_req_callback_data(
3081 req, struct smbd_echo_state);
3082 NTSTATUS status;
3083 char *buf = NULL;
3084 size_t buflen = 0;
3085 uint32_t seqnum = 0;
3086 bool reply;
3088 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3089 TALLOC_FREE(req);
3090 if (!NT_STATUS_IS_OK(status)) {
3091 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3092 nt_errstr(status)));
3093 exit(1);
3096 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3097 if (!reply) {
3098 size_t num_pending;
3099 struct iovec *tmp;
3100 struct iovec *iov;
3102 num_pending = talloc_array_length(state->pending);
3103 tmp = talloc_realloc(state, state->pending, struct iovec,
3104 num_pending+1);
3105 if (tmp == NULL) {
3106 DEBUG(1, ("talloc_realloc failed\n"));
3107 exit(1);
3109 state->pending = tmp;
3111 if (buflen >= smb_size) {
3113 * place the seqnum in the packet so that the main process
3114 * can reply with signing
3116 SIVAL(buf, smb_ss_field, seqnum);
3117 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3120 iov = &state->pending[num_pending];
3121 iov->iov_base = talloc_move(state->pending, &buf);
3122 iov->iov_len = buflen;
3124 DEBUG(10,("echo_handler[%d]: forward to main\n",
3125 (int)getpid()));
3126 smbd_echo_activate_writer(state);
3129 req = smbd_echo_read_send(state, state->ev, state->sconn);
3130 if (req == NULL) {
3131 DEBUG(1, ("smbd_echo_read_send failed\n"));
3132 exit(1);
3134 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3139 * Handle SMBecho requests in a forked child process
3141 bool fork_echo_handler(struct smbd_server_connection *sconn)
3143 int listener_pipe[2];
3144 int res;
3145 pid_t child;
3147 res = pipe(listener_pipe);
3148 if (res == -1) {
3149 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3150 return false;
3152 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lock_directory());
3153 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3154 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3155 goto fail;
3158 child = fork();
3159 if (child == 0) {
3160 NTSTATUS status;
3162 close(listener_pipe[0]);
3163 set_blocking(listener_pipe[1], false);
3165 status = reinit_after_fork(sconn->msg_ctx,
3166 sconn->ev_ctx,
3167 true);
3168 if (!NT_STATUS_IS_OK(status)) {
3169 DEBUG(1, ("reinit_after_fork failed: %s\n",
3170 nt_errstr(status)));
3171 exit(1);
3173 smbd_echo_loop(sconn, listener_pipe[1]);
3174 exit(0);
3176 close(listener_pipe[1]);
3177 listener_pipe[1] = -1;
3178 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3180 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3183 * Without smb signing this is the same as the normal smbd
3184 * listener. This needs to change once signing comes in.
3186 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3187 sconn,
3188 sconn->smb1.echo_handler.trusted_fd,
3189 TEVENT_FD_READ,
3190 smbd_server_echo_handler,
3191 sconn);
3192 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3193 DEBUG(1, ("event_add_fd failed\n"));
3194 goto fail;
3197 return true;
3199 fail:
3200 if (listener_pipe[0] != -1) {
3201 close(listener_pipe[0]);
3203 if (listener_pipe[1] != -1) {
3204 close(listener_pipe[1]);
3206 sconn->smb1.echo_handler.trusted_fd = -1;
3207 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3208 close(sconn->smb1.echo_handler.socket_lock_fd);
3210 sconn->smb1.echo_handler.trusted_fd = -1;
3211 sconn->smb1.echo_handler.socket_lock_fd = -1;
3212 return false;
3215 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3217 while (user) {
3218 if (user->session_info &&
3219 (user->session_info->unix_token->uid == uid)) {
3220 return true;
3222 user = user->next;
3224 return false;
3227 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3229 while (user) {
3230 if (user->session_info != NULL) {
3231 int i;
3232 struct security_unix_token *utok;
3234 utok = user->session_info->unix_token;
3235 if (utok->gid == gid) {
3236 return true;
3238 for(i=0; i<utok->ngroups; i++) {
3239 if (utok->groups[i] == gid) {
3240 return true;
3244 user = user->next;
3246 return false;
3249 static bool sid_in_use(const struct user_struct *user,
3250 const struct dom_sid *psid)
3252 while (user) {
3253 struct security_token *tok;
3255 if (user->session_info == NULL) {
3256 continue;
3258 tok = user->session_info->security_token;
3259 if (tok == NULL) {
3261 * Not sure session_info->security_token can
3262 * ever be NULL. This check might be not
3263 * necessary.
3265 continue;
3267 if (security_token_has_sid(tok, psid)) {
3268 return true;
3270 user = user->next;
3272 return false;
3275 static bool id_in_use(const struct user_struct *user,
3276 const struct id_cache_ref *id)
3278 switch(id->type) {
3279 case UID:
3280 return uid_in_use(user, id->id.uid);
3281 case GID:
3282 return gid_in_use(user, id->id.gid);
3283 case SID:
3284 return sid_in_use(user, &id->id.sid);
3285 default:
3286 break;
3288 return false;
3291 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3292 void *private_data,
3293 uint32_t msg_type,
3294 struct server_id server_id,
3295 DATA_BLOB* data)
3297 const char *msg = (data && data->data)
3298 ? (const char *)data->data : "<NULL>";
3299 struct id_cache_ref id;
3300 struct smbd_server_connection *sconn =
3301 talloc_get_type_abort(private_data,
3302 struct smbd_server_connection);
3304 if (!id_cache_ref_parse(msg, &id)) {
3305 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3306 return;
3309 if (id_in_use(sconn->users, &id)) {
3310 exit_server_cleanly(msg);
3312 id_cache_delete_from_cache(&id);
3315 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3316 enum protocol_types protocol)
3318 NTSTATUS status;
3320 set_Protocol(protocol);
3321 conn->protocol = protocol;
3323 if (protocol >= PROTOCOL_SMB2_02) {
3324 status = smb2srv_session_table_init(conn);
3325 if (!NT_STATUS_IS_OK(status)) {
3326 return status;
3329 status = smb2srv_open_table_init(conn);
3330 if (!NT_STATUS_IS_OK(status)) {
3331 return status;
3333 } else {
3334 status = smb1srv_session_table_init(conn);
3335 if (!NT_STATUS_IS_OK(status)) {
3336 return status;
3339 status = smb1srv_tcon_table_init(conn);
3340 if (!NT_STATUS_IS_OK(status)) {
3341 return status;
3344 status = smb1srv_open_table_init(conn);
3345 if (!NT_STATUS_IS_OK(status)) {
3346 return status;
3350 return NT_STATUS_OK;
3353 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3354 void *private_data)
3356 struct smbXsrv_connection *conn =
3357 talloc_get_type_abort(private_data,
3358 struct smbXsrv_connection);
3360 switch (point) {
3361 case TEVENT_TRACE_BEFORE_WAIT:
3363 * This just removes compiler warning
3364 * without profile support
3366 conn->smbd_idle_profstamp = 0;
3367 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3368 break;
3369 case TEVENT_TRACE_AFTER_WAIT:
3370 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3371 break;
3372 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3373 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3374 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3375 break;
3376 #endif
3380 /****************************************************************************
3381 Process commands from the client
3382 ****************************************************************************/
3384 void smbd_process(struct tevent_context *ev_ctx,
3385 struct messaging_context *msg_ctx,
3386 int sock_fd,
3387 bool interactive)
3389 TALLOC_CTX *frame = talloc_stackframe();
3390 struct smbXsrv_connection *conn;
3391 struct smbd_server_connection *sconn;
3392 struct sockaddr_storage ss;
3393 struct sockaddr *sa = NULL;
3394 socklen_t sa_socklen;
3395 struct tsocket_address *local_address = NULL;
3396 struct tsocket_address *remote_address = NULL;
3397 const char *locaddr = NULL;
3398 const char *remaddr = NULL;
3399 char *rhost;
3400 int ret;
3401 int tmp;
3403 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3404 if (conn == NULL) {
3405 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3406 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3409 conn->ev_ctx = ev_ctx;
3410 conn->msg_ctx = msg_ctx;
3412 sconn = talloc_zero(conn, struct smbd_server_connection);
3413 if (!sconn) {
3414 exit_server("failed to create smbd_server_connection");
3417 conn->sconn = sconn;
3418 sconn->conn = conn;
3421 * TODO: remove this...:-)
3423 global_smbXsrv_connection = conn;
3425 sconn->ev_ctx = ev_ctx;
3426 sconn->msg_ctx = msg_ctx;
3427 sconn->sock = sock_fd;
3428 sconn->smb1.echo_handler.trusted_fd = -1;
3429 sconn->smb1.echo_handler.socket_lock_fd = -1;
3431 if (!interactive) {
3432 smbd_setup_sig_term_handler(sconn);
3433 smbd_setup_sig_hup_handler(sconn);
3435 if (!serverid_register(messaging_server_id(msg_ctx),
3436 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3437 |FLAG_MSG_DBWRAP
3438 |FLAG_MSG_PRINT_GENERAL)) {
3439 exit_server_cleanly("Could not register myself in "
3440 "serverid.tdb");
3444 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3446 * We're not making the decision here,
3447 * we're just allowing the client
3448 * to decide between SMB1 and SMB2
3449 * with the first negprot
3450 * packet.
3452 sconn->using_smb2 = true;
3455 /* Ensure child is set to blocking mode */
3456 set_blocking(sconn->sock,True);
3458 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3459 set_socket_options(sconn->sock, lp_socket_options());
3461 sa = (struct sockaddr *)(void *)&ss;
3462 sa_socklen = sizeof(ss);
3463 ret = getpeername(sconn->sock, sa, &sa_socklen);
3464 if (ret != 0) {
3465 int level = (errno == ENOTCONN)?2:0;
3466 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3467 exit_server_cleanly("getpeername() failed.\n");
3469 ret = tsocket_address_bsd_from_sockaddr(sconn,
3470 sa, sa_socklen,
3471 &remote_address);
3472 if (ret != 0) {
3473 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3474 __location__, strerror(errno)));
3475 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3478 sa = (struct sockaddr *)(void *)&ss;
3479 sa_socklen = sizeof(ss);
3480 ret = getsockname(sconn->sock, sa, &sa_socklen);
3481 if (ret != 0) {
3482 int level = (errno == ENOTCONN)?2:0;
3483 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3484 exit_server_cleanly("getsockname() failed.\n");
3486 ret = tsocket_address_bsd_from_sockaddr(sconn,
3487 sa, sa_socklen,
3488 &local_address);
3489 if (ret != 0) {
3490 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3491 __location__, strerror(errno)));
3492 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3495 sconn->local_address = local_address;
3496 sconn->remote_address = remote_address;
3498 if (tsocket_address_is_inet(local_address, "ip")) {
3499 locaddr = tsocket_address_inet_addr_string(
3500 sconn->local_address,
3501 talloc_tos());
3502 if (locaddr == NULL) {
3503 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3504 __location__, strerror(errno)));
3505 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3507 } else {
3508 locaddr = "0.0.0.0";
3511 if (tsocket_address_is_inet(remote_address, "ip")) {
3512 remaddr = tsocket_address_inet_addr_string(
3513 sconn->remote_address,
3514 talloc_tos());
3515 if (remaddr == NULL) {
3516 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3517 __location__, strerror(errno)));
3518 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3520 } else {
3521 remaddr = "0.0.0.0";
3524 /* this is needed so that we get decent entries
3525 in smbstatus for port 445 connects */
3526 set_remote_machine_name(remaddr, false);
3527 reload_services(sconn, conn_snum_used, true);
3530 * Before the first packet, check the global hosts allow/ hosts deny
3531 * parameters before doing any parsing of packets passed to us by the
3532 * client. This prevents attacks on our parsing code from hosts not in
3533 * the hosts allow list.
3536 ret = get_remote_hostname(remote_address,
3537 &rhost,
3538 talloc_tos());
3539 if (ret < 0) {
3540 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3541 __location__, strerror(errno)));
3542 exit_server_cleanly("get_remote_hostname failed.\n");
3544 if (strequal(rhost, "UNKNOWN")) {
3545 rhost = talloc_strdup(talloc_tos(), remaddr);
3547 sconn->remote_hostname = talloc_move(sconn, &rhost);
3549 sub_set_socket_ids(remaddr,
3550 sconn->remote_hostname,
3551 locaddr);
3553 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3554 sconn->remote_hostname,
3555 remaddr)) {
3557 * send a negative session response "not listening on calling
3558 * name"
3560 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3561 DEBUG( 1, ("Connection denied from %s to %s\n",
3562 tsocket_address_string(remote_address, talloc_tos()),
3563 tsocket_address_string(local_address, talloc_tos())));
3564 (void)srv_send_smb(sconn,(char *)buf, false,
3565 0, false, NULL);
3566 exit_server_cleanly("connection denied");
3569 DEBUG(10, ("Connection allowed from %s to %s\n",
3570 tsocket_address_string(remote_address, talloc_tos()),
3571 tsocket_address_string(local_address, talloc_tos())));
3573 if (lp_preload_modules()) {
3574 smb_load_modules(lp_preload_modules());
3577 smb_perfcount_init();
3579 if (!init_account_policy()) {
3580 exit_server("Could not open account policy tdb.\n");
3583 if (*lp_root_directory(talloc_tos())) {
3584 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3585 DEBUG(0,("Failed to change root to %s\n",
3586 lp_root_directory(talloc_tos())));
3587 exit_server("Failed to chroot()");
3589 if (chdir("/") == -1) {
3590 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3591 exit_server("Failed to chroot()");
3593 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3596 if (!srv_init_signing(sconn)) {
3597 exit_server("Failed to init smb_signing");
3600 if (!file_init(sconn)) {
3601 exit_server("file_init() failed");
3604 /* Setup oplocks */
3605 if (!init_oplocks(sconn))
3606 exit_server("Failed to init oplocks");
3608 /* register our message handlers */
3609 messaging_register(sconn->msg_ctx, sconn,
3610 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3611 messaging_register(sconn->msg_ctx, sconn,
3612 MSG_SMB_CLOSE_FILE, msg_close_file);
3613 messaging_register(sconn->msg_ctx, sconn,
3614 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3616 id_cache_register_msgs(sconn->msg_ctx);
3617 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3618 messaging_register(sconn->msg_ctx, sconn,
3619 ID_CACHE_KILL, smbd_id_cache_kill);
3621 messaging_deregister(sconn->msg_ctx,
3622 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3623 messaging_register(sconn->msg_ctx, sconn,
3624 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3626 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3627 NULL);
3628 messaging_register(sconn->msg_ctx, sconn,
3629 MSG_SMB_KILL_CLIENT_IP,
3630 msg_kill_client_ip);
3632 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3635 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3636 * MSGs to all child processes
3638 messaging_deregister(sconn->msg_ctx,
3639 MSG_DEBUG, NULL);
3640 messaging_register(sconn->msg_ctx, NULL,
3641 MSG_DEBUG, debug_message);
3643 if ((lp_keepalive() != 0)
3644 && !(event_add_idle(ev_ctx, NULL,
3645 timeval_set(lp_keepalive(), 0),
3646 "keepalive", keepalive_fn,
3647 sconn))) {
3648 DEBUG(0, ("Could not add keepalive event\n"));
3649 exit(1);
3652 if (!(event_add_idle(ev_ctx, NULL,
3653 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3654 "deadtime", deadtime_fn, sconn))) {
3655 DEBUG(0, ("Could not add deadtime event\n"));
3656 exit(1);
3659 if (!(event_add_idle(ev_ctx, NULL,
3660 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3661 "housekeeping", housekeeping_fn, sconn))) {
3662 DEBUG(0, ("Could not add housekeeping event\n"));
3663 exit(1);
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 sconn->nbt.got_session = false;
3694 tmp = lp_max_xmit();
3695 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3696 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3698 sconn->smb1.negprot.max_recv = tmp;
3700 sconn->smb1.sessions.done_sesssetup = false;
3701 sconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3703 if (!init_dptrs(sconn)) {
3704 exit_server("init_dptrs() failed");
3707 sconn->smb1.fde = tevent_add_fd(ev_ctx,
3708 sconn,
3709 sconn->sock,
3710 TEVENT_FD_READ,
3711 smbd_server_connection_handler,
3712 sconn);
3713 if (!sconn->smb1.fde) {
3714 exit_server("failed to create smbd_server_connection fde");
3717 sconn->conn->local_address = sconn->local_address;
3718 sconn->conn->remote_address = sconn->remote_address;
3719 sconn->conn->remote_hostname = sconn->remote_hostname;
3720 sconn->conn->protocol = PROTOCOL_NONE;
3722 TALLOC_FREE(frame);
3724 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3726 while (True) {
3727 frame = talloc_stackframe_pool(8192);
3729 errno = 0;
3730 if (tevent_loop_once(ev_ctx) == -1) {
3731 if (errno != EINTR) {
3732 DEBUG(3, ("tevent_loop_once failed: %s,"
3733 " exiting\n", strerror(errno) ));
3734 break;
3738 TALLOC_FREE(frame);
3741 exit_server_cleanly(NULL);
3744 bool req_is_in_chain(const struct smb_request *req)
3746 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3748 * We're right now handling a subsequent request, so we must
3749 * be in a chain
3751 return true;
3754 if (!is_andx_req(req->cmd)) {
3755 return false;
3758 if (req->wct < 2) {
3760 * Okay, an illegal request, but definitely not chained :-)
3762 return false;
3765 return (CVAL(req->vwv+0, 0) != 0xFF);