smbd: Store "struct deferred_open_record" instead of anonymous data on pml
[Samba.git] / source3 / smbd / process.c
blobb1d522dbc34fe2791030061ccf13abc7bec3f68b
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 struct deferred_open_record *open_rec;
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 struct deferred_open_record *open_rec)
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 (open_rec) {
665 msg->open_rec = talloc_move(msg, &open_rec);
668 #if 0
669 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
670 msg,
671 end_time,
672 smbd_deferred_open_timer,
673 msg);
674 if (!msg->te) {
675 DEBUG(0,("push_message: event_add_timed failed\n"));
676 TALLOC_FREE(msg);
677 return false;
679 #endif
681 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
682 struct pending_message_list *);
684 DEBUG(10,("push_message: pushed message length %u on "
685 "deferred_open_queue\n", (unsigned int)msg_len));
687 return True;
690 /****************************************************************************
691 Function to delete a sharing violation open message by mid.
692 ****************************************************************************/
694 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
695 uint64_t mid)
697 struct pending_message_list *pml;
699 if (sconn->using_smb2) {
700 remove_deferred_open_message_smb2(sconn, mid);
701 return;
704 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
705 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
706 DEBUG(10,("remove_deferred_open_message_smb: "
707 "deleting mid %llu len %u\n",
708 (unsigned long long)mid,
709 (unsigned int)pml->buf.length ));
710 DLIST_REMOVE(sconn->deferred_open_queue, pml);
711 TALLOC_FREE(pml);
712 return;
717 /****************************************************************************
718 Move a sharing violation open retry message to the front of the list and
719 schedule it for immediate processing.
720 ****************************************************************************/
722 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
723 uint64_t mid)
725 struct pending_message_list *pml;
726 int i = 0;
728 if (sconn->using_smb2) {
729 return schedule_deferred_open_message_smb2(sconn, mid);
732 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
733 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
735 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
736 "msg_mid = %llu\n",
737 i++,
738 (unsigned long long)msg_mid ));
740 if (mid == msg_mid) {
741 struct tevent_timer *te;
743 if (pml->processed) {
744 /* A processed message should not be
745 * rescheduled. */
746 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
747 "message mid %llu was already processed\n",
748 (unsigned long long)msg_mid ));
749 continue;
752 DEBUG(10,("schedule_deferred_open_message_smb: "
753 "scheduling mid %llu\n",
754 (unsigned long long)mid ));
756 te = tevent_add_timer(pml->sconn->ev_ctx,
757 pml,
758 timeval_zero(),
759 smbd_deferred_open_timer,
760 pml);
761 if (!te) {
762 DEBUG(10,("schedule_deferred_open_message_smb: "
763 "event_add_timed() failed, "
764 "skipping mid %llu\n",
765 (unsigned long long)msg_mid ));
768 TALLOC_FREE(pml->te);
769 pml->te = te;
770 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
771 return true;
775 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
776 "find message mid %llu\n",
777 (unsigned long long)mid ));
779 return false;
782 /****************************************************************************
783 Return true if this mid is on the deferred queue and was not yet processed.
784 ****************************************************************************/
786 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
788 struct pending_message_list *pml;
790 if (sconn->using_smb2) {
791 return open_was_deferred_smb2(sconn, mid);
794 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
795 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
796 return True;
799 return False;
802 /****************************************************************************
803 Return the message queued by this mid.
804 ****************************************************************************/
806 static struct pending_message_list *get_deferred_open_message_smb(
807 struct smbd_server_connection *sconn, uint64_t mid)
809 struct pending_message_list *pml;
811 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
812 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
813 return pml;
816 return NULL;
819 /****************************************************************************
820 Get the state data queued by this mid.
821 ****************************************************************************/
823 bool get_deferred_open_message_state(struct smb_request *smbreq,
824 struct timeval *p_request_time,
825 struct deferred_open_record **open_rec)
827 struct pending_message_list *pml;
829 if (smbreq->sconn->using_smb2) {
830 return get_deferred_open_message_state_smb2(smbreq->smb2req,
831 p_request_time,
832 open_rec);
835 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
836 if (!pml) {
837 return false;
839 if (p_request_time) {
840 *p_request_time = pml->request_time;
842 if (open_rec != NULL) {
843 *open_rec = pml->open_rec;
845 return true;
848 /****************************************************************************
849 Function to push a deferred open smb message onto a linked list of local smb
850 messages ready for processing.
851 ****************************************************************************/
853 bool push_deferred_open_message_smb(struct smb_request *req,
854 struct timeval request_time,
855 struct timeval timeout,
856 struct file_id id,
857 struct deferred_open_record *open_rec)
859 struct timeval end_time;
861 if (req->smb2req) {
862 return push_deferred_open_message_smb2(req->smb2req,
863 request_time,
864 timeout,
866 open_rec);
869 if (req->unread_bytes) {
870 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
871 "unread_bytes = %u\n",
872 (unsigned int)req->unread_bytes ));
873 smb_panic("push_deferred_open_message_smb: "
874 "logic error unread_bytes != 0" );
877 end_time = timeval_sum(&request_time, &timeout);
879 DEBUG(10,("push_deferred_open_message_smb: pushing message "
880 "len %u mid %llu timeout time [%u.%06u]\n",
881 (unsigned int) smb_len(req->inbuf)+4,
882 (unsigned long long)req->mid,
883 (unsigned int)end_time.tv_sec,
884 (unsigned int)end_time.tv_usec));
886 return push_queued_message(req, request_time, end_time, open_rec);
889 static void smbd_sig_term_handler(struct tevent_context *ev,
890 struct tevent_signal *se,
891 int signum,
892 int count,
893 void *siginfo,
894 void *private_data)
896 exit_server_cleanly("termination signal");
899 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
901 struct tevent_signal *se;
903 se = tevent_add_signal(sconn->ev_ctx,
904 sconn,
905 SIGTERM, 0,
906 smbd_sig_term_handler,
907 sconn);
908 if (!se) {
909 exit_server("failed to setup SIGTERM handler");
913 static void smbd_sig_hup_handler(struct tevent_context *ev,
914 struct tevent_signal *se,
915 int signum,
916 int count,
917 void *siginfo,
918 void *private_data)
920 struct smbd_server_connection *sconn =
921 talloc_get_type_abort(private_data,
922 struct smbd_server_connection);
924 change_to_root_user();
925 DEBUG(1,("Reloading services after SIGHUP\n"));
926 reload_services(sconn, conn_snum_used, false);
929 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
931 struct tevent_signal *se;
933 se = tevent_add_signal(sconn->ev_ctx,
934 sconn,
935 SIGHUP, 0,
936 smbd_sig_hup_handler,
937 sconn);
938 if (!se) {
939 exit_server("failed to setup SIGHUP handler");
943 static void smbd_conf_updated(struct messaging_context *msg,
944 void *private_data,
945 uint32_t msg_type,
946 struct server_id server_id,
947 DATA_BLOB *data)
949 struct smbd_server_connection *sconn =
950 talloc_get_type_abort(private_data,
951 struct smbd_server_connection);
953 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
954 "updated. Reloading.\n"));
955 change_to_root_user();
956 reload_services(sconn, conn_snum_used, false);
960 * Only allow 5 outstanding trans requests. We're allocating memory, so
961 * prevent a DoS.
964 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
966 int count = 0;
967 for (; list != NULL; list = list->next) {
969 if (list->mid == mid) {
970 return NT_STATUS_INVALID_PARAMETER;
973 count += 1;
975 if (count > 5) {
976 return NT_STATUS_INSUFFICIENT_RESOURCES;
979 return NT_STATUS_OK;
983 These flags determine some of the permissions required to do an operation
985 Note that I don't set NEED_WRITE on some write operations because they
986 are used by some brain-dead clients when printing, and I don't want to
987 force write permissions on print services.
989 #define AS_USER (1<<0)
990 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
991 #define TIME_INIT (1<<2)
992 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
993 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
994 #define DO_CHDIR (1<<6)
997 define a list of possible SMB messages and their corresponding
998 functions. Any message that has a NULL function is unimplemented -
999 please feel free to contribute implementations!
1001 static const struct smb_message_struct {
1002 const char *name;
1003 void (*fn)(struct smb_request *req);
1004 int flags;
1005 } smb_messages[256] = {
1007 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1008 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1009 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1010 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1011 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1012 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1013 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1014 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1015 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1016 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1017 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1018 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1019 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1020 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1021 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1022 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1023 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1024 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1025 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1026 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1027 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1028 /* 0x15 */ { NULL, NULL, 0 },
1029 /* 0x16 */ { NULL, NULL, 0 },
1030 /* 0x17 */ { NULL, NULL, 0 },
1031 /* 0x18 */ { NULL, NULL, 0 },
1032 /* 0x19 */ { NULL, NULL, 0 },
1033 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1034 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1035 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1036 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1037 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1038 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1039 /* 0x20 */ { "SMBwritec", NULL,0},
1040 /* 0x21 */ { NULL, NULL, 0 },
1041 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1042 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1043 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1044 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1045 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1046 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1047 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1048 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1049 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1050 /* 0x2b */ { "SMBecho",reply_echo,0},
1051 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1052 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1053 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1054 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1055 /* 0x30 */ { NULL, NULL, 0 },
1056 /* 0x31 */ { NULL, NULL, 0 },
1057 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1058 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1059 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1060 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1061 /* 0x36 */ { NULL, NULL, 0 },
1062 /* 0x37 */ { NULL, NULL, 0 },
1063 /* 0x38 */ { NULL, NULL, 0 },
1064 /* 0x39 */ { NULL, NULL, 0 },
1065 /* 0x3a */ { NULL, NULL, 0 },
1066 /* 0x3b */ { NULL, NULL, 0 },
1067 /* 0x3c */ { NULL, NULL, 0 },
1068 /* 0x3d */ { NULL, NULL, 0 },
1069 /* 0x3e */ { NULL, NULL, 0 },
1070 /* 0x3f */ { NULL, NULL, 0 },
1071 /* 0x40 */ { NULL, NULL, 0 },
1072 /* 0x41 */ { NULL, NULL, 0 },
1073 /* 0x42 */ { NULL, NULL, 0 },
1074 /* 0x43 */ { NULL, NULL, 0 },
1075 /* 0x44 */ { NULL, NULL, 0 },
1076 /* 0x45 */ { NULL, NULL, 0 },
1077 /* 0x46 */ { NULL, NULL, 0 },
1078 /* 0x47 */ { NULL, NULL, 0 },
1079 /* 0x48 */ { NULL, NULL, 0 },
1080 /* 0x49 */ { NULL, NULL, 0 },
1081 /* 0x4a */ { NULL, NULL, 0 },
1082 /* 0x4b */ { NULL, NULL, 0 },
1083 /* 0x4c */ { NULL, NULL, 0 },
1084 /* 0x4d */ { NULL, NULL, 0 },
1085 /* 0x4e */ { NULL, NULL, 0 },
1086 /* 0x4f */ { NULL, NULL, 0 },
1087 /* 0x50 */ { NULL, NULL, 0 },
1088 /* 0x51 */ { NULL, NULL, 0 },
1089 /* 0x52 */ { NULL, NULL, 0 },
1090 /* 0x53 */ { NULL, NULL, 0 },
1091 /* 0x54 */ { NULL, NULL, 0 },
1092 /* 0x55 */ { NULL, NULL, 0 },
1093 /* 0x56 */ { NULL, NULL, 0 },
1094 /* 0x57 */ { NULL, NULL, 0 },
1095 /* 0x58 */ { NULL, NULL, 0 },
1096 /* 0x59 */ { NULL, NULL, 0 },
1097 /* 0x5a */ { NULL, NULL, 0 },
1098 /* 0x5b */ { NULL, NULL, 0 },
1099 /* 0x5c */ { NULL, NULL, 0 },
1100 /* 0x5d */ { NULL, NULL, 0 },
1101 /* 0x5e */ { NULL, NULL, 0 },
1102 /* 0x5f */ { NULL, NULL, 0 },
1103 /* 0x60 */ { NULL, NULL, 0 },
1104 /* 0x61 */ { NULL, NULL, 0 },
1105 /* 0x62 */ { NULL, NULL, 0 },
1106 /* 0x63 */ { NULL, NULL, 0 },
1107 /* 0x64 */ { NULL, NULL, 0 },
1108 /* 0x65 */ { NULL, NULL, 0 },
1109 /* 0x66 */ { NULL, NULL, 0 },
1110 /* 0x67 */ { NULL, NULL, 0 },
1111 /* 0x68 */ { NULL, NULL, 0 },
1112 /* 0x69 */ { NULL, NULL, 0 },
1113 /* 0x6a */ { NULL, NULL, 0 },
1114 /* 0x6b */ { NULL, NULL, 0 },
1115 /* 0x6c */ { NULL, NULL, 0 },
1116 /* 0x6d */ { NULL, NULL, 0 },
1117 /* 0x6e */ { NULL, NULL, 0 },
1118 /* 0x6f */ { NULL, NULL, 0 },
1119 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1120 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1121 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1122 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1123 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1124 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1125 /* 0x76 */ { NULL, NULL, 0 },
1126 /* 0x77 */ { NULL, NULL, 0 },
1127 /* 0x78 */ { NULL, NULL, 0 },
1128 /* 0x79 */ { NULL, NULL, 0 },
1129 /* 0x7a */ { NULL, NULL, 0 },
1130 /* 0x7b */ { NULL, NULL, 0 },
1131 /* 0x7c */ { NULL, NULL, 0 },
1132 /* 0x7d */ { NULL, NULL, 0 },
1133 /* 0x7e */ { NULL, NULL, 0 },
1134 /* 0x7f */ { NULL, NULL, 0 },
1135 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1136 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1137 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1138 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1139 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1140 /* 0x85 */ { NULL, NULL, 0 },
1141 /* 0x86 */ { NULL, NULL, 0 },
1142 /* 0x87 */ { NULL, NULL, 0 },
1143 /* 0x88 */ { NULL, NULL, 0 },
1144 /* 0x89 */ { NULL, NULL, 0 },
1145 /* 0x8a */ { NULL, NULL, 0 },
1146 /* 0x8b */ { NULL, NULL, 0 },
1147 /* 0x8c */ { NULL, NULL, 0 },
1148 /* 0x8d */ { NULL, NULL, 0 },
1149 /* 0x8e */ { NULL, NULL, 0 },
1150 /* 0x8f */ { NULL, NULL, 0 },
1151 /* 0x90 */ { NULL, NULL, 0 },
1152 /* 0x91 */ { NULL, NULL, 0 },
1153 /* 0x92 */ { NULL, NULL, 0 },
1154 /* 0x93 */ { NULL, NULL, 0 },
1155 /* 0x94 */ { NULL, NULL, 0 },
1156 /* 0x95 */ { NULL, NULL, 0 },
1157 /* 0x96 */ { NULL, NULL, 0 },
1158 /* 0x97 */ { NULL, NULL, 0 },
1159 /* 0x98 */ { NULL, NULL, 0 },
1160 /* 0x99 */ { NULL, NULL, 0 },
1161 /* 0x9a */ { NULL, NULL, 0 },
1162 /* 0x9b */ { NULL, NULL, 0 },
1163 /* 0x9c */ { NULL, NULL, 0 },
1164 /* 0x9d */ { NULL, NULL, 0 },
1165 /* 0x9e */ { NULL, NULL, 0 },
1166 /* 0x9f */ { NULL, NULL, 0 },
1167 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1168 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1169 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1170 /* 0xa3 */ { NULL, NULL, 0 },
1171 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1172 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1173 /* 0xa6 */ { NULL, NULL, 0 },
1174 /* 0xa7 */ { NULL, NULL, 0 },
1175 /* 0xa8 */ { NULL, NULL, 0 },
1176 /* 0xa9 */ { NULL, NULL, 0 },
1177 /* 0xaa */ { NULL, NULL, 0 },
1178 /* 0xab */ { NULL, NULL, 0 },
1179 /* 0xac */ { NULL, NULL, 0 },
1180 /* 0xad */ { NULL, NULL, 0 },
1181 /* 0xae */ { NULL, NULL, 0 },
1182 /* 0xaf */ { NULL, NULL, 0 },
1183 /* 0xb0 */ { NULL, NULL, 0 },
1184 /* 0xb1 */ { NULL, NULL, 0 },
1185 /* 0xb2 */ { NULL, NULL, 0 },
1186 /* 0xb3 */ { NULL, NULL, 0 },
1187 /* 0xb4 */ { NULL, NULL, 0 },
1188 /* 0xb5 */ { NULL, NULL, 0 },
1189 /* 0xb6 */ { NULL, NULL, 0 },
1190 /* 0xb7 */ { NULL, NULL, 0 },
1191 /* 0xb8 */ { NULL, NULL, 0 },
1192 /* 0xb9 */ { NULL, NULL, 0 },
1193 /* 0xba */ { NULL, NULL, 0 },
1194 /* 0xbb */ { NULL, NULL, 0 },
1195 /* 0xbc */ { NULL, NULL, 0 },
1196 /* 0xbd */ { NULL, NULL, 0 },
1197 /* 0xbe */ { NULL, NULL, 0 },
1198 /* 0xbf */ { NULL, NULL, 0 },
1199 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1200 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1201 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1202 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1203 /* 0xc4 */ { NULL, NULL, 0 },
1204 /* 0xc5 */ { NULL, NULL, 0 },
1205 /* 0xc6 */ { NULL, NULL, 0 },
1206 /* 0xc7 */ { NULL, NULL, 0 },
1207 /* 0xc8 */ { NULL, NULL, 0 },
1208 /* 0xc9 */ { NULL, NULL, 0 },
1209 /* 0xca */ { NULL, NULL, 0 },
1210 /* 0xcb */ { NULL, NULL, 0 },
1211 /* 0xcc */ { NULL, NULL, 0 },
1212 /* 0xcd */ { NULL, NULL, 0 },
1213 /* 0xce */ { NULL, NULL, 0 },
1214 /* 0xcf */ { NULL, NULL, 0 },
1215 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1216 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1217 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1218 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1219 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1220 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1221 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1222 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1223 /* 0xd8 */ { NULL, NULL, 0 },
1224 /* 0xd9 */ { NULL, NULL, 0 },
1225 /* 0xda */ { NULL, NULL, 0 },
1226 /* 0xdb */ { NULL, NULL, 0 },
1227 /* 0xdc */ { NULL, NULL, 0 },
1228 /* 0xdd */ { NULL, NULL, 0 },
1229 /* 0xde */ { NULL, NULL, 0 },
1230 /* 0xdf */ { NULL, NULL, 0 },
1231 /* 0xe0 */ { NULL, NULL, 0 },
1232 /* 0xe1 */ { NULL, NULL, 0 },
1233 /* 0xe2 */ { NULL, NULL, 0 },
1234 /* 0xe3 */ { NULL, NULL, 0 },
1235 /* 0xe4 */ { NULL, NULL, 0 },
1236 /* 0xe5 */ { NULL, NULL, 0 },
1237 /* 0xe6 */ { NULL, NULL, 0 },
1238 /* 0xe7 */ { NULL, NULL, 0 },
1239 /* 0xe8 */ { NULL, NULL, 0 },
1240 /* 0xe9 */ { NULL, NULL, 0 },
1241 /* 0xea */ { NULL, NULL, 0 },
1242 /* 0xeb */ { NULL, NULL, 0 },
1243 /* 0xec */ { NULL, NULL, 0 },
1244 /* 0xed */ { NULL, NULL, 0 },
1245 /* 0xee */ { NULL, NULL, 0 },
1246 /* 0xef */ { NULL, NULL, 0 },
1247 /* 0xf0 */ { NULL, NULL, 0 },
1248 /* 0xf1 */ { NULL, NULL, 0 },
1249 /* 0xf2 */ { NULL, NULL, 0 },
1250 /* 0xf3 */ { NULL, NULL, 0 },
1251 /* 0xf4 */ { NULL, NULL, 0 },
1252 /* 0xf5 */ { NULL, NULL, 0 },
1253 /* 0xf6 */ { NULL, NULL, 0 },
1254 /* 0xf7 */ { NULL, NULL, 0 },
1255 /* 0xf8 */ { NULL, NULL, 0 },
1256 /* 0xf9 */ { NULL, NULL, 0 },
1257 /* 0xfa */ { NULL, NULL, 0 },
1258 /* 0xfb */ { NULL, NULL, 0 },
1259 /* 0xfc */ { NULL, NULL, 0 },
1260 /* 0xfd */ { NULL, NULL, 0 },
1261 /* 0xfe */ { NULL, NULL, 0 },
1262 /* 0xff */ { NULL, NULL, 0 }
1266 /*******************************************************************
1267 allocate and initialize a reply packet
1268 ********************************************************************/
1270 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1271 const char *inbuf, char **outbuf, uint8_t num_words,
1272 uint32_t num_bytes)
1274 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1277 * Protect against integer wrap.
1278 * The SMB layer reply can be up to 0xFFFFFF bytes.
1280 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1281 char *msg;
1282 if (asprintf(&msg, "num_bytes too large: %u",
1283 (unsigned)num_bytes) == -1) {
1284 msg = discard_const_p(char, "num_bytes too large");
1286 smb_panic(msg);
1290 * Here we include the NBT header for now.
1292 *outbuf = talloc_array(mem_ctx, char,
1293 NBT_HDR_SIZE + smb_len);
1294 if (*outbuf == NULL) {
1295 return false;
1298 construct_reply_common(req, inbuf, *outbuf);
1299 srv_set_message(*outbuf, num_words, num_bytes, false);
1301 * Zero out the word area, the caller has to take care of the bcc area
1302 * himself
1304 if (num_words != 0) {
1305 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1308 return true;
1311 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1313 char *outbuf;
1314 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1315 num_bytes)) {
1316 smb_panic("could not allocate output buffer\n");
1318 req->outbuf = (uint8_t *)outbuf;
1322 /*******************************************************************
1323 Dump a packet to a file.
1324 ********************************************************************/
1326 static void smb_dump(const char *name, int type, const char *data)
1328 size_t len;
1329 int fd, i;
1330 char *fname = NULL;
1331 if (DEBUGLEVEL < 50) {
1332 return;
1335 len = smb_len_tcp(data)+4;
1336 for (i=1;i<100;i++) {
1337 fname = talloc_asprintf(talloc_tos(),
1338 "/tmp/%s.%d.%s",
1339 name,
1341 type ? "req" : "resp");
1342 if (fname == NULL) {
1343 return;
1345 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1346 if (fd != -1 || errno != EEXIST) break;
1347 TALLOC_FREE(fname);
1349 if (fd != -1) {
1350 ssize_t ret = write(fd, data, len);
1351 if (ret != len)
1352 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1353 close(fd);
1354 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1356 TALLOC_FREE(fname);
1359 /****************************************************************************
1360 Prepare everything for calling the actual request function, and potentially
1361 call the request function via the "new" interface.
1363 Return False if the "legacy" function needs to be called, everything is
1364 prepared.
1366 Return True if we're done.
1368 I know this API sucks, but it is the one with the least code change I could
1369 find.
1370 ****************************************************************************/
1372 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1374 int flags;
1375 uint64_t session_tag;
1376 connection_struct *conn = NULL;
1377 struct smbd_server_connection *sconn = req->sconn;
1378 NTTIME now = timeval_to_nttime(&req->request_time);
1379 struct smbXsrv_session *session = NULL;
1380 NTSTATUS status;
1382 errno = 0;
1384 if (smb_messages[type].fn == NULL) {
1385 DEBUG(0,("Unknown message type %d!\n",type));
1386 smb_dump("Unknown", 1, (const char *)req->inbuf);
1387 reply_unknown_new(req, type);
1388 return NULL;
1391 flags = smb_messages[type].flags;
1393 /* In share mode security we must ignore the vuid. */
1394 session_tag = req->vuid;
1395 conn = req->conn;
1397 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1398 (int)getpid(), (unsigned long)conn));
1400 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1402 /* Ensure this value is replaced in the incoming packet. */
1403 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1406 * Ensure the correct username is in current_user_info. This is a
1407 * really ugly bugfix for problems with multiple session_setup_and_X's
1408 * being done and allowing %U and %G substitutions to work correctly.
1409 * There is a reason this code is done here, don't move it unless you
1410 * know what you're doing... :-).
1411 * JRA.
1415 * lookup an existing session
1417 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1418 * here, the main check is still in change_to_user()
1420 status = smb1srv_session_lookup(sconn->conn,
1421 session_tag,
1422 now,
1423 &session);
1424 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1425 switch (type) {
1426 case SMBsesssetupX:
1427 status = NT_STATUS_OK;
1428 break;
1429 default:
1430 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1431 (unsigned long long)session_tag,
1432 (unsigned long long)req->mid));
1433 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1434 return conn;
1438 if (session_tag != sconn->conn->last_session_id) {
1439 struct user_struct *vuser = NULL;
1441 sconn->conn->last_session_id = session_tag;
1442 if (session) {
1443 vuser = session->compat;
1445 if (vuser) {
1446 set_current_user_info(
1447 vuser->session_info->unix_info->sanitized_username,
1448 vuser->session_info->unix_info->unix_name,
1449 vuser->session_info->info->domain_name);
1453 /* Does this call need to be run as the connected user? */
1454 if (flags & AS_USER) {
1456 /* Does this call need a valid tree connection? */
1457 if (!conn) {
1459 * Amazingly, the error code depends on the command
1460 * (from Samba4).
1462 if (type == SMBntcreateX) {
1463 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1464 } else {
1465 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1467 return NULL;
1470 if (!change_to_user(conn,session_tag)) {
1471 DEBUG(0, ("Error: Could not change to user. Removing "
1472 "deferred open, mid=%llu.\n",
1473 (unsigned long long)req->mid));
1474 reply_force_doserror(req, ERRSRV, ERRbaduid);
1475 return conn;
1478 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1480 /* Does it need write permission? */
1481 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1482 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1483 return conn;
1486 /* IPC services are limited */
1487 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1488 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1489 return conn;
1491 } else {
1492 /* This call needs to be run as root */
1493 change_to_root_user();
1496 /* load service specific parameters */
1497 if (conn) {
1498 if (req->encrypted) {
1499 conn->encrypted_tid = true;
1500 /* encrypted required from now on. */
1501 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1502 } else if (ENCRYPTION_REQUIRED(conn)) {
1503 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1504 DEBUG(1,("service[%s] requires encryption"
1505 "%s ACCESS_DENIED. mid=%llu\n",
1506 lp_servicename(talloc_tos(), SNUM(conn)),
1507 smb_fn_name(type),
1508 (unsigned long long)req->mid));
1509 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1510 return conn;
1514 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1515 (flags & (AS_USER|DO_CHDIR)
1516 ?True:False))) {
1517 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1518 return conn;
1520 conn->num_smb_operations++;
1524 * Does this protocol need to be run as guest? (Only archane
1525 * messenger service requests have this...)
1527 if (flags & AS_GUEST) {
1528 char *raddr;
1529 bool ok;
1531 if (!change_to_guest()) {
1532 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1533 return conn;
1536 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1537 talloc_tos());
1538 if (raddr == NULL) {
1539 reply_nterror(req, NT_STATUS_NO_MEMORY);
1540 return conn;
1544 * Haven't we checked this in smbd_process already???
1547 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1548 sconn->remote_hostname, raddr);
1549 TALLOC_FREE(raddr);
1551 if (!ok) {
1552 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1553 return conn;
1557 smb_messages[type].fn(req);
1558 return req->conn;
1561 /****************************************************************************
1562 Construct a reply to the incoming packet.
1563 ****************************************************************************/
1565 static void construct_reply(struct smbd_server_connection *sconn,
1566 char *inbuf, int size, size_t unread_bytes,
1567 uint32_t seqnum, bool encrypted,
1568 struct smb_perfcount_data *deferred_pcd)
1570 connection_struct *conn;
1571 struct smb_request *req;
1573 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1574 smb_panic("could not allocate smb_request");
1577 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1578 encrypted, seqnum)) {
1579 exit_server_cleanly("Invalid SMB request");
1582 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1584 /* we popped this message off the queue - keep original perf data */
1585 if (deferred_pcd)
1586 req->pcd = *deferred_pcd;
1587 else {
1588 SMB_PERFCOUNT_START(&req->pcd);
1589 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1590 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1593 conn = switch_message(req->cmd, req);
1595 if (req->outbuf == NULL) {
1596 return;
1599 if (CVAL(req->outbuf,0) == 0) {
1600 show_msg((char *)req->outbuf);
1603 if (!srv_send_smb(req->sconn,
1604 (char *)req->outbuf,
1605 true, req->seqnum+1,
1606 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1607 &req->pcd)) {
1608 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1611 TALLOC_FREE(req);
1613 return;
1616 static void construct_reply_chain(struct smbd_server_connection *sconn,
1617 char *inbuf, int size, uint32_t seqnum,
1618 bool encrypted,
1619 struct smb_perfcount_data *deferred_pcd)
1621 struct smb_request **reqs = NULL;
1622 struct smb_request *req;
1623 unsigned num_reqs;
1624 bool ok;
1626 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1627 seqnum, &reqs, &num_reqs);
1628 if (!ok) {
1629 char errbuf[smb_size];
1630 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1631 __LINE__, __FILE__);
1632 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1633 NULL)) {
1634 exit_server_cleanly("construct_reply_chain: "
1635 "srv_send_smb failed.");
1637 return;
1640 req = reqs[0];
1641 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1643 req->conn = switch_message(req->cmd, req);
1645 if (req->outbuf == NULL) {
1647 * Request has suspended itself, will come
1648 * back here.
1650 return;
1652 smb_request_done(req);
1656 * To be called from an async SMB handler that is potentially chained
1657 * when it is finished for shipping.
1660 void smb_request_done(struct smb_request *req)
1662 struct smb_request **reqs = NULL;
1663 struct smb_request *first_req;
1664 size_t i, num_reqs, next_index;
1665 NTSTATUS status;
1667 if (req->chain == NULL) {
1668 first_req = req;
1669 goto shipit;
1672 reqs = req->chain;
1673 num_reqs = talloc_array_length(reqs);
1675 for (i=0; i<num_reqs; i++) {
1676 if (reqs[i] == req) {
1677 break;
1680 if (i == num_reqs) {
1682 * Invalid chain, should not happen
1684 status = NT_STATUS_INTERNAL_ERROR;
1685 goto error;
1687 next_index = i+1;
1689 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1690 struct smb_request *next = reqs[next_index];
1691 struct smbXsrv_tcon *tcon;
1692 NTTIME now = timeval_to_nttime(&req->request_time);
1694 next->vuid = SVAL(req->outbuf, smb_uid);
1695 next->tid = SVAL(req->outbuf, smb_tid);
1696 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1697 now, &tcon);
1698 if (NT_STATUS_IS_OK(status)) {
1699 req->conn = tcon->compat;
1700 } else {
1701 req->conn = NULL;
1703 next->chain_fsp = req->chain_fsp;
1704 next->inbuf = req->inbuf;
1706 req = next;
1707 req->conn = switch_message(req->cmd, req);
1709 if (req->outbuf == NULL) {
1711 * Request has suspended itself, will come
1712 * back here.
1714 return;
1716 next_index += 1;
1719 first_req = reqs[0];
1721 for (i=1; i<next_index; i++) {
1722 bool ok;
1724 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1725 if (!ok) {
1726 status = NT_STATUS_INTERNAL_ERROR;
1727 goto error;
1731 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1732 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1735 * This scary statement intends to set the
1736 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1737 * to the value last_req->outbuf carries
1739 SSVAL(first_req->outbuf, smb_flg2,
1740 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1741 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1744 * Transfer the error codes from the subrequest to the main one
1746 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1747 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1749 _smb_setlen_large(
1750 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1752 shipit:
1753 if (!srv_send_smb(first_req->sconn,
1754 (char *)first_req->outbuf,
1755 true, first_req->seqnum+1,
1756 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1757 &first_req->pcd)) {
1758 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1759 "failed.");
1761 TALLOC_FREE(req); /* non-chained case */
1762 TALLOC_FREE(reqs); /* chained case */
1763 return;
1765 error:
1767 char errbuf[smb_size];
1768 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1769 if (!srv_send_smb(req->sconn, errbuf, true,
1770 req->seqnum+1, req->encrypted,
1771 NULL)) {
1772 exit_server_cleanly("construct_reply_chain: "
1773 "srv_send_smb failed.");
1776 TALLOC_FREE(req); /* non-chained case */
1777 TALLOC_FREE(reqs); /* chained case */
1780 /****************************************************************************
1781 Process an smb from the client
1782 ****************************************************************************/
1783 static void process_smb(struct smbd_server_connection *sconn,
1784 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1785 uint32_t seqnum, bool encrypted,
1786 struct smb_perfcount_data *deferred_pcd)
1788 int msg_type = CVAL(inbuf,0);
1790 DO_PROFILE_INC(smb_count);
1792 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1793 smb_len(inbuf) ) );
1794 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1795 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1797 if (msg_type != NBSSmessage) {
1799 * NetBIOS session request, keepalive, etc.
1801 reply_special(sconn, (char *)inbuf, nread);
1802 goto done;
1805 if (sconn->using_smb2) {
1806 /* At this point we're not really using smb2,
1807 * we make the decision here.. */
1808 if (smbd_is_smb2_header(inbuf, nread)) {
1809 smbd_smb2_first_negprot(sconn, inbuf, nread);
1810 return;
1811 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1812 && CVAL(inbuf, smb_com) != 0x72) {
1813 /* This is a non-negprot SMB1 packet.
1814 Disable SMB2 from now on. */
1815 sconn->using_smb2 = false;
1819 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1820 * so subtract 4 from it. */
1821 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1822 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1823 smb_len(inbuf)));
1825 /* special magic for immediate exit */
1826 if ((nread == 9) &&
1827 (IVAL(inbuf, 4) == 0x74697865) &&
1828 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1829 uint8_t exitcode = CVAL(inbuf, 8);
1830 DEBUG(1, ("Exiting immediately with code %d\n",
1831 (int)exitcode));
1832 exit(exitcode);
1835 exit_server_cleanly("Non-SMB packet");
1838 show_msg((char *)inbuf);
1840 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1841 construct_reply_chain(sconn, (char *)inbuf, nread,
1842 seqnum, encrypted, deferred_pcd);
1843 } else {
1844 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1845 seqnum, encrypted, deferred_pcd);
1848 sconn->trans_num++;
1850 done:
1851 sconn->num_requests++;
1853 /* The timeout_processing function isn't run nearly
1854 often enough to implement 'max log size' without
1855 overrunning the size of the file by many megabytes.
1856 This is especially true if we are running at debug
1857 level 10. Checking every 50 SMBs is a nice
1858 tradeoff of performance vs log file size overrun. */
1860 if ((sconn->num_requests % 50) == 0 &&
1861 need_to_check_log_size()) {
1862 change_to_root_user();
1863 check_log_size();
1867 /****************************************************************************
1868 Return a string containing the function name of a SMB command.
1869 ****************************************************************************/
1871 const char *smb_fn_name(int type)
1873 const char *unknown_name = "SMBunknown";
1875 if (smb_messages[type].name == NULL)
1876 return(unknown_name);
1878 return(smb_messages[type].name);
1881 /****************************************************************************
1882 Helper functions for contruct_reply.
1883 ****************************************************************************/
1885 void add_to_common_flags2(uint32 v)
1887 common_flags2 |= v;
1890 void remove_from_common_flags2(uint32 v)
1892 common_flags2 &= ~v;
1895 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1896 char *outbuf)
1898 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1899 uint16_t out_flags2 = common_flags2;
1901 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1902 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1903 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1905 srv_set_message(outbuf,0,0,false);
1907 SCVAL(outbuf, smb_com, req->cmd);
1908 SIVAL(outbuf,smb_rcls,0);
1909 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1910 SSVAL(outbuf,smb_flg2, out_flags2);
1911 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1912 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1914 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1915 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1916 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1917 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1920 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1922 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1926 * @brief Find the smb_cmd offset of the last command pushed
1927 * @param[in] buf The buffer we're building up
1928 * @retval Where can we put our next andx cmd?
1930 * While chaining requests, the "next" request we're looking at needs to put
1931 * its SMB_Command before the data the previous request already built up added
1932 * to the chain. Find the offset to the place where we have to put our cmd.
1935 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1937 uint8_t cmd;
1938 size_t ofs;
1940 cmd = CVAL(buf, smb_com);
1942 if (!is_andx_req(cmd)) {
1943 return false;
1946 ofs = smb_vwv0;
1948 while (CVAL(buf, ofs) != 0xff) {
1950 if (!is_andx_req(CVAL(buf, ofs))) {
1951 return false;
1955 * ofs is from start of smb header, so add the 4 length
1956 * bytes. The next cmd is right after the wct field.
1958 ofs = SVAL(buf, ofs+2) + 4 + 1;
1960 if (ofs+4 >= talloc_get_size(buf)) {
1961 return false;
1965 *pofs = ofs;
1966 return true;
1970 * @brief Do the smb chaining at a buffer level
1971 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1972 * @param[in] andx_buf Buffer to be appended
1975 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1977 uint8_t smb_command = CVAL(andx_buf, smb_com);
1978 uint8_t wct = CVAL(andx_buf, smb_wct);
1979 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1980 uint32_t num_bytes = smb_buflen(andx_buf);
1981 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1983 uint8_t *outbuf;
1984 size_t old_size, new_size;
1985 size_t ofs;
1986 size_t chain_padding = 0;
1987 size_t andx_cmd_ofs;
1990 old_size = talloc_get_size(*poutbuf);
1992 if ((old_size % 4) != 0) {
1994 * Align the wct field of subsequent requests to a 4-byte
1995 * boundary
1997 chain_padding = 4 - (old_size % 4);
2001 * After the old request comes the new wct field (1 byte), the vwv's
2002 * and the num_bytes field.
2005 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2006 new_size += num_bytes;
2008 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2009 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2010 (unsigned)new_size));
2011 return false;
2014 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2015 if (outbuf == NULL) {
2016 DEBUG(0, ("talloc failed\n"));
2017 return false;
2019 *poutbuf = outbuf;
2021 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2022 DEBUG(1, ("invalid command chain\n"));
2023 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2024 return false;
2027 if (chain_padding != 0) {
2028 memset(outbuf + old_size, 0, chain_padding);
2029 old_size += chain_padding;
2032 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2033 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2035 ofs = old_size;
2038 * Push the chained request:
2040 * wct field
2043 SCVAL(outbuf, ofs, wct);
2044 ofs += 1;
2047 * vwv array
2050 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2053 * HACK ALERT
2055 * Read&X has an offset into its data buffer at
2056 * vwv[6]. reply_read_andx has no idea anymore that it's
2057 * running from within a chain, so we have to fix up the
2058 * offset here.
2060 * Although it looks disgusting at this place, I want to keep
2061 * it here. The alternative would be to push knowledge about
2062 * the andx chain down into read&x again.
2065 if (smb_command == SMBreadX) {
2066 uint8_t *bytes_addr;
2068 if (wct < 7) {
2070 * Invalid read&x response
2072 return false;
2075 bytes_addr = outbuf + ofs /* vwv start */
2076 + sizeof(uint16_t) * wct /* vwv array */
2077 + sizeof(uint16_t); /* bcc */
2079 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2080 bytes_addr - outbuf - 4);
2083 ofs += sizeof(uint16_t) * wct;
2086 * bcc (byte count)
2089 SSVAL(outbuf, ofs, num_bytes);
2090 ofs += sizeof(uint16_t);
2093 * The bytes field
2096 memcpy(outbuf + ofs, bytes, num_bytes);
2098 return true;
2101 bool smb1_is_chain(const uint8_t *buf)
2103 uint8_t cmd, wct, andx_cmd;
2105 cmd = CVAL(buf, smb_com);
2106 if (!is_andx_req(cmd)) {
2107 return false;
2109 wct = CVAL(buf, smb_wct);
2110 if (wct < 2) {
2111 return false;
2113 andx_cmd = CVAL(buf, smb_vwv);
2114 return (andx_cmd != 0xFF);
2117 bool smb1_walk_chain(const uint8_t *buf,
2118 bool (*fn)(uint8_t cmd,
2119 uint8_t wct, const uint16_t *vwv,
2120 uint16_t num_bytes, const uint8_t *bytes,
2121 void *private_data),
2122 void *private_data)
2124 size_t smblen = smb_len(buf);
2125 const char *smb_buf = smb_base(buf);
2126 uint8_t cmd, chain_cmd;
2127 uint8_t wct;
2128 const uint16_t *vwv;
2129 uint16_t num_bytes;
2130 const uint8_t *bytes;
2132 cmd = CVAL(buf, smb_com);
2133 wct = CVAL(buf, smb_wct);
2134 vwv = (const uint16_t *)(buf + smb_vwv);
2135 num_bytes = smb_buflen(buf);
2136 bytes = (const uint8_t *)smb_buf_const(buf);
2138 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2139 return false;
2142 if (!is_andx_req(cmd)) {
2143 return true;
2145 if (wct < 2) {
2146 return false;
2149 chain_cmd = CVAL(vwv, 0);
2151 while (chain_cmd != 0xff) {
2152 uint32_t chain_offset; /* uint32_t to avoid overflow */
2153 size_t length_needed;
2154 ptrdiff_t vwv_offset;
2156 chain_offset = SVAL(vwv+1, 0);
2159 * Check if the client tries to fool us. The chain
2160 * offset needs to point beyond the current request in
2161 * the chain, it needs to strictly grow. Otherwise we
2162 * might be tricked into an endless loop always
2163 * processing the same request over and over again. We
2164 * used to assume that vwv and the byte buffer array
2165 * in a chain are always attached, but OS/2 the
2166 * Write&X/Read&X chain puts the Read&X vwv array
2167 * right behind the Write&X vwv chain. The Write&X bcc
2168 * array is put behind the Read&X vwv array. So now we
2169 * check whether the chain offset points strictly
2170 * behind the previous vwv array. req->buf points
2171 * right after the vwv array of the previous
2172 * request. See
2173 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2174 * more information.
2177 vwv_offset = ((const char *)vwv - smb_buf);
2178 if (chain_offset <= vwv_offset) {
2179 return false;
2183 * Next check: Make sure the chain offset does not
2184 * point beyond the overall smb request length.
2187 length_needed = chain_offset+1; /* wct */
2188 if (length_needed > smblen) {
2189 return false;
2193 * Now comes the pointer magic. Goal here is to set up
2194 * vwv and buf correctly again. The chain offset (the
2195 * former vwv[1]) points at the new wct field.
2198 wct = CVAL(smb_buf, chain_offset);
2200 if (is_andx_req(chain_cmd) && (wct < 2)) {
2201 return false;
2205 * Next consistency check: Make the new vwv array fits
2206 * in the overall smb request.
2209 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2210 if (length_needed > smblen) {
2211 return false;
2213 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2216 * Now grab the new byte buffer....
2219 num_bytes = SVAL(vwv+wct, 0);
2222 * .. and check that it fits.
2225 length_needed += num_bytes;
2226 if (length_needed > smblen) {
2227 return false;
2229 bytes = (const uint8_t *)(vwv+wct+1);
2231 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2232 return false;
2235 if (!is_andx_req(chain_cmd)) {
2236 return true;
2238 chain_cmd = CVAL(vwv, 0);
2240 return true;
2243 static bool smb1_chain_length_cb(uint8_t cmd,
2244 uint8_t wct, const uint16_t *vwv,
2245 uint16_t num_bytes, const uint8_t *bytes,
2246 void *private_data)
2248 unsigned *count = (unsigned *)private_data;
2249 *count += 1;
2250 return true;
2253 unsigned smb1_chain_length(const uint8_t *buf)
2255 unsigned count = 0;
2257 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2258 return 0;
2260 return count;
2263 struct smb1_parse_chain_state {
2264 TALLOC_CTX *mem_ctx;
2265 const uint8_t *buf;
2266 struct smbd_server_connection *sconn;
2267 bool encrypted;
2268 uint32_t seqnum;
2270 struct smb_request **reqs;
2271 unsigned num_reqs;
2274 static bool smb1_parse_chain_cb(uint8_t cmd,
2275 uint8_t wct, const uint16_t *vwv,
2276 uint16_t num_bytes, const uint8_t *bytes,
2277 void *private_data)
2279 struct smb1_parse_chain_state *state =
2280 (struct smb1_parse_chain_state *)private_data;
2281 struct smb_request **reqs;
2282 struct smb_request *req;
2283 bool ok;
2285 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2286 struct smb_request *, state->num_reqs+1);
2287 if (reqs == NULL) {
2288 return false;
2290 state->reqs = reqs;
2292 req = talloc(reqs, struct smb_request);
2293 if (req == NULL) {
2294 return false;
2297 ok = init_smb_request(req, state->sconn, state->buf, 0,
2298 state->encrypted, state->seqnum);
2299 if (!ok) {
2300 return false;
2302 req->cmd = cmd;
2303 req->wct = wct;
2304 req->vwv = vwv;
2305 req->buflen = num_bytes;
2306 req->buf = bytes;
2308 reqs[state->num_reqs] = req;
2309 state->num_reqs += 1;
2310 return true;
2313 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2314 struct smbd_server_connection *sconn,
2315 bool encrypted, uint32_t seqnum,
2316 struct smb_request ***reqs, unsigned *num_reqs)
2318 struct smb1_parse_chain_state state;
2319 unsigned i;
2321 state.mem_ctx = mem_ctx;
2322 state.buf = buf;
2323 state.sconn = sconn;
2324 state.encrypted = encrypted;
2325 state.seqnum = seqnum;
2326 state.reqs = NULL;
2327 state.num_reqs = 0;
2329 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2330 TALLOC_FREE(state.reqs);
2331 return false;
2333 for (i=0; i<state.num_reqs; i++) {
2334 state.reqs[i]->chain = state.reqs;
2336 *reqs = state.reqs;
2337 *num_reqs = state.num_reqs;
2338 return true;
2341 /****************************************************************************
2342 Check if services need reloading.
2343 ****************************************************************************/
2345 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2348 if (last_smb_conf_reload_time == 0) {
2349 last_smb_conf_reload_time = t;
2352 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2353 reload_services(sconn, conn_snum_used, true);
2354 last_smb_conf_reload_time = t;
2358 static bool fd_is_readable(int fd)
2360 int ret, revents;
2362 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2364 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2368 static void smbd_server_connection_write_handler(
2369 struct smbd_server_connection *sconn)
2371 /* TODO: make write nonblocking */
2374 static void smbd_server_connection_read_handler(
2375 struct smbd_server_connection *sconn, int fd)
2377 uint8_t *inbuf = NULL;
2378 size_t inbuf_len = 0;
2379 size_t unread_bytes = 0;
2380 bool encrypted = false;
2381 TALLOC_CTX *mem_ctx = talloc_tos();
2382 NTSTATUS status;
2383 uint32_t seqnum;
2385 bool async_echo = lp_async_smb_echo_handler();
2386 bool from_client = false;
2388 if (async_echo) {
2389 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2391 * This is the super-ugly hack to prefer the packets
2392 * forwarded by the echo handler over the ones by the
2393 * client directly
2395 fd = sconn->smb1.echo_handler.trusted_fd;
2399 from_client = (sconn->sock == fd);
2401 if (async_echo && from_client) {
2402 smbd_lock_socket(sconn);
2404 if (!fd_is_readable(fd)) {
2405 DEBUG(10,("the echo listener was faster\n"));
2406 smbd_unlock_socket(sconn);
2407 return;
2411 /* TODO: make this completely nonblocking */
2412 status = receive_smb_talloc(mem_ctx, sconn, fd,
2413 (char **)(void *)&inbuf,
2414 0, /* timeout */
2415 &unread_bytes,
2416 &encrypted,
2417 &inbuf_len, &seqnum,
2418 !from_client /* trusted channel */);
2420 if (async_echo && from_client) {
2421 smbd_unlock_socket(sconn);
2424 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2425 goto process;
2427 if (NT_STATUS_IS_ERR(status)) {
2428 exit_server_cleanly("failed to receive smb request");
2430 if (!NT_STATUS_IS_OK(status)) {
2431 return;
2434 process:
2435 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2436 seqnum, encrypted, NULL);
2439 static void smbd_server_connection_handler(struct tevent_context *ev,
2440 struct tevent_fd *fde,
2441 uint16_t flags,
2442 void *private_data)
2444 struct smbd_server_connection *conn = talloc_get_type(private_data,
2445 struct smbd_server_connection);
2447 if (!NT_STATUS_IS_OK(conn->status)) {
2449 * we're not supposed to do any io
2451 TEVENT_FD_NOT_READABLE(conn->smb1.fde);
2452 TEVENT_FD_NOT_WRITEABLE(conn->smb1.fde);
2453 return;
2456 if (flags & TEVENT_FD_WRITE) {
2457 smbd_server_connection_write_handler(conn);
2458 return;
2460 if (flags & TEVENT_FD_READ) {
2461 smbd_server_connection_read_handler(conn, conn->sock);
2462 return;
2466 static void smbd_server_echo_handler(struct tevent_context *ev,
2467 struct tevent_fd *fde,
2468 uint16_t flags,
2469 void *private_data)
2471 struct smbd_server_connection *conn = talloc_get_type(private_data,
2472 struct smbd_server_connection);
2474 if (!NT_STATUS_IS_OK(conn->status)) {
2476 * we're not supposed to do any io
2478 TEVENT_FD_NOT_READABLE(conn->smb1.echo_handler.trusted_fde);
2479 TEVENT_FD_NOT_WRITEABLE(conn->smb1.echo_handler.trusted_fde);
2480 return;
2483 if (flags & TEVENT_FD_WRITE) {
2484 smbd_server_connection_write_handler(conn);
2485 return;
2487 if (flags & TEVENT_FD_READ) {
2488 smbd_server_connection_read_handler(
2489 conn, conn->smb1.echo_handler.trusted_fd);
2490 return;
2494 struct smbd_release_ip_state {
2495 struct smbd_server_connection *sconn;
2496 struct tevent_immediate *im;
2497 char addr[INET6_ADDRSTRLEN];
2500 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2501 struct tevent_immediate *im,
2502 void *private_data)
2504 struct smbd_release_ip_state *state =
2505 talloc_get_type_abort(private_data,
2506 struct smbd_release_ip_state);
2508 if (!NT_STATUS_EQUAL(state->sconn->status, NT_STATUS_ADDRESS_CLOSED)) {
2510 * smbd_server_connection_terminate() already triggered ?
2512 return;
2515 smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
2518 /****************************************************************************
2519 received when we should release a specific IP
2520 ****************************************************************************/
2521 static bool release_ip(const char *ip, void *priv)
2523 struct smbd_release_ip_state *state =
2524 talloc_get_type_abort(priv,
2525 struct smbd_release_ip_state);
2526 const char *addr = state->addr;
2527 const char *p = addr;
2529 if (!NT_STATUS_IS_OK(state->sconn->status)) {
2530 /* avoid recursion */
2531 return false;
2534 if (strncmp("::ffff:", addr, 7) == 0) {
2535 p = addr + 7;
2538 DEBUG(10, ("Got release IP message for %s, "
2539 "our address is %s\n", ip, p));
2541 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2542 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2543 ip));
2545 * With SMB2 we should do a clean disconnect,
2546 * the previous_session_id in the session setup
2547 * will cleanup the old session, tcons and opens.
2549 * A clean disconnect is needed in order to support
2550 * durable handles.
2552 * Note: typically this is never triggered
2553 * as we got a TCP RST (triggered by ctdb event scripts)
2554 * before we get CTDB_SRVID_RELEASE_IP.
2556 * We used to call _exit(1) here, but as this was mostly never
2557 * triggered and has implication on our process model,
2558 * we can just use smbd_server_connection_terminate()
2559 * (also for SMB1).
2561 * We don't call smbd_server_connection_terminate() directly
2562 * as we might be called from within ctdbd_migrate(),
2563 * we need to defer our action to the next event loop
2565 tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
2566 smbd_release_ip_immediate, state);
2569 * Make sure we don't get any io on the connection.
2571 state->sconn->status = NT_STATUS_ADDRESS_CLOSED;
2572 return true;
2575 return false;
2578 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2579 struct sockaddr_storage *srv,
2580 struct sockaddr_storage *clnt)
2582 struct smbd_release_ip_state *state;
2583 struct ctdbd_connection *cconn;
2585 cconn = messaging_ctdbd_connection();
2586 if (cconn == NULL) {
2587 return NT_STATUS_NO_MEMORY;
2590 state = talloc_zero(sconn, struct smbd_release_ip_state);
2591 if (state == NULL) {
2592 return NT_STATUS_NO_MEMORY;
2594 state->sconn = sconn;
2595 state->im = tevent_create_immediate(state);
2596 if (state->im == NULL) {
2597 return NT_STATUS_NO_MEMORY;
2599 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2600 return NT_STATUS_NO_MEMORY;
2603 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2606 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2607 struct sockaddr_storage *client)
2609 socklen_t length;
2610 length = sizeof(*server);
2611 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2612 return -1;
2614 length = sizeof(*client);
2615 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2616 return -1;
2618 return 0;
2621 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2622 void *private_data, uint32_t msg_type,
2623 struct server_id server_id, DATA_BLOB *data)
2625 struct smbd_server_connection *sconn = talloc_get_type_abort(
2626 private_data, struct smbd_server_connection);
2627 const char *ip = (char *) data->data;
2628 char *client_ip;
2630 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2632 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2633 talloc_tos());
2634 if (client_ip == NULL) {
2635 return;
2638 if (strequal(ip, client_ip)) {
2639 DEBUG(1, ("Got kill client message for %s - "
2640 "exiting immediately\n", ip));
2641 exit_server_cleanly("Forced disconnect for client");
2644 TALLOC_FREE(client_ip);
2648 * Send keepalive packets to our client
2650 static bool keepalive_fn(const struct timeval *now, void *private_data)
2652 struct smbd_server_connection *sconn = talloc_get_type_abort(
2653 private_data, struct smbd_server_connection);
2654 bool ret;
2656 if (sconn->using_smb2) {
2657 /* Don't do keepalives on an SMB2 connection. */
2658 return false;
2661 smbd_lock_socket(sconn);
2662 ret = send_keepalive(sconn->sock);
2663 smbd_unlock_socket(sconn);
2665 if (!ret) {
2666 char addr[INET6_ADDRSTRLEN];
2668 * Try and give an error message saying what
2669 * client failed.
2671 DEBUG(0, ("send_keepalive failed for client %s. "
2672 "Error %s - exiting\n",
2673 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2674 strerror(errno)));
2675 return False;
2677 return True;
2681 * Do the recurring check if we're idle
2683 static bool deadtime_fn(const struct timeval *now, void *private_data)
2685 struct smbd_server_connection *sconn =
2686 (struct smbd_server_connection *)private_data;
2688 if ((conn_num_open(sconn) == 0)
2689 || (conn_idle_all(sconn, now->tv_sec))) {
2690 DEBUG( 2, ( "Closing idle connection\n" ) );
2691 messaging_send(sconn->msg_ctx,
2692 messaging_server_id(sconn->msg_ctx),
2693 MSG_SHUTDOWN, &data_blob_null);
2694 return False;
2697 return True;
2701 * Do the recurring log file and smb.conf reload checks.
2704 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2706 struct smbd_server_connection *sconn = talloc_get_type_abort(
2707 private_data, struct smbd_server_connection);
2709 DEBUG(5, ("housekeeping\n"));
2711 change_to_root_user();
2713 /* update printer queue caches if necessary */
2714 update_monitored_printq_cache(sconn->msg_ctx);
2716 /* check if we need to reload services */
2717 check_reload(sconn, time_mono(NULL));
2720 * Force a log file check.
2722 force_check_log_size();
2723 check_log_size();
2724 return true;
2728 * Read an smb packet in the echo handler child, giving the parent
2729 * smbd one second to react once the socket becomes readable.
2732 struct smbd_echo_read_state {
2733 struct tevent_context *ev;
2734 struct smbd_server_connection *sconn;
2736 char *buf;
2737 size_t buflen;
2738 uint32_t seqnum;
2741 static void smbd_echo_read_readable(struct tevent_req *subreq);
2742 static void smbd_echo_read_waited(struct tevent_req *subreq);
2744 static struct tevent_req *smbd_echo_read_send(
2745 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2746 struct smbd_server_connection *sconn)
2748 struct tevent_req *req, *subreq;
2749 struct smbd_echo_read_state *state;
2751 req = tevent_req_create(mem_ctx, &state,
2752 struct smbd_echo_read_state);
2753 if (req == NULL) {
2754 return NULL;
2756 state->ev = ev;
2757 state->sconn = sconn;
2759 subreq = wait_for_read_send(state, ev, sconn->sock);
2760 if (tevent_req_nomem(subreq, req)) {
2761 return tevent_req_post(req, ev);
2763 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2764 return req;
2767 static void smbd_echo_read_readable(struct tevent_req *subreq)
2769 struct tevent_req *req = tevent_req_callback_data(
2770 subreq, struct tevent_req);
2771 struct smbd_echo_read_state *state = tevent_req_data(
2772 req, struct smbd_echo_read_state);
2773 bool ok;
2774 int err;
2776 ok = wait_for_read_recv(subreq, &err);
2777 TALLOC_FREE(subreq);
2778 if (!ok) {
2779 tevent_req_nterror(req, map_nt_error_from_unix(err));
2780 return;
2784 * Give the parent smbd one second to step in
2787 subreq = tevent_wakeup_send(
2788 state, state->ev, timeval_current_ofs(1, 0));
2789 if (tevent_req_nomem(subreq, req)) {
2790 return;
2792 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2795 static void smbd_echo_read_waited(struct tevent_req *subreq)
2797 struct tevent_req *req = tevent_req_callback_data(
2798 subreq, struct tevent_req);
2799 struct smbd_echo_read_state *state = tevent_req_data(
2800 req, struct smbd_echo_read_state);
2801 struct smbd_server_connection *sconn = state->sconn;
2802 bool ok;
2803 NTSTATUS status;
2804 size_t unread = 0;
2805 bool encrypted;
2807 ok = tevent_wakeup_recv(subreq);
2808 TALLOC_FREE(subreq);
2809 if (!ok) {
2810 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2811 return;
2814 ok = smbd_lock_socket_internal(sconn);
2815 if (!ok) {
2816 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2817 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2818 return;
2821 if (!fd_is_readable(sconn->sock)) {
2822 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2823 (int)getpid()));
2825 ok = smbd_unlock_socket_internal(sconn);
2826 if (!ok) {
2827 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2828 DEBUG(1, ("%s: failed to unlock socket\n",
2829 __location__));
2830 return;
2833 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2834 if (tevent_req_nomem(subreq, req)) {
2835 return;
2837 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2838 return;
2841 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2842 0 /* timeout */,
2843 &unread,
2844 &encrypted,
2845 &state->buflen,
2846 &state->seqnum,
2847 false /* trusted_channel*/);
2849 if (tevent_req_nterror(req, status)) {
2850 tevent_req_nterror(req, status);
2851 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2852 (int)getpid(), nt_errstr(status)));
2853 return;
2856 ok = smbd_unlock_socket_internal(sconn);
2857 if (!ok) {
2858 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2859 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2860 return;
2862 tevent_req_done(req);
2865 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2866 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2868 struct smbd_echo_read_state *state = tevent_req_data(
2869 req, struct smbd_echo_read_state);
2870 NTSTATUS status;
2872 if (tevent_req_is_nterror(req, &status)) {
2873 return status;
2875 *pbuf = talloc_move(mem_ctx, &state->buf);
2876 *pbuflen = state->buflen;
2877 *pseqnum = state->seqnum;
2878 return NT_STATUS_OK;
2881 struct smbd_echo_state {
2882 struct tevent_context *ev;
2883 struct iovec *pending;
2884 struct smbd_server_connection *sconn;
2885 int parent_pipe;
2887 struct tevent_fd *parent_fde;
2889 struct tevent_req *write_req;
2892 static void smbd_echo_writer_done(struct tevent_req *req);
2894 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2896 int num_pending;
2898 if (state->write_req != NULL) {
2899 return;
2902 num_pending = talloc_array_length(state->pending);
2903 if (num_pending == 0) {
2904 return;
2907 state->write_req = writev_send(state, state->ev, NULL,
2908 state->parent_pipe, false,
2909 state->pending, num_pending);
2910 if (state->write_req == NULL) {
2911 DEBUG(1, ("writev_send failed\n"));
2912 exit(1);
2915 talloc_steal(state->write_req, state->pending);
2916 state->pending = NULL;
2918 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2919 state);
2922 static void smbd_echo_writer_done(struct tevent_req *req)
2924 struct smbd_echo_state *state = tevent_req_callback_data(
2925 req, struct smbd_echo_state);
2926 ssize_t written;
2927 int err;
2929 written = writev_recv(req, &err);
2930 TALLOC_FREE(req);
2931 state->write_req = NULL;
2932 if (written == -1) {
2933 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2934 exit(1);
2936 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2937 smbd_echo_activate_writer(state);
2940 static bool smbd_echo_reply(struct smbd_echo_state *state,
2941 uint8_t *inbuf, size_t inbuf_len,
2942 uint32_t seqnum)
2944 struct smb_request req;
2945 uint16_t num_replies;
2946 char *outbuf;
2947 bool ok;
2949 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2950 DEBUG(10, ("Got netbios keepalive\n"));
2952 * Just swallow it
2954 return true;
2957 if (inbuf_len < smb_size) {
2958 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2959 return false;
2961 if (!valid_smb_header(state->sconn, inbuf)) {
2962 DEBUG(10, ("Got invalid SMB header\n"));
2963 return false;
2966 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2967 seqnum)) {
2968 return false;
2970 req.inbuf = inbuf;
2972 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2973 smb_messages[req.cmd].name
2974 ? smb_messages[req.cmd].name : "unknown"));
2976 if (req.cmd != SMBecho) {
2977 return false;
2979 if (req.wct < 1) {
2980 return false;
2983 num_replies = SVAL(req.vwv+0, 0);
2984 if (num_replies != 1) {
2985 /* Not a Windows "Hey, you're still there?" request */
2986 return false;
2989 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2990 1, req.buflen)) {
2991 DEBUG(10, ("create_outbuf failed\n"));
2992 return false;
2994 req.outbuf = (uint8_t *)outbuf;
2996 SSVAL(req.outbuf, smb_vwv0, num_replies);
2998 if (req.buflen > 0) {
2999 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3002 ok = srv_send_smb(req.sconn,
3003 (char *)outbuf,
3004 true, seqnum+1,
3005 false, &req.pcd);
3006 TALLOC_FREE(outbuf);
3007 if (!ok) {
3008 exit(1);
3011 return true;
3014 static void smbd_echo_exit(struct tevent_context *ev,
3015 struct tevent_fd *fde, uint16_t flags,
3016 void *private_data)
3018 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3019 exit(0);
3022 static void smbd_echo_got_packet(struct tevent_req *req);
3024 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3025 int parent_pipe)
3027 struct smbd_echo_state *state;
3028 struct tevent_req *read_req;
3030 state = talloc_zero(sconn, struct smbd_echo_state);
3031 if (state == NULL) {
3032 DEBUG(1, ("talloc failed\n"));
3033 return;
3035 state->sconn = sconn;
3036 state->parent_pipe = parent_pipe;
3037 state->ev = s3_tevent_context_init(state);
3038 if (state->ev == NULL) {
3039 DEBUG(1, ("tevent_context_init failed\n"));
3040 TALLOC_FREE(state);
3041 return;
3043 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3044 TEVENT_FD_READ, smbd_echo_exit,
3045 state);
3046 if (state->parent_fde == NULL) {
3047 DEBUG(1, ("tevent_add_fd failed\n"));
3048 TALLOC_FREE(state);
3049 return;
3052 read_req = smbd_echo_read_send(state, state->ev, sconn);
3053 if (read_req == NULL) {
3054 DEBUG(1, ("smbd_echo_read_send failed\n"));
3055 TALLOC_FREE(state);
3056 return;
3058 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3060 while (true) {
3061 if (tevent_loop_once(state->ev) == -1) {
3062 DEBUG(1, ("tevent_loop_once failed: %s\n",
3063 strerror(errno)));
3064 break;
3067 TALLOC_FREE(state);
3070 static void smbd_echo_got_packet(struct tevent_req *req)
3072 struct smbd_echo_state *state = tevent_req_callback_data(
3073 req, struct smbd_echo_state);
3074 NTSTATUS status;
3075 char *buf = NULL;
3076 size_t buflen = 0;
3077 uint32_t seqnum = 0;
3078 bool reply;
3080 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3081 TALLOC_FREE(req);
3082 if (!NT_STATUS_IS_OK(status)) {
3083 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3084 nt_errstr(status)));
3085 exit(1);
3088 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3089 if (!reply) {
3090 size_t num_pending;
3091 struct iovec *tmp;
3092 struct iovec *iov;
3094 num_pending = talloc_array_length(state->pending);
3095 tmp = talloc_realloc(state, state->pending, struct iovec,
3096 num_pending+1);
3097 if (tmp == NULL) {
3098 DEBUG(1, ("talloc_realloc failed\n"));
3099 exit(1);
3101 state->pending = tmp;
3103 if (buflen >= smb_size) {
3105 * place the seqnum in the packet so that the main process
3106 * can reply with signing
3108 SIVAL(buf, smb_ss_field, seqnum);
3109 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3112 iov = &state->pending[num_pending];
3113 iov->iov_base = talloc_move(state->pending, &buf);
3114 iov->iov_len = buflen;
3116 DEBUG(10,("echo_handler[%d]: forward to main\n",
3117 (int)getpid()));
3118 smbd_echo_activate_writer(state);
3121 req = smbd_echo_read_send(state, state->ev, state->sconn);
3122 if (req == NULL) {
3123 DEBUG(1, ("smbd_echo_read_send failed\n"));
3124 exit(1);
3126 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3131 * Handle SMBecho requests in a forked child process
3133 bool fork_echo_handler(struct smbd_server_connection *sconn)
3135 int listener_pipe[2];
3136 int res;
3137 pid_t child;
3139 res = pipe(listener_pipe);
3140 if (res == -1) {
3141 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3142 return false;
3144 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lock_directory());
3145 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3146 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3147 goto fail;
3150 child = fork();
3151 if (child == 0) {
3152 NTSTATUS status;
3154 close(listener_pipe[0]);
3155 set_blocking(listener_pipe[1], false);
3157 status = reinit_after_fork(sconn->msg_ctx,
3158 sconn->ev_ctx,
3159 true);
3160 if (!NT_STATUS_IS_OK(status)) {
3161 DEBUG(1, ("reinit_after_fork failed: %s\n",
3162 nt_errstr(status)));
3163 exit(1);
3165 smbd_echo_loop(sconn, listener_pipe[1]);
3166 exit(0);
3168 close(listener_pipe[1]);
3169 listener_pipe[1] = -1;
3170 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3172 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3175 * Without smb signing this is the same as the normal smbd
3176 * listener. This needs to change once signing comes in.
3178 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3179 sconn,
3180 sconn->smb1.echo_handler.trusted_fd,
3181 TEVENT_FD_READ,
3182 smbd_server_echo_handler,
3183 sconn);
3184 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3185 DEBUG(1, ("event_add_fd failed\n"));
3186 goto fail;
3189 return true;
3191 fail:
3192 if (listener_pipe[0] != -1) {
3193 close(listener_pipe[0]);
3195 if (listener_pipe[1] != -1) {
3196 close(listener_pipe[1]);
3198 sconn->smb1.echo_handler.trusted_fd = -1;
3199 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3200 close(sconn->smb1.echo_handler.socket_lock_fd);
3202 sconn->smb1.echo_handler.trusted_fd = -1;
3203 sconn->smb1.echo_handler.socket_lock_fd = -1;
3204 return false;
3207 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3209 while (user) {
3210 if (user->session_info &&
3211 (user->session_info->unix_token->uid == uid)) {
3212 return true;
3214 user = user->next;
3216 return false;
3219 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3221 while (user) {
3222 if (user->session_info != NULL) {
3223 int i;
3224 struct security_unix_token *utok;
3226 utok = user->session_info->unix_token;
3227 if (utok->gid == gid) {
3228 return true;
3230 for(i=0; i<utok->ngroups; i++) {
3231 if (utok->groups[i] == gid) {
3232 return true;
3236 user = user->next;
3238 return false;
3241 static bool sid_in_use(const struct user_struct *user,
3242 const struct dom_sid *psid)
3244 while (user) {
3245 struct security_token *tok;
3247 if (user->session_info == NULL) {
3248 continue;
3250 tok = user->session_info->security_token;
3251 if (tok == NULL) {
3253 * Not sure session_info->security_token can
3254 * ever be NULL. This check might be not
3255 * necessary.
3257 continue;
3259 if (security_token_has_sid(tok, psid)) {
3260 return true;
3262 user = user->next;
3264 return false;
3267 static bool id_in_use(const struct user_struct *user,
3268 const struct id_cache_ref *id)
3270 switch(id->type) {
3271 case UID:
3272 return uid_in_use(user, id->id.uid);
3273 case GID:
3274 return gid_in_use(user, id->id.gid);
3275 case SID:
3276 return sid_in_use(user, &id->id.sid);
3277 default:
3278 break;
3280 return false;
3283 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3284 void *private_data,
3285 uint32_t msg_type,
3286 struct server_id server_id,
3287 DATA_BLOB* data)
3289 const char *msg = (data && data->data)
3290 ? (const char *)data->data : "<NULL>";
3291 struct id_cache_ref id;
3292 struct smbd_server_connection *sconn =
3293 talloc_get_type_abort(private_data,
3294 struct smbd_server_connection);
3296 if (!id_cache_ref_parse(msg, &id)) {
3297 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3298 return;
3301 if (id_in_use(sconn->users, &id)) {
3302 exit_server_cleanly(msg);
3304 id_cache_delete_from_cache(&id);
3307 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3308 enum protocol_types protocol)
3310 NTSTATUS status;
3312 set_Protocol(protocol);
3313 conn->protocol = protocol;
3315 if (protocol >= PROTOCOL_SMB2_02) {
3316 status = smb2srv_session_table_init(conn);
3317 if (!NT_STATUS_IS_OK(status)) {
3318 return status;
3321 status = smb2srv_open_table_init(conn);
3322 if (!NT_STATUS_IS_OK(status)) {
3323 return status;
3325 } else {
3326 status = smb1srv_session_table_init(conn);
3327 if (!NT_STATUS_IS_OK(status)) {
3328 return status;
3331 status = smb1srv_tcon_table_init(conn);
3332 if (!NT_STATUS_IS_OK(status)) {
3333 return status;
3336 status = smb1srv_open_table_init(conn);
3337 if (!NT_STATUS_IS_OK(status)) {
3338 return status;
3342 return NT_STATUS_OK;
3345 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3346 void *private_data)
3348 struct smbXsrv_connection *conn =
3349 talloc_get_type_abort(private_data,
3350 struct smbXsrv_connection);
3352 switch (point) {
3353 case TEVENT_TRACE_BEFORE_WAIT:
3355 * This just removes compiler warning
3356 * without profile support
3358 conn->smbd_idle_profstamp = 0;
3359 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3360 break;
3361 case TEVENT_TRACE_AFTER_WAIT:
3362 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3363 break;
3364 #ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
3365 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3366 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3367 break;
3368 #endif
3372 /****************************************************************************
3373 Process commands from the client
3374 ****************************************************************************/
3376 void smbd_process(struct tevent_context *ev_ctx,
3377 struct messaging_context *msg_ctx,
3378 int sock_fd,
3379 bool interactive)
3381 TALLOC_CTX *frame = talloc_stackframe();
3382 struct smbXsrv_connection *conn;
3383 struct smbd_server_connection *sconn;
3384 struct sockaddr_storage ss;
3385 struct sockaddr *sa = NULL;
3386 socklen_t sa_socklen;
3387 struct tsocket_address *local_address = NULL;
3388 struct tsocket_address *remote_address = NULL;
3389 const char *locaddr = NULL;
3390 const char *remaddr = NULL;
3391 char *rhost;
3392 int ret;
3393 int tmp;
3395 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3396 if (conn == NULL) {
3397 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3398 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3401 conn->ev_ctx = ev_ctx;
3402 conn->msg_ctx = msg_ctx;
3404 sconn = talloc_zero(conn, struct smbd_server_connection);
3405 if (!sconn) {
3406 exit_server("failed to create smbd_server_connection");
3409 conn->sconn = sconn;
3410 sconn->conn = conn;
3413 * TODO: remove this...:-)
3415 global_smbXsrv_connection = conn;
3417 sconn->ev_ctx = ev_ctx;
3418 sconn->msg_ctx = msg_ctx;
3419 sconn->sock = sock_fd;
3420 sconn->smb1.echo_handler.trusted_fd = -1;
3421 sconn->smb1.echo_handler.socket_lock_fd = -1;
3423 if (!interactive) {
3424 smbd_setup_sig_term_handler(sconn);
3425 smbd_setup_sig_hup_handler(sconn);
3427 if (!serverid_register(messaging_server_id(msg_ctx),
3428 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3429 |FLAG_MSG_DBWRAP
3430 |FLAG_MSG_PRINT_GENERAL)) {
3431 exit_server_cleanly("Could not register myself in "
3432 "serverid.tdb");
3436 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3438 * We're not making the decision here,
3439 * we're just allowing the client
3440 * to decide between SMB1 and SMB2
3441 * with the first negprot
3442 * packet.
3444 sconn->using_smb2 = true;
3447 /* Ensure child is set to blocking mode */
3448 set_blocking(sconn->sock,True);
3450 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3451 set_socket_options(sconn->sock, lp_socket_options());
3453 sa = (struct sockaddr *)(void *)&ss;
3454 sa_socklen = sizeof(ss);
3455 ret = getpeername(sconn->sock, sa, &sa_socklen);
3456 if (ret != 0) {
3457 int level = (errno == ENOTCONN)?2:0;
3458 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3459 exit_server_cleanly("getpeername() failed.\n");
3461 ret = tsocket_address_bsd_from_sockaddr(sconn,
3462 sa, sa_socklen,
3463 &remote_address);
3464 if (ret != 0) {
3465 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3466 __location__, strerror(errno)));
3467 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3470 sa = (struct sockaddr *)(void *)&ss;
3471 sa_socklen = sizeof(ss);
3472 ret = getsockname(sconn->sock, sa, &sa_socklen);
3473 if (ret != 0) {
3474 int level = (errno == ENOTCONN)?2:0;
3475 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3476 exit_server_cleanly("getsockname() failed.\n");
3478 ret = tsocket_address_bsd_from_sockaddr(sconn,
3479 sa, sa_socklen,
3480 &local_address);
3481 if (ret != 0) {
3482 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3483 __location__, strerror(errno)));
3484 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3487 sconn->local_address = local_address;
3488 sconn->remote_address = remote_address;
3490 if (tsocket_address_is_inet(local_address, "ip")) {
3491 locaddr = tsocket_address_inet_addr_string(
3492 sconn->local_address,
3493 talloc_tos());
3494 if (locaddr == NULL) {
3495 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3496 __location__, strerror(errno)));
3497 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3499 } else {
3500 locaddr = "0.0.0.0";
3503 if (tsocket_address_is_inet(remote_address, "ip")) {
3504 remaddr = tsocket_address_inet_addr_string(
3505 sconn->remote_address,
3506 talloc_tos());
3507 if (remaddr == NULL) {
3508 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3509 __location__, strerror(errno)));
3510 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3512 } else {
3513 remaddr = "0.0.0.0";
3516 /* this is needed so that we get decent entries
3517 in smbstatus for port 445 connects */
3518 set_remote_machine_name(remaddr, false);
3519 reload_services(sconn, conn_snum_used, true);
3522 * Before the first packet, check the global hosts allow/ hosts deny
3523 * parameters before doing any parsing of packets passed to us by the
3524 * client. This prevents attacks on our parsing code from hosts not in
3525 * the hosts allow list.
3528 ret = get_remote_hostname(remote_address,
3529 &rhost,
3530 talloc_tos());
3531 if (ret < 0) {
3532 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3533 __location__, strerror(errno)));
3534 exit_server_cleanly("get_remote_hostname failed.\n");
3536 if (strequal(rhost, "UNKNOWN")) {
3537 rhost = talloc_strdup(talloc_tos(), remaddr);
3539 sconn->remote_hostname = talloc_move(sconn, &rhost);
3541 sub_set_socket_ids(remaddr,
3542 sconn->remote_hostname,
3543 locaddr);
3545 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3546 sconn->remote_hostname,
3547 remaddr)) {
3549 * send a negative session response "not listening on calling
3550 * name"
3552 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3553 DEBUG( 1, ("Connection denied from %s to %s\n",
3554 tsocket_address_string(remote_address, talloc_tos()),
3555 tsocket_address_string(local_address, talloc_tos())));
3556 (void)srv_send_smb(sconn,(char *)buf, false,
3557 0, false, NULL);
3558 exit_server_cleanly("connection denied");
3561 DEBUG(10, ("Connection allowed from %s to %s\n",
3562 tsocket_address_string(remote_address, talloc_tos()),
3563 tsocket_address_string(local_address, talloc_tos())));
3565 if (lp_preload_modules()) {
3566 smb_load_modules(lp_preload_modules());
3569 smb_perfcount_init();
3571 if (!init_account_policy()) {
3572 exit_server("Could not open account policy tdb.\n");
3575 if (*lp_root_directory(talloc_tos())) {
3576 if (chroot(lp_root_directory(talloc_tos())) != 0) {
3577 DEBUG(0,("Failed to change root to %s\n",
3578 lp_root_directory(talloc_tos())));
3579 exit_server("Failed to chroot()");
3581 if (chdir("/") == -1) {
3582 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
3583 exit_server("Failed to chroot()");
3585 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
3588 if (!srv_init_signing(sconn)) {
3589 exit_server("Failed to init smb_signing");
3592 if (!file_init(sconn)) {
3593 exit_server("file_init() failed");
3596 /* Setup oplocks */
3597 if (!init_oplocks(sconn))
3598 exit_server("Failed to init oplocks");
3600 /* register our message handlers */
3601 messaging_register(sconn->msg_ctx, sconn,
3602 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3603 messaging_register(sconn->msg_ctx, sconn,
3604 MSG_SMB_CLOSE_FILE, msg_close_file);
3605 messaging_register(sconn->msg_ctx, sconn,
3606 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3608 id_cache_register_msgs(sconn->msg_ctx);
3609 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3610 messaging_register(sconn->msg_ctx, sconn,
3611 ID_CACHE_KILL, smbd_id_cache_kill);
3613 messaging_deregister(sconn->msg_ctx,
3614 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3615 messaging_register(sconn->msg_ctx, sconn,
3616 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3618 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3619 NULL);
3620 messaging_register(sconn->msg_ctx, sconn,
3621 MSG_SMB_KILL_CLIENT_IP,
3622 msg_kill_client_ip);
3624 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3627 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3628 * MSGs to all child processes
3630 messaging_deregister(sconn->msg_ctx,
3631 MSG_DEBUG, NULL);
3632 messaging_register(sconn->msg_ctx, NULL,
3633 MSG_DEBUG, debug_message);
3635 if ((lp_keepalive() != 0)
3636 && !(event_add_idle(ev_ctx, NULL,
3637 timeval_set(lp_keepalive(), 0),
3638 "keepalive", keepalive_fn,
3639 sconn))) {
3640 DEBUG(0, ("Could not add keepalive event\n"));
3641 exit(1);
3644 if (!(event_add_idle(ev_ctx, NULL,
3645 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3646 "deadtime", deadtime_fn, sconn))) {
3647 DEBUG(0, ("Could not add deadtime event\n"));
3648 exit(1);
3651 if (!(event_add_idle(ev_ctx, NULL,
3652 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3653 "housekeeping", housekeeping_fn, sconn))) {
3654 DEBUG(0, ("Could not add housekeeping event\n"));
3655 exit(1);
3658 if (lp_clustering()) {
3660 * We need to tell ctdb about our client's TCP
3661 * connection, so that for failover ctdbd can send
3662 * tickle acks, triggering a reconnection by the
3663 * client.
3666 struct sockaddr_storage srv, clnt;
3668 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3669 NTSTATUS status;
3670 status = smbd_register_ips(sconn, &srv, &clnt);
3671 if (!NT_STATUS_IS_OK(status)) {
3672 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3673 nt_errstr(status)));
3675 } else {
3676 int level = (errno == ENOTCONN)?2:0;
3677 DEBUG(level,("Unable to get tcp info for "
3678 "smbd_register_ips: %s\n",
3679 strerror(errno)));
3680 exit_server_cleanly("client_get_tcp_info() failed.\n");
3684 sconn->nbt.got_session = false;
3686 tmp = lp_max_xmit();
3687 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3688 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3690 sconn->smb1.negprot.max_recv = tmp;
3692 sconn->smb1.sessions.done_sesssetup = false;
3693 sconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3695 if (!init_dptrs(sconn)) {
3696 exit_server("init_dptrs() failed");
3699 sconn->smb1.fde = tevent_add_fd(ev_ctx,
3700 sconn,
3701 sconn->sock,
3702 TEVENT_FD_READ,
3703 smbd_server_connection_handler,
3704 sconn);
3705 if (!sconn->smb1.fde) {
3706 exit_server("failed to create smbd_server_connection fde");
3709 sconn->conn->local_address = sconn->local_address;
3710 sconn->conn->remote_address = sconn->remote_address;
3711 sconn->conn->remote_hostname = sconn->remote_hostname;
3712 sconn->conn->protocol = PROTOCOL_NONE;
3714 TALLOC_FREE(frame);
3716 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3718 while (True) {
3719 frame = talloc_stackframe_pool(8192);
3721 errno = 0;
3722 if (tevent_loop_once(ev_ctx) == -1) {
3723 if (errno != EINTR) {
3724 DEBUG(3, ("tevent_loop_once failed: %s,"
3725 " exiting\n", strerror(errno) ));
3726 break;
3730 TALLOC_FREE(frame);
3733 exit_server_cleanly(NULL);
3736 bool req_is_in_chain(const struct smb_request *req)
3738 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3740 * We're right now handling a subsequent request, so we must
3741 * be in a chain
3743 return true;
3746 if (!is_andx_req(req->cmd)) {
3747 return false;
3750 if (req->wct < 2) {
3752 * Okay, an illegal request, but definitely not chained :-)
3754 return false;
3757 return (CVAL(req->vwv+0, 0) != 0xFF);