auth: Make sure that creds_out is initialized with NULL.
[Samba.git] / source3 / smbd / process.c
blobe67c56cf60d9c15bbc69a88613df7ebc930a5b01
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 timed_event *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 for 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 size_t nwritten=0;
153 ssize_t ret;
154 char *buf_out = buffer;
156 if (!NT_STATUS_IS_OK(sconn->status)) {
158 * we're not supposed to do any io
160 return true;
163 smbd_lock_socket(sconn);
165 if (do_signing) {
166 /* Sign the outgoing packet if required. */
167 srv_calculate_sign_mac(sconn, buf_out, seqnum);
170 if (do_encrypt) {
171 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
172 if (!NT_STATUS_IS_OK(status)) {
173 DEBUG(0, ("send_smb: SMB encryption failed "
174 "on outgoing packet! Error %s\n",
175 nt_errstr(status) ));
176 goto out;
180 len = smb_len_large(buf_out) + 4;
182 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
183 if (ret <= 0) {
185 char addr[INET6_ADDRSTRLEN];
187 * Try and give an error message saying what
188 * client failed.
190 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
191 (int)getpid(), (int)len,
192 get_peer_addr(sconn->sock, addr, sizeof(addr)),
193 (int)ret, strerror(errno) ));
195 srv_free_enc_buffer(sconn, buf_out);
196 goto out;
199 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
200 srv_free_enc_buffer(sconn, buf_out);
201 out:
202 SMB_PERFCOUNT_END(pcd);
204 smbd_unlock_socket(sconn);
205 return (ret > 0);
208 /*******************************************************************
209 Setup the word count and byte count for a smb message.
210 ********************************************************************/
212 int srv_set_message(char *buf,
213 int num_words,
214 int num_bytes,
215 bool zero)
217 if (zero && (num_words || num_bytes)) {
218 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
220 SCVAL(buf,smb_wct,num_words);
221 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
222 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
223 return (smb_size + num_words*2 + num_bytes);
226 static bool valid_smb_header(struct smbd_server_connection *sconn,
227 const uint8_t *inbuf)
229 if (is_encrypted_packet(sconn, inbuf)) {
230 return true;
233 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
234 * but it just looks weird to call strncmp for this one.
236 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
239 /* Socket functions for smbd packet processing. */
241 static bool valid_packet_size(size_t len)
244 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
245 * of header. Don't print the error if this fits.... JRA.
248 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
249 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
250 (unsigned long)len));
251 return false;
253 return true;
256 static NTSTATUS read_packet_remainder(int fd, char *buffer,
257 unsigned int timeout, ssize_t len)
259 NTSTATUS status;
261 if (len <= 0) {
262 return NT_STATUS_OK;
265 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
266 if (!NT_STATUS_IS_OK(status)) {
267 char addr[INET6_ADDRSTRLEN];
268 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
269 "error = %s.\n",
270 get_peer_addr(fd, addr, sizeof(addr)),
271 nt_errstr(status)));
273 return status;
276 /****************************************************************************
277 Attempt a zerocopy writeX read. We know here that len > smb_size-4
278 ****************************************************************************/
281 * Unfortunately, earlier versions of smbclient/libsmbclient
282 * don't send this "standard" writeX header. I've fixed this
283 * for 3.2 but we'll use the old method with earlier versions.
284 * Windows and CIFSFS at least use this standard size. Not
285 * sure about MacOSX.
288 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
289 (2*14) + /* word count (including bcc) */ \
290 1 /* pad byte */)
292 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
293 const char lenbuf[4],
294 struct smbd_server_connection *sconn,
295 int sock,
296 char **buffer,
297 unsigned int timeout,
298 size_t *p_unread,
299 size_t *len_ret)
301 /* Size of a WRITEX call (+4 byte len). */
302 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
303 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
304 ssize_t toread;
305 NTSTATUS status;
307 memcpy(writeX_header, lenbuf, 4);
309 status = read_fd_with_timeout(
310 sock, writeX_header + 4,
311 STANDARD_WRITE_AND_X_HEADER_SIZE,
312 STANDARD_WRITE_AND_X_HEADER_SIZE,
313 timeout, NULL);
315 if (!NT_STATUS_IS_OK(status)) {
316 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
317 "error = %s.\n",
318 tsocket_address_string(sconn->remote_address,
319 talloc_tos()),
320 nt_errstr(status)));
321 return status;
325 * Ok - now try and see if this is a possible
326 * valid writeX call.
329 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
331 * If the data offset is beyond what
332 * we've read, drain the extra bytes.
334 uint16_t doff = SVAL(writeX_header,smb_vwv11);
335 ssize_t newlen;
337 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
338 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
339 if (drain_socket(sock, drain) != drain) {
340 smb_panic("receive_smb_raw_talloc_partial_read:"
341 " failed to drain pending bytes");
343 } else {
344 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
347 /* Spoof down the length and null out the bcc. */
348 set_message_bcc(writeX_header, 0);
349 newlen = smb_len(writeX_header);
351 /* Copy the header we've written. */
353 *buffer = (char *)talloc_memdup(mem_ctx,
354 writeX_header,
355 sizeof(writeX_header));
357 if (*buffer == NULL) {
358 DEBUG(0, ("Could not allocate inbuf of length %d\n",
359 (int)sizeof(writeX_header)));
360 return NT_STATUS_NO_MEMORY;
363 /* Work out the remaining bytes. */
364 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
365 *len_ret = newlen + 4;
366 return NT_STATUS_OK;
369 if (!valid_packet_size(len)) {
370 return NT_STATUS_INVALID_PARAMETER;
374 * Not a valid writeX call. Just do the standard
375 * talloc and return.
378 *buffer = talloc_array(mem_ctx, char, len+4);
380 if (*buffer == NULL) {
381 DEBUG(0, ("Could not allocate inbuf of length %d\n",
382 (int)len+4));
383 return NT_STATUS_NO_MEMORY;
386 /* Copy in what we already read. */
387 memcpy(*buffer,
388 writeX_header,
389 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
390 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
392 if(toread > 0) {
393 status = read_packet_remainder(
394 sock,
395 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
396 timeout, toread);
398 if (!NT_STATUS_IS_OK(status)) {
399 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
400 nt_errstr(status)));
401 return status;
405 *len_ret = len + 4;
406 return NT_STATUS_OK;
409 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
410 struct smbd_server_connection *sconn,
411 int sock,
412 char **buffer, unsigned int timeout,
413 size_t *p_unread, size_t *plen)
415 char lenbuf[4];
416 size_t len;
417 int min_recv_size = lp_min_receive_file_size();
418 NTSTATUS status;
420 *p_unread = 0;
422 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
423 &len);
424 if (!NT_STATUS_IS_OK(status)) {
425 return status;
428 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
429 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
430 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
431 !srv_is_signing_active(sconn) &&
432 sconn->smb1.echo_handler.trusted_fde == NULL) {
434 return receive_smb_raw_talloc_partial_read(
435 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
436 p_unread, plen);
439 if (!valid_packet_size(len)) {
440 return NT_STATUS_INVALID_PARAMETER;
444 * The +4 here can't wrap, we've checked the length above already.
447 *buffer = talloc_array(mem_ctx, char, len+4);
449 if (*buffer == NULL) {
450 DEBUG(0, ("Could not allocate inbuf of length %d\n",
451 (int)len+4));
452 return NT_STATUS_NO_MEMORY;
455 memcpy(*buffer, lenbuf, sizeof(lenbuf));
457 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
458 if (!NT_STATUS_IS_OK(status)) {
459 return status;
462 *plen = len + 4;
463 return NT_STATUS_OK;
466 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
467 struct smbd_server_connection *sconn,
468 int sock,
469 char **buffer, unsigned int timeout,
470 size_t *p_unread, bool *p_encrypted,
471 size_t *p_len,
472 uint32_t *seqnum,
473 bool trusted_channel)
475 size_t len = 0;
476 NTSTATUS status;
478 *p_encrypted = false;
480 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
481 p_unread, &len);
482 if (!NT_STATUS_IS_OK(status)) {
483 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
484 ("receive_smb_raw_talloc failed for client %s "
485 "read error = %s.\n",
486 tsocket_address_string(sconn->remote_address,
487 talloc_tos()),
488 nt_errstr(status)) );
489 return status;
492 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
493 status = srv_decrypt_buffer(sconn, *buffer);
494 if (!NT_STATUS_IS_OK(status)) {
495 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
496 "incoming packet! Error %s\n",
497 nt_errstr(status) ));
498 return status;
500 *p_encrypted = true;
503 /* Check the incoming SMB signature. */
504 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
505 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
506 "incoming packet!\n"));
507 return NT_STATUS_INVALID_NETWORK_RESPONSE;
510 *p_len = len;
511 return NT_STATUS_OK;
515 * Initialize a struct smb_request from an inbuf
518 static bool init_smb_request(struct smb_request *req,
519 struct smbd_server_connection *sconn,
520 const uint8 *inbuf,
521 size_t unread_bytes, bool encrypted,
522 uint32_t seqnum)
524 struct smbXsrv_tcon *tcon;
525 NTSTATUS status;
526 NTTIME now;
527 size_t req_size = smb_len(inbuf) + 4;
529 /* Ensure we have at least smb_size bytes. */
530 if (req_size < smb_size) {
531 DEBUG(0,("init_smb_request: invalid request size %u\n",
532 (unsigned int)req_size ));
533 return false;
536 req->request_time = timeval_current();
537 now = timeval_to_nttime(&req->request_time);
539 req->cmd = CVAL(inbuf, smb_com);
540 req->flags2 = SVAL(inbuf, smb_flg2);
541 req->smbpid = SVAL(inbuf, smb_pid);
542 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
543 req->seqnum = seqnum;
544 req->vuid = SVAL(inbuf, smb_uid);
545 req->tid = SVAL(inbuf, smb_tid);
546 req->wct = CVAL(inbuf, smb_wct);
547 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
548 req->buflen = smb_buflen(inbuf);
549 req->buf = (const uint8_t *)smb_buf_const(inbuf);
550 req->unread_bytes = unread_bytes;
551 req->encrypted = encrypted;
552 req->sconn = sconn;
553 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
554 if (NT_STATUS_IS_OK(status)) {
555 req->conn = tcon->compat;
556 } else {
557 req->conn = NULL;
559 req->chain_fsp = NULL;
560 req->smb2req = NULL;
561 req->priv_paths = NULL;
562 req->chain = NULL;
563 smb_init_perfcount_data(&req->pcd);
565 /* Ensure we have at least wct words and 2 bytes of bcc. */
566 if (smb_size + req->wct*2 > req_size) {
567 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
568 (unsigned int)req->wct,
569 (unsigned int)req_size));
570 return false;
572 /* Ensure bcc is correct. */
573 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
574 DEBUG(0,("init_smb_request: invalid bcc number %u "
575 "(wct = %u, size %u)\n",
576 (unsigned int)req->buflen,
577 (unsigned int)req->wct,
578 (unsigned int)req_size));
579 return false;
582 req->outbuf = NULL;
583 return true;
586 static void process_smb(struct smbd_server_connection *conn,
587 uint8_t *inbuf, size_t nread, size_t unread_bytes,
588 uint32_t seqnum, bool encrypted,
589 struct smb_perfcount_data *deferred_pcd);
591 static void smbd_deferred_open_timer(struct event_context *ev,
592 struct timed_event *te,
593 struct timeval _tval,
594 void *private_data)
596 struct pending_message_list *msg = talloc_get_type(private_data,
597 struct pending_message_list);
598 struct smbd_server_connection *sconn = msg->sconn;
599 TALLOC_CTX *mem_ctx = talloc_tos();
600 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
601 uint8_t *inbuf;
603 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
604 msg->buf.length);
605 if (inbuf == NULL) {
606 exit_server("smbd_deferred_open_timer: talloc failed\n");
607 return;
610 /* We leave this message on the queue so the open code can
611 know this is a retry. */
612 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
613 (unsigned long long)mid ));
615 /* Mark the message as processed so this is not
616 * re-processed in error. */
617 msg->processed = true;
619 process_smb(sconn, inbuf,
620 msg->buf.length, 0,
621 msg->seqnum, msg->encrypted, &msg->pcd);
623 /* If it's still there and was processed, remove it. */
624 msg = get_deferred_open_message_smb(sconn, mid);
625 if (msg && msg->processed) {
626 remove_deferred_open_message_smb(sconn, mid);
630 /****************************************************************************
631 Function to push a message onto the tail of a linked list of smb messages ready
632 for processing.
633 ****************************************************************************/
635 static bool push_queued_message(struct smb_request *req,
636 struct timeval request_time,
637 struct timeval end_time,
638 char *private_data, size_t private_len)
640 int msg_len = smb_len(req->inbuf) + 4;
641 struct pending_message_list *msg;
643 msg = talloc_zero(NULL, struct pending_message_list);
645 if(msg == NULL) {
646 DEBUG(0,("push_message: malloc fail (1)\n"));
647 return False;
649 msg->sconn = req->sconn;
651 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
652 if(msg->buf.data == NULL) {
653 DEBUG(0,("push_message: malloc fail (2)\n"));
654 TALLOC_FREE(msg);
655 return False;
658 msg->request_time = request_time;
659 msg->seqnum = req->seqnum;
660 msg->encrypted = req->encrypted;
661 msg->processed = false;
662 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
664 if (private_data) {
665 msg->private_data = data_blob_talloc(msg, private_data,
666 private_len);
667 if (msg->private_data.data == NULL) {
668 DEBUG(0,("push_message: malloc fail (3)\n"));
669 TALLOC_FREE(msg);
670 return False;
674 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;
685 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
686 struct pending_message_list *);
688 DEBUG(10,("push_message: pushed message length %u on "
689 "deferred_open_queue\n", (unsigned int)msg_len));
691 return True;
694 /****************************************************************************
695 Function to delete a sharing violation open message by mid.
696 ****************************************************************************/
698 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
699 uint64_t mid)
701 struct pending_message_list *pml;
703 if (sconn->using_smb2) {
704 remove_deferred_open_message_smb2(sconn, mid);
705 return;
708 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
709 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
710 DEBUG(10,("remove_deferred_open_message_smb: "
711 "deleting mid %llu len %u\n",
712 (unsigned long long)mid,
713 (unsigned int)pml->buf.length ));
714 DLIST_REMOVE(sconn->deferred_open_queue, pml);
715 TALLOC_FREE(pml);
716 return;
721 /****************************************************************************
722 Move a sharing violation open retry message to the front of the list and
723 schedule it for immediate processing.
724 ****************************************************************************/
726 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
727 uint64_t mid)
729 struct pending_message_list *pml;
730 int i = 0;
732 if (sconn->using_smb2) {
733 return schedule_deferred_open_message_smb2(sconn, mid);
736 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
737 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
739 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
740 "msg_mid = %llu\n",
741 i++,
742 (unsigned long long)msg_mid ));
744 if (mid == msg_mid) {
745 struct timed_event *te;
747 if (pml->processed) {
748 /* A processed message should not be
749 * rescheduled. */
750 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
751 "message mid %llu was already processed\n",
752 (unsigned long long)msg_mid ));
753 continue;
756 DEBUG(10,("schedule_deferred_open_message_smb: "
757 "scheduling mid %llu\n",
758 (unsigned long long)mid ));
760 te = tevent_add_timer(pml->sconn->ev_ctx,
761 pml,
762 timeval_zero(),
763 smbd_deferred_open_timer,
764 pml);
765 if (!te) {
766 DEBUG(10,("schedule_deferred_open_message_smb: "
767 "event_add_timed() failed, "
768 "skipping mid %llu\n",
769 (unsigned long long)msg_mid ));
772 TALLOC_FREE(pml->te);
773 pml->te = te;
774 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
775 return true;
779 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
780 "find message mid %llu\n",
781 (unsigned long long)mid ));
783 return false;
786 /****************************************************************************
787 Return true if this mid is on the deferred queue and was not yet processed.
788 ****************************************************************************/
790 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
792 struct pending_message_list *pml;
794 if (sconn->using_smb2) {
795 return open_was_deferred_smb2(sconn, mid);
798 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
799 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
800 return True;
803 return False;
806 /****************************************************************************
807 Return the message queued by this mid.
808 ****************************************************************************/
810 static struct pending_message_list *get_deferred_open_message_smb(
811 struct smbd_server_connection *sconn, uint64_t mid)
813 struct pending_message_list *pml;
815 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
816 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
817 return pml;
820 return NULL;
823 /****************************************************************************
824 Get the state data queued by this mid.
825 ****************************************************************************/
827 bool get_deferred_open_message_state(struct smb_request *smbreq,
828 struct timeval *p_request_time,
829 void **pp_state)
831 struct pending_message_list *pml;
833 if (smbreq->sconn->using_smb2) {
834 return get_deferred_open_message_state_smb2(smbreq->smb2req,
835 p_request_time,
836 pp_state);
839 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
840 if (!pml) {
841 return false;
843 if (p_request_time) {
844 *p_request_time = pml->request_time;
846 if (pp_state) {
847 *pp_state = (void *)pml->private_data.data;
849 return true;
852 /****************************************************************************
853 Function to push a deferred open smb message onto a linked list of local smb
854 messages ready for processing.
855 ****************************************************************************/
857 bool push_deferred_open_message_smb(struct smb_request *req,
858 struct timeval request_time,
859 struct timeval timeout,
860 struct file_id id,
861 char *private_data, size_t priv_len)
863 struct timeval end_time;
865 if (req->smb2req) {
866 return push_deferred_open_message_smb2(req->smb2req,
867 request_time,
868 timeout,
870 private_data,
871 priv_len);
874 if (req->unread_bytes) {
875 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
876 "unread_bytes = %u\n",
877 (unsigned int)req->unread_bytes ));
878 smb_panic("push_deferred_open_message_smb: "
879 "logic error unread_bytes != 0" );
882 end_time = timeval_sum(&request_time, &timeout);
884 DEBUG(10,("push_deferred_open_message_smb: pushing message "
885 "len %u mid %llu timeout time [%u.%06u]\n",
886 (unsigned int) smb_len(req->inbuf)+4,
887 (unsigned long long)req->mid,
888 (unsigned int)end_time.tv_sec,
889 (unsigned int)end_time.tv_usec));
891 return push_queued_message(req, request_time, end_time,
892 private_data, priv_len);
895 static void smbd_sig_term_handler(struct tevent_context *ev,
896 struct tevent_signal *se,
897 int signum,
898 int count,
899 void *siginfo,
900 void *private_data)
902 exit_server_cleanly("termination signal");
905 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
907 struct tevent_signal *se;
909 se = tevent_add_signal(sconn->ev_ctx,
910 sconn,
911 SIGTERM, 0,
912 smbd_sig_term_handler,
913 sconn);
914 if (!se) {
915 exit_server("failed to setup SIGTERM handler");
919 static void smbd_sig_hup_handler(struct tevent_context *ev,
920 struct tevent_signal *se,
921 int signum,
922 int count,
923 void *siginfo,
924 void *private_data)
926 struct smbd_server_connection *sconn =
927 talloc_get_type_abort(private_data,
928 struct smbd_server_connection);
930 change_to_root_user();
931 DEBUG(1,("Reloading services after SIGHUP\n"));
932 reload_services(sconn, conn_snum_used, false);
935 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
937 struct tevent_signal *se;
939 se = tevent_add_signal(sconn->ev_ctx,
940 sconn,
941 SIGHUP, 0,
942 smbd_sig_hup_handler,
943 sconn);
944 if (!se) {
945 exit_server("failed to setup SIGHUP handler");
949 static void smbd_conf_updated(struct messaging_context *msg,
950 void *private_data,
951 uint32_t msg_type,
952 struct server_id server_id,
953 DATA_BLOB *data)
955 struct smbd_server_connection *sconn =
956 talloc_get_type_abort(private_data,
957 struct smbd_server_connection);
959 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
960 "updated. Reloading.\n"));
961 change_to_root_user();
962 reload_services(sconn, conn_snum_used, false);
966 * Only allow 5 outstanding trans requests. We're allocating memory, so
967 * prevent a DoS.
970 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
972 int count = 0;
973 for (; list != NULL; list = list->next) {
975 if (list->mid == mid) {
976 return NT_STATUS_INVALID_PARAMETER;
979 count += 1;
981 if (count > 5) {
982 return NT_STATUS_INSUFFICIENT_RESOURCES;
985 return NT_STATUS_OK;
989 These flags determine some of the permissions required to do an operation
991 Note that I don't set NEED_WRITE on some write operations because they
992 are used by some brain-dead clients when printing, and I don't want to
993 force write permissions on print services.
995 #define AS_USER (1<<0)
996 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
997 #define TIME_INIT (1<<2)
998 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
999 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1000 #define DO_CHDIR (1<<6)
1003 define a list of possible SMB messages and their corresponding
1004 functions. Any message that has a NULL function is unimplemented -
1005 please feel free to contribute implementations!
1007 static const struct smb_message_struct {
1008 const char *name;
1009 void (*fn)(struct smb_request *req);
1010 int flags;
1011 } smb_messages[256] = {
1013 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1014 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1015 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1016 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1017 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1018 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1019 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1020 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1021 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1022 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1023 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1024 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1025 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1026 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1027 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1028 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1029 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1030 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1031 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1032 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1033 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1034 /* 0x15 */ { NULL, NULL, 0 },
1035 /* 0x16 */ { NULL, NULL, 0 },
1036 /* 0x17 */ { NULL, NULL, 0 },
1037 /* 0x18 */ { NULL, NULL, 0 },
1038 /* 0x19 */ { NULL, NULL, 0 },
1039 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1040 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1041 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1042 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1043 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1044 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1045 /* 0x20 */ { "SMBwritec", NULL,0},
1046 /* 0x21 */ { NULL, NULL, 0 },
1047 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1048 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1049 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1050 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1051 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1052 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1053 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1054 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1055 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1056 /* 0x2b */ { "SMBecho",reply_echo,0},
1057 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1058 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1059 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1060 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1061 /* 0x30 */ { NULL, NULL, 0 },
1062 /* 0x31 */ { NULL, NULL, 0 },
1063 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1064 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1065 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1066 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1067 /* 0x36 */ { NULL, NULL, 0 },
1068 /* 0x37 */ { NULL, NULL, 0 },
1069 /* 0x38 */ { NULL, NULL, 0 },
1070 /* 0x39 */ { NULL, NULL, 0 },
1071 /* 0x3a */ { NULL, NULL, 0 },
1072 /* 0x3b */ { NULL, NULL, 0 },
1073 /* 0x3c */ { NULL, NULL, 0 },
1074 /* 0x3d */ { NULL, NULL, 0 },
1075 /* 0x3e */ { NULL, NULL, 0 },
1076 /* 0x3f */ { NULL, NULL, 0 },
1077 /* 0x40 */ { NULL, NULL, 0 },
1078 /* 0x41 */ { NULL, NULL, 0 },
1079 /* 0x42 */ { NULL, NULL, 0 },
1080 /* 0x43 */ { NULL, NULL, 0 },
1081 /* 0x44 */ { NULL, NULL, 0 },
1082 /* 0x45 */ { NULL, NULL, 0 },
1083 /* 0x46 */ { NULL, NULL, 0 },
1084 /* 0x47 */ { NULL, NULL, 0 },
1085 /* 0x48 */ { NULL, NULL, 0 },
1086 /* 0x49 */ { NULL, NULL, 0 },
1087 /* 0x4a */ { NULL, NULL, 0 },
1088 /* 0x4b */ { NULL, NULL, 0 },
1089 /* 0x4c */ { NULL, NULL, 0 },
1090 /* 0x4d */ { NULL, NULL, 0 },
1091 /* 0x4e */ { NULL, NULL, 0 },
1092 /* 0x4f */ { NULL, NULL, 0 },
1093 /* 0x50 */ { NULL, NULL, 0 },
1094 /* 0x51 */ { NULL, NULL, 0 },
1095 /* 0x52 */ { NULL, NULL, 0 },
1096 /* 0x53 */ { NULL, NULL, 0 },
1097 /* 0x54 */ { NULL, NULL, 0 },
1098 /* 0x55 */ { NULL, NULL, 0 },
1099 /* 0x56 */ { NULL, NULL, 0 },
1100 /* 0x57 */ { NULL, NULL, 0 },
1101 /* 0x58 */ { NULL, NULL, 0 },
1102 /* 0x59 */ { NULL, NULL, 0 },
1103 /* 0x5a */ { NULL, NULL, 0 },
1104 /* 0x5b */ { NULL, NULL, 0 },
1105 /* 0x5c */ { NULL, NULL, 0 },
1106 /* 0x5d */ { NULL, NULL, 0 },
1107 /* 0x5e */ { NULL, NULL, 0 },
1108 /* 0x5f */ { NULL, NULL, 0 },
1109 /* 0x60 */ { NULL, NULL, 0 },
1110 /* 0x61 */ { NULL, NULL, 0 },
1111 /* 0x62 */ { NULL, NULL, 0 },
1112 /* 0x63 */ { NULL, NULL, 0 },
1113 /* 0x64 */ { NULL, NULL, 0 },
1114 /* 0x65 */ { NULL, NULL, 0 },
1115 /* 0x66 */ { NULL, NULL, 0 },
1116 /* 0x67 */ { NULL, NULL, 0 },
1117 /* 0x68 */ { NULL, NULL, 0 },
1118 /* 0x69 */ { NULL, NULL, 0 },
1119 /* 0x6a */ { NULL, NULL, 0 },
1120 /* 0x6b */ { NULL, NULL, 0 },
1121 /* 0x6c */ { NULL, NULL, 0 },
1122 /* 0x6d */ { NULL, NULL, 0 },
1123 /* 0x6e */ { NULL, NULL, 0 },
1124 /* 0x6f */ { NULL, NULL, 0 },
1125 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1126 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1127 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1128 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1129 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1130 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1131 /* 0x76 */ { NULL, NULL, 0 },
1132 /* 0x77 */ { NULL, NULL, 0 },
1133 /* 0x78 */ { NULL, NULL, 0 },
1134 /* 0x79 */ { NULL, NULL, 0 },
1135 /* 0x7a */ { NULL, NULL, 0 },
1136 /* 0x7b */ { NULL, NULL, 0 },
1137 /* 0x7c */ { NULL, NULL, 0 },
1138 /* 0x7d */ { NULL, NULL, 0 },
1139 /* 0x7e */ { NULL, NULL, 0 },
1140 /* 0x7f */ { NULL, NULL, 0 },
1141 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1142 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1143 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1144 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1145 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1146 /* 0x85 */ { NULL, NULL, 0 },
1147 /* 0x86 */ { NULL, NULL, 0 },
1148 /* 0x87 */ { NULL, NULL, 0 },
1149 /* 0x88 */ { NULL, NULL, 0 },
1150 /* 0x89 */ { NULL, NULL, 0 },
1151 /* 0x8a */ { NULL, NULL, 0 },
1152 /* 0x8b */ { NULL, NULL, 0 },
1153 /* 0x8c */ { NULL, NULL, 0 },
1154 /* 0x8d */ { NULL, NULL, 0 },
1155 /* 0x8e */ { NULL, NULL, 0 },
1156 /* 0x8f */ { NULL, NULL, 0 },
1157 /* 0x90 */ { NULL, NULL, 0 },
1158 /* 0x91 */ { NULL, NULL, 0 },
1159 /* 0x92 */ { NULL, NULL, 0 },
1160 /* 0x93 */ { NULL, NULL, 0 },
1161 /* 0x94 */ { NULL, NULL, 0 },
1162 /* 0x95 */ { NULL, NULL, 0 },
1163 /* 0x96 */ { NULL, NULL, 0 },
1164 /* 0x97 */ { NULL, NULL, 0 },
1165 /* 0x98 */ { NULL, NULL, 0 },
1166 /* 0x99 */ { NULL, NULL, 0 },
1167 /* 0x9a */ { NULL, NULL, 0 },
1168 /* 0x9b */ { NULL, NULL, 0 },
1169 /* 0x9c */ { NULL, NULL, 0 },
1170 /* 0x9d */ { NULL, NULL, 0 },
1171 /* 0x9e */ { NULL, NULL, 0 },
1172 /* 0x9f */ { NULL, NULL, 0 },
1173 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1174 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1175 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1176 /* 0xa3 */ { NULL, NULL, 0 },
1177 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1178 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1179 /* 0xa6 */ { NULL, NULL, 0 },
1180 /* 0xa7 */ { NULL, NULL, 0 },
1181 /* 0xa8 */ { NULL, NULL, 0 },
1182 /* 0xa9 */ { NULL, NULL, 0 },
1183 /* 0xaa */ { NULL, NULL, 0 },
1184 /* 0xab */ { NULL, NULL, 0 },
1185 /* 0xac */ { NULL, NULL, 0 },
1186 /* 0xad */ { NULL, NULL, 0 },
1187 /* 0xae */ { NULL, NULL, 0 },
1188 /* 0xaf */ { NULL, NULL, 0 },
1189 /* 0xb0 */ { NULL, NULL, 0 },
1190 /* 0xb1 */ { NULL, NULL, 0 },
1191 /* 0xb2 */ { NULL, NULL, 0 },
1192 /* 0xb3 */ { NULL, NULL, 0 },
1193 /* 0xb4 */ { NULL, NULL, 0 },
1194 /* 0xb5 */ { NULL, NULL, 0 },
1195 /* 0xb6 */ { NULL, NULL, 0 },
1196 /* 0xb7 */ { NULL, NULL, 0 },
1197 /* 0xb8 */ { NULL, NULL, 0 },
1198 /* 0xb9 */ { NULL, NULL, 0 },
1199 /* 0xba */ { NULL, NULL, 0 },
1200 /* 0xbb */ { NULL, NULL, 0 },
1201 /* 0xbc */ { NULL, NULL, 0 },
1202 /* 0xbd */ { NULL, NULL, 0 },
1203 /* 0xbe */ { NULL, NULL, 0 },
1204 /* 0xbf */ { NULL, NULL, 0 },
1205 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1206 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1207 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1208 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1209 /* 0xc4 */ { NULL, NULL, 0 },
1210 /* 0xc5 */ { NULL, NULL, 0 },
1211 /* 0xc6 */ { NULL, NULL, 0 },
1212 /* 0xc7 */ { NULL, NULL, 0 },
1213 /* 0xc8 */ { NULL, NULL, 0 },
1214 /* 0xc9 */ { NULL, NULL, 0 },
1215 /* 0xca */ { NULL, NULL, 0 },
1216 /* 0xcb */ { NULL, NULL, 0 },
1217 /* 0xcc */ { NULL, NULL, 0 },
1218 /* 0xcd */ { NULL, NULL, 0 },
1219 /* 0xce */ { NULL, NULL, 0 },
1220 /* 0xcf */ { NULL, NULL, 0 },
1221 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1222 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1223 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1224 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1225 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1226 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1227 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1228 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1229 /* 0xd8 */ { NULL, NULL, 0 },
1230 /* 0xd9 */ { NULL, NULL, 0 },
1231 /* 0xda */ { NULL, NULL, 0 },
1232 /* 0xdb */ { NULL, NULL, 0 },
1233 /* 0xdc */ { NULL, NULL, 0 },
1234 /* 0xdd */ { NULL, NULL, 0 },
1235 /* 0xde */ { NULL, NULL, 0 },
1236 /* 0xdf */ { NULL, NULL, 0 },
1237 /* 0xe0 */ { NULL, NULL, 0 },
1238 /* 0xe1 */ { NULL, NULL, 0 },
1239 /* 0xe2 */ { NULL, NULL, 0 },
1240 /* 0xe3 */ { NULL, NULL, 0 },
1241 /* 0xe4 */ { NULL, NULL, 0 },
1242 /* 0xe5 */ { NULL, NULL, 0 },
1243 /* 0xe6 */ { NULL, NULL, 0 },
1244 /* 0xe7 */ { NULL, NULL, 0 },
1245 /* 0xe8 */ { NULL, NULL, 0 },
1246 /* 0xe9 */ { NULL, NULL, 0 },
1247 /* 0xea */ { NULL, NULL, 0 },
1248 /* 0xeb */ { NULL, NULL, 0 },
1249 /* 0xec */ { NULL, NULL, 0 },
1250 /* 0xed */ { NULL, NULL, 0 },
1251 /* 0xee */ { NULL, NULL, 0 },
1252 /* 0xef */ { NULL, NULL, 0 },
1253 /* 0xf0 */ { NULL, NULL, 0 },
1254 /* 0xf1 */ { NULL, NULL, 0 },
1255 /* 0xf2 */ { NULL, NULL, 0 },
1256 /* 0xf3 */ { NULL, NULL, 0 },
1257 /* 0xf4 */ { NULL, NULL, 0 },
1258 /* 0xf5 */ { NULL, NULL, 0 },
1259 /* 0xf6 */ { NULL, NULL, 0 },
1260 /* 0xf7 */ { NULL, NULL, 0 },
1261 /* 0xf8 */ { NULL, NULL, 0 },
1262 /* 0xf9 */ { NULL, NULL, 0 },
1263 /* 0xfa */ { NULL, NULL, 0 },
1264 /* 0xfb */ { NULL, NULL, 0 },
1265 /* 0xfc */ { NULL, NULL, 0 },
1266 /* 0xfd */ { NULL, NULL, 0 },
1267 /* 0xfe */ { NULL, NULL, 0 },
1268 /* 0xff */ { NULL, NULL, 0 }
1272 /*******************************************************************
1273 allocate and initialize a reply packet
1274 ********************************************************************/
1276 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1277 const char *inbuf, char **outbuf, uint8_t num_words,
1278 uint32_t num_bytes)
1280 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1283 * Protect against integer wrap.
1284 * The SMB layer reply can be up to 0xFFFFFF bytes.
1286 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1287 char *msg;
1288 if (asprintf(&msg, "num_bytes too large: %u",
1289 (unsigned)num_bytes) == -1) {
1290 msg = discard_const_p(char, "num_bytes too large");
1292 smb_panic(msg);
1296 * Here we include the NBT header for now.
1298 *outbuf = talloc_array(mem_ctx, char,
1299 NBT_HDR_SIZE + smb_len);
1300 if (*outbuf == NULL) {
1301 return false;
1304 construct_reply_common(req, inbuf, *outbuf);
1305 srv_set_message(*outbuf, num_words, num_bytes, false);
1307 * Zero out the word area, the caller has to take care of the bcc area
1308 * himself
1310 if (num_words != 0) {
1311 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1314 return true;
1317 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1319 char *outbuf;
1320 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1321 num_bytes)) {
1322 smb_panic("could not allocate output buffer\n");
1324 req->outbuf = (uint8_t *)outbuf;
1328 /*******************************************************************
1329 Dump a packet to a file.
1330 ********************************************************************/
1332 static void smb_dump(const char *name, int type, const char *data)
1334 size_t len;
1335 int fd, i;
1336 char *fname = NULL;
1337 if (DEBUGLEVEL < 50) {
1338 return;
1341 len = smb_len_tcp(data)+4;
1342 for (i=1;i<100;i++) {
1343 fname = talloc_asprintf(talloc_tos(),
1344 "/tmp/%s.%d.%s",
1345 name,
1347 type ? "req" : "resp");
1348 if (fname == NULL) {
1349 return;
1351 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1352 if (fd != -1 || errno != EEXIST) break;
1353 TALLOC_FREE(fname);
1355 if (fd != -1) {
1356 ssize_t ret = write(fd, data, len);
1357 if (ret != len)
1358 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1359 close(fd);
1360 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1362 TALLOC_FREE(fname);
1365 /****************************************************************************
1366 Prepare everything for calling the actual request function, and potentially
1367 call the request function via the "new" interface.
1369 Return False if the "legacy" function needs to be called, everything is
1370 prepared.
1372 Return True if we're done.
1374 I know this API sucks, but it is the one with the least code change I could
1375 find.
1376 ****************************************************************************/
1378 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1380 int flags;
1381 uint64_t session_tag;
1382 connection_struct *conn = NULL;
1383 struct smbd_server_connection *sconn = req->sconn;
1384 NTTIME now = timeval_to_nttime(&req->request_time);
1385 struct smbXsrv_session *session = NULL;
1386 NTSTATUS status;
1388 errno = 0;
1390 if (smb_messages[type].fn == NULL) {
1391 DEBUG(0,("Unknown message type %d!\n",type));
1392 smb_dump("Unknown", 1, (const char *)req->inbuf);
1393 reply_unknown_new(req, type);
1394 return NULL;
1397 flags = smb_messages[type].flags;
1399 /* In share mode security we must ignore the vuid. */
1400 session_tag = req->vuid;
1401 conn = req->conn;
1403 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1404 (int)getpid(), (unsigned long)conn));
1406 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1408 /* Ensure this value is replaced in the incoming packet. */
1409 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1412 * Ensure the correct username is in current_user_info. This is a
1413 * really ugly bugfix for problems with multiple session_setup_and_X's
1414 * being done and allowing %U and %G substitutions to work correctly.
1415 * There is a reason this code is done here, don't move it unless you
1416 * know what you're doing... :-).
1417 * JRA.
1421 * lookup an existing session
1423 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1424 * here, the main check is still in change_to_user()
1426 status = smb1srv_session_lookup(sconn->conn,
1427 session_tag,
1428 now,
1429 &session);
1430 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1431 switch (type) {
1432 case SMBsesssetupX:
1433 status = NT_STATUS_OK;
1434 break;
1435 default:
1436 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1437 (unsigned long long)session_tag,
1438 (unsigned long long)req->mid));
1439 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1440 return conn;
1444 if (session_tag != sconn->conn->last_session_id) {
1445 struct user_struct *vuser = NULL;
1447 sconn->conn->last_session_id = session_tag;
1448 if (session) {
1449 vuser = session->compat;
1451 if (vuser) {
1452 set_current_user_info(
1453 vuser->session_info->unix_info->sanitized_username,
1454 vuser->session_info->unix_info->unix_name,
1455 vuser->session_info->info->domain_name);
1459 /* Does this call need to be run as the connected user? */
1460 if (flags & AS_USER) {
1462 /* Does this call need a valid tree connection? */
1463 if (!conn) {
1465 * Amazingly, the error code depends on the command
1466 * (from Samba4).
1468 if (type == SMBntcreateX) {
1469 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1470 } else {
1471 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1473 return NULL;
1476 if (!change_to_user(conn,session_tag)) {
1477 DEBUG(0, ("Error: Could not change to user. Removing "
1478 "deferred open, mid=%llu.\n",
1479 (unsigned long long)req->mid));
1480 reply_force_doserror(req, ERRSRV, ERRbaduid);
1481 return conn;
1484 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1486 /* Does it need write permission? */
1487 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1488 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1489 return conn;
1492 /* IPC services are limited */
1493 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1494 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1495 return conn;
1497 } else {
1498 /* This call needs to be run as root */
1499 change_to_root_user();
1502 /* load service specific parameters */
1503 if (conn) {
1504 if (req->encrypted) {
1505 conn->encrypted_tid = true;
1506 /* encrypted required from now on. */
1507 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1508 } else if (ENCRYPTION_REQUIRED(conn)) {
1509 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1510 DEBUG(1,("service[%s] requires encryption"
1511 "%s ACCESS_DENIED. mid=%llu\n",
1512 lp_servicename(talloc_tos(), SNUM(conn)),
1513 smb_fn_name(type),
1514 (unsigned long long)req->mid));
1515 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1516 return conn;
1520 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1521 (flags & (AS_USER|DO_CHDIR)
1522 ?True:False))) {
1523 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1524 return conn;
1526 conn->num_smb_operations++;
1530 * Does this protocol need to be run as guest? (Only archane
1531 * messenger service requests have this...)
1533 if (flags & AS_GUEST) {
1534 char *raddr;
1535 bool ok;
1537 if (!change_to_guest()) {
1538 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1539 return conn;
1542 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1543 talloc_tos());
1544 if (raddr == NULL) {
1545 reply_nterror(req, NT_STATUS_NO_MEMORY);
1546 return conn;
1550 * Haven't we checked this in smbd_process already???
1553 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1554 sconn->remote_hostname, raddr);
1555 TALLOC_FREE(raddr);
1557 if (!ok) {
1558 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1559 return conn;
1563 smb_messages[type].fn(req);
1564 return req->conn;
1567 /****************************************************************************
1568 Construct a reply to the incoming packet.
1569 ****************************************************************************/
1571 static void construct_reply(struct smbd_server_connection *sconn,
1572 char *inbuf, int size, size_t unread_bytes,
1573 uint32_t seqnum, bool encrypted,
1574 struct smb_perfcount_data *deferred_pcd)
1576 connection_struct *conn;
1577 struct smb_request *req;
1579 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1580 smb_panic("could not allocate smb_request");
1583 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1584 encrypted, seqnum)) {
1585 exit_server_cleanly("Invalid SMB request");
1588 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1590 /* we popped this message off the queue - keep original perf data */
1591 if (deferred_pcd)
1592 req->pcd = *deferred_pcd;
1593 else {
1594 SMB_PERFCOUNT_START(&req->pcd);
1595 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1596 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1599 conn = switch_message(req->cmd, req);
1601 if (req->outbuf == NULL) {
1602 return;
1605 if (CVAL(req->outbuf,0) == 0) {
1606 show_msg((char *)req->outbuf);
1609 if (!srv_send_smb(req->sconn,
1610 (char *)req->outbuf,
1611 true, req->seqnum+1,
1612 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1613 &req->pcd)) {
1614 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1617 TALLOC_FREE(req);
1619 return;
1622 static void construct_reply_chain(struct smbd_server_connection *sconn,
1623 char *inbuf, int size, uint32_t seqnum,
1624 bool encrypted,
1625 struct smb_perfcount_data *deferred_pcd)
1627 struct smb_request **reqs = NULL;
1628 struct smb_request *req;
1629 unsigned num_reqs;
1630 bool ok;
1632 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1633 seqnum, &reqs, &num_reqs);
1634 if (!ok) {
1635 char errbuf[smb_size];
1636 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1637 __LINE__, __FILE__);
1638 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1639 NULL)) {
1640 exit_server_cleanly("construct_reply_chain: "
1641 "srv_send_smb failed.");
1643 return;
1646 req = reqs[0];
1647 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1649 req->conn = switch_message(req->cmd, req);
1651 if (req->outbuf == NULL) {
1653 * Request has suspended itself, will come
1654 * back here.
1656 return;
1658 smb_request_done(req);
1662 * To be called from an async SMB handler that is potentially chained
1663 * when it is finished for shipping.
1666 void smb_request_done(struct smb_request *req)
1668 struct smb_request **reqs = NULL;
1669 struct smb_request *first_req;
1670 size_t i, num_reqs, next_index;
1671 NTSTATUS status;
1673 if (req->chain == NULL) {
1674 first_req = req;
1675 goto shipit;
1678 reqs = req->chain;
1679 num_reqs = talloc_array_length(reqs);
1681 for (i=0; i<num_reqs; i++) {
1682 if (reqs[i] == req) {
1683 break;
1686 if (i == num_reqs) {
1688 * Invalid chain, should not happen
1690 status = NT_STATUS_INTERNAL_ERROR;
1691 goto error;
1693 next_index = i+1;
1695 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1696 struct smb_request *next = reqs[next_index];
1697 struct smbXsrv_tcon *tcon;
1698 NTTIME now = timeval_to_nttime(&req->request_time);
1700 next->vuid = SVAL(req->outbuf, smb_uid);
1701 next->tid = SVAL(req->outbuf, smb_tid);
1702 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1703 now, &tcon);
1704 if (NT_STATUS_IS_OK(status)) {
1705 req->conn = tcon->compat;
1706 } else {
1707 req->conn = NULL;
1709 next->chain_fsp = req->chain_fsp;
1710 next->inbuf = (uint8_t *)req->inbuf;
1712 req = next;
1713 req->conn = switch_message(req->cmd, req);
1715 if (req->outbuf == NULL) {
1717 * Request has suspended itself, will come
1718 * back here.
1720 return;
1722 next_index += 1;
1725 first_req = reqs[0];
1727 for (i=1; i<next_index; i++) {
1728 bool ok;
1730 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1731 if (!ok) {
1732 status = NT_STATUS_INTERNAL_ERROR;
1733 goto error;
1737 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1738 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1741 * This scary statement intends to set the
1742 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1743 * to the value last_req->outbuf carries
1745 SSVAL(first_req->outbuf, smb_flg2,
1746 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1747 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1750 * Transfer the error codes from the subrequest to the main one
1752 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1753 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1755 _smb_setlen_large(
1756 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1758 shipit:
1759 if (!srv_send_smb(first_req->sconn,
1760 (char *)first_req->outbuf,
1761 true, first_req->seqnum+1,
1762 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1763 &first_req->pcd)) {
1764 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1765 "failed.");
1767 TALLOC_FREE(req); /* non-chained case */
1768 TALLOC_FREE(reqs); /* chained case */
1769 return;
1771 error:
1773 char errbuf[smb_size];
1774 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1775 if (!srv_send_smb(req->sconn, errbuf, true,
1776 req->seqnum+1, req->encrypted,
1777 NULL)) {
1778 exit_server_cleanly("construct_reply_chain: "
1779 "srv_send_smb failed.");
1782 TALLOC_FREE(req); /* non-chained case */
1783 TALLOC_FREE(reqs); /* chained case */
1786 /****************************************************************************
1787 Process an smb from the client
1788 ****************************************************************************/
1789 static void process_smb(struct smbd_server_connection *sconn,
1790 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1791 uint32_t seqnum, bool encrypted,
1792 struct smb_perfcount_data *deferred_pcd)
1794 int msg_type = CVAL(inbuf,0);
1796 DO_PROFILE_INC(smb_count);
1798 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1799 smb_len(inbuf) ) );
1800 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1801 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1803 if (msg_type != NBSSmessage) {
1805 * NetBIOS session request, keepalive, etc.
1807 reply_special(sconn, (char *)inbuf, nread);
1808 goto done;
1811 if (sconn->using_smb2) {
1812 /* At this point we're not really using smb2,
1813 * we make the decision here.. */
1814 if (smbd_is_smb2_header(inbuf, nread)) {
1815 smbd_smb2_first_negprot(sconn, inbuf, nread);
1816 return;
1817 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1818 && CVAL(inbuf, smb_com) != 0x72) {
1819 /* This is a non-negprot SMB1 packet.
1820 Disable SMB2 from now on. */
1821 sconn->using_smb2 = false;
1825 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1826 * so subtract 4 from it. */
1827 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1828 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1829 smb_len(inbuf)));
1831 /* special magic for immediate exit */
1832 if ((nread == 9) &&
1833 (IVAL(inbuf, 4) == 0x74697865) &&
1834 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1835 uint8_t exitcode = CVAL(inbuf, 8);
1836 DEBUG(1, ("Exiting immediately with code %d\n",
1837 (int)exitcode));
1838 exit(exitcode);
1841 exit_server_cleanly("Non-SMB packet");
1844 show_msg((char *)inbuf);
1846 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1847 construct_reply_chain(sconn, (char *)inbuf, nread,
1848 seqnum, encrypted, deferred_pcd);
1849 } else {
1850 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1851 seqnum, encrypted, deferred_pcd);
1854 sconn->trans_num++;
1856 done:
1857 sconn->num_requests++;
1859 /* The timeout_processing function isn't run nearly
1860 often enough to implement 'max log size' without
1861 overrunning the size of the file by many megabytes.
1862 This is especially true if we are running at debug
1863 level 10. Checking every 50 SMBs is a nice
1864 tradeoff of performance vs log file size overrun. */
1866 if ((sconn->num_requests % 50) == 0 &&
1867 need_to_check_log_size()) {
1868 change_to_root_user();
1869 check_log_size();
1873 /****************************************************************************
1874 Return a string containing the function name of a SMB command.
1875 ****************************************************************************/
1877 const char *smb_fn_name(int type)
1879 const char *unknown_name = "SMBunknown";
1881 if (smb_messages[type].name == NULL)
1882 return(unknown_name);
1884 return(smb_messages[type].name);
1887 /****************************************************************************
1888 Helper functions for contruct_reply.
1889 ****************************************************************************/
1891 void add_to_common_flags2(uint32 v)
1893 common_flags2 |= v;
1896 void remove_from_common_flags2(uint32 v)
1898 common_flags2 &= ~v;
1901 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1902 char *outbuf)
1904 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1905 uint16_t out_flags2 = common_flags2;
1907 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1908 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1909 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1911 srv_set_message(outbuf,0,0,false);
1913 SCVAL(outbuf, smb_com, req->cmd);
1914 SIVAL(outbuf,smb_rcls,0);
1915 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1916 SSVAL(outbuf,smb_flg2, out_flags2);
1917 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1918 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1920 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1921 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1922 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1923 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1926 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1928 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1932 * @brief Find the smb_cmd offset of the last command pushed
1933 * @param[in] buf The buffer we're building up
1934 * @retval Where can we put our next andx cmd?
1936 * While chaining requests, the "next" request we're looking at needs to put
1937 * its SMB_Command before the data the previous request already built up added
1938 * to the chain. Find the offset to the place where we have to put our cmd.
1941 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1943 uint8_t cmd;
1944 size_t ofs;
1946 cmd = CVAL(buf, smb_com);
1948 if (!is_andx_req(cmd)) {
1949 return false;
1952 ofs = smb_vwv0;
1954 while (CVAL(buf, ofs) != 0xff) {
1956 if (!is_andx_req(CVAL(buf, ofs))) {
1957 return false;
1961 * ofs is from start of smb header, so add the 4 length
1962 * bytes. The next cmd is right after the wct field.
1964 ofs = SVAL(buf, ofs+2) + 4 + 1;
1966 if (ofs+4 >= talloc_get_size(buf)) {
1967 return false;
1971 *pofs = ofs;
1972 return true;
1976 * @brief Do the smb chaining at a buffer level
1977 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1978 * @param[in] andx_buf Buffer to be appended
1981 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1983 uint8_t smb_command = CVAL(andx_buf, smb_com);
1984 uint8_t wct = CVAL(andx_buf, smb_wct);
1985 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1986 uint32_t num_bytes = smb_buflen(andx_buf);
1987 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1989 uint8_t *outbuf;
1990 size_t old_size, new_size;
1991 size_t ofs;
1992 size_t chain_padding = 0;
1993 size_t andx_cmd_ofs;
1996 old_size = talloc_get_size(*poutbuf);
1998 if ((old_size % 4) != 0) {
2000 * Align the wct field of subsequent requests to a 4-byte
2001 * boundary
2003 chain_padding = 4 - (old_size % 4);
2007 * After the old request comes the new wct field (1 byte), the vwv's
2008 * and the num_bytes field.
2011 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2012 new_size += num_bytes;
2014 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2015 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2016 (unsigned)new_size));
2017 return false;
2020 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2021 if (outbuf == NULL) {
2022 DEBUG(0, ("talloc failed\n"));
2023 return false;
2025 *poutbuf = outbuf;
2027 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2028 DEBUG(1, ("invalid command chain\n"));
2029 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2030 return false;
2033 if (chain_padding != 0) {
2034 memset(outbuf + old_size, 0, chain_padding);
2035 old_size += chain_padding;
2038 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2039 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2041 ofs = old_size;
2044 * Push the chained request:
2046 * wct field
2049 SCVAL(outbuf, ofs, wct);
2050 ofs += 1;
2053 * vwv array
2056 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2059 * HACK ALERT
2061 * Read&X has an offset into its data buffer at
2062 * vwv[6]. reply_read_andx has no idea anymore that it's
2063 * running from within a chain, so we have to fix up the
2064 * offset here.
2066 * Although it looks disgusting at this place, I want to keep
2067 * it here. The alternative would be to push knowledge about
2068 * the andx chain down into read&x again.
2071 if (smb_command == SMBreadX) {
2072 uint8_t *bytes_addr;
2074 if (wct < 7) {
2076 * Invalid read&x response
2078 return false;
2081 bytes_addr = outbuf + ofs /* vwv start */
2082 + sizeof(uint16_t) * wct /* vwv array */
2083 + sizeof(uint16_t); /* bcc */
2085 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2086 bytes_addr - outbuf - 4);
2089 ofs += sizeof(uint16_t) * wct;
2092 * bcc (byte count)
2095 SSVAL(outbuf, ofs, num_bytes);
2096 ofs += sizeof(uint16_t);
2099 * The bytes field
2102 memcpy(outbuf + ofs, bytes, num_bytes);
2104 return true;
2107 bool smb1_is_chain(const uint8_t *buf)
2109 uint8_t cmd, wct, andx_cmd;
2111 cmd = CVAL(buf, smb_com);
2112 if (!is_andx_req(cmd)) {
2113 return false;
2115 wct = CVAL(buf, smb_wct);
2116 if (wct < 2) {
2117 return false;
2119 andx_cmd = CVAL(buf, smb_vwv);
2120 return (andx_cmd != 0xFF);
2123 bool smb1_walk_chain(const uint8_t *buf,
2124 bool (*fn)(uint8_t cmd,
2125 uint8_t wct, const uint16_t *vwv,
2126 uint16_t num_bytes, const uint8_t *bytes,
2127 void *private_data),
2128 void *private_data)
2130 size_t smblen = smb_len(buf);
2131 const char *smb_buf = smb_base(buf);
2132 uint8_t cmd, chain_cmd;
2133 uint8_t wct;
2134 const uint16_t *vwv;
2135 uint16_t num_bytes;
2136 const uint8_t *bytes;
2138 cmd = CVAL(buf, smb_com);
2139 wct = CVAL(buf, smb_wct);
2140 vwv = (const uint16_t *)(buf + smb_vwv);
2141 num_bytes = smb_buflen(buf);
2142 bytes = (uint8_t *)smb_buf_const(buf);
2144 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2145 return false;
2148 if (!is_andx_req(cmd)) {
2149 return true;
2151 if (wct < 2) {
2152 return false;
2155 chain_cmd = CVAL(vwv, 0);
2157 while (chain_cmd != 0xff) {
2158 uint32_t chain_offset; /* uint32_t to avoid overflow */
2159 size_t length_needed;
2160 ptrdiff_t vwv_offset;
2162 chain_offset = SVAL(vwv+1, 0);
2165 * Check if the client tries to fool us. The chain
2166 * offset needs to point beyond the current request in
2167 * the chain, it needs to strictly grow. Otherwise we
2168 * might be tricked into an endless loop always
2169 * processing the same request over and over again. We
2170 * used to assume that vwv and the byte buffer array
2171 * in a chain are always attached, but OS/2 the
2172 * Write&X/Read&X chain puts the Read&X vwv array
2173 * right behind the Write&X vwv chain. The Write&X bcc
2174 * array is put behind the Read&X vwv array. So now we
2175 * check whether the chain offset points strictly
2176 * behind the previous vwv array. req->buf points
2177 * right after the vwv array of the previous
2178 * request. See
2179 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2180 * more information.
2183 vwv_offset = ((const char *)vwv - smb_buf);
2184 if (chain_offset <= vwv_offset) {
2185 return false;
2189 * Next check: Make sure the chain offset does not
2190 * point beyond the overall smb request length.
2193 length_needed = chain_offset+1; /* wct */
2194 if (length_needed > smblen) {
2195 return false;
2199 * Now comes the pointer magic. Goal here is to set up
2200 * vwv and buf correctly again. The chain offset (the
2201 * former vwv[1]) points at the new wct field.
2204 wct = CVAL(smb_buf, chain_offset);
2206 if (is_andx_req(chain_cmd) && (wct < 2)) {
2207 return false;
2211 * Next consistency check: Make the new vwv array fits
2212 * in the overall smb request.
2215 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2216 if (length_needed > smblen) {
2217 return false;
2219 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2222 * Now grab the new byte buffer....
2225 num_bytes = SVAL(vwv+wct, 0);
2228 * .. and check that it fits.
2231 length_needed += num_bytes;
2232 if (length_needed > smblen) {
2233 return false;
2235 bytes = (const uint8_t *)(vwv+wct+1);
2237 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2238 return false;
2241 if (!is_andx_req(chain_cmd)) {
2242 return true;
2244 chain_cmd = CVAL(vwv, 0);
2246 return true;
2249 static bool smb1_chain_length_cb(uint8_t cmd,
2250 uint8_t wct, const uint16_t *vwv,
2251 uint16_t num_bytes, const uint8_t *bytes,
2252 void *private_data)
2254 unsigned *count = (unsigned *)private_data;
2255 *count += 1;
2256 return true;
2259 unsigned smb1_chain_length(const uint8_t *buf)
2261 unsigned count = 0;
2263 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2264 return 0;
2266 return count;
2269 struct smb1_parse_chain_state {
2270 TALLOC_CTX *mem_ctx;
2271 const uint8_t *buf;
2272 struct smbd_server_connection *sconn;
2273 bool encrypted;
2274 uint32_t seqnum;
2276 struct smb_request **reqs;
2277 unsigned num_reqs;
2280 static bool smb1_parse_chain_cb(uint8_t cmd,
2281 uint8_t wct, const uint16_t *vwv,
2282 uint16_t num_bytes, const uint8_t *bytes,
2283 void *private_data)
2285 struct smb1_parse_chain_state *state =
2286 (struct smb1_parse_chain_state *)private_data;
2287 struct smb_request **reqs;
2288 struct smb_request *req;
2289 bool ok;
2291 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2292 struct smb_request *, state->num_reqs+1);
2293 if (reqs == NULL) {
2294 return false;
2296 state->reqs = reqs;
2298 req = talloc(reqs, struct smb_request);
2299 if (req == NULL) {
2300 return false;
2303 ok = init_smb_request(req, state->sconn, state->buf, 0,
2304 state->encrypted, state->seqnum);
2305 if (!ok) {
2306 return false;
2308 req->cmd = cmd;
2309 req->wct = wct;
2310 req->vwv = vwv;
2311 req->buflen = num_bytes;
2312 req->buf = bytes;
2314 reqs[state->num_reqs] = req;
2315 state->num_reqs += 1;
2316 return true;
2319 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2320 struct smbd_server_connection *sconn,
2321 bool encrypted, uint32_t seqnum,
2322 struct smb_request ***reqs, unsigned *num_reqs)
2324 struct smb1_parse_chain_state state;
2325 unsigned i;
2327 state.mem_ctx = mem_ctx;
2328 state.buf = buf;
2329 state.sconn = sconn;
2330 state.encrypted = encrypted;
2331 state.seqnum = seqnum;
2332 state.reqs = NULL;
2333 state.num_reqs = 0;
2335 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2336 TALLOC_FREE(state.reqs);
2337 return false;
2339 for (i=0; i<state.num_reqs; i++) {
2340 state.reqs[i]->chain = state.reqs;
2342 *reqs = state.reqs;
2343 *num_reqs = state.num_reqs;
2344 return true;
2347 /****************************************************************************
2348 Check if services need reloading.
2349 ****************************************************************************/
2351 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2354 if (last_smb_conf_reload_time == 0) {
2355 last_smb_conf_reload_time = t;
2358 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2359 reload_services(sconn, conn_snum_used, true);
2360 last_smb_conf_reload_time = t;
2364 static bool fd_is_readable(int fd)
2366 int ret, revents;
2368 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2370 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2374 static void smbd_server_connection_write_handler(
2375 struct smbd_server_connection *sconn)
2377 /* TODO: make write nonblocking */
2380 static void smbd_server_connection_read_handler(
2381 struct smbd_server_connection *sconn, int fd)
2383 uint8_t *inbuf = NULL;
2384 size_t inbuf_len = 0;
2385 size_t unread_bytes = 0;
2386 bool encrypted = false;
2387 TALLOC_CTX *mem_ctx = talloc_tos();
2388 NTSTATUS status;
2389 uint32_t seqnum;
2391 bool from_client;
2393 if (lp_async_smb_echo_handler()
2394 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2396 * This is the super-ugly hack to prefer the packets
2397 * forwarded by the echo handler over the ones by the
2398 * client directly
2400 fd = sconn->smb1.echo_handler.trusted_fd;
2403 from_client = (sconn->sock == fd);
2405 if (from_client) {
2406 smbd_lock_socket(sconn);
2408 if (!fd_is_readable(fd)) {
2409 DEBUG(10,("the echo listener was faster\n"));
2410 smbd_unlock_socket(sconn);
2411 return;
2415 /* TODO: make this completely nonblocking */
2416 status = receive_smb_talloc(mem_ctx, sconn, fd,
2417 (char **)(void *)&inbuf,
2418 0, /* timeout */
2419 &unread_bytes,
2420 &encrypted,
2421 &inbuf_len, &seqnum,
2422 !from_client /* trusted channel */);
2424 if (from_client) {
2425 smbd_unlock_socket(sconn);
2428 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2429 goto process;
2431 if (NT_STATUS_IS_ERR(status)) {
2432 exit_server_cleanly("failed to receive smb request");
2434 if (!NT_STATUS_IS_OK(status)) {
2435 return;
2438 process:
2439 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2440 seqnum, encrypted, NULL);
2443 static void smbd_server_connection_handler(struct event_context *ev,
2444 struct fd_event *fde,
2445 uint16_t flags,
2446 void *private_data)
2448 struct smbd_server_connection *conn = talloc_get_type(private_data,
2449 struct smbd_server_connection);
2451 if (!NT_STATUS_IS_OK(conn->status)) {
2453 * we're not supposed to do any io
2455 TEVENT_FD_NOT_READABLE(conn->smb1.fde);
2456 TEVENT_FD_NOT_WRITEABLE(conn->smb1.fde);
2457 return;
2460 if (flags & TEVENT_FD_WRITE) {
2461 smbd_server_connection_write_handler(conn);
2462 return;
2464 if (flags & TEVENT_FD_READ) {
2465 smbd_server_connection_read_handler(conn, conn->sock);
2466 return;
2470 static void smbd_server_echo_handler(struct event_context *ev,
2471 struct fd_event *fde,
2472 uint16_t flags,
2473 void *private_data)
2475 struct smbd_server_connection *conn = talloc_get_type(private_data,
2476 struct smbd_server_connection);
2478 if (!NT_STATUS_IS_OK(conn->status)) {
2480 * we're not supposed to do any io
2482 TEVENT_FD_NOT_READABLE(conn->smb1.echo_handler.trusted_fde);
2483 TEVENT_FD_NOT_WRITEABLE(conn->smb1.echo_handler.trusted_fde);
2484 return;
2487 if (flags & TEVENT_FD_WRITE) {
2488 smbd_server_connection_write_handler(conn);
2489 return;
2491 if (flags & TEVENT_FD_READ) {
2492 smbd_server_connection_read_handler(
2493 conn, conn->smb1.echo_handler.trusted_fd);
2494 return;
2498 #ifdef CLUSTER_SUPPORT
2500 struct smbd_release_ip_state {
2501 struct smbd_server_connection *sconn;
2502 struct tevent_immediate *im;
2503 char addr[INET6_ADDRSTRLEN];
2506 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2507 struct tevent_immediate *im,
2508 void *private_data)
2510 struct smbd_release_ip_state *state =
2511 talloc_get_type_abort(private_data,
2512 struct smbd_release_ip_state);
2514 if (!NT_STATUS_EQUAL(state->sconn->status, NT_STATUS_ADDRESS_CLOSED)) {
2516 * smbd_server_connection_terminate() already triggered ?
2518 return;
2521 smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
2524 /****************************************************************************
2525 received when we should release a specific IP
2526 ****************************************************************************/
2527 static bool release_ip(const char *ip, void *priv)
2529 struct smbd_release_ip_state *state =
2530 talloc_get_type_abort(priv,
2531 struct smbd_release_ip_state);
2532 const char *addr = state->addr;
2533 const char *p = addr;
2535 if (!NT_STATUS_IS_OK(state->sconn->status)) {
2536 /* avoid recursion */
2537 return false;
2540 if (strncmp("::ffff:", addr, 7) == 0) {
2541 p = addr + 7;
2544 DEBUG(10, ("Got release IP message for %s, "
2545 "our address is %s\n", ip, p));
2547 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2548 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2549 ip));
2551 * With SMB2 we should do a clean disconnect,
2552 * the previous_session_id in the session setup
2553 * will cleanup the old session, tcons and opens.
2555 * A clean disconnect is needed in order to support
2556 * durable handles.
2558 * Note: typically this is never triggered
2559 * as we got a TCP RST (triggered by ctdb event scripts)
2560 * before we get CTDB_SRVID_RELEASE_IP.
2562 * We used to call _exit(1) here, but as this was mostly never
2563 * triggered and has implication on our process model,
2564 * we can just use smbd_server_connection_terminate()
2565 * (also for SMB1).
2567 * We don't call smbd_server_connection_terminate() directly
2568 * as we might be called from within ctdbd_migrate(),
2569 * we need to defer our action to the next event loop
2571 tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
2572 smbd_release_ip_immediate, state);
2575 * Make sure we don't get any io on the connection.
2577 state->sconn->status = NT_STATUS_ADDRESS_CLOSED;
2578 return true;
2581 return false;
2584 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2585 struct sockaddr_storage *srv,
2586 struct sockaddr_storage *clnt)
2588 struct smbd_release_ip_state *state;
2589 struct ctdbd_connection *cconn;
2591 cconn = messaging_ctdbd_connection();
2592 if (cconn == NULL) {
2593 return NT_STATUS_NO_MEMORY;
2596 state = talloc_zero(sconn, struct smbd_release_ip_state);
2597 if (state == NULL) {
2598 return NT_STATUS_NO_MEMORY;
2600 state->sconn = sconn;
2601 state->im = tevent_create_immediate(state);
2602 if (state->im == NULL) {
2603 return NT_STATUS_NO_MEMORY;
2605 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2606 return NT_STATUS_NO_MEMORY;
2609 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2612 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2613 struct sockaddr_storage *client)
2615 socklen_t length;
2616 length = sizeof(*server);
2617 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2618 return -1;
2620 length = sizeof(*client);
2621 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2622 return -1;
2624 return 0;
2626 #endif
2629 * Send keepalive packets to our client
2631 static bool keepalive_fn(const struct timeval *now, void *private_data)
2633 struct smbd_server_connection *sconn = talloc_get_type_abort(
2634 private_data, struct smbd_server_connection);
2635 bool ret;
2637 if (sconn->using_smb2) {
2638 /* Don't do keepalives on an SMB2 connection. */
2639 return false;
2642 smbd_lock_socket(sconn);
2643 ret = send_keepalive(sconn->sock);
2644 smbd_unlock_socket(sconn);
2646 if (!ret) {
2647 char addr[INET6_ADDRSTRLEN];
2649 * Try and give an error message saying what
2650 * client failed.
2652 DEBUG(0, ("send_keepalive failed for client %s. "
2653 "Error %s - exiting\n",
2654 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2655 strerror(errno)));
2656 return False;
2658 return True;
2662 * Do the recurring check if we're idle
2664 static bool deadtime_fn(const struct timeval *now, void *private_data)
2666 struct smbd_server_connection *sconn =
2667 (struct smbd_server_connection *)private_data;
2669 if ((conn_num_open(sconn) == 0)
2670 || (conn_idle_all(sconn, now->tv_sec))) {
2671 DEBUG( 2, ( "Closing idle connection\n" ) );
2672 messaging_send(sconn->msg_ctx,
2673 messaging_server_id(sconn->msg_ctx),
2674 MSG_SHUTDOWN, &data_blob_null);
2675 return False;
2678 return True;
2682 * Do the recurring log file and smb.conf reload checks.
2685 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2687 struct smbd_server_connection *sconn = talloc_get_type_abort(
2688 private_data, struct smbd_server_connection);
2690 DEBUG(5, ("housekeeping\n"));
2692 change_to_root_user();
2694 /* update printer queue caches if necessary */
2695 update_monitored_printq_cache(sconn->msg_ctx);
2697 /* check if we need to reload services */
2698 check_reload(sconn, time_mono(NULL));
2701 * Force a log file check.
2703 force_check_log_size();
2704 check_log_size();
2705 return true;
2709 * Read an smb packet in the echo handler child, giving the parent
2710 * smbd one second to react once the socket becomes readable.
2713 struct smbd_echo_read_state {
2714 struct tevent_context *ev;
2715 struct smbd_server_connection *sconn;
2717 char *buf;
2718 size_t buflen;
2719 uint32_t seqnum;
2722 static void smbd_echo_read_readable(struct tevent_req *subreq);
2723 static void smbd_echo_read_waited(struct tevent_req *subreq);
2725 static struct tevent_req *smbd_echo_read_send(
2726 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2727 struct smbd_server_connection *sconn)
2729 struct tevent_req *req, *subreq;
2730 struct smbd_echo_read_state *state;
2732 req = tevent_req_create(mem_ctx, &state,
2733 struct smbd_echo_read_state);
2734 if (req == NULL) {
2735 return NULL;
2737 state->ev = ev;
2738 state->sconn = sconn;
2740 subreq = wait_for_read_send(state, ev, sconn->sock);
2741 if (tevent_req_nomem(subreq, req)) {
2742 return tevent_req_post(req, ev);
2744 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2745 return req;
2748 static void smbd_echo_read_readable(struct tevent_req *subreq)
2750 struct tevent_req *req = tevent_req_callback_data(
2751 subreq, struct tevent_req);
2752 struct smbd_echo_read_state *state = tevent_req_data(
2753 req, struct smbd_echo_read_state);
2754 bool ok;
2755 int err;
2757 ok = wait_for_read_recv(subreq, &err);
2758 TALLOC_FREE(subreq);
2759 if (!ok) {
2760 tevent_req_nterror(req, map_nt_error_from_unix(err));
2761 return;
2765 * Give the parent smbd one second to step in
2768 subreq = tevent_wakeup_send(
2769 state, state->ev, timeval_current_ofs(1, 0));
2770 if (tevent_req_nomem(subreq, req)) {
2771 return;
2773 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2776 static void smbd_echo_read_waited(struct tevent_req *subreq)
2778 struct tevent_req *req = tevent_req_callback_data(
2779 subreq, struct tevent_req);
2780 struct smbd_echo_read_state *state = tevent_req_data(
2781 req, struct smbd_echo_read_state);
2782 struct smbd_server_connection *sconn = state->sconn;
2783 bool ok;
2784 NTSTATUS status;
2785 size_t unread = 0;
2786 bool encrypted;
2788 ok = tevent_wakeup_recv(subreq);
2789 TALLOC_FREE(subreq);
2790 if (!ok) {
2791 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2792 return;
2795 ok = smbd_lock_socket_internal(sconn);
2796 if (!ok) {
2797 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2798 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2799 return;
2802 if (!fd_is_readable(sconn->sock)) {
2803 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2804 (int)getpid()));
2806 ok = smbd_unlock_socket_internal(sconn);
2807 if (!ok) {
2808 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2809 DEBUG(1, ("%s: failed to unlock socket\n",
2810 __location__));
2811 return;
2814 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2815 if (tevent_req_nomem(subreq, req)) {
2816 return;
2818 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2819 return;
2822 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2823 0 /* timeout */,
2824 &unread,
2825 &encrypted,
2826 &state->buflen,
2827 &state->seqnum,
2828 false /* trusted_channel*/);
2830 if (tevent_req_nterror(req, status)) {
2831 tevent_req_nterror(req, status);
2832 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2833 (int)getpid(), nt_errstr(status)));
2834 return;
2837 ok = smbd_unlock_socket_internal(sconn);
2838 if (!ok) {
2839 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2840 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2841 return;
2843 tevent_req_done(req);
2846 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2847 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2849 struct smbd_echo_read_state *state = tevent_req_data(
2850 req, struct smbd_echo_read_state);
2851 NTSTATUS status;
2853 if (tevent_req_is_nterror(req, &status)) {
2854 return status;
2856 *pbuf = talloc_move(mem_ctx, &state->buf);
2857 *pbuflen = state->buflen;
2858 *pseqnum = state->seqnum;
2859 return NT_STATUS_OK;
2862 struct smbd_echo_state {
2863 struct tevent_context *ev;
2864 struct iovec *pending;
2865 struct smbd_server_connection *sconn;
2866 int parent_pipe;
2868 struct tevent_fd *parent_fde;
2870 struct tevent_req *write_req;
2873 static void smbd_echo_writer_done(struct tevent_req *req);
2875 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2877 int num_pending;
2879 if (state->write_req != NULL) {
2880 return;
2883 num_pending = talloc_array_length(state->pending);
2884 if (num_pending == 0) {
2885 return;
2888 state->write_req = writev_send(state, state->ev, NULL,
2889 state->parent_pipe, false,
2890 state->pending, num_pending);
2891 if (state->write_req == NULL) {
2892 DEBUG(1, ("writev_send failed\n"));
2893 exit(1);
2896 talloc_steal(state->write_req, state->pending);
2897 state->pending = NULL;
2899 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2900 state);
2903 static void smbd_echo_writer_done(struct tevent_req *req)
2905 struct smbd_echo_state *state = tevent_req_callback_data(
2906 req, struct smbd_echo_state);
2907 ssize_t written;
2908 int err;
2910 written = writev_recv(req, &err);
2911 TALLOC_FREE(req);
2912 state->write_req = NULL;
2913 if (written == -1) {
2914 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2915 exit(1);
2917 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2918 smbd_echo_activate_writer(state);
2921 static bool smbd_echo_reply(struct smbd_echo_state *state,
2922 uint8_t *inbuf, size_t inbuf_len,
2923 uint32_t seqnum)
2925 struct smb_request req;
2926 uint16_t num_replies;
2927 char *outbuf;
2928 bool ok;
2930 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2931 DEBUG(10, ("Got netbios keepalive\n"));
2933 * Just swallow it
2935 return true;
2938 if (inbuf_len < smb_size) {
2939 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2940 return false;
2942 if (!valid_smb_header(state->sconn, inbuf)) {
2943 DEBUG(10, ("Got invalid SMB header\n"));
2944 return false;
2947 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2948 seqnum)) {
2949 return false;
2951 req.inbuf = inbuf;
2953 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2954 smb_messages[req.cmd].name
2955 ? smb_messages[req.cmd].name : "unknown"));
2957 if (req.cmd != SMBecho) {
2958 return false;
2960 if (req.wct < 1) {
2961 return false;
2964 num_replies = SVAL(req.vwv+0, 0);
2965 if (num_replies != 1) {
2966 /* Not a Windows "Hey, you're still there?" request */
2967 return false;
2970 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2971 1, req.buflen)) {
2972 DEBUG(10, ("create_outbuf failed\n"));
2973 return false;
2975 req.outbuf = (uint8_t *)outbuf;
2977 SSVAL(req.outbuf, smb_vwv0, num_replies);
2979 if (req.buflen > 0) {
2980 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2983 ok = srv_send_smb(req.sconn,
2984 (char *)outbuf,
2985 true, seqnum+1,
2986 false, &req.pcd);
2987 TALLOC_FREE(outbuf);
2988 if (!ok) {
2989 exit(1);
2992 return true;
2995 static void smbd_echo_exit(struct tevent_context *ev,
2996 struct tevent_fd *fde, uint16_t flags,
2997 void *private_data)
2999 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3000 exit(0);
3003 static void smbd_echo_got_packet(struct tevent_req *req);
3005 static void smbd_echo_loop(struct smbd_server_connection *sconn,
3006 int parent_pipe)
3008 struct smbd_echo_state *state;
3009 struct tevent_req *read_req;
3011 state = talloc_zero(sconn, struct smbd_echo_state);
3012 if (state == NULL) {
3013 DEBUG(1, ("talloc failed\n"));
3014 return;
3016 state->sconn = sconn;
3017 state->parent_pipe = parent_pipe;
3018 state->ev = s3_tevent_context_init(state);
3019 if (state->ev == NULL) {
3020 DEBUG(1, ("tevent_context_init failed\n"));
3021 TALLOC_FREE(state);
3022 return;
3024 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3025 TEVENT_FD_READ, smbd_echo_exit,
3026 state);
3027 if (state->parent_fde == NULL) {
3028 DEBUG(1, ("tevent_add_fd failed\n"));
3029 TALLOC_FREE(state);
3030 return;
3033 read_req = smbd_echo_read_send(state, state->ev, sconn);
3034 if (read_req == NULL) {
3035 DEBUG(1, ("smbd_echo_read_send failed\n"));
3036 TALLOC_FREE(state);
3037 return;
3039 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3041 while (true) {
3042 if (tevent_loop_once(state->ev) == -1) {
3043 DEBUG(1, ("tevent_loop_once failed: %s\n",
3044 strerror(errno)));
3045 break;
3048 TALLOC_FREE(state);
3051 static void smbd_echo_got_packet(struct tevent_req *req)
3053 struct smbd_echo_state *state = tevent_req_callback_data(
3054 req, struct smbd_echo_state);
3055 NTSTATUS status;
3056 char *buf = NULL;
3057 size_t buflen = 0;
3058 uint32_t seqnum = 0;
3059 bool reply;
3061 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3062 TALLOC_FREE(req);
3063 if (!NT_STATUS_IS_OK(status)) {
3064 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3065 nt_errstr(status)));
3066 exit(1);
3069 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3070 if (!reply) {
3071 size_t num_pending;
3072 struct iovec *tmp;
3073 struct iovec *iov;
3075 num_pending = talloc_array_length(state->pending);
3076 tmp = talloc_realloc(state, state->pending, struct iovec,
3077 num_pending+1);
3078 if (tmp == NULL) {
3079 DEBUG(1, ("talloc_realloc failed\n"));
3080 exit(1);
3082 state->pending = tmp;
3084 if (buflen >= smb_size) {
3086 * place the seqnum in the packet so that the main process
3087 * can reply with signing
3089 SIVAL(buf, smb_ss_field, seqnum);
3090 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3093 iov = &state->pending[num_pending];
3094 iov->iov_base = talloc_move(state->pending, &buf);
3095 iov->iov_len = buflen;
3097 DEBUG(10,("echo_handler[%d]: forward to main\n",
3098 (int)getpid()));
3099 smbd_echo_activate_writer(state);
3102 req = smbd_echo_read_send(state, state->ev, state->sconn);
3103 if (req == NULL) {
3104 DEBUG(1, ("smbd_echo_read_send failed\n"));
3105 exit(1);
3107 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3112 * Handle SMBecho requests in a forked child process
3114 bool fork_echo_handler(struct smbd_server_connection *sconn)
3116 int listener_pipe[2];
3117 int res;
3118 pid_t child;
3120 res = pipe(listener_pipe);
3121 if (res == -1) {
3122 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3123 return false;
3125 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
3126 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3127 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3128 goto fail;
3131 child = fork();
3132 if (child == 0) {
3133 NTSTATUS status;
3135 close(listener_pipe[0]);
3136 set_blocking(listener_pipe[1], false);
3138 status = reinit_after_fork(sconn->msg_ctx,
3139 sconn->ev_ctx,
3140 false);
3141 if (!NT_STATUS_IS_OK(status)) {
3142 DEBUG(1, ("reinit_after_fork failed: %s\n",
3143 nt_errstr(status)));
3144 exit(1);
3146 smbd_echo_loop(sconn, listener_pipe[1]);
3147 exit(0);
3149 close(listener_pipe[1]);
3150 listener_pipe[1] = -1;
3151 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3153 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), child));
3156 * Without smb signing this is the same as the normal smbd
3157 * listener. This needs to change once signing comes in.
3159 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3160 sconn,
3161 sconn->smb1.echo_handler.trusted_fd,
3162 TEVENT_FD_READ,
3163 smbd_server_echo_handler,
3164 sconn);
3165 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3166 DEBUG(1, ("event_add_fd failed\n"));
3167 goto fail;
3170 return true;
3172 fail:
3173 if (listener_pipe[0] != -1) {
3174 close(listener_pipe[0]);
3176 if (listener_pipe[1] != -1) {
3177 close(listener_pipe[1]);
3179 sconn->smb1.echo_handler.trusted_fd = -1;
3180 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3181 close(sconn->smb1.echo_handler.socket_lock_fd);
3183 sconn->smb1.echo_handler.trusted_fd = -1;
3184 sconn->smb1.echo_handler.socket_lock_fd = -1;
3185 return false;
3188 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3190 while (user) {
3191 if (user->session_info &&
3192 (user->session_info->unix_token->uid == uid)) {
3193 return true;
3195 user = user->next;
3197 return false;
3200 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3202 while (user) {
3203 if (user->session_info != NULL) {
3204 int i;
3205 struct security_unix_token *utok;
3207 utok = user->session_info->unix_token;
3208 if (utok->gid == gid) {
3209 return true;
3211 for(i=0; i<utok->ngroups; i++) {
3212 if (utok->groups[i] == gid) {
3213 return true;
3217 user = user->next;
3219 return false;
3222 static bool sid_in_use(const struct user_struct *user,
3223 const struct dom_sid *psid)
3225 while (user) {
3226 struct security_token *tok;
3228 if (user->session_info == NULL) {
3229 continue;
3231 tok = user->session_info->security_token;
3232 if (tok == NULL) {
3234 * Not sure session_info->security_token can
3235 * ever be NULL. This check might be not
3236 * necessary.
3238 continue;
3240 if (security_token_has_sid(tok, psid)) {
3241 return true;
3243 user = user->next;
3245 return false;
3248 static bool id_in_use(const struct user_struct *user,
3249 const struct id_cache_ref *id)
3251 switch(id->type) {
3252 case UID:
3253 return uid_in_use(user, id->id.uid);
3254 case GID:
3255 return gid_in_use(user, id->id.gid);
3256 case SID:
3257 return sid_in_use(user, &id->id.sid);
3258 default:
3259 break;
3261 return false;
3264 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3265 void *private_data,
3266 uint32_t msg_type,
3267 struct server_id server_id,
3268 DATA_BLOB* data)
3270 const char *msg = (data && data->data)
3271 ? (const char *)data->data : "<NULL>";
3272 struct id_cache_ref id;
3273 struct smbd_server_connection *sconn =
3274 talloc_get_type_abort(private_data,
3275 struct smbd_server_connection);
3277 if (!id_cache_ref_parse(msg, &id)) {
3278 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3279 return;
3282 if (id_in_use(sconn->users, &id)) {
3283 exit_server_cleanly(msg);
3285 id_cache_delete_from_cache(&id);
3288 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3289 enum protocol_types protocol)
3291 NTSTATUS status;
3293 set_Protocol(protocol);
3294 conn->protocol = protocol;
3296 if (protocol >= PROTOCOL_SMB2_02) {
3297 status = smb2srv_session_table_init(conn);
3298 if (!NT_STATUS_IS_OK(status)) {
3299 return status;
3302 status = smb2srv_open_table_init(conn);
3303 if (!NT_STATUS_IS_OK(status)) {
3304 return status;
3306 } else {
3307 status = smb1srv_session_table_init(conn);
3308 if (!NT_STATUS_IS_OK(status)) {
3309 return status;
3312 status = smb1srv_tcon_table_init(conn);
3313 if (!NT_STATUS_IS_OK(status)) {
3314 return status;
3317 status = smb1srv_open_table_init(conn);
3318 if (!NT_STATUS_IS_OK(status)) {
3319 return status;
3323 return NT_STATUS_OK;
3326 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3327 void *private_data)
3329 struct smbXsrv_connection *conn =
3330 talloc_get_type_abort(private_data,
3331 struct smbXsrv_connection);
3333 switch (point) {
3334 case TEVENT_TRACE_BEFORE_WAIT:
3336 * This just removes compiler warning
3337 * without profile support
3339 conn->smbd_idle_profstamp = 0;
3340 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3341 break;
3342 case TEVENT_TRACE_AFTER_WAIT:
3343 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3344 break;
3348 /****************************************************************************
3349 Process commands from the client
3350 ****************************************************************************/
3352 void smbd_process(struct tevent_context *ev_ctx,
3353 struct messaging_context *msg_ctx,
3354 int sock_fd,
3355 bool interactive)
3357 TALLOC_CTX *frame = talloc_stackframe();
3358 struct smbXsrv_connection *conn;
3359 struct smbd_server_connection *sconn;
3360 struct sockaddr_storage ss;
3361 struct sockaddr *sa = NULL;
3362 socklen_t sa_socklen;
3363 struct tsocket_address *local_address = NULL;
3364 struct tsocket_address *remote_address = NULL;
3365 const char *locaddr = NULL;
3366 const char *remaddr = NULL;
3367 char *rhost;
3368 int ret;
3369 int tmp;
3371 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3372 if (conn == NULL) {
3373 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3374 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3377 conn->ev_ctx = ev_ctx;
3378 conn->msg_ctx = msg_ctx;
3380 sconn = talloc_zero(conn, struct smbd_server_connection);
3381 if (!sconn) {
3382 exit_server("failed to create smbd_server_connection");
3385 conn->sconn = sconn;
3386 sconn->conn = conn;
3389 * TODO: remove this...:-)
3391 global_smbXsrv_connection = conn;
3393 sconn->ev_ctx = ev_ctx;
3394 sconn->msg_ctx = msg_ctx;
3395 sconn->sock = sock_fd;
3396 sconn->smb1.echo_handler.trusted_fd = -1;
3397 sconn->smb1.echo_handler.socket_lock_fd = -1;
3399 if (!interactive) {
3400 smbd_setup_sig_term_handler(sconn);
3401 smbd_setup_sig_hup_handler(sconn);
3403 if (!serverid_register(messaging_server_id(msg_ctx),
3404 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3405 |FLAG_MSG_DBWRAP
3406 |FLAG_MSG_PRINT_GENERAL)) {
3407 exit_server_cleanly("Could not register myself in "
3408 "serverid.tdb");
3412 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3414 * We're not making the decision here,
3415 * we're just allowing the client
3416 * to decide between SMB1 and SMB2
3417 * with the first negprot
3418 * packet.
3420 sconn->using_smb2 = true;
3423 /* Ensure child is set to blocking mode */
3424 set_blocking(sconn->sock,True);
3426 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3427 set_socket_options(sconn->sock, lp_socket_options());
3429 sa = (struct sockaddr *)(void *)&ss;
3430 sa_socklen = sizeof(ss);
3431 ret = getpeername(sconn->sock, sa, &sa_socklen);
3432 if (ret != 0) {
3433 int level = (errno == ENOTCONN)?2:0;
3434 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3435 exit_server_cleanly("getpeername() failed.\n");
3437 ret = tsocket_address_bsd_from_sockaddr(sconn,
3438 sa, sa_socklen,
3439 &remote_address);
3440 if (ret != 0) {
3441 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3442 __location__, strerror(errno)));
3443 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3446 sa = (struct sockaddr *)(void *)&ss;
3447 sa_socklen = sizeof(ss);
3448 ret = getsockname(sconn->sock, sa, &sa_socklen);
3449 if (ret != 0) {
3450 int level = (errno == ENOTCONN)?2:0;
3451 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3452 exit_server_cleanly("getsockname() failed.\n");
3454 ret = tsocket_address_bsd_from_sockaddr(sconn,
3455 sa, sa_socklen,
3456 &local_address);
3457 if (ret != 0) {
3458 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3459 __location__, strerror(errno)));
3460 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3463 sconn->local_address = local_address;
3464 sconn->remote_address = remote_address;
3466 if (tsocket_address_is_inet(local_address, "ip")) {
3467 locaddr = tsocket_address_inet_addr_string(
3468 sconn->local_address,
3469 talloc_tos());
3470 if (locaddr == NULL) {
3471 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3472 __location__, strerror(errno)));
3473 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3475 } else {
3476 locaddr = "0.0.0.0";
3479 if (tsocket_address_is_inet(remote_address, "ip")) {
3480 remaddr = tsocket_address_inet_addr_string(
3481 sconn->remote_address,
3482 talloc_tos());
3483 if (remaddr == NULL) {
3484 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3485 __location__, strerror(errno)));
3486 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3488 } else {
3489 remaddr = "0.0.0.0";
3492 /* this is needed so that we get decent entries
3493 in smbstatus for port 445 connects */
3494 set_remote_machine_name(remaddr, false);
3495 reload_services(sconn, conn_snum_used, true);
3498 * Before the first packet, check the global hosts allow/ hosts deny
3499 * parameters before doing any parsing of packets passed to us by the
3500 * client. This prevents attacks on our parsing code from hosts not in
3501 * the hosts allow list.
3504 ret = get_remote_hostname(remote_address,
3505 &rhost,
3506 talloc_tos());
3507 if (ret < 0) {
3508 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3509 __location__, strerror(errno)));
3510 exit_server_cleanly("get_remote_hostname failed.\n");
3512 if (strequal(rhost, "UNKNOWN")) {
3513 rhost = talloc_strdup(talloc_tos(), remaddr);
3515 sconn->remote_hostname = talloc_move(sconn, &rhost);
3517 sub_set_socket_ids(remaddr,
3518 sconn->remote_hostname,
3519 locaddr);
3521 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3522 sconn->remote_hostname,
3523 remaddr)) {
3525 * send a negative session response "not listening on calling
3526 * name"
3528 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3529 DEBUG( 1, ("Connection denied from %s to %s\n",
3530 tsocket_address_string(remote_address, talloc_tos()),
3531 tsocket_address_string(local_address, talloc_tos())));
3532 (void)srv_send_smb(sconn,(char *)buf, false,
3533 0, false, NULL);
3534 exit_server_cleanly("connection denied");
3537 DEBUG(10, ("Connection allowed from %s to %s\n",
3538 tsocket_address_string(remote_address, talloc_tos()),
3539 tsocket_address_string(local_address, talloc_tos())));
3541 if (lp_preload_modules()) {
3542 smb_load_modules(lp_preload_modules());
3545 smb_perfcount_init();
3547 if (!init_account_policy()) {
3548 exit_server("Could not open account policy tdb.\n");
3551 if (*lp_rootdir(talloc_tos())) {
3552 if (chroot(lp_rootdir(talloc_tos())) != 0) {
3553 DEBUG(0,("Failed to change root to %s\n",
3554 lp_rootdir(talloc_tos())));
3555 exit_server("Failed to chroot()");
3557 if (chdir("/") == -1) {
3558 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir(talloc_tos())));
3559 exit_server("Failed to chroot()");
3561 DEBUG(0,("Changed root to %s\n", lp_rootdir(talloc_tos())));
3564 if (!srv_init_signing(sconn)) {
3565 exit_server("Failed to init smb_signing");
3568 if (!file_init(sconn)) {
3569 exit_server("file_init() failed");
3572 /* Setup oplocks */
3573 if (!init_oplocks(sconn))
3574 exit_server("Failed to init oplocks");
3576 /* register our message handlers */
3577 messaging_register(sconn->msg_ctx, sconn,
3578 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3579 messaging_register(sconn->msg_ctx, sconn,
3580 MSG_SMB_CLOSE_FILE, msg_close_file);
3581 messaging_register(sconn->msg_ctx, sconn,
3582 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3584 id_cache_register_msgs(sconn->msg_ctx);
3585 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3586 messaging_register(sconn->msg_ctx, sconn,
3587 ID_CACHE_KILL, smbd_id_cache_kill);
3589 messaging_deregister(sconn->msg_ctx,
3590 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3591 messaging_register(sconn->msg_ctx, sconn,
3592 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3595 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3596 * MSGs to all child processes
3598 messaging_deregister(sconn->msg_ctx,
3599 MSG_DEBUG, NULL);
3600 messaging_register(sconn->msg_ctx, NULL,
3601 MSG_DEBUG, debug_message);
3603 if ((lp_keepalive() != 0)
3604 && !(event_add_idle(ev_ctx, NULL,
3605 timeval_set(lp_keepalive(), 0),
3606 "keepalive", keepalive_fn,
3607 sconn))) {
3608 DEBUG(0, ("Could not add keepalive event\n"));
3609 exit(1);
3612 if (!(event_add_idle(ev_ctx, NULL,
3613 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3614 "deadtime", deadtime_fn, sconn))) {
3615 DEBUG(0, ("Could not add deadtime event\n"));
3616 exit(1);
3619 if (!(event_add_idle(ev_ctx, NULL,
3620 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3621 "housekeeping", housekeeping_fn, sconn))) {
3622 DEBUG(0, ("Could not add housekeeping event\n"));
3623 exit(1);
3626 #ifdef CLUSTER_SUPPORT
3628 if (lp_clustering()) {
3630 * We need to tell ctdb about our client's TCP
3631 * connection, so that for failover ctdbd can send
3632 * tickle acks, triggering a reconnection by the
3633 * client.
3636 struct sockaddr_storage srv, clnt;
3638 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3639 NTSTATUS status;
3640 status = smbd_register_ips(sconn, &srv, &clnt);
3641 if (!NT_STATUS_IS_OK(status)) {
3642 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3643 nt_errstr(status)));
3645 } else
3647 DEBUG(0,("Unable to get tcp info for "
3648 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3649 strerror(errno)));
3653 #endif
3655 sconn->nbt.got_session = false;
3657 tmp = lp_max_xmit();
3658 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3659 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3661 sconn->smb1.negprot.max_recv = tmp;
3663 sconn->smb1.sessions.done_sesssetup = false;
3664 sconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3666 if (!init_dptrs(sconn)) {
3667 exit_server("init_dptrs() failed");
3670 sconn->smb1.fde = event_add_fd(ev_ctx,
3671 sconn,
3672 sconn->sock,
3673 EVENT_FD_READ,
3674 smbd_server_connection_handler,
3675 sconn);
3676 if (!sconn->smb1.fde) {
3677 exit_server("failed to create smbd_server_connection fde");
3680 sconn->conn->local_address = sconn->local_address;
3681 sconn->conn->remote_address = sconn->remote_address;
3682 sconn->conn->remote_hostname = sconn->remote_hostname;
3683 sconn->conn->protocol = PROTOCOL_NONE;
3685 TALLOC_FREE(frame);
3687 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3689 while (True) {
3690 frame = talloc_stackframe_pool(8192);
3692 errno = 0;
3693 if (tevent_loop_once(ev_ctx) == -1) {
3694 if (errno != EINTR) {
3695 DEBUG(3, ("tevent_loop_once failed: %s,"
3696 " exiting\n", strerror(errno) ));
3697 break;
3701 TALLOC_FREE(frame);
3704 exit_server_cleanly(NULL);
3707 bool req_is_in_chain(const struct smb_request *req)
3709 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3711 * We're right now handling a subsequent request, so we must
3712 * be in a chain
3714 return true;
3717 if (!is_andx_req(req->cmd)) {
3718 return false;
3721 if (req->wct < 2) {
3723 * Okay, an illegal request, but definitely not chained :-)
3725 return false;
3728 return (CVAL(req->vwv+0, 0) != 0xFF);