s3:smbd: use SMB_BUFFER_SIZE_MIN/MAX to limit lp_max_xmit()
[Samba.git] / source3 / smbd / process.c
blob02a219eec8f929baeefd9fa8717d8db61f423fe2
1 /*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
42 #include "serverid.h"
44 /* Internal message queue for deferred opens. */
45 struct pending_message_list {
46 struct pending_message_list *next, *prev;
47 struct timeval request_time; /* When was this first issued? */
48 struct smbd_server_connection *sconn;
49 struct tevent_timer *te;
50 struct smb_perfcount_data pcd;
51 uint32_t seqnum;
52 bool encrypted;
53 bool processed;
54 DATA_BLOB buf;
55 DATA_BLOB private_data;
58 static void construct_reply_common(struct smb_request *req, const char *inbuf,
59 char *outbuf);
60 static struct pending_message_list *get_deferred_open_message_smb(
61 struct smbd_server_connection *sconn, uint64_t mid);
62 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
64 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
66 bool ok;
68 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
69 return true;
72 sconn->smb1.echo_handler.ref_count++;
74 if (sconn->smb1.echo_handler.ref_count > 1) {
75 return true;
78 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
80 do {
81 ok = fcntl_lock(
82 sconn->smb1.echo_handler.socket_lock_fd,
83 F_SETLKW, 0, 0, F_WRLCK);
84 } while (!ok && (errno == EINTR));
86 if (!ok) {
87 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
88 return false;
91 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
93 return true;
96 void smbd_lock_socket(struct smbd_server_connection *sconn)
98 if (!smbd_lock_socket_internal(sconn)) {
99 exit_server_cleanly("failed to lock socket");
103 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
105 bool ok;
107 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
108 return true;
111 sconn->smb1.echo_handler.ref_count--;
113 if (sconn->smb1.echo_handler.ref_count > 0) {
114 return true;
117 do {
118 ok = fcntl_lock(
119 sconn->smb1.echo_handler.socket_lock_fd,
120 F_SETLKW, 0, 0, F_UNLCK);
121 } while (!ok && (errno == EINTR));
123 if (!ok) {
124 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
125 return false;
128 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
130 return true;
133 void smbd_unlock_socket(struct smbd_server_connection *sconn)
135 if (!smbd_unlock_socket_internal(sconn)) {
136 exit_server_cleanly("failed to unlock socket");
140 /* Accessor function for smb_read_error for smbd functions. */
142 /****************************************************************************
143 Send an smb to a fd.
144 ****************************************************************************/
146 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
147 bool do_signing, uint32_t seqnum,
148 bool do_encrypt,
149 struct smb_perfcount_data *pcd)
151 size_t len = 0;
152 ssize_t ret;
153 char *buf_out = buffer;
155 if (!NT_STATUS_IS_OK(sconn->status)) {
157 * we're not supposed to do any io
159 return true;
162 smbd_lock_socket(sconn);
164 if (do_signing) {
165 /* Sign the outgoing packet if required. */
166 srv_calculate_sign_mac(sconn, buf_out, seqnum);
169 if (do_encrypt) {
170 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
171 if (!NT_STATUS_IS_OK(status)) {
172 DEBUG(0, ("send_smb: SMB encryption failed "
173 "on outgoing packet! Error %s\n",
174 nt_errstr(status) ));
175 goto out;
179 len = smb_len_large(buf_out) + 4;
181 ret = write_data(sconn->sock, buf_out, len);
182 if (ret <= 0) {
184 char addr[INET6_ADDRSTRLEN];
186 * Try and give an error message saying what
187 * client failed.
189 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
190 (int)getpid(), (int)len,
191 get_peer_addr(sconn->sock, addr, sizeof(addr)),
192 (int)ret, strerror(errno) ));
194 srv_free_enc_buffer(sconn, buf_out);
195 goto out;
198 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
199 srv_free_enc_buffer(sconn, buf_out);
200 out:
201 SMB_PERFCOUNT_END(pcd);
203 smbd_unlock_socket(sconn);
204 return true;
207 /*******************************************************************
208 Setup the word count and byte count for a smb message.
209 ********************************************************************/
211 int srv_set_message(char *buf,
212 int num_words,
213 int num_bytes,
214 bool zero)
216 if (zero && (num_words || num_bytes)) {
217 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
219 SCVAL(buf,smb_wct,num_words);
220 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
221 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
222 return (smb_size + num_words*2 + num_bytes);
225 static bool valid_smb_header(struct smbd_server_connection *sconn,
226 const uint8_t *inbuf)
228 if (is_encrypted_packet(sconn, inbuf)) {
229 return true;
232 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
233 * but it just looks weird to call strncmp for this one.
235 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
238 /* Socket functions for smbd packet processing. */
240 static bool valid_packet_size(size_t len)
243 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
244 * of header. Don't print the error if this fits.... JRA.
247 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
248 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
249 (unsigned long)len));
250 return false;
252 return true;
255 static NTSTATUS read_packet_remainder(int fd, char *buffer,
256 unsigned int timeout, ssize_t len)
258 NTSTATUS status;
260 if (len <= 0) {
261 return NT_STATUS_OK;
264 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
265 if (!NT_STATUS_IS_OK(status)) {
266 char addr[INET6_ADDRSTRLEN];
267 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
268 "error = %s.\n",
269 get_peer_addr(fd, addr, sizeof(addr)),
270 nt_errstr(status)));
272 return status;
275 /****************************************************************************
276 Attempt a zerocopy writeX read. We know here that len > smb_size-4
277 ****************************************************************************/
280 * Unfortunately, earlier versions of smbclient/libsmbclient
281 * don't send this "standard" writeX header. I've fixed this
282 * for 3.2 but we'll use the old method with earlier versions.
283 * Windows and CIFSFS at least use this standard size. Not
284 * sure about MacOSX.
287 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
288 (2*14) + /* word count (including bcc) */ \
289 1 /* pad byte */)
291 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
292 const char lenbuf[4],
293 struct smbd_server_connection *sconn,
294 int sock,
295 char **buffer,
296 unsigned int timeout,
297 size_t *p_unread,
298 size_t *len_ret)
300 /* Size of a WRITEX call (+4 byte len). */
301 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
302 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
303 ssize_t toread;
304 NTSTATUS status;
306 memcpy(writeX_header, lenbuf, 4);
308 status = read_fd_with_timeout(
309 sock, writeX_header + 4,
310 STANDARD_WRITE_AND_X_HEADER_SIZE,
311 STANDARD_WRITE_AND_X_HEADER_SIZE,
312 timeout, NULL);
314 if (!NT_STATUS_IS_OK(status)) {
315 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
316 "error = %s.\n",
317 tsocket_address_string(sconn->remote_address,
318 talloc_tos()),
319 nt_errstr(status)));
320 return status;
324 * Ok - now try and see if this is a possible
325 * valid writeX call.
328 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
330 * If the data offset is beyond what
331 * we've read, drain the extra bytes.
333 uint16_t doff = SVAL(writeX_header,smb_vwv11);
334 ssize_t newlen;
336 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
337 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
338 if (drain_socket(sock, drain) != drain) {
339 smb_panic("receive_smb_raw_talloc_partial_read:"
340 " failed to drain pending bytes");
342 } else {
343 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
346 /* Spoof down the length and null out the bcc. */
347 set_message_bcc(writeX_header, 0);
348 newlen = smb_len(writeX_header);
350 /* Copy the header we've written. */
352 *buffer = (char *)talloc_memdup(mem_ctx,
353 writeX_header,
354 sizeof(writeX_header));
356 if (*buffer == NULL) {
357 DEBUG(0, ("Could not allocate inbuf of length %d\n",
358 (int)sizeof(writeX_header)));
359 return NT_STATUS_NO_MEMORY;
362 /* Work out the remaining bytes. */
363 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
364 *len_ret = newlen + 4;
365 return NT_STATUS_OK;
368 if (!valid_packet_size(len)) {
369 return NT_STATUS_INVALID_PARAMETER;
373 * Not a valid writeX call. Just do the standard
374 * talloc and return.
377 *buffer = talloc_array(mem_ctx, char, len+4);
379 if (*buffer == NULL) {
380 DEBUG(0, ("Could not allocate inbuf of length %d\n",
381 (int)len+4));
382 return NT_STATUS_NO_MEMORY;
385 /* Copy in what we already read. */
386 memcpy(*buffer,
387 writeX_header,
388 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
389 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
391 if(toread > 0) {
392 status = read_packet_remainder(
393 sock,
394 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
395 timeout, toread);
397 if (!NT_STATUS_IS_OK(status)) {
398 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
399 nt_errstr(status)));
400 return status;
404 *len_ret = len + 4;
405 return NT_STATUS_OK;
408 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
409 struct smbd_server_connection *sconn,
410 int sock,
411 char **buffer, unsigned int timeout,
412 size_t *p_unread, size_t *plen)
414 char lenbuf[4];
415 size_t len;
416 int min_recv_size = lp_min_receive_file_size();
417 NTSTATUS status;
419 *p_unread = 0;
421 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
422 &len);
423 if (!NT_STATUS_IS_OK(status)) {
424 return status;
427 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
428 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
429 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
430 !srv_is_signing_active(sconn) &&
431 sconn->smb1.echo_handler.trusted_fde == NULL) {
433 return receive_smb_raw_talloc_partial_read(
434 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
435 p_unread, plen);
438 if (!valid_packet_size(len)) {
439 return NT_STATUS_INVALID_PARAMETER;
443 * The +4 here can't wrap, we've checked the length above already.
446 *buffer = talloc_array(mem_ctx, char, len+4);
448 if (*buffer == NULL) {
449 DEBUG(0, ("Could not allocate inbuf of length %d\n",
450 (int)len+4));
451 return NT_STATUS_NO_MEMORY;
454 memcpy(*buffer, lenbuf, sizeof(lenbuf));
456 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
457 if (!NT_STATUS_IS_OK(status)) {
458 return status;
461 *plen = len + 4;
462 return NT_STATUS_OK;
465 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
466 struct smbd_server_connection *sconn,
467 int sock,
468 char **buffer, unsigned int timeout,
469 size_t *p_unread, bool *p_encrypted,
470 size_t *p_len,
471 uint32_t *seqnum,
472 bool trusted_channel)
474 size_t len = 0;
475 NTSTATUS status;
477 *p_encrypted = false;
479 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
480 p_unread, &len);
481 if (!NT_STATUS_IS_OK(status)) {
482 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
483 ("receive_smb_raw_talloc failed for client %s "
484 "read error = %s.\n",
485 tsocket_address_string(sconn->remote_address,
486 talloc_tos()),
487 nt_errstr(status)) );
488 return status;
491 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
492 status = srv_decrypt_buffer(sconn, *buffer);
493 if (!NT_STATUS_IS_OK(status)) {
494 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
495 "incoming packet! Error %s\n",
496 nt_errstr(status) ));
497 return status;
499 *p_encrypted = true;
502 /* Check the incoming SMB signature. */
503 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
504 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
505 "incoming packet!\n"));
506 return NT_STATUS_INVALID_NETWORK_RESPONSE;
509 *p_len = len;
510 return NT_STATUS_OK;
514 * Initialize a struct smb_request from an inbuf
517 static bool init_smb_request(struct smb_request *req,
518 struct smbd_server_connection *sconn,
519 const uint8 *inbuf,
520 size_t unread_bytes, bool encrypted,
521 uint32_t seqnum)
523 struct smbXsrv_tcon *tcon;
524 NTSTATUS status;
525 NTTIME now;
526 size_t req_size = smb_len(inbuf) + 4;
528 /* Ensure we have at least smb_size bytes. */
529 if (req_size < smb_size) {
530 DEBUG(0,("init_smb_request: invalid request size %u\n",
531 (unsigned int)req_size ));
532 return false;
535 req->request_time = timeval_current();
536 now = timeval_to_nttime(&req->request_time);
538 req->cmd = CVAL(inbuf, smb_com);
539 req->flags2 = SVAL(inbuf, smb_flg2);
540 req->smbpid = SVAL(inbuf, smb_pid);
541 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
542 req->seqnum = seqnum;
543 req->vuid = SVAL(inbuf, smb_uid);
544 req->tid = SVAL(inbuf, smb_tid);
545 req->wct = CVAL(inbuf, smb_wct);
546 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
547 req->buflen = smb_buflen(inbuf);
548 req->buf = (const uint8_t *)smb_buf_const(inbuf);
549 req->unread_bytes = unread_bytes;
550 req->encrypted = encrypted;
551 req->sconn = sconn;
552 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
553 if (NT_STATUS_IS_OK(status)) {
554 req->conn = tcon->compat;
555 } else {
556 req->conn = NULL;
558 req->chain_fsp = NULL;
559 req->smb2req = NULL;
560 req->priv_paths = NULL;
561 req->chain = NULL;
562 smb_init_perfcount_data(&req->pcd);
564 /* Ensure we have at least wct words and 2 bytes of bcc. */
565 if (smb_size + req->wct*2 > req_size) {
566 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
567 (unsigned int)req->wct,
568 (unsigned int)req_size));
569 return false;
571 /* Ensure bcc is correct. */
572 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
573 DEBUG(0,("init_smb_request: invalid bcc number %u "
574 "(wct = %u, size %u)\n",
575 (unsigned int)req->buflen,
576 (unsigned int)req->wct,
577 (unsigned int)req_size));
578 return false;
581 req->outbuf = NULL;
582 return true;
585 static void process_smb(struct smbd_server_connection *conn,
586 uint8_t *inbuf, size_t nread, size_t unread_bytes,
587 uint32_t seqnum, bool encrypted,
588 struct smb_perfcount_data *deferred_pcd);
590 static void smbd_deferred_open_timer(struct tevent_context *ev,
591 struct tevent_timer *te,
592 struct timeval _tval,
593 void *private_data)
595 struct pending_message_list *msg = talloc_get_type(private_data,
596 struct pending_message_list);
597 struct smbd_server_connection *sconn = msg->sconn;
598 TALLOC_CTX *mem_ctx = talloc_tos();
599 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
600 uint8_t *inbuf;
602 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
603 msg->buf.length);
604 if (inbuf == NULL) {
605 exit_server("smbd_deferred_open_timer: talloc failed\n");
606 return;
609 /* We leave this message on the queue so the open code can
610 know this is a retry. */
611 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
612 (unsigned long long)mid ));
614 /* Mark the message as processed so this is not
615 * re-processed in error. */
616 msg->processed = true;
618 process_smb(sconn, inbuf,
619 msg->buf.length, 0,
620 msg->seqnum, msg->encrypted, &msg->pcd);
622 /* If it's still there and was processed, remove it. */
623 msg = get_deferred_open_message_smb(sconn, mid);
624 if (msg && msg->processed) {
625 remove_deferred_open_message_smb(sconn, mid);
629 /****************************************************************************
630 Function to push a message onto the tail of a linked list of smb messages ready
631 for processing.
632 ****************************************************************************/
634 static bool push_queued_message(struct smb_request *req,
635 struct timeval request_time,
636 struct timeval end_time,
637 char *private_data, size_t private_len)
639 int msg_len = smb_len(req->inbuf) + 4;
640 struct pending_message_list *msg;
642 msg = talloc_zero(NULL, struct pending_message_list);
644 if(msg == NULL) {
645 DEBUG(0,("push_message: malloc fail (1)\n"));
646 return False;
648 msg->sconn = req->sconn;
650 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
651 if(msg->buf.data == NULL) {
652 DEBUG(0,("push_message: malloc fail (2)\n"));
653 TALLOC_FREE(msg);
654 return False;
657 msg->request_time = request_time;
658 msg->seqnum = req->seqnum;
659 msg->encrypted = req->encrypted;
660 msg->processed = false;
661 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
663 if (private_data) {
664 msg->private_data = data_blob_talloc(msg, private_data,
665 private_len);
666 if (msg->private_data.data == NULL) {
667 DEBUG(0,("push_message: malloc fail (3)\n"));
668 TALLOC_FREE(msg);
669 return False;
673 #if 0
674 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
675 msg,
676 end_time,
677 smbd_deferred_open_timer,
678 msg);
679 if (!msg->te) {
680 DEBUG(0,("push_message: event_add_timed failed\n"));
681 TALLOC_FREE(msg);
682 return false;
684 #endif
686 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
687 struct pending_message_list *);
689 DEBUG(10,("push_message: pushed message length %u on "
690 "deferred_open_queue\n", (unsigned int)msg_len));
692 return True;
695 /****************************************************************************
696 Function to delete a sharing violation open message by mid.
697 ****************************************************************************/
699 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
700 uint64_t mid)
702 struct pending_message_list *pml;
704 if (sconn->using_smb2) {
705 remove_deferred_open_message_smb2(sconn, mid);
706 return;
709 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
710 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
711 DEBUG(10,("remove_deferred_open_message_smb: "
712 "deleting mid %llu len %u\n",
713 (unsigned long long)mid,
714 (unsigned int)pml->buf.length ));
715 DLIST_REMOVE(sconn->deferred_open_queue, pml);
716 TALLOC_FREE(pml);
717 return;
722 /****************************************************************************
723 Move a sharing violation open retry message to the front of the list and
724 schedule it for immediate processing.
725 ****************************************************************************/
727 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
728 uint64_t mid)
730 struct pending_message_list *pml;
731 int i = 0;
733 if (sconn->using_smb2) {
734 return schedule_deferred_open_message_smb2(sconn, mid);
737 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
738 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
740 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
741 "msg_mid = %llu\n",
742 i++,
743 (unsigned long long)msg_mid ));
745 if (mid == msg_mid) {
746 struct tevent_timer *te;
748 if (pml->processed) {
749 /* A processed message should not be
750 * rescheduled. */
751 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
752 "message mid %llu was already processed\n",
753 (unsigned long long)msg_mid ));
754 continue;
757 DEBUG(10,("schedule_deferred_open_message_smb: "
758 "scheduling mid %llu\n",
759 (unsigned long long)mid ));
761 te = tevent_add_timer(pml->sconn->ev_ctx,
762 pml,
763 timeval_zero(),
764 smbd_deferred_open_timer,
765 pml);
766 if (!te) {
767 DEBUG(10,("schedule_deferred_open_message_smb: "
768 "event_add_timed() failed, "
769 "skipping mid %llu\n",
770 (unsigned long long)msg_mid ));
773 TALLOC_FREE(pml->te);
774 pml->te = te;
775 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
776 return true;
780 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
781 "find message mid %llu\n",
782 (unsigned long long)mid ));
784 return false;
787 /****************************************************************************
788 Return true if this mid is on the deferred queue and was not yet processed.
789 ****************************************************************************/
791 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
793 struct pending_message_list *pml;
795 if (sconn->using_smb2) {
796 return open_was_deferred_smb2(sconn, mid);
799 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
800 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
801 return True;
804 return False;
807 /****************************************************************************
808 Return the message queued by this mid.
809 ****************************************************************************/
811 static struct pending_message_list *get_deferred_open_message_smb(
812 struct smbd_server_connection *sconn, uint64_t mid)
814 struct pending_message_list *pml;
816 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
817 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
818 return pml;
821 return NULL;
824 /****************************************************************************
825 Get the state data queued by this mid.
826 ****************************************************************************/
828 bool get_deferred_open_message_state(struct smb_request *smbreq,
829 struct timeval *p_request_time,
830 void **pp_state)
832 struct pending_message_list *pml;
834 if (smbreq->sconn->using_smb2) {
835 return get_deferred_open_message_state_smb2(smbreq->smb2req,
836 p_request_time,
837 pp_state);
840 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
841 if (!pml) {
842 return false;
844 if (p_request_time) {
845 *p_request_time = pml->request_time;
847 if (pp_state) {
848 *pp_state = (void *)pml->private_data.data;
850 return true;
853 /****************************************************************************
854 Function to push a deferred open smb message onto a linked list of local smb
855 messages ready for processing.
856 ****************************************************************************/
858 bool push_deferred_open_message_smb(struct smb_request *req,
859 struct timeval request_time,
860 struct timeval timeout,
861 struct file_id id,
862 char *private_data, size_t priv_len)
864 struct timeval end_time;
866 if (req->smb2req) {
867 return push_deferred_open_message_smb2(req->smb2req,
868 request_time,
869 timeout,
871 private_data,
872 priv_len);
875 if (req->unread_bytes) {
876 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
877 "unread_bytes = %u\n",
878 (unsigned int)req->unread_bytes ));
879 smb_panic("push_deferred_open_message_smb: "
880 "logic error unread_bytes != 0" );
883 end_time = timeval_sum(&request_time, &timeout);
885 DEBUG(10,("push_deferred_open_message_smb: pushing message "
886 "len %u mid %llu timeout time [%u.%06u]\n",
887 (unsigned int) smb_len(req->inbuf)+4,
888 (unsigned long long)req->mid,
889 (unsigned int)end_time.tv_sec,
890 (unsigned int)end_time.tv_usec));
892 return push_queued_message(req, request_time, end_time,
893 private_data, priv_len);
896 static void smbd_sig_term_handler(struct tevent_context *ev,
897 struct tevent_signal *se,
898 int signum,
899 int count,
900 void *siginfo,
901 void *private_data)
903 exit_server_cleanly("termination signal");
906 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
908 struct tevent_signal *se;
910 se = tevent_add_signal(sconn->ev_ctx,
911 sconn,
912 SIGTERM, 0,
913 smbd_sig_term_handler,
914 sconn);
915 if (!se) {
916 exit_server("failed to setup SIGTERM handler");
920 static void smbd_sig_hup_handler(struct tevent_context *ev,
921 struct tevent_signal *se,
922 int signum,
923 int count,
924 void *siginfo,
925 void *private_data)
927 struct smbd_server_connection *sconn =
928 talloc_get_type_abort(private_data,
929 struct smbd_server_connection);
931 change_to_root_user();
932 DEBUG(1,("Reloading services after SIGHUP\n"));
933 reload_services(sconn, conn_snum_used, false);
936 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
938 struct tevent_signal *se;
940 se = tevent_add_signal(sconn->ev_ctx,
941 sconn,
942 SIGHUP, 0,
943 smbd_sig_hup_handler,
944 sconn);
945 if (!se) {
946 exit_server("failed to setup SIGHUP handler");
950 static void smbd_conf_updated(struct messaging_context *msg,
951 void *private_data,
952 uint32_t msg_type,
953 struct server_id server_id,
954 DATA_BLOB *data)
956 struct smbd_server_connection *sconn =
957 talloc_get_type_abort(private_data,
958 struct smbd_server_connection);
960 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
961 "updated. Reloading.\n"));
962 change_to_root_user();
963 reload_services(sconn, conn_snum_used, false);
967 * Only allow 5 outstanding trans requests. We're allocating memory, so
968 * prevent a DoS.
971 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
973 int count = 0;
974 for (; list != NULL; list = list->next) {
976 if (list->mid == mid) {
977 return NT_STATUS_INVALID_PARAMETER;
980 count += 1;
982 if (count > 5) {
983 return NT_STATUS_INSUFFICIENT_RESOURCES;
986 return NT_STATUS_OK;
990 These flags determine some of the permissions required to do an operation
992 Note that I don't set NEED_WRITE on some write operations because they
993 are used by some brain-dead clients when printing, and I don't want to
994 force write permissions on print services.
996 #define AS_USER (1<<0)
997 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
998 #define TIME_INIT (1<<2)
999 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1000 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1001 #define DO_CHDIR (1<<6)
1004 define a list of possible SMB messages and their corresponding
1005 functions. Any message that has a NULL function is unimplemented -
1006 please feel free to contribute implementations!
1008 static const struct smb_message_struct {
1009 const char *name;
1010 void (*fn)(struct smb_request *req);
1011 int flags;
1012 } smb_messages[256] = {
1014 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1015 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1016 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1017 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1018 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1019 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1020 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1021 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1022 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1023 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1024 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1025 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1026 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1027 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1028 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1029 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1030 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1031 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1032 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1033 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1034 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1035 /* 0x15 */ { NULL, NULL, 0 },
1036 /* 0x16 */ { NULL, NULL, 0 },
1037 /* 0x17 */ { NULL, NULL, 0 },
1038 /* 0x18 */ { NULL, NULL, 0 },
1039 /* 0x19 */ { NULL, NULL, 0 },
1040 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1041 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1042 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1043 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1044 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1045 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1046 /* 0x20 */ { "SMBwritec", NULL,0},
1047 /* 0x21 */ { NULL, NULL, 0 },
1048 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1049 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1050 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1051 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1052 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1053 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1054 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1055 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1056 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1057 /* 0x2b */ { "SMBecho",reply_echo,0},
1058 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1059 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1060 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1061 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1062 /* 0x30 */ { NULL, NULL, 0 },
1063 /* 0x31 */ { NULL, NULL, 0 },
1064 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1065 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1066 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1067 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1068 /* 0x36 */ { NULL, NULL, 0 },
1069 /* 0x37 */ { NULL, NULL, 0 },
1070 /* 0x38 */ { NULL, NULL, 0 },
1071 /* 0x39 */ { NULL, NULL, 0 },
1072 /* 0x3a */ { NULL, NULL, 0 },
1073 /* 0x3b */ { NULL, NULL, 0 },
1074 /* 0x3c */ { NULL, NULL, 0 },
1075 /* 0x3d */ { NULL, NULL, 0 },
1076 /* 0x3e */ { NULL, NULL, 0 },
1077 /* 0x3f */ { NULL, NULL, 0 },
1078 /* 0x40 */ { NULL, NULL, 0 },
1079 /* 0x41 */ { NULL, NULL, 0 },
1080 /* 0x42 */ { NULL, NULL, 0 },
1081 /* 0x43 */ { NULL, NULL, 0 },
1082 /* 0x44 */ { NULL, NULL, 0 },
1083 /* 0x45 */ { NULL, NULL, 0 },
1084 /* 0x46 */ { NULL, NULL, 0 },
1085 /* 0x47 */ { NULL, NULL, 0 },
1086 /* 0x48 */ { NULL, NULL, 0 },
1087 /* 0x49 */ { NULL, NULL, 0 },
1088 /* 0x4a */ { NULL, NULL, 0 },
1089 /* 0x4b */ { NULL, NULL, 0 },
1090 /* 0x4c */ { NULL, NULL, 0 },
1091 /* 0x4d */ { NULL, NULL, 0 },
1092 /* 0x4e */ { NULL, NULL, 0 },
1093 /* 0x4f */ { NULL, NULL, 0 },
1094 /* 0x50 */ { NULL, NULL, 0 },
1095 /* 0x51 */ { NULL, NULL, 0 },
1096 /* 0x52 */ { NULL, NULL, 0 },
1097 /* 0x53 */ { NULL, NULL, 0 },
1098 /* 0x54 */ { NULL, NULL, 0 },
1099 /* 0x55 */ { NULL, NULL, 0 },
1100 /* 0x56 */ { NULL, NULL, 0 },
1101 /* 0x57 */ { NULL, NULL, 0 },
1102 /* 0x58 */ { NULL, NULL, 0 },
1103 /* 0x59 */ { NULL, NULL, 0 },
1104 /* 0x5a */ { NULL, NULL, 0 },
1105 /* 0x5b */ { NULL, NULL, 0 },
1106 /* 0x5c */ { NULL, NULL, 0 },
1107 /* 0x5d */ { NULL, NULL, 0 },
1108 /* 0x5e */ { NULL, NULL, 0 },
1109 /* 0x5f */ { NULL, NULL, 0 },
1110 /* 0x60 */ { NULL, NULL, 0 },
1111 /* 0x61 */ { NULL, NULL, 0 },
1112 /* 0x62 */ { NULL, NULL, 0 },
1113 /* 0x63 */ { NULL, NULL, 0 },
1114 /* 0x64 */ { NULL, NULL, 0 },
1115 /* 0x65 */ { NULL, NULL, 0 },
1116 /* 0x66 */ { NULL, NULL, 0 },
1117 /* 0x67 */ { NULL, NULL, 0 },
1118 /* 0x68 */ { NULL, NULL, 0 },
1119 /* 0x69 */ { NULL, NULL, 0 },
1120 /* 0x6a */ { NULL, NULL, 0 },
1121 /* 0x6b */ { NULL, NULL, 0 },
1122 /* 0x6c */ { NULL, NULL, 0 },
1123 /* 0x6d */ { NULL, NULL, 0 },
1124 /* 0x6e */ { NULL, NULL, 0 },
1125 /* 0x6f */ { NULL, NULL, 0 },
1126 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1127 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1128 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1129 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1130 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1131 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1132 /* 0x76 */ { NULL, NULL, 0 },
1133 /* 0x77 */ { NULL, NULL, 0 },
1134 /* 0x78 */ { NULL, NULL, 0 },
1135 /* 0x79 */ { NULL, NULL, 0 },
1136 /* 0x7a */ { NULL, NULL, 0 },
1137 /* 0x7b */ { NULL, NULL, 0 },
1138 /* 0x7c */ { NULL, NULL, 0 },
1139 /* 0x7d */ { NULL, NULL, 0 },
1140 /* 0x7e */ { NULL, NULL, 0 },
1141 /* 0x7f */ { NULL, NULL, 0 },
1142 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1143 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1144 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1145 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1146 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1147 /* 0x85 */ { NULL, NULL, 0 },
1148 /* 0x86 */ { NULL, NULL, 0 },
1149 /* 0x87 */ { NULL, NULL, 0 },
1150 /* 0x88 */ { NULL, NULL, 0 },
1151 /* 0x89 */ { NULL, NULL, 0 },
1152 /* 0x8a */ { NULL, NULL, 0 },
1153 /* 0x8b */ { NULL, NULL, 0 },
1154 /* 0x8c */ { NULL, NULL, 0 },
1155 /* 0x8d */ { NULL, NULL, 0 },
1156 /* 0x8e */ { NULL, NULL, 0 },
1157 /* 0x8f */ { NULL, NULL, 0 },
1158 /* 0x90 */ { NULL, NULL, 0 },
1159 /* 0x91 */ { NULL, NULL, 0 },
1160 /* 0x92 */ { NULL, NULL, 0 },
1161 /* 0x93 */ { NULL, NULL, 0 },
1162 /* 0x94 */ { NULL, NULL, 0 },
1163 /* 0x95 */ { NULL, NULL, 0 },
1164 /* 0x96 */ { NULL, NULL, 0 },
1165 /* 0x97 */ { NULL, NULL, 0 },
1166 /* 0x98 */ { NULL, NULL, 0 },
1167 /* 0x99 */ { NULL, NULL, 0 },
1168 /* 0x9a */ { NULL, NULL, 0 },
1169 /* 0x9b */ { NULL, NULL, 0 },
1170 /* 0x9c */ { NULL, NULL, 0 },
1171 /* 0x9d */ { NULL, NULL, 0 },
1172 /* 0x9e */ { NULL, NULL, 0 },
1173 /* 0x9f */ { NULL, NULL, 0 },
1174 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1175 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1176 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1177 /* 0xa3 */ { NULL, NULL, 0 },
1178 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1179 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1180 /* 0xa6 */ { NULL, NULL, 0 },
1181 /* 0xa7 */ { NULL, NULL, 0 },
1182 /* 0xa8 */ { NULL, NULL, 0 },
1183 /* 0xa9 */ { NULL, NULL, 0 },
1184 /* 0xaa */ { NULL, NULL, 0 },
1185 /* 0xab */ { NULL, NULL, 0 },
1186 /* 0xac */ { NULL, NULL, 0 },
1187 /* 0xad */ { NULL, NULL, 0 },
1188 /* 0xae */ { NULL, NULL, 0 },
1189 /* 0xaf */ { NULL, NULL, 0 },
1190 /* 0xb0 */ { NULL, NULL, 0 },
1191 /* 0xb1 */ { NULL, NULL, 0 },
1192 /* 0xb2 */ { NULL, NULL, 0 },
1193 /* 0xb3 */ { NULL, NULL, 0 },
1194 /* 0xb4 */ { NULL, NULL, 0 },
1195 /* 0xb5 */ { NULL, NULL, 0 },
1196 /* 0xb6 */ { NULL, NULL, 0 },
1197 /* 0xb7 */ { NULL, NULL, 0 },
1198 /* 0xb8 */ { NULL, NULL, 0 },
1199 /* 0xb9 */ { NULL, NULL, 0 },
1200 /* 0xba */ { NULL, NULL, 0 },
1201 /* 0xbb */ { NULL, NULL, 0 },
1202 /* 0xbc */ { NULL, NULL, 0 },
1203 /* 0xbd */ { NULL, NULL, 0 },
1204 /* 0xbe */ { NULL, NULL, 0 },
1205 /* 0xbf */ { NULL, NULL, 0 },
1206 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1207 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1208 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1209 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1210 /* 0xc4 */ { NULL, NULL, 0 },
1211 /* 0xc5 */ { NULL, NULL, 0 },
1212 /* 0xc6 */ { NULL, NULL, 0 },
1213 /* 0xc7 */ { NULL, NULL, 0 },
1214 /* 0xc8 */ { NULL, NULL, 0 },
1215 /* 0xc9 */ { NULL, NULL, 0 },
1216 /* 0xca */ { NULL, NULL, 0 },
1217 /* 0xcb */ { NULL, NULL, 0 },
1218 /* 0xcc */ { NULL, NULL, 0 },
1219 /* 0xcd */ { NULL, NULL, 0 },
1220 /* 0xce */ { NULL, NULL, 0 },
1221 /* 0xcf */ { NULL, NULL, 0 },
1222 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1223 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1224 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1225 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1226 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1227 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1228 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1229 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1230 /* 0xd8 */ { NULL, NULL, 0 },
1231 /* 0xd9 */ { NULL, NULL, 0 },
1232 /* 0xda */ { NULL, NULL, 0 },
1233 /* 0xdb */ { NULL, NULL, 0 },
1234 /* 0xdc */ { NULL, NULL, 0 },
1235 /* 0xdd */ { NULL, NULL, 0 },
1236 /* 0xde */ { NULL, NULL, 0 },
1237 /* 0xdf */ { NULL, NULL, 0 },
1238 /* 0xe0 */ { NULL, NULL, 0 },
1239 /* 0xe1 */ { NULL, NULL, 0 },
1240 /* 0xe2 */ { NULL, NULL, 0 },
1241 /* 0xe3 */ { NULL, NULL, 0 },
1242 /* 0xe4 */ { NULL, NULL, 0 },
1243 /* 0xe5 */ { NULL, NULL, 0 },
1244 /* 0xe6 */ { NULL, NULL, 0 },
1245 /* 0xe7 */ { NULL, NULL, 0 },
1246 /* 0xe8 */ { NULL, NULL, 0 },
1247 /* 0xe9 */ { NULL, NULL, 0 },
1248 /* 0xea */ { NULL, NULL, 0 },
1249 /* 0xeb */ { NULL, NULL, 0 },
1250 /* 0xec */ { NULL, NULL, 0 },
1251 /* 0xed */ { NULL, NULL, 0 },
1252 /* 0xee */ { NULL, NULL, 0 },
1253 /* 0xef */ { NULL, NULL, 0 },
1254 /* 0xf0 */ { NULL, NULL, 0 },
1255 /* 0xf1 */ { NULL, NULL, 0 },
1256 /* 0xf2 */ { NULL, NULL, 0 },
1257 /* 0xf3 */ { NULL, NULL, 0 },
1258 /* 0xf4 */ { NULL, NULL, 0 },
1259 /* 0xf5 */ { NULL, NULL, 0 },
1260 /* 0xf6 */ { NULL, NULL, 0 },
1261 /* 0xf7 */ { NULL, NULL, 0 },
1262 /* 0xf8 */ { NULL, NULL, 0 },
1263 /* 0xf9 */ { NULL, NULL, 0 },
1264 /* 0xfa */ { NULL, NULL, 0 },
1265 /* 0xfb */ { NULL, NULL, 0 },
1266 /* 0xfc */ { NULL, NULL, 0 },
1267 /* 0xfd */ { NULL, NULL, 0 },
1268 /* 0xfe */ { NULL, NULL, 0 },
1269 /* 0xff */ { NULL, NULL, 0 }
1273 /*******************************************************************
1274 allocate and initialize a reply packet
1275 ********************************************************************/
1277 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1278 const char *inbuf, char **outbuf, uint8_t num_words,
1279 uint32_t num_bytes)
1281 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1284 * Protect against integer wrap.
1285 * The SMB layer reply can be up to 0xFFFFFF bytes.
1287 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1288 char *msg;
1289 if (asprintf(&msg, "num_bytes too large: %u",
1290 (unsigned)num_bytes) == -1) {
1291 msg = discard_const_p(char, "num_bytes too large");
1293 smb_panic(msg);
1297 * Here we include the NBT header for now.
1299 *outbuf = talloc_array(mem_ctx, char,
1300 NBT_HDR_SIZE + smb_len);
1301 if (*outbuf == NULL) {
1302 return false;
1305 construct_reply_common(req, inbuf, *outbuf);
1306 srv_set_message(*outbuf, num_words, num_bytes, false);
1308 * Zero out the word area, the caller has to take care of the bcc area
1309 * himself
1311 if (num_words != 0) {
1312 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1315 return true;
1318 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1320 char *outbuf;
1321 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1322 num_bytes)) {
1323 smb_panic("could not allocate output buffer\n");
1325 req->outbuf = (uint8_t *)outbuf;
1329 /*******************************************************************
1330 Dump a packet to a file.
1331 ********************************************************************/
1333 static void smb_dump(const char *name, int type, const char *data)
1335 size_t len;
1336 int fd, i;
1337 char *fname = NULL;
1338 if (DEBUGLEVEL < 50) {
1339 return;
1342 len = smb_len_tcp(data)+4;
1343 for (i=1;i<100;i++) {
1344 fname = talloc_asprintf(talloc_tos(),
1345 "/tmp/%s.%d.%s",
1346 name,
1348 type ? "req" : "resp");
1349 if (fname == NULL) {
1350 return;
1352 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1353 if (fd != -1 || errno != EEXIST) break;
1354 TALLOC_FREE(fname);
1356 if (fd != -1) {
1357 ssize_t ret = write(fd, data, len);
1358 if (ret != len)
1359 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1360 close(fd);
1361 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1363 TALLOC_FREE(fname);
1366 /****************************************************************************
1367 Prepare everything for calling the actual request function, and potentially
1368 call the request function via the "new" interface.
1370 Return False if the "legacy" function needs to be called, everything is
1371 prepared.
1373 Return True if we're done.
1375 I know this API sucks, but it is the one with the least code change I could
1376 find.
1377 ****************************************************************************/
1379 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1381 int flags;
1382 uint64_t session_tag;
1383 connection_struct *conn = NULL;
1384 struct smbd_server_connection *sconn = req->sconn;
1385 NTTIME now = timeval_to_nttime(&req->request_time);
1386 struct smbXsrv_session *session = NULL;
1387 NTSTATUS status;
1389 errno = 0;
1391 if (smb_messages[type].fn == NULL) {
1392 DEBUG(0,("Unknown message type %d!\n",type));
1393 smb_dump("Unknown", 1, (const char *)req->inbuf);
1394 reply_unknown_new(req, type);
1395 return NULL;
1398 flags = smb_messages[type].flags;
1400 /* In share mode security we must ignore the vuid. */
1401 session_tag = req->vuid;
1402 conn = req->conn;
1404 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1405 (int)getpid(), (unsigned long)conn));
1407 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1409 /* Ensure this value is replaced in the incoming packet. */
1410 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1413 * Ensure the correct username is in current_user_info. This is a
1414 * really ugly bugfix for problems with multiple session_setup_and_X's
1415 * being done and allowing %U and %G substitutions to work correctly.
1416 * There is a reason this code is done here, don't move it unless you
1417 * know what you're doing... :-).
1418 * JRA.
1422 * lookup an existing session
1424 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1425 * here, the main check is still in change_to_user()
1427 status = smb1srv_session_lookup(sconn->conn,
1428 session_tag,
1429 now,
1430 &session);
1431 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1432 switch (type) {
1433 case SMBsesssetupX:
1434 status = NT_STATUS_OK;
1435 break;
1436 default:
1437 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1438 (unsigned long long)session_tag,
1439 (unsigned long long)req->mid));
1440 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1441 return conn;
1445 if (session_tag != sconn->conn->last_session_id) {
1446 struct user_struct *vuser = NULL;
1448 sconn->conn->last_session_id = session_tag;
1449 if (session) {
1450 vuser = session->compat;
1452 if (vuser) {
1453 set_current_user_info(
1454 vuser->session_info->unix_info->sanitized_username,
1455 vuser->session_info->unix_info->unix_name,
1456 vuser->session_info->info->domain_name);
1460 /* Does this call need to be run as the connected user? */
1461 if (flags & AS_USER) {
1463 /* Does this call need a valid tree connection? */
1464 if (!conn) {
1466 * Amazingly, the error code depends on the command
1467 * (from Samba4).
1469 if (type == SMBntcreateX) {
1470 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1471 } else {
1472 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1474 return NULL;
1477 if (!change_to_user(conn,session_tag)) {
1478 DEBUG(0, ("Error: Could not change to user. Removing "
1479 "deferred open, mid=%llu.\n",
1480 (unsigned long long)req->mid));
1481 reply_force_doserror(req, ERRSRV, ERRbaduid);
1482 return conn;
1485 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1487 /* Does it need write permission? */
1488 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1489 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1490 return conn;
1493 /* IPC services are limited */
1494 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1495 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1496 return conn;
1498 } else {
1499 /* This call needs to be run as root */
1500 change_to_root_user();
1503 /* load service specific parameters */
1504 if (conn) {
1505 if (req->encrypted) {
1506 conn->encrypted_tid = true;
1507 /* encrypted required from now on. */
1508 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1509 } else if (ENCRYPTION_REQUIRED(conn)) {
1510 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1511 DEBUG(1,("service[%s] requires encryption"
1512 "%s ACCESS_DENIED. mid=%llu\n",
1513 lp_servicename(talloc_tos(), SNUM(conn)),
1514 smb_fn_name(type),
1515 (unsigned long long)req->mid));
1516 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1517 return conn;
1521 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1522 (flags & (AS_USER|DO_CHDIR)
1523 ?True:False))) {
1524 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1525 return conn;
1527 conn->num_smb_operations++;
1531 * Does this protocol need to be run as guest? (Only archane
1532 * messenger service requests have this...)
1534 if (flags & AS_GUEST) {
1535 char *raddr;
1536 bool ok;
1538 if (!change_to_guest()) {
1539 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1540 return conn;
1543 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1544 talloc_tos());
1545 if (raddr == NULL) {
1546 reply_nterror(req, NT_STATUS_NO_MEMORY);
1547 return conn;
1551 * Haven't we checked this in smbd_process already???
1554 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1555 sconn->remote_hostname, raddr);
1556 TALLOC_FREE(raddr);
1558 if (!ok) {
1559 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1560 return conn;
1564 smb_messages[type].fn(req);
1565 return req->conn;
1568 /****************************************************************************
1569 Construct a reply to the incoming packet.
1570 ****************************************************************************/
1572 static void construct_reply(struct smbd_server_connection *sconn,
1573 char *inbuf, int size, size_t unread_bytes,
1574 uint32_t seqnum, bool encrypted,
1575 struct smb_perfcount_data *deferred_pcd)
1577 connection_struct *conn;
1578 struct smb_request *req;
1580 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1581 smb_panic("could not allocate smb_request");
1584 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1585 encrypted, seqnum)) {
1586 exit_server_cleanly("Invalid SMB request");
1589 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1591 /* we popped this message off the queue - keep original perf data */
1592 if (deferred_pcd)
1593 req->pcd = *deferred_pcd;
1594 else {
1595 SMB_PERFCOUNT_START(&req->pcd);
1596 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1597 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1600 conn = switch_message(req->cmd, req);
1602 if (req->outbuf == NULL) {
1603 return;
1606 if (CVAL(req->outbuf,0) == 0) {
1607 show_msg((char *)req->outbuf);
1610 if (!srv_send_smb(req->sconn,
1611 (char *)req->outbuf,
1612 true, req->seqnum+1,
1613 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1614 &req->pcd)) {
1615 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1618 TALLOC_FREE(req);
1620 return;
1623 static void construct_reply_chain(struct smbd_server_connection *sconn,
1624 char *inbuf, int size, uint32_t seqnum,
1625 bool encrypted,
1626 struct smb_perfcount_data *deferred_pcd)
1628 struct smb_request **reqs = NULL;
1629 struct smb_request *req;
1630 unsigned num_reqs;
1631 bool ok;
1633 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1634 seqnum, &reqs, &num_reqs);
1635 if (!ok) {
1636 char errbuf[smb_size];
1637 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1638 __LINE__, __FILE__);
1639 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1640 NULL)) {
1641 exit_server_cleanly("construct_reply_chain: "
1642 "srv_send_smb failed.");
1644 return;
1647 req = reqs[0];
1648 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1650 req->conn = switch_message(req->cmd, req);
1652 if (req->outbuf == NULL) {
1654 * Request has suspended itself, will come
1655 * back here.
1657 return;
1659 smb_request_done(req);
1663 * To be called from an async SMB handler that is potentially chained
1664 * when it is finished for shipping.
1667 void smb_request_done(struct smb_request *req)
1669 struct smb_request **reqs = NULL;
1670 struct smb_request *first_req;
1671 size_t i, num_reqs, next_index;
1672 NTSTATUS status;
1674 if (req->chain == NULL) {
1675 first_req = req;
1676 goto shipit;
1679 reqs = req->chain;
1680 num_reqs = talloc_array_length(reqs);
1682 for (i=0; i<num_reqs; i++) {
1683 if (reqs[i] == req) {
1684 break;
1687 if (i == num_reqs) {
1689 * Invalid chain, should not happen
1691 status = NT_STATUS_INTERNAL_ERROR;
1692 goto error;
1694 next_index = i+1;
1696 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1697 struct smb_request *next = reqs[next_index];
1698 struct smbXsrv_tcon *tcon;
1699 NTTIME now = timeval_to_nttime(&req->request_time);
1701 next->vuid = SVAL(req->outbuf, smb_uid);
1702 next->tid = SVAL(req->outbuf, smb_tid);
1703 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1704 now, &tcon);
1705 if (NT_STATUS_IS_OK(status)) {
1706 req->conn = tcon->compat;
1707 } else {
1708 req->conn = NULL;
1710 next->chain_fsp = req->chain_fsp;
1711 next->inbuf = req->inbuf;
1713 req = next;
1714 req->conn = switch_message(req->cmd, req);
1716 if (req->outbuf == NULL) {
1718 * Request has suspended itself, will come
1719 * back here.
1721 return;
1723 next_index += 1;
1726 first_req = reqs[0];
1728 for (i=1; i<next_index; i++) {
1729 bool ok;
1731 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1732 if (!ok) {
1733 status = NT_STATUS_INTERNAL_ERROR;
1734 goto error;
1738 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1739 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1742 * This scary statement intends to set the
1743 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1744 * to the value last_req->outbuf carries
1746 SSVAL(first_req->outbuf, smb_flg2,
1747 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1748 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1751 * Transfer the error codes from the subrequest to the main one
1753 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1754 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1756 _smb_setlen_large(
1757 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1759 shipit:
1760 if (!srv_send_smb(first_req->sconn,
1761 (char *)first_req->outbuf,
1762 true, first_req->seqnum+1,
1763 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1764 &first_req->pcd)) {
1765 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1766 "failed.");
1768 TALLOC_FREE(req); /* non-chained case */
1769 TALLOC_FREE(reqs); /* chained case */
1770 return;
1772 error:
1774 char errbuf[smb_size];
1775 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1776 if (!srv_send_smb(req->sconn, errbuf, true,
1777 req->seqnum+1, req->encrypted,
1778 NULL)) {
1779 exit_server_cleanly("construct_reply_chain: "
1780 "srv_send_smb failed.");
1783 TALLOC_FREE(req); /* non-chained case */
1784 TALLOC_FREE(reqs); /* chained case */
1787 /****************************************************************************
1788 Process an smb from the client
1789 ****************************************************************************/
1790 static void process_smb(struct smbd_server_connection *sconn,
1791 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1792 uint32_t seqnum, bool encrypted,
1793 struct smb_perfcount_data *deferred_pcd)
1795 int msg_type = CVAL(inbuf,0);
1797 DO_PROFILE_INC(smb_count);
1799 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1800 smb_len(inbuf) ) );
1801 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1802 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1804 if (msg_type != NBSSmessage) {
1806 * NetBIOS session request, keepalive, etc.
1808 reply_special(sconn, (char *)inbuf, nread);
1809 goto done;
1812 if (sconn->using_smb2) {
1813 /* At this point we're not really using smb2,
1814 * we make the decision here.. */
1815 if (smbd_is_smb2_header(inbuf, nread)) {
1816 smbd_smb2_first_negprot(sconn, inbuf, nread);
1817 return;
1818 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1819 && CVAL(inbuf, smb_com) != 0x72) {
1820 /* This is a non-negprot SMB1 packet.
1821 Disable SMB2 from now on. */
1822 sconn->using_smb2 = false;
1826 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1827 * so subtract 4 from it. */
1828 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1829 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1830 smb_len(inbuf)));
1832 /* special magic for immediate exit */
1833 if ((nread == 9) &&
1834 (IVAL(inbuf, 4) == 0x74697865) &&
1835 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1836 uint8_t exitcode = CVAL(inbuf, 8);
1837 DEBUG(1, ("Exiting immediately with code %d\n",
1838 (int)exitcode));
1839 exit(exitcode);
1842 exit_server_cleanly("Non-SMB packet");
1845 show_msg((char *)inbuf);
1847 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1848 construct_reply_chain(sconn, (char *)inbuf, nread,
1849 seqnum, encrypted, deferred_pcd);
1850 } else {
1851 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1852 seqnum, encrypted, deferred_pcd);
1855 sconn->trans_num++;
1857 done:
1858 sconn->num_requests++;
1860 /* The timeout_processing function isn't run nearly
1861 often enough to implement 'max log size' without
1862 overrunning the size of the file by many megabytes.
1863 This is especially true if we are running at debug
1864 level 10. Checking every 50 SMBs is a nice
1865 tradeoff of performance vs log file size overrun. */
1867 if ((sconn->num_requests % 50) == 0 &&
1868 need_to_check_log_size()) {
1869 change_to_root_user();
1870 check_log_size();
1874 /****************************************************************************
1875 Return a string containing the function name of a SMB command.
1876 ****************************************************************************/
1878 const char *smb_fn_name(int type)
1880 const char *unknown_name = "SMBunknown";
1882 if (smb_messages[type].name == NULL)
1883 return(unknown_name);
1885 return(smb_messages[type].name);
1888 /****************************************************************************
1889 Helper functions for contruct_reply.
1890 ****************************************************************************/
1892 void add_to_common_flags2(uint32 v)
1894 common_flags2 |= v;
1897 void remove_from_common_flags2(uint32 v)
1899 common_flags2 &= ~v;
1902 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1903 char *outbuf)
1905 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1906 uint16_t out_flags2 = common_flags2;
1908 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1909 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1910 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1912 srv_set_message(outbuf,0,0,false);
1914 SCVAL(outbuf, smb_com, req->cmd);
1915 SIVAL(outbuf,smb_rcls,0);
1916 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1917 SSVAL(outbuf,smb_flg2, out_flags2);
1918 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1919 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1921 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1922 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1923 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1924 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1927 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1929 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1933 * @brief Find the smb_cmd offset of the last command pushed
1934 * @param[in] buf The buffer we're building up
1935 * @retval Where can we put our next andx cmd?
1937 * While chaining requests, the "next" request we're looking at needs to put
1938 * its SMB_Command before the data the previous request already built up added
1939 * to the chain. Find the offset to the place where we have to put our cmd.
1942 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1944 uint8_t cmd;
1945 size_t ofs;
1947 cmd = CVAL(buf, smb_com);
1949 if (!is_andx_req(cmd)) {
1950 return false;
1953 ofs = smb_vwv0;
1955 while (CVAL(buf, ofs) != 0xff) {
1957 if (!is_andx_req(CVAL(buf, ofs))) {
1958 return false;
1962 * ofs is from start of smb header, so add the 4 length
1963 * bytes. The next cmd is right after the wct field.
1965 ofs = SVAL(buf, ofs+2) + 4 + 1;
1967 if (ofs+4 >= talloc_get_size(buf)) {
1968 return false;
1972 *pofs = ofs;
1973 return true;
1977 * @brief Do the smb chaining at a buffer level
1978 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1979 * @param[in] andx_buf Buffer to be appended
1982 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1984 uint8_t smb_command = CVAL(andx_buf, smb_com);
1985 uint8_t wct = CVAL(andx_buf, smb_wct);
1986 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1987 uint32_t num_bytes = smb_buflen(andx_buf);
1988 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1990 uint8_t *outbuf;
1991 size_t old_size, new_size;
1992 size_t ofs;
1993 size_t chain_padding = 0;
1994 size_t andx_cmd_ofs;
1997 old_size = talloc_get_size(*poutbuf);
1999 if ((old_size % 4) != 0) {
2001 * Align the wct field of subsequent requests to a 4-byte
2002 * boundary
2004 chain_padding = 4 - (old_size % 4);
2008 * After the old request comes the new wct field (1 byte), the vwv's
2009 * and the num_bytes field.
2012 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2013 new_size += num_bytes;
2015 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2016 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2017 (unsigned)new_size));
2018 return false;
2021 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2022 if (outbuf == NULL) {
2023 DEBUG(0, ("talloc failed\n"));
2024 return false;
2026 *poutbuf = outbuf;
2028 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2029 DEBUG(1, ("invalid command chain\n"));
2030 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2031 return false;
2034 if (chain_padding != 0) {
2035 memset(outbuf + old_size, 0, chain_padding);
2036 old_size += chain_padding;
2039 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2040 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2042 ofs = old_size;
2045 * Push the chained request:
2047 * wct field
2050 SCVAL(outbuf, ofs, wct);
2051 ofs += 1;
2054 * vwv array
2057 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2060 * HACK ALERT
2062 * Read&X has an offset into its data buffer at
2063 * vwv[6]. reply_read_andx has no idea anymore that it's
2064 * running from within a chain, so we have to fix up the
2065 * offset here.
2067 * Although it looks disgusting at this place, I want to keep
2068 * it here. The alternative would be to push knowledge about
2069 * the andx chain down into read&x again.
2072 if (smb_command == SMBreadX) {
2073 uint8_t *bytes_addr;
2075 if (wct < 7) {
2077 * Invalid read&x response
2079 return false;
2082 bytes_addr = outbuf + ofs /* vwv start */
2083 + sizeof(uint16_t) * wct /* vwv array */
2084 + sizeof(uint16_t); /* bcc */
2086 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2087 bytes_addr - outbuf - 4);
2090 ofs += sizeof(uint16_t) * wct;
2093 * bcc (byte count)
2096 SSVAL(outbuf, ofs, num_bytes);
2097 ofs += sizeof(uint16_t);
2100 * The bytes field
2103 memcpy(outbuf + ofs, bytes, num_bytes);
2105 return true;
2108 bool smb1_is_chain(const uint8_t *buf)
2110 uint8_t cmd, wct, andx_cmd;
2112 cmd = CVAL(buf, smb_com);
2113 if (!is_andx_req(cmd)) {
2114 return false;
2116 wct = CVAL(buf, smb_wct);
2117 if (wct < 2) {
2118 return false;
2120 andx_cmd = CVAL(buf, smb_vwv);
2121 return (andx_cmd != 0xFF);
2124 bool smb1_walk_chain(const uint8_t *buf,
2125 bool (*fn)(uint8_t cmd,
2126 uint8_t wct, const uint16_t *vwv,
2127 uint16_t num_bytes, const uint8_t *bytes,
2128 void *private_data),
2129 void *private_data)
2131 size_t smblen = smb_len(buf);
2132 const char *smb_buf = smb_base(buf);
2133 uint8_t cmd, chain_cmd;
2134 uint8_t wct;
2135 const uint16_t *vwv;
2136 uint16_t num_bytes;
2137 const uint8_t *bytes;
2139 cmd = CVAL(buf, smb_com);
2140 wct = CVAL(buf, smb_wct);
2141 vwv = (const uint16_t *)(buf + smb_vwv);
2142 num_bytes = smb_buflen(buf);
2143 bytes = (const uint8_t *)smb_buf_const(buf);
2145 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2146 return false;
2149 if (!is_andx_req(cmd)) {
2150 return true;
2152 if (wct < 2) {
2153 return false;
2156 chain_cmd = CVAL(vwv, 0);
2158 while (chain_cmd != 0xff) {
2159 uint32_t chain_offset; /* uint32_t to avoid overflow */
2160 size_t length_needed;
2161 ptrdiff_t vwv_offset;
2163 chain_offset = SVAL(vwv+1, 0);
2166 * Check if the client tries to fool us. The chain
2167 * offset needs to point beyond the current request in
2168 * the chain, it needs to strictly grow. Otherwise we
2169 * might be tricked into an endless loop always
2170 * processing the same request over and over again. We
2171 * used to assume that vwv and the byte buffer array
2172 * in a chain are always attached, but OS/2 the
2173 * Write&X/Read&X chain puts the Read&X vwv array
2174 * right behind the Write&X vwv chain. The Write&X bcc
2175 * array is put behind the Read&X vwv array. So now we
2176 * check whether the chain offset points strictly
2177 * behind the previous vwv array. req->buf points
2178 * right after the vwv array of the previous
2179 * request. See
2180 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2181 * more information.
2184 vwv_offset = ((const char *)vwv - smb_buf);
2185 if (chain_offset <= vwv_offset) {
2186 return false;
2190 * Next check: Make sure the chain offset does not
2191 * point beyond the overall smb request length.
2194 length_needed = chain_offset+1; /* wct */
2195 if (length_needed > smblen) {
2196 return false;
2200 * Now comes the pointer magic. Goal here is to set up
2201 * vwv and buf correctly again. The chain offset (the
2202 * former vwv[1]) points at the new wct field.
2205 wct = CVAL(smb_buf, chain_offset);
2207 if (is_andx_req(chain_cmd) && (wct < 2)) {
2208 return false;
2212 * Next consistency check: Make the new vwv array fits
2213 * in the overall smb request.
2216 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2217 if (length_needed > smblen) {
2218 return false;
2220 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2223 * Now grab the new byte buffer....
2226 num_bytes = SVAL(vwv+wct, 0);
2229 * .. and check that it fits.
2232 length_needed += num_bytes;
2233 if (length_needed > smblen) {
2234 return false;
2236 bytes = (const uint8_t *)(vwv+wct+1);
2238 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2239 return false;
2242 if (!is_andx_req(chain_cmd)) {
2243 return true;
2245 chain_cmd = CVAL(vwv, 0);
2247 return true;
2250 static bool smb1_chain_length_cb(uint8_t cmd,
2251 uint8_t wct, const uint16_t *vwv,
2252 uint16_t num_bytes, const uint8_t *bytes,
2253 void *private_data)
2255 unsigned *count = (unsigned *)private_data;
2256 *count += 1;
2257 return true;
2260 unsigned smb1_chain_length(const uint8_t *buf)
2262 unsigned count = 0;
2264 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2265 return 0;
2267 return count;
2270 struct smb1_parse_chain_state {
2271 TALLOC_CTX *mem_ctx;
2272 const uint8_t *buf;
2273 struct smbd_server_connection *sconn;
2274 bool encrypted;
2275 uint32_t seqnum;
2277 struct smb_request **reqs;
2278 unsigned num_reqs;
2281 static bool smb1_parse_chain_cb(uint8_t cmd,
2282 uint8_t wct, const uint16_t *vwv,
2283 uint16_t num_bytes, const uint8_t *bytes,
2284 void *private_data)
2286 struct smb1_parse_chain_state *state =
2287 (struct smb1_parse_chain_state *)private_data;
2288 struct smb_request **reqs;
2289 struct smb_request *req;
2290 bool ok;
2292 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2293 struct smb_request *, state->num_reqs+1);
2294 if (reqs == NULL) {
2295 return false;
2297 state->reqs = reqs;
2299 req = talloc(reqs, struct smb_request);
2300 if (req == NULL) {
2301 return false;
2304 ok = init_smb_request(req, state->sconn, state->buf, 0,
2305 state->encrypted, state->seqnum);
2306 if (!ok) {
2307 return false;
2309 req->cmd = cmd;
2310 req->wct = wct;
2311 req->vwv = vwv;
2312 req->buflen = num_bytes;
2313 req->buf = bytes;
2315 reqs[state->num_reqs] = req;
2316 state->num_reqs += 1;
2317 return true;
2320 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2321 struct smbd_server_connection *sconn,
2322 bool encrypted, uint32_t seqnum,
2323 struct smb_request ***reqs, unsigned *num_reqs)
2325 struct smb1_parse_chain_state state;
2326 unsigned i;
2328 state.mem_ctx = mem_ctx;
2329 state.buf = buf;
2330 state.sconn = sconn;
2331 state.encrypted = encrypted;
2332 state.seqnum = seqnum;
2333 state.reqs = NULL;
2334 state.num_reqs = 0;
2336 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2337 TALLOC_FREE(state.reqs);
2338 return false;
2340 for (i=0; i<state.num_reqs; i++) {
2341 state.reqs[i]->chain = state.reqs;
2343 *reqs = state.reqs;
2344 *num_reqs = state.num_reqs;
2345 return true;
2348 /****************************************************************************
2349 Check if services need reloading.
2350 ****************************************************************************/
2352 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2355 if (last_smb_conf_reload_time == 0) {
2356 last_smb_conf_reload_time = t;
2359 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2360 reload_services(sconn, conn_snum_used, true);
2361 last_smb_conf_reload_time = t;
2365 static bool fd_is_readable(int fd)
2367 int ret, revents;
2369 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2371 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2375 static void smbd_server_connection_write_handler(
2376 struct smbd_server_connection *sconn)
2378 /* TODO: make write nonblocking */
2381 static void smbd_server_connection_read_handler(
2382 struct smbd_server_connection *sconn, int fd)
2384 uint8_t *inbuf = NULL;
2385 size_t inbuf_len = 0;
2386 size_t unread_bytes = 0;
2387 bool encrypted = false;
2388 TALLOC_CTX *mem_ctx = talloc_tos();
2389 NTSTATUS status;
2390 uint32_t seqnum;
2392 bool from_client;
2394 if (lp_async_smb_echo_handler()
2395 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2397 * This is the super-ugly hack to prefer the packets
2398 * forwarded by the echo handler over the ones by the
2399 * client directly
2401 fd = sconn->smb1.echo_handler.trusted_fd;
2404 from_client = (sconn->sock == fd);
2406 if (from_client) {
2407 smbd_lock_socket(sconn);
2409 if (!fd_is_readable(fd)) {
2410 DEBUG(10,("the echo listener was faster\n"));
2411 smbd_unlock_socket(sconn);
2412 return;
2416 /* TODO: make this completely nonblocking */
2417 status = receive_smb_talloc(mem_ctx, sconn, fd,
2418 (char **)(void *)&inbuf,
2419 0, /* timeout */
2420 &unread_bytes,
2421 &encrypted,
2422 &inbuf_len, &seqnum,
2423 !from_client /* trusted channel */);
2425 if (from_client) {
2426 smbd_unlock_socket(sconn);
2429 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2430 goto process;
2432 if (NT_STATUS_IS_ERR(status)) {
2433 exit_server_cleanly("failed to receive smb request");
2435 if (!NT_STATUS_IS_OK(status)) {
2436 return;
2439 process:
2440 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2441 seqnum, encrypted, NULL);
2444 static void smbd_server_connection_handler(struct tevent_context *ev,
2445 struct tevent_fd *fde,
2446 uint16_t flags,
2447 void *private_data)
2449 struct smbd_server_connection *conn = talloc_get_type(private_data,
2450 struct smbd_server_connection);
2452 if (!NT_STATUS_IS_OK(conn->status)) {
2454 * we're not supposed to do any io
2456 TEVENT_FD_NOT_READABLE(conn->smb1.fde);
2457 TEVENT_FD_NOT_WRITEABLE(conn->smb1.fde);
2458 return;
2461 if (flags & TEVENT_FD_WRITE) {
2462 smbd_server_connection_write_handler(conn);
2463 return;
2465 if (flags & TEVENT_FD_READ) {
2466 smbd_server_connection_read_handler(conn, conn->sock);
2467 return;
2471 static void smbd_server_echo_handler(struct tevent_context *ev,
2472 struct tevent_fd *fde,
2473 uint16_t flags,
2474 void *private_data)
2476 struct smbd_server_connection *conn = talloc_get_type(private_data,
2477 struct smbd_server_connection);
2479 if (!NT_STATUS_IS_OK(conn->status)) {
2481 * we're not supposed to do any io
2483 TEVENT_FD_NOT_READABLE(conn->smb1.echo_handler.trusted_fde);
2484 TEVENT_FD_NOT_WRITEABLE(conn->smb1.echo_handler.trusted_fde);
2485 return;
2488 if (flags & TEVENT_FD_WRITE) {
2489 smbd_server_connection_write_handler(conn);
2490 return;
2492 if (flags & TEVENT_FD_READ) {
2493 smbd_server_connection_read_handler(
2494 conn, conn->smb1.echo_handler.trusted_fd);
2495 return;
2499 #ifdef CLUSTER_SUPPORT
2501 struct smbd_release_ip_state {
2502 struct smbd_server_connection *sconn;
2503 struct tevent_immediate *im;
2504 char addr[INET6_ADDRSTRLEN];
2507 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2508 struct tevent_immediate *im,
2509 void *private_data)
2511 struct smbd_release_ip_state *state =
2512 talloc_get_type_abort(private_data,
2513 struct smbd_release_ip_state);
2515 if (!NT_STATUS_EQUAL(state->sconn->status, NT_STATUS_ADDRESS_CLOSED)) {
2517 * smbd_server_connection_terminate() already triggered ?
2519 return;
2522 smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
2525 /****************************************************************************
2526 received when we should release a specific IP
2527 ****************************************************************************/
2528 static bool release_ip(const char *ip, void *priv)
2530 struct smbd_release_ip_state *state =
2531 talloc_get_type_abort(priv,
2532 struct smbd_release_ip_state);
2533 const char *addr = state->addr;
2534 const char *p = addr;
2536 if (!NT_STATUS_IS_OK(state->sconn->status)) {
2537 /* avoid recursion */
2538 return false;
2541 if (strncmp("::ffff:", addr, 7) == 0) {
2542 p = addr + 7;
2545 DEBUG(10, ("Got release IP message for %s, "
2546 "our address is %s\n", ip, p));
2548 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2549 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2550 ip));
2552 * With SMB2 we should do a clean disconnect,
2553 * the previous_session_id in the session setup
2554 * will cleanup the old session, tcons and opens.
2556 * A clean disconnect is needed in order to support
2557 * durable handles.
2559 * Note: typically this is never triggered
2560 * as we got a TCP RST (triggered by ctdb event scripts)
2561 * before we get CTDB_SRVID_RELEASE_IP.
2563 * We used to call _exit(1) here, but as this was mostly never
2564 * triggered and has implication on our process model,
2565 * we can just use smbd_server_connection_terminate()
2566 * (also for SMB1).
2568 * We don't call smbd_server_connection_terminate() directly
2569 * as we might be called from within ctdbd_migrate(),
2570 * we need to defer our action to the next event loop
2572 tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
2573 smbd_release_ip_immediate, state);
2576 * Make sure we don't get any io on the connection.
2578 state->sconn->status = NT_STATUS_ADDRESS_CLOSED;
2579 return true;
2582 return false;
2585 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2586 struct sockaddr_storage *srv,
2587 struct sockaddr_storage *clnt)
2589 struct smbd_release_ip_state *state;
2590 struct ctdbd_connection *cconn;
2592 cconn = messaging_ctdbd_connection();
2593 if (cconn == NULL) {
2594 return NT_STATUS_NO_MEMORY;
2597 state = talloc_zero(sconn, struct smbd_release_ip_state);
2598 if (state == NULL) {
2599 return NT_STATUS_NO_MEMORY;
2601 state->sconn = sconn;
2602 state->im = tevent_create_immediate(state);
2603 if (state->im == NULL) {
2604 return NT_STATUS_NO_MEMORY;
2606 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2607 return NT_STATUS_NO_MEMORY;
2610 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2613 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2614 struct sockaddr_storage *client)
2616 socklen_t length;
2617 length = sizeof(*server);
2618 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2619 return -1;
2621 length = sizeof(*client);
2622 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2623 return -1;
2625 return 0;
2627 #endif
2630 * Send keepalive packets to our client
2632 static bool keepalive_fn(const struct timeval *now, void *private_data)
2634 struct smbd_server_connection *sconn = talloc_get_type_abort(
2635 private_data, struct smbd_server_connection);
2636 bool ret;
2638 if (sconn->using_smb2) {
2639 /* Don't do keepalives on an SMB2 connection. */
2640 return false;
2643 smbd_lock_socket(sconn);
2644 ret = send_keepalive(sconn->sock);
2645 smbd_unlock_socket(sconn);
2647 if (!ret) {
2648 char addr[INET6_ADDRSTRLEN];
2650 * Try and give an error message saying what
2651 * client failed.
2653 DEBUG(0, ("send_keepalive failed for client %s. "
2654 "Error %s - exiting\n",
2655 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2656 strerror(errno)));
2657 return False;
2659 return True;
2663 * Do the recurring check if we're idle
2665 static bool deadtime_fn(const struct timeval *now, void *private_data)
2667 struct smbd_server_connection *sconn =
2668 (struct smbd_server_connection *)private_data;
2670 if ((conn_num_open(sconn) == 0)
2671 || (conn_idle_all(sconn, now->tv_sec))) {
2672 DEBUG( 2, ( "Closing idle connection\n" ) );
2673 messaging_send(sconn->msg_ctx,
2674 messaging_server_id(sconn->msg_ctx),
2675 MSG_SHUTDOWN, &data_blob_null);
2676 return False;
2679 return True;
2683 * Do the recurring log file and smb.conf reload checks.
2686 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2688 struct smbd_server_connection *sconn = talloc_get_type_abort(
2689 private_data, struct smbd_server_connection);
2691 DEBUG(5, ("housekeeping\n"));
2693 change_to_root_user();
2695 /* update printer queue caches if necessary */
2696 update_monitored_printq_cache(sconn->msg_ctx);
2698 /* check if we need to reload services */
2699 check_reload(sconn, time_mono(NULL));
2702 * Force a log file check.
2704 force_check_log_size();
2705 check_log_size();
2706 return true;
2710 * Read an smb packet in the echo handler child, giving the parent
2711 * smbd one second to react once the socket becomes readable.
2714 struct smbd_echo_read_state {
2715 struct tevent_context *ev;
2716 struct smbd_server_connection *sconn;
2718 char *buf;
2719 size_t buflen;
2720 uint32_t seqnum;
2723 static void smbd_echo_read_readable(struct tevent_req *subreq);
2724 static void smbd_echo_read_waited(struct tevent_req *subreq);
2726 static struct tevent_req *smbd_echo_read_send(
2727 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2728 struct smbd_server_connection *sconn)
2730 struct tevent_req *req, *subreq;
2731 struct smbd_echo_read_state *state;
2733 req = tevent_req_create(mem_ctx, &state,
2734 struct smbd_echo_read_state);
2735 if (req == NULL) {
2736 return NULL;
2738 state->ev = ev;
2739 state->sconn = sconn;
2741 subreq = wait_for_read_send(state, ev, sconn->sock);
2742 if (tevent_req_nomem(subreq, req)) {
2743 return tevent_req_post(req, ev);
2745 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2746 return req;
2749 static void smbd_echo_read_readable(struct tevent_req *subreq)
2751 struct tevent_req *req = tevent_req_callback_data(
2752 subreq, struct tevent_req);
2753 struct smbd_echo_read_state *state = tevent_req_data(
2754 req, struct smbd_echo_read_state);
2755 bool ok;
2756 int err;
2758 ok = wait_for_read_recv(subreq, &err);
2759 TALLOC_FREE(subreq);
2760 if (!ok) {
2761 tevent_req_nterror(req, map_nt_error_from_unix(err));
2762 return;
2766 * Give the parent smbd one second to step in
2769 subreq = tevent_wakeup_send(
2770 state, state->ev, timeval_current_ofs(1, 0));
2771 if (tevent_req_nomem(subreq, req)) {
2772 return;
2774 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2777 static void smbd_echo_read_waited(struct tevent_req *subreq)
2779 struct tevent_req *req = tevent_req_callback_data(
2780 subreq, struct tevent_req);
2781 struct smbd_echo_read_state *state = tevent_req_data(
2782 req, struct smbd_echo_read_state);
2783 struct smbd_server_connection *sconn = state->sconn;
2784 bool ok;
2785 NTSTATUS status;
2786 size_t unread = 0;
2787 bool encrypted;
2789 ok = tevent_wakeup_recv(subreq);
2790 TALLOC_FREE(subreq);
2791 if (!ok) {
2792 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2793 return;
2796 ok = smbd_lock_socket_internal(sconn);
2797 if (!ok) {
2798 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2799 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2800 return;
2803 if (!fd_is_readable(sconn->sock)) {
2804 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2805 (int)getpid()));
2807 ok = smbd_unlock_socket_internal(sconn);
2808 if (!ok) {
2809 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2810 DEBUG(1, ("%s: failed to unlock socket\n",
2811 __location__));
2812 return;
2815 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2816 if (tevent_req_nomem(subreq, req)) {
2817 return;
2819 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2820 return;
2823 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2824 0 /* timeout */,
2825 &unread,
2826 &encrypted,
2827 &state->buflen,
2828 &state->seqnum,
2829 false /* trusted_channel*/);
2831 if (tevent_req_nterror(req, status)) {
2832 tevent_req_nterror(req, status);
2833 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2834 (int)getpid(), nt_errstr(status)));
2835 return;
2838 ok = smbd_unlock_socket_internal(sconn);
2839 if (!ok) {
2840 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2841 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2842 return;
2844 tevent_req_done(req);
2847 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2848 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2850 struct smbd_echo_read_state *state = tevent_req_data(
2851 req, struct smbd_echo_read_state);
2852 NTSTATUS status;
2854 if (tevent_req_is_nterror(req, &status)) {
2855 return status;
2857 *pbuf = talloc_move(mem_ctx, &state->buf);
2858 *pbuflen = state->buflen;
2859 *pseqnum = state->seqnum;
2860 return NT_STATUS_OK;
2863 struct smbd_echo_state {
2864 struct tevent_context *ev;
2865 struct iovec *pending;
2866 struct smbd_server_connection *sconn;
2867 int parent_pipe;
2869 struct tevent_fd *parent_fde;
2871 struct tevent_req *write_req;
2874 static void smbd_echo_writer_done(struct tevent_req *req);
2876 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2878 int num_pending;
2880 if (state->write_req != NULL) {
2881 return;
2884 num_pending = talloc_array_length(state->pending);
2885 if (num_pending == 0) {
2886 return;
2889 state->write_req = writev_send(state, state->ev, NULL,
2890 state->parent_pipe, false,
2891 state->pending, num_pending);
2892 if (state->write_req == NULL) {
2893 DEBUG(1, ("writev_send failed\n"));
2894 exit(1);
2897 talloc_steal(state->write_req, state->pending);
2898 state->pending = NULL;
2900 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2901 state);
2904 static void smbd_echo_writer_done(struct tevent_req *req)
2906 struct smbd_echo_state *state = tevent_req_callback_data(
2907 req, struct smbd_echo_state);
2908 ssize_t written;
2909 int err;
2911 written = writev_recv(req, &err);
2912 TALLOC_FREE(req);
2913 state->write_req = NULL;
2914 if (written == -1) {
2915 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2916 exit(1);
2918 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2919 smbd_echo_activate_writer(state);
2922 static bool smbd_echo_reply(struct smbd_echo_state *state,
2923 uint8_t *inbuf, size_t inbuf_len,
2924 uint32_t seqnum)
2926 struct smb_request req;
2927 uint16_t num_replies;
2928 char *outbuf;
2929 bool ok;
2931 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2932 DEBUG(10, ("Got netbios keepalive\n"));
2934 * Just swallow it
2936 return true;
2939 if (inbuf_len < smb_size) {
2940 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2941 return false;
2943 if (!valid_smb_header(state->sconn, inbuf)) {
2944 DEBUG(10, ("Got invalid SMB header\n"));
2945 return false;
2948 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2949 seqnum)) {
2950 return false;
2952 req.inbuf = inbuf;
2954 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2955 smb_messages[req.cmd].name
2956 ? smb_messages[req.cmd].name : "unknown"));
2958 if (req.cmd != SMBecho) {
2959 return false;
2961 if (req.wct < 1) {
2962 return false;
2965 num_replies = SVAL(req.vwv+0, 0);
2966 if (num_replies != 1) {
2967 /* Not a Windows "Hey, you're still there?" request */
2968 return false;
2971 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2972 1, req.buflen)) {
2973 DEBUG(10, ("create_outbuf failed\n"));
2974 return false;
2976 req.outbuf = (uint8_t *)outbuf;
2978 SSVAL(req.outbuf, smb_vwv0, num_replies);
2980 if (req.buflen > 0) {
2981 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2984 ok = srv_send_smb(req.sconn,
2985 (char *)outbuf,
2986 true, seqnum+1,
2987 false, &req.pcd);
2988 TALLOC_FREE(outbuf);
2989 if (!ok) {
2990 exit(1);
2993 return true;
2996 static void smbd_echo_exit(struct tevent_context *ev,
2997 struct tevent_fd *fde, uint16_t flags,
2998 void *private_data)
3000 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3001 exit(0);
3004 static void smbd_echo_got_packet(struct tevent_req *req);
3006 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3007 int parent_pipe)
3009 struct smbd_echo_state *state;
3010 struct tevent_req *read_req;
3012 state = talloc_zero(sconn, struct smbd_echo_state);
3013 if (state == NULL) {
3014 DEBUG(1, ("talloc failed\n"));
3015 return;
3017 state->sconn = sconn;
3018 state->parent_pipe = parent_pipe;
3019 state->ev = s3_tevent_context_init(state);
3020 if (state->ev == NULL) {
3021 DEBUG(1, ("tevent_context_init failed\n"));
3022 TALLOC_FREE(state);
3023 return;
3025 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3026 TEVENT_FD_READ, smbd_echo_exit,
3027 state);
3028 if (state->parent_fde == NULL) {
3029 DEBUG(1, ("tevent_add_fd failed\n"));
3030 TALLOC_FREE(state);
3031 return;
3034 read_req = smbd_echo_read_send(state, state->ev, sconn);
3035 if (read_req == NULL) {
3036 DEBUG(1, ("smbd_echo_read_send failed\n"));
3037 TALLOC_FREE(state);
3038 return;
3040 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3042 while (true) {
3043 if (tevent_loop_once(state->ev) == -1) {
3044 DEBUG(1, ("tevent_loop_once failed: %s\n",
3045 strerror(errno)));
3046 break;
3049 TALLOC_FREE(state);
3052 static void smbd_echo_got_packet(struct tevent_req *req)
3054 struct smbd_echo_state *state = tevent_req_callback_data(
3055 req, struct smbd_echo_state);
3056 NTSTATUS status;
3057 char *buf = NULL;
3058 size_t buflen = 0;
3059 uint32_t seqnum = 0;
3060 bool reply;
3062 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3063 TALLOC_FREE(req);
3064 if (!NT_STATUS_IS_OK(status)) {
3065 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3066 nt_errstr(status)));
3067 exit(1);
3070 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3071 if (!reply) {
3072 size_t num_pending;
3073 struct iovec *tmp;
3074 struct iovec *iov;
3076 num_pending = talloc_array_length(state->pending);
3077 tmp = talloc_realloc(state, state->pending, struct iovec,
3078 num_pending+1);
3079 if (tmp == NULL) {
3080 DEBUG(1, ("talloc_realloc failed\n"));
3081 exit(1);
3083 state->pending = tmp;
3085 if (buflen >= smb_size) {
3087 * place the seqnum in the packet so that the main process
3088 * can reply with signing
3090 SIVAL(buf, smb_ss_field, seqnum);
3091 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3094 iov = &state->pending[num_pending];
3095 iov->iov_base = talloc_move(state->pending, &buf);
3096 iov->iov_len = buflen;
3098 DEBUG(10,("echo_handler[%d]: forward to main\n",
3099 (int)getpid()));
3100 smbd_echo_activate_writer(state);
3103 req = smbd_echo_read_send(state, state->ev, state->sconn);
3104 if (req == NULL) {
3105 DEBUG(1, ("smbd_echo_read_send failed\n"));
3106 exit(1);
3108 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3113 * Handle SMBecho requests in a forked child process
3115 bool fork_echo_handler(struct smbd_server_connection *sconn)
3117 int listener_pipe[2];
3118 int res;
3119 pid_t child;
3121 res = pipe(listener_pipe);
3122 if (res == -1) {
3123 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3124 return false;
3126 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
3127 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3128 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3129 goto fail;
3132 child = fork();
3133 if (child == 0) {
3134 NTSTATUS status;
3136 close(listener_pipe[0]);
3137 set_blocking(listener_pipe[1], false);
3139 status = reinit_after_fork(sconn->msg_ctx,
3140 sconn->ev_ctx,
3141 true);
3142 if (!NT_STATUS_IS_OK(status)) {
3143 DEBUG(1, ("reinit_after_fork failed: %s\n",
3144 nt_errstr(status)));
3145 exit(1);
3147 smbd_echo_loop(sconn, listener_pipe[1]);
3148 exit(0);
3150 close(listener_pipe[1]);
3151 listener_pipe[1] = -1;
3152 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3154 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3157 * Without smb signing this is the same as the normal smbd
3158 * listener. This needs to change once signing comes in.
3160 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3161 sconn,
3162 sconn->smb1.echo_handler.trusted_fd,
3163 TEVENT_FD_READ,
3164 smbd_server_echo_handler,
3165 sconn);
3166 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3167 DEBUG(1, ("event_add_fd failed\n"));
3168 goto fail;
3171 return true;
3173 fail:
3174 if (listener_pipe[0] != -1) {
3175 close(listener_pipe[0]);
3177 if (listener_pipe[1] != -1) {
3178 close(listener_pipe[1]);
3180 sconn->smb1.echo_handler.trusted_fd = -1;
3181 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3182 close(sconn->smb1.echo_handler.socket_lock_fd);
3184 sconn->smb1.echo_handler.trusted_fd = -1;
3185 sconn->smb1.echo_handler.socket_lock_fd = -1;
3186 return false;
3189 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3191 while (user) {
3192 if (user->session_info &&
3193 (user->session_info->unix_token->uid == uid)) {
3194 return true;
3196 user = user->next;
3198 return false;
3201 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3203 while (user) {
3204 if (user->session_info != NULL) {
3205 int i;
3206 struct security_unix_token *utok;
3208 utok = user->session_info->unix_token;
3209 if (utok->gid == gid) {
3210 return true;
3212 for(i=0; i<utok->ngroups; i++) {
3213 if (utok->groups[i] == gid) {
3214 return true;
3218 user = user->next;
3220 return false;
3223 static bool sid_in_use(const struct user_struct *user,
3224 const struct dom_sid *psid)
3226 while (user) {
3227 struct security_token *tok;
3229 if (user->session_info == NULL) {
3230 continue;
3232 tok = user->session_info->security_token;
3233 if (tok == NULL) {
3235 * Not sure session_info->security_token can
3236 * ever be NULL. This check might be not
3237 * necessary.
3239 continue;
3241 if (security_token_has_sid(tok, psid)) {
3242 return true;
3244 user = user->next;
3246 return false;
3249 static bool id_in_use(const struct user_struct *user,
3250 const struct id_cache_ref *id)
3252 switch(id->type) {
3253 case UID:
3254 return uid_in_use(user, id->id.uid);
3255 case GID:
3256 return gid_in_use(user, id->id.gid);
3257 case SID:
3258 return sid_in_use(user, &id->id.sid);
3259 default:
3260 break;
3262 return false;
3265 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3266 void *private_data,
3267 uint32_t msg_type,
3268 struct server_id server_id,
3269 DATA_BLOB* data)
3271 const char *msg = (data && data->data)
3272 ? (const char *)data->data : "<NULL>";
3273 struct id_cache_ref id;
3274 struct smbd_server_connection *sconn =
3275 talloc_get_type_abort(private_data,
3276 struct smbd_server_connection);
3278 if (!id_cache_ref_parse(msg, &id)) {
3279 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3280 return;
3283 if (id_in_use(sconn->users, &id)) {
3284 exit_server_cleanly(msg);
3286 id_cache_delete_from_cache(&id);
3289 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3290 enum protocol_types protocol)
3292 NTSTATUS status;
3294 set_Protocol(protocol);
3295 conn->protocol = protocol;
3297 if (protocol >= PROTOCOL_SMB2_02) {
3298 status = smb2srv_session_table_init(conn);
3299 if (!NT_STATUS_IS_OK(status)) {
3300 return status;
3303 status = smb2srv_open_table_init(conn);
3304 if (!NT_STATUS_IS_OK(status)) {
3305 return status;
3307 } else {
3308 status = smb1srv_session_table_init(conn);
3309 if (!NT_STATUS_IS_OK(status)) {
3310 return status;
3313 status = smb1srv_tcon_table_init(conn);
3314 if (!NT_STATUS_IS_OK(status)) {
3315 return status;
3318 status = smb1srv_open_table_init(conn);
3319 if (!NT_STATUS_IS_OK(status)) {
3320 return status;
3324 return NT_STATUS_OK;
3327 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3328 void *private_data)
3330 struct smbXsrv_connection *conn =
3331 talloc_get_type_abort(private_data,
3332 struct smbXsrv_connection);
3334 switch (point) {
3335 case TEVENT_TRACE_BEFORE_WAIT:
3337 * This just removes compiler warning
3338 * without profile support
3340 conn->smbd_idle_profstamp = 0;
3341 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3342 break;
3343 case TEVENT_TRACE_AFTER_WAIT:
3344 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3345 break;
3349 /****************************************************************************
3350 Process commands from the client
3351 ****************************************************************************/
3353 void smbd_process(struct tevent_context *ev_ctx,
3354 struct messaging_context *msg_ctx,
3355 int sock_fd,
3356 bool interactive)
3358 TALLOC_CTX *frame = talloc_stackframe();
3359 struct smbXsrv_connection *conn;
3360 struct smbd_server_connection *sconn;
3361 struct sockaddr_storage ss;
3362 struct sockaddr *sa = NULL;
3363 socklen_t sa_socklen;
3364 struct tsocket_address *local_address = NULL;
3365 struct tsocket_address *remote_address = NULL;
3366 const char *locaddr = NULL;
3367 const char *remaddr = NULL;
3368 char *rhost;
3369 int ret;
3370 int tmp;
3372 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3373 if (conn == NULL) {
3374 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3375 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3378 conn->ev_ctx = ev_ctx;
3379 conn->msg_ctx = msg_ctx;
3381 sconn = talloc_zero(conn, struct smbd_server_connection);
3382 if (!sconn) {
3383 exit_server("failed to create smbd_server_connection");
3386 conn->sconn = sconn;
3387 sconn->conn = conn;
3390 * TODO: remove this...:-)
3392 global_smbXsrv_connection = conn;
3394 sconn->ev_ctx = ev_ctx;
3395 sconn->msg_ctx = msg_ctx;
3396 sconn->sock = sock_fd;
3397 sconn->smb1.echo_handler.trusted_fd = -1;
3398 sconn->smb1.echo_handler.socket_lock_fd = -1;
3400 if (!interactive) {
3401 smbd_setup_sig_term_handler(sconn);
3402 smbd_setup_sig_hup_handler(sconn);
3404 if (!serverid_register(messaging_server_id(msg_ctx),
3405 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3406 |FLAG_MSG_DBWRAP
3407 |FLAG_MSG_PRINT_GENERAL)) {
3408 exit_server_cleanly("Could not register myself in "
3409 "serverid.tdb");
3413 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3415 * We're not making the decision here,
3416 * we're just allowing the client
3417 * to decide between SMB1 and SMB2
3418 * with the first negprot
3419 * packet.
3421 sconn->using_smb2 = true;
3424 /* Ensure child is set to blocking mode */
3425 set_blocking(sconn->sock,True);
3427 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3428 set_socket_options(sconn->sock, lp_socket_options());
3430 sa = (struct sockaddr *)(void *)&ss;
3431 sa_socklen = sizeof(ss);
3432 ret = getpeername(sconn->sock, sa, &sa_socklen);
3433 if (ret != 0) {
3434 int level = (errno == ENOTCONN)?2:0;
3435 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3436 exit_server_cleanly("getpeername() failed.\n");
3438 ret = tsocket_address_bsd_from_sockaddr(sconn,
3439 sa, sa_socklen,
3440 &remote_address);
3441 if (ret != 0) {
3442 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3443 __location__, strerror(errno)));
3444 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3447 sa = (struct sockaddr *)(void *)&ss;
3448 sa_socklen = sizeof(ss);
3449 ret = getsockname(sconn->sock, sa, &sa_socklen);
3450 if (ret != 0) {
3451 int level = (errno == ENOTCONN)?2:0;
3452 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3453 exit_server_cleanly("getsockname() failed.\n");
3455 ret = tsocket_address_bsd_from_sockaddr(sconn,
3456 sa, sa_socklen,
3457 &local_address);
3458 if (ret != 0) {
3459 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3460 __location__, strerror(errno)));
3461 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3464 sconn->local_address = local_address;
3465 sconn->remote_address = remote_address;
3467 if (tsocket_address_is_inet(local_address, "ip")) {
3468 locaddr = tsocket_address_inet_addr_string(
3469 sconn->local_address,
3470 talloc_tos());
3471 if (locaddr == NULL) {
3472 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3473 __location__, strerror(errno)));
3474 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3476 } else {
3477 locaddr = "0.0.0.0";
3480 if (tsocket_address_is_inet(remote_address, "ip")) {
3481 remaddr = tsocket_address_inet_addr_string(
3482 sconn->remote_address,
3483 talloc_tos());
3484 if (remaddr == NULL) {
3485 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3486 __location__, strerror(errno)));
3487 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3489 } else {
3490 remaddr = "0.0.0.0";
3493 /* this is needed so that we get decent entries
3494 in smbstatus for port 445 connects */
3495 set_remote_machine_name(remaddr, false);
3496 reload_services(sconn, conn_snum_used, true);
3499 * Before the first packet, check the global hosts allow/ hosts deny
3500 * parameters before doing any parsing of packets passed to us by the
3501 * client. This prevents attacks on our parsing code from hosts not in
3502 * the hosts allow list.
3505 ret = get_remote_hostname(remote_address,
3506 &rhost,
3507 talloc_tos());
3508 if (ret < 0) {
3509 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3510 __location__, strerror(errno)));
3511 exit_server_cleanly("get_remote_hostname failed.\n");
3513 if (strequal(rhost, "UNKNOWN")) {
3514 rhost = talloc_strdup(talloc_tos(), remaddr);
3516 sconn->remote_hostname = talloc_move(sconn, &rhost);
3518 sub_set_socket_ids(remaddr,
3519 sconn->remote_hostname,
3520 locaddr);
3522 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3523 sconn->remote_hostname,
3524 remaddr)) {
3526 * send a negative session response "not listening on calling
3527 * name"
3529 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3530 DEBUG( 1, ("Connection denied from %s to %s\n",
3531 tsocket_address_string(remote_address, talloc_tos()),
3532 tsocket_address_string(local_address, talloc_tos())));
3533 (void)srv_send_smb(sconn,(char *)buf, false,
3534 0, false, NULL);
3535 exit_server_cleanly("connection denied");
3538 DEBUG(10, ("Connection allowed from %s to %s\n",
3539 tsocket_address_string(remote_address, talloc_tos()),
3540 tsocket_address_string(local_address, talloc_tos())));
3542 if (lp_preload_modules()) {
3543 smb_load_modules(lp_preload_modules());
3546 smb_perfcount_init();
3548 if (!init_account_policy()) {
3549 exit_server("Could not open account policy tdb.\n");
3552 if (*lp_rootdir(talloc_tos())) {
3553 if (chroot(lp_rootdir(talloc_tos())) != 0) {
3554 DEBUG(0,("Failed to change root to %s\n",
3555 lp_rootdir(talloc_tos())));
3556 exit_server("Failed to chroot()");
3558 if (chdir("/") == -1) {
3559 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir(talloc_tos())));
3560 exit_server("Failed to chroot()");
3562 DEBUG(0,("Changed root to %s\n", lp_rootdir(talloc_tos())));
3565 if (!srv_init_signing(sconn)) {
3566 exit_server("Failed to init smb_signing");
3569 if (!file_init(sconn)) {
3570 exit_server("file_init() failed");
3573 /* Setup oplocks */
3574 if (!init_oplocks(sconn))
3575 exit_server("Failed to init oplocks");
3577 /* register our message handlers */
3578 messaging_register(sconn->msg_ctx, sconn,
3579 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3580 messaging_register(sconn->msg_ctx, sconn,
3581 MSG_SMB_CLOSE_FILE, msg_close_file);
3582 messaging_register(sconn->msg_ctx, sconn,
3583 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3585 id_cache_register_msgs(sconn->msg_ctx);
3586 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3587 messaging_register(sconn->msg_ctx, sconn,
3588 ID_CACHE_KILL, smbd_id_cache_kill);
3590 messaging_deregister(sconn->msg_ctx,
3591 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3592 messaging_register(sconn->msg_ctx, sconn,
3593 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3596 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3597 * MSGs to all child processes
3599 messaging_deregister(sconn->msg_ctx,
3600 MSG_DEBUG, NULL);
3601 messaging_register(sconn->msg_ctx, NULL,
3602 MSG_DEBUG, debug_message);
3604 if ((lp_keepalive() != 0)
3605 && !(event_add_idle(ev_ctx, NULL,
3606 timeval_set(lp_keepalive(), 0),
3607 "keepalive", keepalive_fn,
3608 sconn))) {
3609 DEBUG(0, ("Could not add keepalive event\n"));
3610 exit(1);
3613 if (!(event_add_idle(ev_ctx, NULL,
3614 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3615 "deadtime", deadtime_fn, sconn))) {
3616 DEBUG(0, ("Could not add deadtime event\n"));
3617 exit(1);
3620 if (!(event_add_idle(ev_ctx, NULL,
3621 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3622 "housekeeping", housekeeping_fn, sconn))) {
3623 DEBUG(0, ("Could not add housekeeping event\n"));
3624 exit(1);
3627 #ifdef CLUSTER_SUPPORT
3629 if (lp_clustering()) {
3631 * We need to tell ctdb about our client's TCP
3632 * connection, so that for failover ctdbd can send
3633 * tickle acks, triggering a reconnection by the
3634 * client.
3637 struct sockaddr_storage srv, clnt;
3639 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3640 NTSTATUS status;
3641 status = smbd_register_ips(sconn, &srv, &clnt);
3642 if (!NT_STATUS_IS_OK(status)) {
3643 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3644 nt_errstr(status)));
3646 } else {
3647 int level = (errno == ENOTCONN)?2:0;
3648 DEBUG(level,("Unable to get tcp info for "
3649 "smbd_register_ips: %s\n",
3650 strerror(errno)));
3651 exit_server_cleanly("client_get_tcp_info() failed.\n");
3655 #endif
3657 sconn->nbt.got_session = false;
3659 tmp = lp_max_xmit();
3660 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3661 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3663 sconn->smb1.negprot.max_recv = tmp;
3665 sconn->smb1.sessions.done_sesssetup = false;
3666 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3668 if (!init_dptrs(sconn)) {
3669 exit_server("init_dptrs() failed");
3672 sconn->smb1.fde = tevent_add_fd(ev_ctx,
3673 sconn,
3674 sconn->sock,
3675 TEVENT_FD_READ,
3676 smbd_server_connection_handler,
3677 sconn);
3678 if (!sconn->smb1.fde) {
3679 exit_server("failed to create smbd_server_connection fde");
3682 sconn->conn->local_address = sconn->local_address;
3683 sconn->conn->remote_address = sconn->remote_address;
3684 sconn->conn->remote_hostname = sconn->remote_hostname;
3685 sconn->conn->protocol = PROTOCOL_NONE;
3687 TALLOC_FREE(frame);
3689 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3691 while (True) {
3692 frame = talloc_stackframe_pool(8192);
3694 errno = 0;
3695 if (tevent_loop_once(ev_ctx) == -1) {
3696 if (errno != EINTR) {
3697 DEBUG(3, ("tevent_loop_once failed: %s,"
3698 " exiting\n", strerror(errno) ));
3699 break;
3703 TALLOC_FREE(frame);
3706 exit_server_cleanly(NULL);
3709 bool req_is_in_chain(const struct smb_request *req)
3711 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3713 * We're right now handling a subsequent request, so we must
3714 * be in a chain
3716 return true;
3719 if (!is_andx_req(req->cmd)) {
3720 return false;
3723 if (req->wct < 2) {
3725 * Okay, an illegal request, but definitely not chained :-)
3727 return false;
3730 return (CVAL(req->vwv+0, 0) != 0xFF);