smbd: Fix a const warning
[Samba/bjacke.git] / source3 / smbd / process.c
blob484832b20063a260315168a7d3b9b283b1be048e
1 /*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
42 #include "serverid.h"
44 /* Internal message queue for deferred opens. */
45 struct pending_message_list {
46 struct pending_message_list *next, *prev;
47 struct timeval request_time; /* When was this first issued? */
48 struct smbd_server_connection *sconn;
49 struct tevent_timer *te;
50 struct smb_perfcount_data pcd;
51 uint32_t seqnum;
52 bool encrypted;
53 bool processed;
54 DATA_BLOB buf;
55 DATA_BLOB private_data;
58 static void construct_reply_common(struct smb_request *req, const char *inbuf,
59 char *outbuf);
60 static struct pending_message_list *get_deferred_open_message_smb(
61 struct smbd_server_connection *sconn, uint64_t mid);
62 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
64 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
66 bool ok;
68 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
69 return true;
72 sconn->smb1.echo_handler.ref_count++;
74 if (sconn->smb1.echo_handler.ref_count > 1) {
75 return true;
78 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
80 do {
81 ok = fcntl_lock(
82 sconn->smb1.echo_handler.socket_lock_fd,
83 F_SETLKW, 0, 0, F_WRLCK);
84 } while (!ok && (errno == EINTR));
86 if (!ok) {
87 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
88 return false;
91 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
93 return true;
96 void smbd_lock_socket(struct smbd_server_connection *sconn)
98 if (!smbd_lock_socket_internal(sconn)) {
99 exit_server_cleanly("failed to lock socket");
103 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
105 bool ok;
107 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
108 return true;
111 sconn->smb1.echo_handler.ref_count--;
113 if (sconn->smb1.echo_handler.ref_count > 0) {
114 return true;
117 do {
118 ok = fcntl_lock(
119 sconn->smb1.echo_handler.socket_lock_fd,
120 F_SETLKW, 0, 0, F_UNLCK);
121 } while (!ok && (errno == EINTR));
123 if (!ok) {
124 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
125 return false;
128 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
130 return true;
133 void smbd_unlock_socket(struct smbd_server_connection *sconn)
135 if (!smbd_unlock_socket_internal(sconn)) {
136 exit_server_cleanly("failed to unlock socket");
140 /* Accessor function for smb_read_error for smbd functions. */
142 /****************************************************************************
143 Send an smb to a fd.
144 ****************************************************************************/
146 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
147 bool do_signing, uint32_t seqnum,
148 bool do_encrypt,
149 struct smb_perfcount_data *pcd)
151 size_t len = 0;
152 ssize_t ret;
153 char *buf_out = buffer;
155 smbd_lock_socket(sconn);
157 if (do_signing) {
158 /* Sign the outgoing packet if required. */
159 srv_calculate_sign_mac(sconn, buf_out, seqnum);
162 if (do_encrypt) {
163 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
164 if (!NT_STATUS_IS_OK(status)) {
165 DEBUG(0, ("send_smb: SMB encryption failed "
166 "on outgoing packet! Error %s\n",
167 nt_errstr(status) ));
168 goto out;
172 len = smb_len_large(buf_out) + 4;
174 ret = write_data(sconn->sock, buf_out, len);
175 if (ret <= 0) {
177 char addr[INET6_ADDRSTRLEN];
179 * Try and give an error message saying what
180 * client failed.
182 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
183 (int)getpid(), (int)len,
184 get_peer_addr(sconn->sock, addr, sizeof(addr)),
185 (int)ret, strerror(errno) ));
187 srv_free_enc_buffer(sconn, buf_out);
188 goto out;
191 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
192 srv_free_enc_buffer(sconn, buf_out);
193 out:
194 SMB_PERFCOUNT_END(pcd);
196 smbd_unlock_socket(sconn);
197 return true;
200 /*******************************************************************
201 Setup the word count and byte count for a smb message.
202 ********************************************************************/
204 int srv_set_message(char *buf,
205 int num_words,
206 int num_bytes,
207 bool zero)
209 if (zero && (num_words || num_bytes)) {
210 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
212 SCVAL(buf,smb_wct,num_words);
213 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
214 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
215 return (smb_size + num_words*2 + num_bytes);
218 static bool valid_smb_header(struct smbd_server_connection *sconn,
219 const uint8_t *inbuf)
221 if (is_encrypted_packet(sconn, inbuf)) {
222 return true;
225 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
226 * but it just looks weird to call strncmp for this one.
228 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
231 /* Socket functions for smbd packet processing. */
233 static bool valid_packet_size(size_t len)
236 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
237 * of header. Don't print the error if this fits.... JRA.
240 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
241 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
242 (unsigned long)len));
243 return false;
245 return true;
248 static NTSTATUS read_packet_remainder(int fd, char *buffer,
249 unsigned int timeout, ssize_t len)
251 NTSTATUS status;
253 if (len <= 0) {
254 return NT_STATUS_OK;
257 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
258 if (!NT_STATUS_IS_OK(status)) {
259 char addr[INET6_ADDRSTRLEN];
260 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
261 "error = %s.\n",
262 get_peer_addr(fd, addr, sizeof(addr)),
263 nt_errstr(status)));
265 return status;
268 /****************************************************************************
269 Attempt a zerocopy writeX read. We know here that len > smb_size-4
270 ****************************************************************************/
273 * Unfortunately, earlier versions of smbclient/libsmbclient
274 * don't send this "standard" writeX header. I've fixed this
275 * for 3.2 but we'll use the old method with earlier versions.
276 * Windows and CIFSFS at least use this standard size. Not
277 * sure about MacOSX.
280 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
281 (2*14) + /* word count (including bcc) */ \
282 1 /* pad byte */)
284 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
285 const char lenbuf[4],
286 struct smbd_server_connection *sconn,
287 int sock,
288 char **buffer,
289 unsigned int timeout,
290 size_t *p_unread,
291 size_t *len_ret)
293 /* Size of a WRITEX call (+4 byte len). */
294 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
295 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
296 ssize_t toread;
297 NTSTATUS status;
299 memcpy(writeX_header, lenbuf, 4);
301 status = read_fd_with_timeout(
302 sock, writeX_header + 4,
303 STANDARD_WRITE_AND_X_HEADER_SIZE,
304 STANDARD_WRITE_AND_X_HEADER_SIZE,
305 timeout, NULL);
307 if (!NT_STATUS_IS_OK(status)) {
308 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
309 "error = %s.\n",
310 tsocket_address_string(sconn->remote_address,
311 talloc_tos()),
312 nt_errstr(status)));
313 return status;
317 * Ok - now try and see if this is a possible
318 * valid writeX call.
321 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
323 * If the data offset is beyond what
324 * we've read, drain the extra bytes.
326 uint16_t doff = SVAL(writeX_header,smb_vwv11);
327 ssize_t newlen;
329 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
330 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
331 if (drain_socket(sock, drain) != drain) {
332 smb_panic("receive_smb_raw_talloc_partial_read:"
333 " failed to drain pending bytes");
335 } else {
336 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
339 /* Spoof down the length and null out the bcc. */
340 set_message_bcc(writeX_header, 0);
341 newlen = smb_len(writeX_header);
343 /* Copy the header we've written. */
345 *buffer = (char *)talloc_memdup(mem_ctx,
346 writeX_header,
347 sizeof(writeX_header));
349 if (*buffer == NULL) {
350 DEBUG(0, ("Could not allocate inbuf of length %d\n",
351 (int)sizeof(writeX_header)));
352 return NT_STATUS_NO_MEMORY;
355 /* Work out the remaining bytes. */
356 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
357 *len_ret = newlen + 4;
358 return NT_STATUS_OK;
361 if (!valid_packet_size(len)) {
362 return NT_STATUS_INVALID_PARAMETER;
366 * Not a valid writeX call. Just do the standard
367 * talloc and return.
370 *buffer = talloc_array(mem_ctx, char, len+4);
372 if (*buffer == NULL) {
373 DEBUG(0, ("Could not allocate inbuf of length %d\n",
374 (int)len+4));
375 return NT_STATUS_NO_MEMORY;
378 /* Copy in what we already read. */
379 memcpy(*buffer,
380 writeX_header,
381 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
382 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
384 if(toread > 0) {
385 status = read_packet_remainder(
386 sock,
387 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
388 timeout, toread);
390 if (!NT_STATUS_IS_OK(status)) {
391 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
392 nt_errstr(status)));
393 return status;
397 *len_ret = len + 4;
398 return NT_STATUS_OK;
401 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
402 struct smbd_server_connection *sconn,
403 int sock,
404 char **buffer, unsigned int timeout,
405 size_t *p_unread, size_t *plen)
407 char lenbuf[4];
408 size_t len;
409 int min_recv_size = lp_min_receive_file_size();
410 NTSTATUS status;
412 *p_unread = 0;
414 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
415 &len);
416 if (!NT_STATUS_IS_OK(status)) {
417 return status;
420 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
421 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
422 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
423 !srv_is_signing_active(sconn) &&
424 sconn->smb1.echo_handler.trusted_fde == NULL) {
426 return receive_smb_raw_talloc_partial_read(
427 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
428 p_unread, plen);
431 if (!valid_packet_size(len)) {
432 return NT_STATUS_INVALID_PARAMETER;
436 * The +4 here can't wrap, we've checked the length above already.
439 *buffer = talloc_array(mem_ctx, char, len+4);
441 if (*buffer == NULL) {
442 DEBUG(0, ("Could not allocate inbuf of length %d\n",
443 (int)len+4));
444 return NT_STATUS_NO_MEMORY;
447 memcpy(*buffer, lenbuf, sizeof(lenbuf));
449 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
450 if (!NT_STATUS_IS_OK(status)) {
451 return status;
454 *plen = len + 4;
455 return NT_STATUS_OK;
458 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
459 struct smbd_server_connection *sconn,
460 int sock,
461 char **buffer, unsigned int timeout,
462 size_t *p_unread, bool *p_encrypted,
463 size_t *p_len,
464 uint32_t *seqnum,
465 bool trusted_channel)
467 size_t len = 0;
468 NTSTATUS status;
470 *p_encrypted = false;
472 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
473 p_unread, &len);
474 if (!NT_STATUS_IS_OK(status)) {
475 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
476 ("receive_smb_raw_talloc failed for client %s "
477 "read error = %s.\n",
478 tsocket_address_string(sconn->remote_address,
479 talloc_tos()),
480 nt_errstr(status)) );
481 return status;
484 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
485 status = srv_decrypt_buffer(sconn, *buffer);
486 if (!NT_STATUS_IS_OK(status)) {
487 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
488 "incoming packet! Error %s\n",
489 nt_errstr(status) ));
490 return status;
492 *p_encrypted = true;
495 /* Check the incoming SMB signature. */
496 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
497 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
498 "incoming packet!\n"));
499 return NT_STATUS_INVALID_NETWORK_RESPONSE;
502 *p_len = len;
503 return NT_STATUS_OK;
507 * Initialize a struct smb_request from an inbuf
510 static bool init_smb_request(struct smb_request *req,
511 struct smbd_server_connection *sconn,
512 const uint8 *inbuf,
513 size_t unread_bytes, bool encrypted,
514 uint32_t seqnum)
516 struct smbXsrv_tcon *tcon;
517 NTSTATUS status;
518 NTTIME now;
519 size_t req_size = smb_len(inbuf) + 4;
521 /* Ensure we have at least smb_size bytes. */
522 if (req_size < smb_size) {
523 DEBUG(0,("init_smb_request: invalid request size %u\n",
524 (unsigned int)req_size ));
525 return false;
528 req->request_time = timeval_current();
529 now = timeval_to_nttime(&req->request_time);
531 req->cmd = CVAL(inbuf, smb_com);
532 req->flags2 = SVAL(inbuf, smb_flg2);
533 req->smbpid = SVAL(inbuf, smb_pid);
534 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
535 req->seqnum = seqnum;
536 req->vuid = SVAL(inbuf, smb_uid);
537 req->tid = SVAL(inbuf, smb_tid);
538 req->wct = CVAL(inbuf, smb_wct);
539 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
540 req->buflen = smb_buflen(inbuf);
541 req->buf = (const uint8_t *)smb_buf_const(inbuf);
542 req->unread_bytes = unread_bytes;
543 req->encrypted = encrypted;
544 req->sconn = sconn;
545 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
546 if (NT_STATUS_IS_OK(status)) {
547 req->conn = tcon->compat;
548 } else {
549 req->conn = NULL;
551 req->chain_fsp = NULL;
552 req->smb2req = NULL;
553 req->priv_paths = NULL;
554 req->chain = NULL;
555 smb_init_perfcount_data(&req->pcd);
557 /* Ensure we have at least wct words and 2 bytes of bcc. */
558 if (smb_size + req->wct*2 > req_size) {
559 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
560 (unsigned int)req->wct,
561 (unsigned int)req_size));
562 return false;
564 /* Ensure bcc is correct. */
565 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
566 DEBUG(0,("init_smb_request: invalid bcc number %u "
567 "(wct = %u, size %u)\n",
568 (unsigned int)req->buflen,
569 (unsigned int)req->wct,
570 (unsigned int)req_size));
571 return false;
574 req->outbuf = NULL;
575 return true;
578 static void process_smb(struct smbd_server_connection *conn,
579 uint8_t *inbuf, size_t nread, size_t unread_bytes,
580 uint32_t seqnum, bool encrypted,
581 struct smb_perfcount_data *deferred_pcd);
583 static void smbd_deferred_open_timer(struct tevent_context *ev,
584 struct tevent_timer *te,
585 struct timeval _tval,
586 void *private_data)
588 struct pending_message_list *msg = talloc_get_type(private_data,
589 struct pending_message_list);
590 struct smbd_server_connection *sconn = msg->sconn;
591 TALLOC_CTX *mem_ctx = talloc_tos();
592 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
593 uint8_t *inbuf;
595 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
596 msg->buf.length);
597 if (inbuf == NULL) {
598 exit_server("smbd_deferred_open_timer: talloc failed\n");
599 return;
602 /* We leave this message on the queue so the open code can
603 know this is a retry. */
604 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
605 (unsigned long long)mid ));
607 /* Mark the message as processed so this is not
608 * re-processed in error. */
609 msg->processed = true;
611 process_smb(sconn, inbuf,
612 msg->buf.length, 0,
613 msg->seqnum, msg->encrypted, &msg->pcd);
615 /* If it's still there and was processed, remove it. */
616 msg = get_deferred_open_message_smb(sconn, mid);
617 if (msg && msg->processed) {
618 remove_deferred_open_message_smb(sconn, mid);
622 /****************************************************************************
623 Function to push a message onto the tail of a linked list of smb messages ready
624 for processing.
625 ****************************************************************************/
627 static bool push_queued_message(struct smb_request *req,
628 struct timeval request_time,
629 struct timeval end_time,
630 char *private_data, size_t private_len)
632 int msg_len = smb_len(req->inbuf) + 4;
633 struct pending_message_list *msg;
635 msg = talloc_zero(NULL, struct pending_message_list);
637 if(msg == NULL) {
638 DEBUG(0,("push_message: malloc fail (1)\n"));
639 return False;
641 msg->sconn = req->sconn;
643 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
644 if(msg->buf.data == NULL) {
645 DEBUG(0,("push_message: malloc fail (2)\n"));
646 TALLOC_FREE(msg);
647 return False;
650 msg->request_time = request_time;
651 msg->seqnum = req->seqnum;
652 msg->encrypted = req->encrypted;
653 msg->processed = false;
654 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
656 if (private_data) {
657 msg->private_data = data_blob_talloc(msg, private_data,
658 private_len);
659 if (msg->private_data.data == NULL) {
660 DEBUG(0,("push_message: malloc fail (3)\n"));
661 TALLOC_FREE(msg);
662 return False;
666 #if 0
667 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
668 msg,
669 end_time,
670 smbd_deferred_open_timer,
671 msg);
672 if (!msg->te) {
673 DEBUG(0,("push_message: event_add_timed failed\n"));
674 TALLOC_FREE(msg);
675 return false;
677 #endif
679 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
680 struct pending_message_list *);
682 DEBUG(10,("push_message: pushed message length %u on "
683 "deferred_open_queue\n", (unsigned int)msg_len));
685 return True;
688 /****************************************************************************
689 Function to delete a sharing violation open message by mid.
690 ****************************************************************************/
692 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
693 uint64_t mid)
695 struct pending_message_list *pml;
697 if (sconn->using_smb2) {
698 remove_deferred_open_message_smb2(sconn, mid);
699 return;
702 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
703 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
704 DEBUG(10,("remove_deferred_open_message_smb: "
705 "deleting mid %llu len %u\n",
706 (unsigned long long)mid,
707 (unsigned int)pml->buf.length ));
708 DLIST_REMOVE(sconn->deferred_open_queue, pml);
709 TALLOC_FREE(pml);
710 return;
715 /****************************************************************************
716 Move a sharing violation open retry message to the front of the list and
717 schedule it for immediate processing.
718 ****************************************************************************/
720 bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
721 uint64_t mid)
723 struct pending_message_list *pml;
724 int i = 0;
726 if (sconn->using_smb2) {
727 return schedule_deferred_open_message_smb2(sconn, mid);
730 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
731 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
733 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
734 "msg_mid = %llu\n",
735 i++,
736 (unsigned long long)msg_mid ));
738 if (mid == msg_mid) {
739 struct tevent_timer *te;
741 if (pml->processed) {
742 /* A processed message should not be
743 * rescheduled. */
744 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
745 "message mid %llu was already processed\n",
746 (unsigned long long)msg_mid ));
747 continue;
750 DEBUG(10,("schedule_deferred_open_message_smb: "
751 "scheduling mid %llu\n",
752 (unsigned long long)mid ));
754 te = tevent_add_timer(pml->sconn->ev_ctx,
755 pml,
756 timeval_zero(),
757 smbd_deferred_open_timer,
758 pml);
759 if (!te) {
760 DEBUG(10,("schedule_deferred_open_message_smb: "
761 "event_add_timed() failed, "
762 "skipping mid %llu\n",
763 (unsigned long long)msg_mid ));
766 TALLOC_FREE(pml->te);
767 pml->te = te;
768 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
769 return true;
773 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
774 "find message mid %llu\n",
775 (unsigned long long)mid ));
777 return false;
780 /****************************************************************************
781 Return true if this mid is on the deferred queue and was not yet processed.
782 ****************************************************************************/
784 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
786 struct pending_message_list *pml;
788 if (sconn->using_smb2) {
789 return open_was_deferred_smb2(sconn, mid);
792 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
793 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
794 return True;
797 return False;
800 /****************************************************************************
801 Return the message queued by this mid.
802 ****************************************************************************/
804 static struct pending_message_list *get_deferred_open_message_smb(
805 struct smbd_server_connection *sconn, uint64_t mid)
807 struct pending_message_list *pml;
809 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
810 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
811 return pml;
814 return NULL;
817 /****************************************************************************
818 Get the state data queued by this mid.
819 ****************************************************************************/
821 bool get_deferred_open_message_state(struct smb_request *smbreq,
822 struct timeval *p_request_time,
823 void **pp_state)
825 struct pending_message_list *pml;
827 if (smbreq->sconn->using_smb2) {
828 return get_deferred_open_message_state_smb2(smbreq->smb2req,
829 p_request_time,
830 pp_state);
833 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
834 if (!pml) {
835 return false;
837 if (p_request_time) {
838 *p_request_time = pml->request_time;
840 if (pp_state) {
841 *pp_state = (void *)pml->private_data.data;
843 return true;
846 /****************************************************************************
847 Function to push a deferred open smb message onto a linked list of local smb
848 messages ready for processing.
849 ****************************************************************************/
851 bool push_deferred_open_message_smb(struct smb_request *req,
852 struct timeval request_time,
853 struct timeval timeout,
854 struct file_id id,
855 char *private_data, size_t priv_len)
857 struct timeval end_time;
859 if (req->smb2req) {
860 return push_deferred_open_message_smb2(req->smb2req,
861 request_time,
862 timeout,
864 private_data,
865 priv_len);
868 if (req->unread_bytes) {
869 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
870 "unread_bytes = %u\n",
871 (unsigned int)req->unread_bytes ));
872 smb_panic("push_deferred_open_message_smb: "
873 "logic error unread_bytes != 0" );
876 end_time = timeval_sum(&request_time, &timeout);
878 DEBUG(10,("push_deferred_open_message_smb: pushing message "
879 "len %u mid %llu timeout time [%u.%06u]\n",
880 (unsigned int) smb_len(req->inbuf)+4,
881 (unsigned long long)req->mid,
882 (unsigned int)end_time.tv_sec,
883 (unsigned int)end_time.tv_usec));
885 return push_queued_message(req, request_time, end_time,
886 private_data, priv_len);
889 static void smbd_sig_term_handler(struct tevent_context *ev,
890 struct tevent_signal *se,
891 int signum,
892 int count,
893 void *siginfo,
894 void *private_data)
896 exit_server_cleanly("termination signal");
899 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
901 struct tevent_signal *se;
903 se = tevent_add_signal(sconn->ev_ctx,
904 sconn,
905 SIGTERM, 0,
906 smbd_sig_term_handler,
907 sconn);
908 if (!se) {
909 exit_server("failed to setup SIGTERM handler");
913 static void smbd_sig_hup_handler(struct tevent_context *ev,
914 struct tevent_signal *se,
915 int signum,
916 int count,
917 void *siginfo,
918 void *private_data)
920 struct smbd_server_connection *sconn =
921 talloc_get_type_abort(private_data,
922 struct smbd_server_connection);
924 change_to_root_user();
925 DEBUG(1,("Reloading services after SIGHUP\n"));
926 reload_services(sconn, conn_snum_used, false);
929 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
931 struct tevent_signal *se;
933 se = tevent_add_signal(sconn->ev_ctx,
934 sconn,
935 SIGHUP, 0,
936 smbd_sig_hup_handler,
937 sconn);
938 if (!se) {
939 exit_server("failed to setup SIGHUP handler");
943 static void smbd_conf_updated(struct messaging_context *msg,
944 void *private_data,
945 uint32_t msg_type,
946 struct server_id server_id,
947 DATA_BLOB *data)
949 struct smbd_server_connection *sconn =
950 talloc_get_type_abort(private_data,
951 struct smbd_server_connection);
953 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
954 "updated. Reloading.\n"));
955 change_to_root_user();
956 reload_services(sconn, conn_snum_used, false);
960 * Only allow 5 outstanding trans requests. We're allocating memory, so
961 * prevent a DoS.
964 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
966 int count = 0;
967 for (; list != NULL; list = list->next) {
969 if (list->mid == mid) {
970 return NT_STATUS_INVALID_PARAMETER;
973 count += 1;
975 if (count > 5) {
976 return NT_STATUS_INSUFFICIENT_RESOURCES;
979 return NT_STATUS_OK;
983 These flags determine some of the permissions required to do an operation
985 Note that I don't set NEED_WRITE on some write operations because they
986 are used by some brain-dead clients when printing, and I don't want to
987 force write permissions on print services.
989 #define AS_USER (1<<0)
990 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
991 #define TIME_INIT (1<<2)
992 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
993 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
994 #define DO_CHDIR (1<<6)
997 define a list of possible SMB messages and their corresponding
998 functions. Any message that has a NULL function is unimplemented -
999 please feel free to contribute implementations!
1001 static const struct smb_message_struct {
1002 const char *name;
1003 void (*fn)(struct smb_request *req);
1004 int flags;
1005 } smb_messages[256] = {
1007 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1008 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1009 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1010 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1011 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1012 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1013 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1014 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1015 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1016 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1017 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1018 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1019 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1020 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1021 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1022 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1023 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1024 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1025 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1026 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1027 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1028 /* 0x15 */ { NULL, NULL, 0 },
1029 /* 0x16 */ { NULL, NULL, 0 },
1030 /* 0x17 */ { NULL, NULL, 0 },
1031 /* 0x18 */ { NULL, NULL, 0 },
1032 /* 0x19 */ { NULL, NULL, 0 },
1033 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1034 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1035 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1036 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1037 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1038 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1039 /* 0x20 */ { "SMBwritec", NULL,0},
1040 /* 0x21 */ { NULL, NULL, 0 },
1041 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1042 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1043 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1044 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1045 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1046 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1047 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1048 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1049 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1050 /* 0x2b */ { "SMBecho",reply_echo,0},
1051 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1052 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1053 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1054 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1055 /* 0x30 */ { NULL, NULL, 0 },
1056 /* 0x31 */ { NULL, NULL, 0 },
1057 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1058 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1059 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1060 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1061 /* 0x36 */ { NULL, NULL, 0 },
1062 /* 0x37 */ { NULL, NULL, 0 },
1063 /* 0x38 */ { NULL, NULL, 0 },
1064 /* 0x39 */ { NULL, NULL, 0 },
1065 /* 0x3a */ { NULL, NULL, 0 },
1066 /* 0x3b */ { NULL, NULL, 0 },
1067 /* 0x3c */ { NULL, NULL, 0 },
1068 /* 0x3d */ { NULL, NULL, 0 },
1069 /* 0x3e */ { NULL, NULL, 0 },
1070 /* 0x3f */ { NULL, NULL, 0 },
1071 /* 0x40 */ { NULL, NULL, 0 },
1072 /* 0x41 */ { NULL, NULL, 0 },
1073 /* 0x42 */ { NULL, NULL, 0 },
1074 /* 0x43 */ { NULL, NULL, 0 },
1075 /* 0x44 */ { NULL, NULL, 0 },
1076 /* 0x45 */ { NULL, NULL, 0 },
1077 /* 0x46 */ { NULL, NULL, 0 },
1078 /* 0x47 */ { NULL, NULL, 0 },
1079 /* 0x48 */ { NULL, NULL, 0 },
1080 /* 0x49 */ { NULL, NULL, 0 },
1081 /* 0x4a */ { NULL, NULL, 0 },
1082 /* 0x4b */ { NULL, NULL, 0 },
1083 /* 0x4c */ { NULL, NULL, 0 },
1084 /* 0x4d */ { NULL, NULL, 0 },
1085 /* 0x4e */ { NULL, NULL, 0 },
1086 /* 0x4f */ { NULL, NULL, 0 },
1087 /* 0x50 */ { NULL, NULL, 0 },
1088 /* 0x51 */ { NULL, NULL, 0 },
1089 /* 0x52 */ { NULL, NULL, 0 },
1090 /* 0x53 */ { NULL, NULL, 0 },
1091 /* 0x54 */ { NULL, NULL, 0 },
1092 /* 0x55 */ { NULL, NULL, 0 },
1093 /* 0x56 */ { NULL, NULL, 0 },
1094 /* 0x57 */ { NULL, NULL, 0 },
1095 /* 0x58 */ { NULL, NULL, 0 },
1096 /* 0x59 */ { NULL, NULL, 0 },
1097 /* 0x5a */ { NULL, NULL, 0 },
1098 /* 0x5b */ { NULL, NULL, 0 },
1099 /* 0x5c */ { NULL, NULL, 0 },
1100 /* 0x5d */ { NULL, NULL, 0 },
1101 /* 0x5e */ { NULL, NULL, 0 },
1102 /* 0x5f */ { NULL, NULL, 0 },
1103 /* 0x60 */ { NULL, NULL, 0 },
1104 /* 0x61 */ { NULL, NULL, 0 },
1105 /* 0x62 */ { NULL, NULL, 0 },
1106 /* 0x63 */ { NULL, NULL, 0 },
1107 /* 0x64 */ { NULL, NULL, 0 },
1108 /* 0x65 */ { NULL, NULL, 0 },
1109 /* 0x66 */ { NULL, NULL, 0 },
1110 /* 0x67 */ { NULL, NULL, 0 },
1111 /* 0x68 */ { NULL, NULL, 0 },
1112 /* 0x69 */ { NULL, NULL, 0 },
1113 /* 0x6a */ { NULL, NULL, 0 },
1114 /* 0x6b */ { NULL, NULL, 0 },
1115 /* 0x6c */ { NULL, NULL, 0 },
1116 /* 0x6d */ { NULL, NULL, 0 },
1117 /* 0x6e */ { NULL, NULL, 0 },
1118 /* 0x6f */ { NULL, NULL, 0 },
1119 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1120 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1121 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1122 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1123 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1124 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1125 /* 0x76 */ { NULL, NULL, 0 },
1126 /* 0x77 */ { NULL, NULL, 0 },
1127 /* 0x78 */ { NULL, NULL, 0 },
1128 /* 0x79 */ { NULL, NULL, 0 },
1129 /* 0x7a */ { NULL, NULL, 0 },
1130 /* 0x7b */ { NULL, NULL, 0 },
1131 /* 0x7c */ { NULL, NULL, 0 },
1132 /* 0x7d */ { NULL, NULL, 0 },
1133 /* 0x7e */ { NULL, NULL, 0 },
1134 /* 0x7f */ { NULL, NULL, 0 },
1135 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1136 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1137 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1138 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1139 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1140 /* 0x85 */ { NULL, NULL, 0 },
1141 /* 0x86 */ { NULL, NULL, 0 },
1142 /* 0x87 */ { NULL, NULL, 0 },
1143 /* 0x88 */ { NULL, NULL, 0 },
1144 /* 0x89 */ { NULL, NULL, 0 },
1145 /* 0x8a */ { NULL, NULL, 0 },
1146 /* 0x8b */ { NULL, NULL, 0 },
1147 /* 0x8c */ { NULL, NULL, 0 },
1148 /* 0x8d */ { NULL, NULL, 0 },
1149 /* 0x8e */ { NULL, NULL, 0 },
1150 /* 0x8f */ { NULL, NULL, 0 },
1151 /* 0x90 */ { NULL, NULL, 0 },
1152 /* 0x91 */ { NULL, NULL, 0 },
1153 /* 0x92 */ { NULL, NULL, 0 },
1154 /* 0x93 */ { NULL, NULL, 0 },
1155 /* 0x94 */ { NULL, NULL, 0 },
1156 /* 0x95 */ { NULL, NULL, 0 },
1157 /* 0x96 */ { NULL, NULL, 0 },
1158 /* 0x97 */ { NULL, NULL, 0 },
1159 /* 0x98 */ { NULL, NULL, 0 },
1160 /* 0x99 */ { NULL, NULL, 0 },
1161 /* 0x9a */ { NULL, NULL, 0 },
1162 /* 0x9b */ { NULL, NULL, 0 },
1163 /* 0x9c */ { NULL, NULL, 0 },
1164 /* 0x9d */ { NULL, NULL, 0 },
1165 /* 0x9e */ { NULL, NULL, 0 },
1166 /* 0x9f */ { NULL, NULL, 0 },
1167 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1168 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1169 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1170 /* 0xa3 */ { NULL, NULL, 0 },
1171 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1172 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1173 /* 0xa6 */ { NULL, NULL, 0 },
1174 /* 0xa7 */ { NULL, NULL, 0 },
1175 /* 0xa8 */ { NULL, NULL, 0 },
1176 /* 0xa9 */ { NULL, NULL, 0 },
1177 /* 0xaa */ { NULL, NULL, 0 },
1178 /* 0xab */ { NULL, NULL, 0 },
1179 /* 0xac */ { NULL, NULL, 0 },
1180 /* 0xad */ { NULL, NULL, 0 },
1181 /* 0xae */ { NULL, NULL, 0 },
1182 /* 0xaf */ { NULL, NULL, 0 },
1183 /* 0xb0 */ { NULL, NULL, 0 },
1184 /* 0xb1 */ { NULL, NULL, 0 },
1185 /* 0xb2 */ { NULL, NULL, 0 },
1186 /* 0xb3 */ { NULL, NULL, 0 },
1187 /* 0xb4 */ { NULL, NULL, 0 },
1188 /* 0xb5 */ { NULL, NULL, 0 },
1189 /* 0xb6 */ { NULL, NULL, 0 },
1190 /* 0xb7 */ { NULL, NULL, 0 },
1191 /* 0xb8 */ { NULL, NULL, 0 },
1192 /* 0xb9 */ { NULL, NULL, 0 },
1193 /* 0xba */ { NULL, NULL, 0 },
1194 /* 0xbb */ { NULL, NULL, 0 },
1195 /* 0xbc */ { NULL, NULL, 0 },
1196 /* 0xbd */ { NULL, NULL, 0 },
1197 /* 0xbe */ { NULL, NULL, 0 },
1198 /* 0xbf */ { NULL, NULL, 0 },
1199 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1200 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1201 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1202 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1203 /* 0xc4 */ { NULL, NULL, 0 },
1204 /* 0xc5 */ { NULL, NULL, 0 },
1205 /* 0xc6 */ { NULL, NULL, 0 },
1206 /* 0xc7 */ { NULL, NULL, 0 },
1207 /* 0xc8 */ { NULL, NULL, 0 },
1208 /* 0xc9 */ { NULL, NULL, 0 },
1209 /* 0xca */ { NULL, NULL, 0 },
1210 /* 0xcb */ { NULL, NULL, 0 },
1211 /* 0xcc */ { NULL, NULL, 0 },
1212 /* 0xcd */ { NULL, NULL, 0 },
1213 /* 0xce */ { NULL, NULL, 0 },
1214 /* 0xcf */ { NULL, NULL, 0 },
1215 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1216 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1217 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1218 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1219 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1220 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1221 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1222 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1223 /* 0xd8 */ { NULL, NULL, 0 },
1224 /* 0xd9 */ { NULL, NULL, 0 },
1225 /* 0xda */ { NULL, NULL, 0 },
1226 /* 0xdb */ { NULL, NULL, 0 },
1227 /* 0xdc */ { NULL, NULL, 0 },
1228 /* 0xdd */ { NULL, NULL, 0 },
1229 /* 0xde */ { NULL, NULL, 0 },
1230 /* 0xdf */ { NULL, NULL, 0 },
1231 /* 0xe0 */ { NULL, NULL, 0 },
1232 /* 0xe1 */ { NULL, NULL, 0 },
1233 /* 0xe2 */ { NULL, NULL, 0 },
1234 /* 0xe3 */ { NULL, NULL, 0 },
1235 /* 0xe4 */ { NULL, NULL, 0 },
1236 /* 0xe5 */ { NULL, NULL, 0 },
1237 /* 0xe6 */ { NULL, NULL, 0 },
1238 /* 0xe7 */ { NULL, NULL, 0 },
1239 /* 0xe8 */ { NULL, NULL, 0 },
1240 /* 0xe9 */ { NULL, NULL, 0 },
1241 /* 0xea */ { NULL, NULL, 0 },
1242 /* 0xeb */ { NULL, NULL, 0 },
1243 /* 0xec */ { NULL, NULL, 0 },
1244 /* 0xed */ { NULL, NULL, 0 },
1245 /* 0xee */ { NULL, NULL, 0 },
1246 /* 0xef */ { NULL, NULL, 0 },
1247 /* 0xf0 */ { NULL, NULL, 0 },
1248 /* 0xf1 */ { NULL, NULL, 0 },
1249 /* 0xf2 */ { NULL, NULL, 0 },
1250 /* 0xf3 */ { NULL, NULL, 0 },
1251 /* 0xf4 */ { NULL, NULL, 0 },
1252 /* 0xf5 */ { NULL, NULL, 0 },
1253 /* 0xf6 */ { NULL, NULL, 0 },
1254 /* 0xf7 */ { NULL, NULL, 0 },
1255 /* 0xf8 */ { NULL, NULL, 0 },
1256 /* 0xf9 */ { NULL, NULL, 0 },
1257 /* 0xfa */ { NULL, NULL, 0 },
1258 /* 0xfb */ { NULL, NULL, 0 },
1259 /* 0xfc */ { NULL, NULL, 0 },
1260 /* 0xfd */ { NULL, NULL, 0 },
1261 /* 0xfe */ { NULL, NULL, 0 },
1262 /* 0xff */ { NULL, NULL, 0 }
1266 /*******************************************************************
1267 allocate and initialize a reply packet
1268 ********************************************************************/
1270 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1271 const char *inbuf, char **outbuf, uint8_t num_words,
1272 uint32_t num_bytes)
1274 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1277 * Protect against integer wrap.
1278 * The SMB layer reply can be up to 0xFFFFFF bytes.
1280 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1281 char *msg;
1282 if (asprintf(&msg, "num_bytes too large: %u",
1283 (unsigned)num_bytes) == -1) {
1284 msg = discard_const_p(char, "num_bytes too large");
1286 smb_panic(msg);
1290 * Here we include the NBT header for now.
1292 *outbuf = talloc_array(mem_ctx, char,
1293 NBT_HDR_SIZE + smb_len);
1294 if (*outbuf == NULL) {
1295 return false;
1298 construct_reply_common(req, inbuf, *outbuf);
1299 srv_set_message(*outbuf, num_words, num_bytes, false);
1301 * Zero out the word area, the caller has to take care of the bcc area
1302 * himself
1304 if (num_words != 0) {
1305 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1308 return true;
1311 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1313 char *outbuf;
1314 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1315 num_bytes)) {
1316 smb_panic("could not allocate output buffer\n");
1318 req->outbuf = (uint8_t *)outbuf;
1322 /*******************************************************************
1323 Dump a packet to a file.
1324 ********************************************************************/
1326 static void smb_dump(const char *name, int type, const char *data)
1328 size_t len;
1329 int fd, i;
1330 char *fname = NULL;
1331 if (DEBUGLEVEL < 50) {
1332 return;
1335 len = smb_len_tcp(data)+4;
1336 for (i=1;i<100;i++) {
1337 fname = talloc_asprintf(talloc_tos(),
1338 "/tmp/%s.%d.%s",
1339 name,
1341 type ? "req" : "resp");
1342 if (fname == NULL) {
1343 return;
1345 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1346 if (fd != -1 || errno != EEXIST) break;
1347 TALLOC_FREE(fname);
1349 if (fd != -1) {
1350 ssize_t ret = write(fd, data, len);
1351 if (ret != len)
1352 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1353 close(fd);
1354 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1356 TALLOC_FREE(fname);
1359 /****************************************************************************
1360 Prepare everything for calling the actual request function, and potentially
1361 call the request function via the "new" interface.
1363 Return False if the "legacy" function needs to be called, everything is
1364 prepared.
1366 Return True if we're done.
1368 I know this API sucks, but it is the one with the least code change I could
1369 find.
1370 ****************************************************************************/
1372 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1374 int flags;
1375 uint64_t session_tag;
1376 connection_struct *conn = NULL;
1377 struct smbd_server_connection *sconn = req->sconn;
1378 NTTIME now = timeval_to_nttime(&req->request_time);
1379 struct smbXsrv_session *session = NULL;
1380 NTSTATUS status;
1382 errno = 0;
1384 if (smb_messages[type].fn == NULL) {
1385 DEBUG(0,("Unknown message type %d!\n",type));
1386 smb_dump("Unknown", 1, (const char *)req->inbuf);
1387 reply_unknown_new(req, type);
1388 return NULL;
1391 flags = smb_messages[type].flags;
1393 /* In share mode security we must ignore the vuid. */
1394 session_tag = req->vuid;
1395 conn = req->conn;
1397 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1398 (int)getpid(), (unsigned long)conn));
1400 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1402 /* Ensure this value is replaced in the incoming packet. */
1403 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1406 * Ensure the correct username is in current_user_info. This is a
1407 * really ugly bugfix for problems with multiple session_setup_and_X's
1408 * being done and allowing %U and %G substitutions to work correctly.
1409 * There is a reason this code is done here, don't move it unless you
1410 * know what you're doing... :-).
1411 * JRA.
1415 * lookup an existing session
1417 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1418 * here, the main check is still in change_to_user()
1420 status = smb1srv_session_lookup(sconn->conn,
1421 session_tag,
1422 now,
1423 &session);
1424 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1425 switch (type) {
1426 case SMBsesssetupX:
1427 status = NT_STATUS_OK;
1428 break;
1429 default:
1430 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1431 (unsigned long long)session_tag,
1432 (unsigned long long)req->mid));
1433 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1434 return conn;
1438 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1439 struct user_struct *vuser = NULL;
1441 sconn->smb1.sessions.last_session_tag = session_tag;
1442 if (session) {
1443 vuser = session->compat;
1445 if (vuser) {
1446 set_current_user_info(
1447 vuser->session_info->unix_info->sanitized_username,
1448 vuser->session_info->unix_info->unix_name,
1449 vuser->session_info->info->domain_name);
1453 /* Does this call need to be run as the connected user? */
1454 if (flags & AS_USER) {
1456 /* Does this call need a valid tree connection? */
1457 if (!conn) {
1459 * Amazingly, the error code depends on the command
1460 * (from Samba4).
1462 if (type == SMBntcreateX) {
1463 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1464 } else {
1465 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1467 return NULL;
1470 if (!change_to_user(conn,session_tag)) {
1471 DEBUG(0, ("Error: Could not change to user. Removing "
1472 "deferred open, mid=%llu.\n",
1473 (unsigned long long)req->mid));
1474 reply_force_doserror(req, ERRSRV, ERRbaduid);
1475 return conn;
1478 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1480 /* Does it need write permission? */
1481 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1482 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1483 return conn;
1486 /* IPC services are limited */
1487 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1488 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1489 return conn;
1491 } else {
1492 /* This call needs to be run as root */
1493 change_to_root_user();
1496 /* load service specific parameters */
1497 if (conn) {
1498 if (req->encrypted) {
1499 conn->encrypted_tid = true;
1500 /* encrypted required from now on. */
1501 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1502 } else if (ENCRYPTION_REQUIRED(conn)) {
1503 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1504 DEBUG(1,("service[%s] requires encryption"
1505 "%s ACCESS_DENIED. mid=%llu\n",
1506 lp_servicename(talloc_tos(), SNUM(conn)),
1507 smb_fn_name(type),
1508 (unsigned long long)req->mid));
1509 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1510 return conn;
1514 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1515 (flags & (AS_USER|DO_CHDIR)
1516 ?True:False))) {
1517 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1518 return conn;
1520 conn->num_smb_operations++;
1524 * Does this protocol need to be run as guest? (Only archane
1525 * messenger service requests have this...)
1527 if (flags & AS_GUEST) {
1528 char *raddr;
1529 bool ok;
1531 if (!change_to_guest()) {
1532 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1533 return conn;
1536 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1537 talloc_tos());
1538 if (raddr == NULL) {
1539 reply_nterror(req, NT_STATUS_NO_MEMORY);
1540 return conn;
1544 * Haven't we checked this in smbd_process already???
1547 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1548 sconn->remote_hostname, raddr);
1549 TALLOC_FREE(raddr);
1551 if (!ok) {
1552 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1553 return conn;
1557 smb_messages[type].fn(req);
1558 return req->conn;
1561 /****************************************************************************
1562 Construct a reply to the incoming packet.
1563 ****************************************************************************/
1565 static void construct_reply(struct smbd_server_connection *sconn,
1566 char *inbuf, int size, size_t unread_bytes,
1567 uint32_t seqnum, bool encrypted,
1568 struct smb_perfcount_data *deferred_pcd)
1570 connection_struct *conn;
1571 struct smb_request *req;
1573 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1574 smb_panic("could not allocate smb_request");
1577 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1578 encrypted, seqnum)) {
1579 exit_server_cleanly("Invalid SMB request");
1582 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1584 /* we popped this message off the queue - keep original perf data */
1585 if (deferred_pcd)
1586 req->pcd = *deferred_pcd;
1587 else {
1588 SMB_PERFCOUNT_START(&req->pcd);
1589 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1590 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1593 conn = switch_message(req->cmd, req);
1595 if (req->outbuf == NULL) {
1596 return;
1599 if (CVAL(req->outbuf,0) == 0) {
1600 show_msg((char *)req->outbuf);
1603 if (!srv_send_smb(req->sconn,
1604 (char *)req->outbuf,
1605 true, req->seqnum+1,
1606 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1607 &req->pcd)) {
1608 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1611 TALLOC_FREE(req);
1613 return;
1616 static void construct_reply_chain(struct smbd_server_connection *sconn,
1617 char *inbuf, int size, uint32_t seqnum,
1618 bool encrypted,
1619 struct smb_perfcount_data *deferred_pcd)
1621 struct smb_request **reqs = NULL;
1622 struct smb_request *req;
1623 unsigned num_reqs;
1624 bool ok;
1626 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1627 seqnum, &reqs, &num_reqs);
1628 if (!ok) {
1629 char errbuf[smb_size];
1630 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1631 __LINE__, __FILE__);
1632 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1633 NULL)) {
1634 exit_server_cleanly("construct_reply_chain: "
1635 "srv_send_smb failed.");
1637 return;
1640 req = reqs[0];
1641 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1643 req->conn = switch_message(req->cmd, req);
1645 if (req->outbuf == NULL) {
1647 * Request has suspended itself, will come
1648 * back here.
1650 return;
1652 smb_request_done(req);
1656 * To be called from an async SMB handler that is potentially chained
1657 * when it is finished for shipping.
1660 void smb_request_done(struct smb_request *req)
1662 struct smb_request **reqs = NULL;
1663 struct smb_request *first_req;
1664 size_t i, num_reqs, next_index;
1665 NTSTATUS status;
1667 if (req->chain == NULL) {
1668 first_req = req;
1669 goto shipit;
1672 reqs = req->chain;
1673 num_reqs = talloc_array_length(reqs);
1675 for (i=0; i<num_reqs; i++) {
1676 if (reqs[i] == req) {
1677 break;
1680 if (i == num_reqs) {
1682 * Invalid chain, should not happen
1684 status = NT_STATUS_INTERNAL_ERROR;
1685 goto error;
1687 next_index = i+1;
1689 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1690 struct smb_request *next = reqs[next_index];
1691 struct smbXsrv_tcon *tcon;
1692 NTTIME now = timeval_to_nttime(&req->request_time);
1694 next->vuid = SVAL(req->outbuf, smb_uid);
1695 next->tid = SVAL(req->outbuf, smb_tid);
1696 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1697 now, &tcon);
1698 if (NT_STATUS_IS_OK(status)) {
1699 req->conn = tcon->compat;
1700 } else {
1701 req->conn = NULL;
1703 next->chain_fsp = req->chain_fsp;
1704 next->inbuf = req->inbuf;
1706 req = next;
1707 req->conn = switch_message(req->cmd, req);
1709 if (req->outbuf == NULL) {
1711 * Request has suspended itself, will come
1712 * back here.
1714 return;
1716 next_index += 1;
1719 first_req = reqs[0];
1721 for (i=1; i<next_index; i++) {
1722 bool ok;
1724 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1725 if (!ok) {
1726 status = NT_STATUS_INTERNAL_ERROR;
1727 goto error;
1731 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1732 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1735 * This scary statement intends to set the
1736 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1737 * to the value last_req->outbuf carries
1739 SSVAL(first_req->outbuf, smb_flg2,
1740 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1741 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1744 * Transfer the error codes from the subrequest to the main one
1746 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1747 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1749 _smb_setlen_large(
1750 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1752 shipit:
1753 if (!srv_send_smb(first_req->sconn,
1754 (char *)first_req->outbuf,
1755 true, first_req->seqnum+1,
1756 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1757 &first_req->pcd)) {
1758 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1759 "failed.");
1761 TALLOC_FREE(req); /* non-chained case */
1762 TALLOC_FREE(reqs); /* chained case */
1763 return;
1765 error:
1767 char errbuf[smb_size];
1768 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1769 if (!srv_send_smb(req->sconn, errbuf, true,
1770 req->seqnum+1, req->encrypted,
1771 NULL)) {
1772 exit_server_cleanly("construct_reply_chain: "
1773 "srv_send_smb failed.");
1776 TALLOC_FREE(req); /* non-chained case */
1777 TALLOC_FREE(reqs); /* chained case */
1780 /****************************************************************************
1781 Process an smb from the client
1782 ****************************************************************************/
1783 static void process_smb(struct smbd_server_connection *sconn,
1784 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1785 uint32_t seqnum, bool encrypted,
1786 struct smb_perfcount_data *deferred_pcd)
1788 int msg_type = CVAL(inbuf,0);
1790 DO_PROFILE_INC(smb_count);
1792 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1793 smb_len(inbuf) ) );
1794 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1795 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1797 if (msg_type != NBSSmessage) {
1799 * NetBIOS session request, keepalive, etc.
1801 reply_special(sconn, (char *)inbuf, nread);
1802 goto done;
1805 if (sconn->using_smb2) {
1806 /* At this point we're not really using smb2,
1807 * we make the decision here.. */
1808 if (smbd_is_smb2_header(inbuf, nread)) {
1809 smbd_smb2_first_negprot(sconn, inbuf, nread);
1810 return;
1811 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1812 && CVAL(inbuf, smb_com) != 0x72) {
1813 /* This is a non-negprot SMB1 packet.
1814 Disable SMB2 from now on. */
1815 sconn->using_smb2 = false;
1819 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1820 * so subtract 4 from it. */
1821 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1822 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1823 smb_len(inbuf)));
1825 /* special magic for immediate exit */
1826 if ((nread == 9) &&
1827 (IVAL(inbuf, 4) == 0x74697865) &&
1828 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1829 uint8_t exitcode = CVAL(inbuf, 8);
1830 DEBUG(1, ("Exiting immediately with code %d\n",
1831 (int)exitcode));
1832 exit(exitcode);
1835 exit_server_cleanly("Non-SMB packet");
1838 show_msg((char *)inbuf);
1840 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1841 construct_reply_chain(sconn, (char *)inbuf, nread,
1842 seqnum, encrypted, deferred_pcd);
1843 } else {
1844 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1845 seqnum, encrypted, deferred_pcd);
1848 sconn->trans_num++;
1850 done:
1851 sconn->num_requests++;
1853 /* The timeout_processing function isn't run nearly
1854 often enough to implement 'max log size' without
1855 overrunning the size of the file by many megabytes.
1856 This is especially true if we are running at debug
1857 level 10. Checking every 50 SMBs is a nice
1858 tradeoff of performance vs log file size overrun. */
1860 if ((sconn->num_requests % 50) == 0 &&
1861 need_to_check_log_size()) {
1862 change_to_root_user();
1863 check_log_size();
1867 /****************************************************************************
1868 Return a string containing the function name of a SMB command.
1869 ****************************************************************************/
1871 const char *smb_fn_name(int type)
1873 const char *unknown_name = "SMBunknown";
1875 if (smb_messages[type].name == NULL)
1876 return(unknown_name);
1878 return(smb_messages[type].name);
1881 /****************************************************************************
1882 Helper functions for contruct_reply.
1883 ****************************************************************************/
1885 void add_to_common_flags2(uint32 v)
1887 common_flags2 |= v;
1890 void remove_from_common_flags2(uint32 v)
1892 common_flags2 &= ~v;
1895 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1896 char *outbuf)
1898 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1899 uint16_t out_flags2 = common_flags2;
1901 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1902 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1903 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1905 srv_set_message(outbuf,0,0,false);
1907 SCVAL(outbuf, smb_com, req->cmd);
1908 SIVAL(outbuf,smb_rcls,0);
1909 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1910 SSVAL(outbuf,smb_flg2, out_flags2);
1911 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1912 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1914 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1915 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1916 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1917 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1920 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1922 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1926 * @brief Find the smb_cmd offset of the last command pushed
1927 * @param[in] buf The buffer we're building up
1928 * @retval Where can we put our next andx cmd?
1930 * While chaining requests, the "next" request we're looking at needs to put
1931 * its SMB_Command before the data the previous request already built up added
1932 * to the chain. Find the offset to the place where we have to put our cmd.
1935 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1937 uint8_t cmd;
1938 size_t ofs;
1940 cmd = CVAL(buf, smb_com);
1942 if (!is_andx_req(cmd)) {
1943 return false;
1946 ofs = smb_vwv0;
1948 while (CVAL(buf, ofs) != 0xff) {
1950 if (!is_andx_req(CVAL(buf, ofs))) {
1951 return false;
1955 * ofs is from start of smb header, so add the 4 length
1956 * bytes. The next cmd is right after the wct field.
1958 ofs = SVAL(buf, ofs+2) + 4 + 1;
1960 if (ofs+4 >= talloc_get_size(buf)) {
1961 return false;
1965 *pofs = ofs;
1966 return true;
1970 * @brief Do the smb chaining at a buffer level
1971 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1972 * @param[in] andx_buf Buffer to be appended
1975 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1977 uint8_t smb_command = CVAL(andx_buf, smb_com);
1978 uint8_t wct = CVAL(andx_buf, smb_wct);
1979 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1980 uint32_t num_bytes = smb_buflen(andx_buf);
1981 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1983 uint8_t *outbuf;
1984 size_t old_size, new_size;
1985 size_t ofs;
1986 size_t chain_padding = 0;
1987 size_t andx_cmd_ofs;
1990 old_size = talloc_get_size(*poutbuf);
1992 if ((old_size % 4) != 0) {
1994 * Align the wct field of subsequent requests to a 4-byte
1995 * boundary
1997 chain_padding = 4 - (old_size % 4);
2001 * After the old request comes the new wct field (1 byte), the vwv's
2002 * and the num_bytes field.
2005 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2006 new_size += num_bytes;
2008 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2009 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2010 (unsigned)new_size));
2011 return false;
2014 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2015 if (outbuf == NULL) {
2016 DEBUG(0, ("talloc failed\n"));
2017 return false;
2019 *poutbuf = outbuf;
2021 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2022 DEBUG(1, ("invalid command chain\n"));
2023 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2024 return false;
2027 if (chain_padding != 0) {
2028 memset(outbuf + old_size, 0, chain_padding);
2029 old_size += chain_padding;
2032 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2033 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2035 ofs = old_size;
2038 * Push the chained request:
2040 * wct field
2043 SCVAL(outbuf, ofs, wct);
2044 ofs += 1;
2047 * vwv array
2050 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2053 * HACK ALERT
2055 * Read&X has an offset into its data buffer at
2056 * vwv[6]. reply_read_andx has no idea anymore that it's
2057 * running from within a chain, so we have to fix up the
2058 * offset here.
2060 * Although it looks disgusting at this place, I want to keep
2061 * it here. The alternative would be to push knowledge about
2062 * the andx chain down into read&x again.
2065 if (smb_command == SMBreadX) {
2066 uint8_t *bytes_addr;
2068 if (wct < 7) {
2070 * Invalid read&x response
2072 return false;
2075 bytes_addr = outbuf + ofs /* vwv start */
2076 + sizeof(uint16_t) * wct /* vwv array */
2077 + sizeof(uint16_t); /* bcc */
2079 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2080 bytes_addr - outbuf - 4);
2083 ofs += sizeof(uint16_t) * wct;
2086 * bcc (byte count)
2089 SSVAL(outbuf, ofs, num_bytes);
2090 ofs += sizeof(uint16_t);
2093 * The bytes field
2096 memcpy(outbuf + ofs, bytes, num_bytes);
2098 return true;
2101 bool smb1_is_chain(const uint8_t *buf)
2103 uint8_t cmd, wct, andx_cmd;
2105 cmd = CVAL(buf, smb_com);
2106 if (!is_andx_req(cmd)) {
2107 return false;
2109 wct = CVAL(buf, smb_wct);
2110 if (wct < 2) {
2111 return false;
2113 andx_cmd = CVAL(buf, smb_vwv);
2114 return (andx_cmd != 0xFF);
2117 bool smb1_walk_chain(const uint8_t *buf,
2118 bool (*fn)(uint8_t cmd,
2119 uint8_t wct, const uint16_t *vwv,
2120 uint16_t num_bytes, const uint8_t *bytes,
2121 void *private_data),
2122 void *private_data)
2124 size_t smblen = smb_len(buf);
2125 const char *smb_buf = smb_base(buf);
2126 uint8_t cmd, chain_cmd;
2127 uint8_t wct;
2128 const uint16_t *vwv;
2129 uint16_t num_bytes;
2130 const uint8_t *bytes;
2132 cmd = CVAL(buf, smb_com);
2133 wct = CVAL(buf, smb_wct);
2134 vwv = (const uint16_t *)(buf + smb_vwv);
2135 num_bytes = smb_buflen(buf);
2136 bytes = (uint8_t *)smb_buf_const(buf);
2138 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2139 return false;
2142 if (!is_andx_req(cmd)) {
2143 return true;
2145 if (wct < 2) {
2146 return false;
2149 chain_cmd = CVAL(vwv, 0);
2151 while (chain_cmd != 0xff) {
2152 uint32_t chain_offset; /* uint32_t to avoid overflow */
2153 size_t length_needed;
2154 ptrdiff_t vwv_offset;
2156 chain_offset = SVAL(vwv+1, 0);
2159 * Check if the client tries to fool us. The chain
2160 * offset needs to point beyond the current request in
2161 * the chain, it needs to strictly grow. Otherwise we
2162 * might be tricked into an endless loop always
2163 * processing the same request over and over again. We
2164 * used to assume that vwv and the byte buffer array
2165 * in a chain are always attached, but OS/2 the
2166 * Write&X/Read&X chain puts the Read&X vwv array
2167 * right behind the Write&X vwv chain. The Write&X bcc
2168 * array is put behind the Read&X vwv array. So now we
2169 * check whether the chain offset points strictly
2170 * behind the previous vwv array. req->buf points
2171 * right after the vwv array of the previous
2172 * request. See
2173 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2174 * more information.
2177 vwv_offset = ((const char *)vwv - smb_buf);
2178 if (chain_offset <= vwv_offset) {
2179 return false;
2183 * Next check: Make sure the chain offset does not
2184 * point beyond the overall smb request length.
2187 length_needed = chain_offset+1; /* wct */
2188 if (length_needed > smblen) {
2189 return false;
2193 * Now comes the pointer magic. Goal here is to set up
2194 * vwv and buf correctly again. The chain offset (the
2195 * former vwv[1]) points at the new wct field.
2198 wct = CVAL(smb_buf, chain_offset);
2200 if (is_andx_req(chain_cmd) && (wct < 2)) {
2201 return false;
2205 * Next consistency check: Make the new vwv array fits
2206 * in the overall smb request.
2209 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2210 if (length_needed > smblen) {
2211 return false;
2213 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2216 * Now grab the new byte buffer....
2219 num_bytes = SVAL(vwv+wct, 0);
2222 * .. and check that it fits.
2225 length_needed += num_bytes;
2226 if (length_needed > smblen) {
2227 return false;
2229 bytes = (const uint8_t *)(vwv+wct+1);
2231 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2232 return false;
2235 if (!is_andx_req(chain_cmd)) {
2236 return true;
2238 chain_cmd = CVAL(vwv, 0);
2240 return true;
2243 static bool smb1_chain_length_cb(uint8_t cmd,
2244 uint8_t wct, const uint16_t *vwv,
2245 uint16_t num_bytes, const uint8_t *bytes,
2246 void *private_data)
2248 unsigned *count = (unsigned *)private_data;
2249 *count += 1;
2250 return true;
2253 unsigned smb1_chain_length(const uint8_t *buf)
2255 unsigned count = 0;
2257 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2258 return 0;
2260 return count;
2263 struct smb1_parse_chain_state {
2264 TALLOC_CTX *mem_ctx;
2265 const uint8_t *buf;
2266 struct smbd_server_connection *sconn;
2267 bool encrypted;
2268 uint32_t seqnum;
2270 struct smb_request **reqs;
2271 unsigned num_reqs;
2274 static bool smb1_parse_chain_cb(uint8_t cmd,
2275 uint8_t wct, const uint16_t *vwv,
2276 uint16_t num_bytes, const uint8_t *bytes,
2277 void *private_data)
2279 struct smb1_parse_chain_state *state =
2280 (struct smb1_parse_chain_state *)private_data;
2281 struct smb_request **reqs;
2282 struct smb_request *req;
2283 bool ok;
2285 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2286 struct smb_request *, state->num_reqs+1);
2287 if (reqs == NULL) {
2288 return false;
2290 state->reqs = reqs;
2292 req = talloc(reqs, struct smb_request);
2293 if (req == NULL) {
2294 return false;
2297 ok = init_smb_request(req, state->sconn, state->buf, 0,
2298 state->encrypted, state->seqnum);
2299 if (!ok) {
2300 return false;
2302 req->cmd = cmd;
2303 req->wct = wct;
2304 req->vwv = vwv;
2305 req->buflen = num_bytes;
2306 req->buf = bytes;
2308 reqs[state->num_reqs] = req;
2309 state->num_reqs += 1;
2310 return true;
2313 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2314 struct smbd_server_connection *sconn,
2315 bool encrypted, uint32_t seqnum,
2316 struct smb_request ***reqs, unsigned *num_reqs)
2318 struct smb1_parse_chain_state state;
2319 unsigned i;
2321 state.mem_ctx = mem_ctx;
2322 state.buf = buf;
2323 state.sconn = sconn;
2324 state.encrypted = encrypted;
2325 state.seqnum = seqnum;
2326 state.reqs = NULL;
2327 state.num_reqs = 0;
2329 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2330 TALLOC_FREE(state.reqs);
2331 return false;
2333 for (i=0; i<state.num_reqs; i++) {
2334 state.reqs[i]->chain = state.reqs;
2336 *reqs = state.reqs;
2337 *num_reqs = state.num_reqs;
2338 return true;
2341 /****************************************************************************
2342 Check if services need reloading.
2343 ****************************************************************************/
2345 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2348 if (last_smb_conf_reload_time == 0) {
2349 last_smb_conf_reload_time = t;
2352 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2353 reload_services(sconn, conn_snum_used, true);
2354 last_smb_conf_reload_time = t;
2358 static bool fd_is_readable(int fd)
2360 int ret, revents;
2362 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2364 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2368 static void smbd_server_connection_write_handler(
2369 struct smbd_server_connection *sconn)
2371 /* TODO: make write nonblocking */
2374 static void smbd_server_connection_read_handler(
2375 struct smbd_server_connection *sconn, int fd)
2377 uint8_t *inbuf = NULL;
2378 size_t inbuf_len = 0;
2379 size_t unread_bytes = 0;
2380 bool encrypted = false;
2381 TALLOC_CTX *mem_ctx = talloc_tos();
2382 NTSTATUS status;
2383 uint32_t seqnum;
2385 bool from_client;
2387 if (lp_async_smb_echo_handler()
2388 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2390 * This is the super-ugly hack to prefer the packets
2391 * forwarded by the echo handler over the ones by the
2392 * client directly
2394 fd = sconn->smb1.echo_handler.trusted_fd;
2397 from_client = (sconn->sock == fd);
2399 if (from_client) {
2400 smbd_lock_socket(sconn);
2402 if (!fd_is_readable(fd)) {
2403 DEBUG(10,("the echo listener was faster\n"));
2404 smbd_unlock_socket(sconn);
2405 return;
2409 /* TODO: make this completely nonblocking */
2410 status = receive_smb_talloc(mem_ctx, sconn, fd,
2411 (char **)(void *)&inbuf,
2412 0, /* timeout */
2413 &unread_bytes,
2414 &encrypted,
2415 &inbuf_len, &seqnum,
2416 !from_client /* trusted channel */);
2418 if (from_client) {
2419 smbd_unlock_socket(sconn);
2422 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2423 goto process;
2425 if (NT_STATUS_IS_ERR(status)) {
2426 exit_server_cleanly("failed to receive smb request");
2428 if (!NT_STATUS_IS_OK(status)) {
2429 return;
2432 process:
2433 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2434 seqnum, encrypted, NULL);
2437 static void smbd_server_connection_handler(struct tevent_context *ev,
2438 struct tevent_fd *fde,
2439 uint16_t flags,
2440 void *private_data)
2442 struct smbd_server_connection *conn = talloc_get_type(private_data,
2443 struct smbd_server_connection);
2445 if (flags & TEVENT_FD_WRITE) {
2446 smbd_server_connection_write_handler(conn);
2447 return;
2449 if (flags & TEVENT_FD_READ) {
2450 smbd_server_connection_read_handler(conn, conn->sock);
2451 return;
2455 static void smbd_server_echo_handler(struct tevent_context *ev,
2456 struct tevent_fd *fde,
2457 uint16_t flags,
2458 void *private_data)
2460 struct smbd_server_connection *conn = talloc_get_type(private_data,
2461 struct smbd_server_connection);
2463 if (flags & TEVENT_FD_WRITE) {
2464 smbd_server_connection_write_handler(conn);
2465 return;
2467 if (flags & TEVENT_FD_READ) {
2468 smbd_server_connection_read_handler(
2469 conn, conn->smb1.echo_handler.trusted_fd);
2470 return;
2474 #ifdef CLUSTER_SUPPORT
2476 struct smbd_release_ip_state {
2477 struct smbd_server_connection *sconn;
2478 char addr[INET6_ADDRSTRLEN];
2481 /****************************************************************************
2482 received when we should release a specific IP
2483 ****************************************************************************/
2484 static void release_ip(const char *ip, void *priv)
2486 struct smbd_release_ip_state *state =
2487 talloc_get_type_abort(priv,
2488 struct smbd_release_ip_state);
2489 const char *addr = state->addr;
2490 const char *p = addr;
2492 if (strncmp("::ffff:", addr, 7) == 0) {
2493 p = addr + 7;
2496 DEBUG(10, ("Got release IP message for %s, "
2497 "our address is %s\n", ip, p));
2499 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2500 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2501 ip));
2503 * With SMB2 we should do a clean disconnect,
2504 * the previous_session_id in the session setup
2505 * will cleanup the old session, tcons and opens.
2507 * A clean disconnect is needed in order to support
2508 * durable handles.
2510 * Note: typically this is never triggered
2511 * as we got a TCP RST (triggered by ctdb event scripts)
2512 * before we get CTDB_SRVID_RELEASE_IP.
2514 * We used to call _exit(1) here, but as this was mostly never
2515 * triggered and has implication on our process model,
2516 * we can just use smbd_server_connection_terminate()
2517 * (also for SMB1).
2519 smbd_server_connection_terminate(state->sconn,
2520 "CTDB_SRVID_RELEASE_IP");
2521 return;
2525 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2526 struct sockaddr_storage *srv,
2527 struct sockaddr_storage *clnt)
2529 struct smbd_release_ip_state *state;
2530 struct ctdbd_connection *cconn;
2532 cconn = messaging_ctdbd_connection();
2533 if (cconn == NULL) {
2534 return NT_STATUS_NO_MEMORY;
2537 state = talloc_zero(sconn, struct smbd_release_ip_state);
2538 if (state == NULL) {
2539 return NT_STATUS_NO_MEMORY;
2541 state->sconn = sconn;
2542 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2543 return NT_STATUS_NO_MEMORY;
2546 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2549 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2550 struct sockaddr_storage *client)
2552 socklen_t length;
2553 length = sizeof(*server);
2554 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2555 return -1;
2557 length = sizeof(*client);
2558 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2559 return -1;
2561 return 0;
2563 #endif
2566 * Send keepalive packets to our client
2568 static bool keepalive_fn(const struct timeval *now, void *private_data)
2570 struct smbd_server_connection *sconn = talloc_get_type_abort(
2571 private_data, struct smbd_server_connection);
2572 bool ret;
2574 if (sconn->using_smb2) {
2575 /* Don't do keepalives on an SMB2 connection. */
2576 return false;
2579 smbd_lock_socket(sconn);
2580 ret = send_keepalive(sconn->sock);
2581 smbd_unlock_socket(sconn);
2583 if (!ret) {
2584 char addr[INET6_ADDRSTRLEN];
2586 * Try and give an error message saying what
2587 * client failed.
2589 DEBUG(0, ("send_keepalive failed for client %s. "
2590 "Error %s - exiting\n",
2591 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2592 strerror(errno)));
2593 return False;
2595 return True;
2599 * Do the recurring check if we're idle
2601 static bool deadtime_fn(const struct timeval *now, void *private_data)
2603 struct smbd_server_connection *sconn =
2604 (struct smbd_server_connection *)private_data;
2606 if ((conn_num_open(sconn) == 0)
2607 || (conn_idle_all(sconn, now->tv_sec))) {
2608 DEBUG( 2, ( "Closing idle connection\n" ) );
2609 messaging_send(sconn->msg_ctx,
2610 messaging_server_id(sconn->msg_ctx),
2611 MSG_SHUTDOWN, &data_blob_null);
2612 return False;
2615 return True;
2619 * Do the recurring log file and smb.conf reload checks.
2622 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2624 struct smbd_server_connection *sconn = talloc_get_type_abort(
2625 private_data, struct smbd_server_connection);
2627 DEBUG(5, ("housekeeping\n"));
2629 change_to_root_user();
2631 /* update printer queue caches if necessary */
2632 update_monitored_printq_cache(sconn->msg_ctx);
2634 /* check if we need to reload services */
2635 check_reload(sconn, time_mono(NULL));
2638 * Force a log file check.
2640 force_check_log_size();
2641 check_log_size();
2642 return true;
2646 * Read an smb packet in the echo handler child, giving the parent
2647 * smbd one second to react once the socket becomes readable.
2650 struct smbd_echo_read_state {
2651 struct tevent_context *ev;
2652 struct smbd_server_connection *sconn;
2654 char *buf;
2655 size_t buflen;
2656 uint32_t seqnum;
2659 static void smbd_echo_read_readable(struct tevent_req *subreq);
2660 static void smbd_echo_read_waited(struct tevent_req *subreq);
2662 static struct tevent_req *smbd_echo_read_send(
2663 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2664 struct smbd_server_connection *sconn)
2666 struct tevent_req *req, *subreq;
2667 struct smbd_echo_read_state *state;
2669 req = tevent_req_create(mem_ctx, &state,
2670 struct smbd_echo_read_state);
2671 if (req == NULL) {
2672 return NULL;
2674 state->ev = ev;
2675 state->sconn = sconn;
2677 subreq = wait_for_read_send(state, ev, sconn->sock);
2678 if (tevent_req_nomem(subreq, req)) {
2679 return tevent_req_post(req, ev);
2681 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2682 return req;
2685 static void smbd_echo_read_readable(struct tevent_req *subreq)
2687 struct tevent_req *req = tevent_req_callback_data(
2688 subreq, struct tevent_req);
2689 struct smbd_echo_read_state *state = tevent_req_data(
2690 req, struct smbd_echo_read_state);
2691 bool ok;
2692 int err;
2694 ok = wait_for_read_recv(subreq, &err);
2695 TALLOC_FREE(subreq);
2696 if (!ok) {
2697 tevent_req_nterror(req, map_nt_error_from_unix(err));
2698 return;
2702 * Give the parent smbd one second to step in
2705 subreq = tevent_wakeup_send(
2706 state, state->ev, timeval_current_ofs(1, 0));
2707 if (tevent_req_nomem(subreq, req)) {
2708 return;
2710 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2713 static void smbd_echo_read_waited(struct tevent_req *subreq)
2715 struct tevent_req *req = tevent_req_callback_data(
2716 subreq, struct tevent_req);
2717 struct smbd_echo_read_state *state = tevent_req_data(
2718 req, struct smbd_echo_read_state);
2719 struct smbd_server_connection *sconn = state->sconn;
2720 bool ok;
2721 NTSTATUS status;
2722 size_t unread = 0;
2723 bool encrypted;
2725 ok = tevent_wakeup_recv(subreq);
2726 TALLOC_FREE(subreq);
2727 if (!ok) {
2728 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2729 return;
2732 ok = smbd_lock_socket_internal(sconn);
2733 if (!ok) {
2734 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2735 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2736 return;
2739 if (!fd_is_readable(sconn->sock)) {
2740 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2741 (int)getpid()));
2743 ok = smbd_unlock_socket_internal(sconn);
2744 if (!ok) {
2745 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2746 DEBUG(1, ("%s: failed to unlock socket\n",
2747 __location__));
2748 return;
2751 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2752 if (tevent_req_nomem(subreq, req)) {
2753 return;
2755 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2756 return;
2759 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2760 0 /* timeout */,
2761 &unread,
2762 &encrypted,
2763 &state->buflen,
2764 &state->seqnum,
2765 false /* trusted_channel*/);
2767 if (tevent_req_nterror(req, status)) {
2768 tevent_req_nterror(req, status);
2769 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2770 (int)getpid(), nt_errstr(status)));
2771 return;
2774 ok = smbd_unlock_socket_internal(sconn);
2775 if (!ok) {
2776 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2777 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2778 return;
2780 tevent_req_done(req);
2783 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2784 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2786 struct smbd_echo_read_state *state = tevent_req_data(
2787 req, struct smbd_echo_read_state);
2788 NTSTATUS status;
2790 if (tevent_req_is_nterror(req, &status)) {
2791 return status;
2793 *pbuf = talloc_move(mem_ctx, &state->buf);
2794 *pbuflen = state->buflen;
2795 *pseqnum = state->seqnum;
2796 return NT_STATUS_OK;
2799 struct smbd_echo_state {
2800 struct tevent_context *ev;
2801 struct iovec *pending;
2802 struct smbd_server_connection *sconn;
2803 int parent_pipe;
2805 struct tevent_fd *parent_fde;
2807 struct tevent_req *write_req;
2810 static void smbd_echo_writer_done(struct tevent_req *req);
2812 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2814 int num_pending;
2816 if (state->write_req != NULL) {
2817 return;
2820 num_pending = talloc_array_length(state->pending);
2821 if (num_pending == 0) {
2822 return;
2825 state->write_req = writev_send(state, state->ev, NULL,
2826 state->parent_pipe, false,
2827 state->pending, num_pending);
2828 if (state->write_req == NULL) {
2829 DEBUG(1, ("writev_send failed\n"));
2830 exit(1);
2833 talloc_steal(state->write_req, state->pending);
2834 state->pending = NULL;
2836 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2837 state);
2840 static void smbd_echo_writer_done(struct tevent_req *req)
2842 struct smbd_echo_state *state = tevent_req_callback_data(
2843 req, struct smbd_echo_state);
2844 ssize_t written;
2845 int err;
2847 written = writev_recv(req, &err);
2848 TALLOC_FREE(req);
2849 state->write_req = NULL;
2850 if (written == -1) {
2851 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2852 exit(1);
2854 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2855 smbd_echo_activate_writer(state);
2858 static bool smbd_echo_reply(struct smbd_echo_state *state,
2859 uint8_t *inbuf, size_t inbuf_len,
2860 uint32_t seqnum)
2862 struct smb_request req;
2863 uint16_t num_replies;
2864 char *outbuf;
2865 bool ok;
2867 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2868 DEBUG(10, ("Got netbios keepalive\n"));
2870 * Just swallow it
2872 return true;
2875 if (inbuf_len < smb_size) {
2876 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2877 return false;
2879 if (!valid_smb_header(state->sconn, inbuf)) {
2880 DEBUG(10, ("Got invalid SMB header\n"));
2881 return false;
2884 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2885 seqnum)) {
2886 return false;
2888 req.inbuf = inbuf;
2890 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2891 smb_messages[req.cmd].name
2892 ? smb_messages[req.cmd].name : "unknown"));
2894 if (req.cmd != SMBecho) {
2895 return false;
2897 if (req.wct < 1) {
2898 return false;
2901 num_replies = SVAL(req.vwv+0, 0);
2902 if (num_replies != 1) {
2903 /* Not a Windows "Hey, you're still there?" request */
2904 return false;
2907 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2908 1, req.buflen)) {
2909 DEBUG(10, ("create_outbuf failed\n"));
2910 return false;
2912 req.outbuf = (uint8_t *)outbuf;
2914 SSVAL(req.outbuf, smb_vwv0, num_replies);
2916 if (req.buflen > 0) {
2917 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2920 ok = srv_send_smb(req.sconn,
2921 (char *)outbuf,
2922 true, seqnum+1,
2923 false, &req.pcd);
2924 TALLOC_FREE(outbuf);
2925 if (!ok) {
2926 exit(1);
2929 return true;
2932 static void smbd_echo_exit(struct tevent_context *ev,
2933 struct tevent_fd *fde, uint16_t flags,
2934 void *private_data)
2936 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2937 exit(0);
2940 static void smbd_echo_got_packet(struct tevent_req *req);
2942 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2943 int parent_pipe)
2945 struct smbd_echo_state *state;
2946 struct tevent_req *read_req;
2948 state = talloc_zero(sconn, struct smbd_echo_state);
2949 if (state == NULL) {
2950 DEBUG(1, ("talloc failed\n"));
2951 return;
2953 state->sconn = sconn;
2954 state->parent_pipe = parent_pipe;
2955 state->ev = s3_tevent_context_init(state);
2956 if (state->ev == NULL) {
2957 DEBUG(1, ("tevent_context_init failed\n"));
2958 TALLOC_FREE(state);
2959 return;
2961 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2962 TEVENT_FD_READ, smbd_echo_exit,
2963 state);
2964 if (state->parent_fde == NULL) {
2965 DEBUG(1, ("tevent_add_fd failed\n"));
2966 TALLOC_FREE(state);
2967 return;
2970 read_req = smbd_echo_read_send(state, state->ev, sconn);
2971 if (read_req == NULL) {
2972 DEBUG(1, ("smbd_echo_read_send failed\n"));
2973 TALLOC_FREE(state);
2974 return;
2976 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2978 while (true) {
2979 if (tevent_loop_once(state->ev) == -1) {
2980 DEBUG(1, ("tevent_loop_once failed: %s\n",
2981 strerror(errno)));
2982 break;
2985 TALLOC_FREE(state);
2988 static void smbd_echo_got_packet(struct tevent_req *req)
2990 struct smbd_echo_state *state = tevent_req_callback_data(
2991 req, struct smbd_echo_state);
2992 NTSTATUS status;
2993 char *buf = NULL;
2994 size_t buflen = 0;
2995 uint32_t seqnum = 0;
2996 bool reply;
2998 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2999 TALLOC_FREE(req);
3000 if (!NT_STATUS_IS_OK(status)) {
3001 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3002 nt_errstr(status)));
3003 exit(1);
3006 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3007 if (!reply) {
3008 size_t num_pending;
3009 struct iovec *tmp;
3010 struct iovec *iov;
3012 num_pending = talloc_array_length(state->pending);
3013 tmp = talloc_realloc(state, state->pending, struct iovec,
3014 num_pending+1);
3015 if (tmp == NULL) {
3016 DEBUG(1, ("talloc_realloc failed\n"));
3017 exit(1);
3019 state->pending = tmp;
3021 if (buflen >= smb_size) {
3023 * place the seqnum in the packet so that the main process
3024 * can reply with signing
3026 SIVAL(buf, smb_ss_field, seqnum);
3027 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3030 iov = &state->pending[num_pending];
3031 iov->iov_base = talloc_move(state->pending, &buf);
3032 iov->iov_len = buflen;
3034 DEBUG(10,("echo_handler[%d]: forward to main\n",
3035 (int)getpid()));
3036 smbd_echo_activate_writer(state);
3039 req = smbd_echo_read_send(state, state->ev, state->sconn);
3040 if (req == NULL) {
3041 DEBUG(1, ("smbd_echo_read_send failed\n"));
3042 exit(1);
3044 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3049 * Handle SMBecho requests in a forked child process
3051 bool fork_echo_handler(struct smbd_server_connection *sconn)
3053 int listener_pipe[2];
3054 int res;
3055 pid_t child;
3057 res = pipe(listener_pipe);
3058 if (res == -1) {
3059 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3060 return false;
3062 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
3063 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3064 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3065 goto fail;
3068 child = fork();
3069 if (child == 0) {
3070 NTSTATUS status;
3072 close(listener_pipe[0]);
3073 set_blocking(listener_pipe[1], false);
3075 status = reinit_after_fork(sconn->msg_ctx,
3076 sconn->ev_ctx,
3077 true);
3078 if (!NT_STATUS_IS_OK(status)) {
3079 DEBUG(1, ("reinit_after_fork failed: %s\n",
3080 nt_errstr(status)));
3081 exit(1);
3083 smbd_echo_loop(sconn, listener_pipe[1]);
3084 exit(0);
3086 close(listener_pipe[1]);
3087 listener_pipe[1] = -1;
3088 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3090 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3093 * Without smb signing this is the same as the normal smbd
3094 * listener. This needs to change once signing comes in.
3096 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3097 sconn,
3098 sconn->smb1.echo_handler.trusted_fd,
3099 TEVENT_FD_READ,
3100 smbd_server_echo_handler,
3101 sconn);
3102 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3103 DEBUG(1, ("event_add_fd failed\n"));
3104 goto fail;
3107 return true;
3109 fail:
3110 if (listener_pipe[0] != -1) {
3111 close(listener_pipe[0]);
3113 if (listener_pipe[1] != -1) {
3114 close(listener_pipe[1]);
3116 sconn->smb1.echo_handler.trusted_fd = -1;
3117 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3118 close(sconn->smb1.echo_handler.socket_lock_fd);
3120 sconn->smb1.echo_handler.trusted_fd = -1;
3121 sconn->smb1.echo_handler.socket_lock_fd = -1;
3122 return false;
3125 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3127 while (user) {
3128 if (user->session_info &&
3129 (user->session_info->unix_token->uid == uid)) {
3130 return true;
3132 user = user->next;
3134 return false;
3137 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3139 while (user) {
3140 if (user->session_info != NULL) {
3141 int i;
3142 struct security_unix_token *utok;
3144 utok = user->session_info->unix_token;
3145 if (utok->gid == gid) {
3146 return true;
3148 for(i=0; i<utok->ngroups; i++) {
3149 if (utok->groups[i] == gid) {
3150 return true;
3154 user = user->next;
3156 return false;
3159 static bool sid_in_use(const struct user_struct *user,
3160 const struct dom_sid *psid)
3162 while (user) {
3163 struct security_token *tok;
3165 if (user->session_info == NULL) {
3166 continue;
3168 tok = user->session_info->security_token;
3169 if (tok == NULL) {
3171 * Not sure session_info->security_token can
3172 * ever be NULL. This check might be not
3173 * necessary.
3175 continue;
3177 if (security_token_has_sid(tok, psid)) {
3178 return true;
3180 user = user->next;
3182 return false;
3185 static bool id_in_use(const struct user_struct *user,
3186 const struct id_cache_ref *id)
3188 switch(id->type) {
3189 case UID:
3190 return uid_in_use(user, id->id.uid);
3191 case GID:
3192 return gid_in_use(user, id->id.gid);
3193 case SID:
3194 return sid_in_use(user, &id->id.sid);
3195 default:
3196 break;
3198 return false;
3201 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3202 void *private_data,
3203 uint32_t msg_type,
3204 struct server_id server_id,
3205 DATA_BLOB* data)
3207 const char *msg = (data && data->data)
3208 ? (const char *)data->data : "<NULL>";
3209 struct id_cache_ref id;
3210 struct smbd_server_connection *sconn =
3211 talloc_get_type_abort(private_data,
3212 struct smbd_server_connection);
3214 if (!id_cache_ref_parse(msg, &id)) {
3215 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3216 return;
3219 if (id_in_use(sconn->users, &id)) {
3220 exit_server_cleanly(msg);
3222 id_cache_delete_from_cache(&id);
3225 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3226 enum protocol_types protocol)
3228 NTSTATUS status;
3230 set_Protocol(protocol);
3231 conn->protocol = protocol;
3233 if (protocol >= PROTOCOL_SMB2_02) {
3234 status = smb2srv_session_table_init(conn);
3235 if (!NT_STATUS_IS_OK(status)) {
3236 return status;
3239 status = smb2srv_open_table_init(conn);
3240 if (!NT_STATUS_IS_OK(status)) {
3241 return status;
3243 } else {
3244 status = smb1srv_session_table_init(conn);
3245 if (!NT_STATUS_IS_OK(status)) {
3246 return status;
3249 status = smb1srv_tcon_table_init(conn);
3250 if (!NT_STATUS_IS_OK(status)) {
3251 return status;
3254 status = smb1srv_open_table_init(conn);
3255 if (!NT_STATUS_IS_OK(status)) {
3256 return status;
3260 return NT_STATUS_OK;
3263 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3264 void *private_data)
3266 struct smbXsrv_connection *conn =
3267 talloc_get_type_abort(private_data,
3268 struct smbXsrv_connection);
3270 switch (point) {
3271 case TEVENT_TRACE_BEFORE_WAIT:
3273 * This just removes compiler warning
3274 * without profile support
3276 conn->smbd_idle_profstamp = 0;
3277 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3278 break;
3279 case TEVENT_TRACE_AFTER_WAIT:
3280 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3281 break;
3285 /****************************************************************************
3286 Process commands from the client
3287 ****************************************************************************/
3289 void smbd_process(struct tevent_context *ev_ctx,
3290 struct messaging_context *msg_ctx,
3291 int sock_fd,
3292 bool interactive)
3294 TALLOC_CTX *frame = talloc_stackframe();
3295 struct smbXsrv_connection *conn;
3296 struct smbd_server_connection *sconn;
3297 struct sockaddr_storage ss;
3298 struct sockaddr *sa = NULL;
3299 socklen_t sa_socklen;
3300 struct tsocket_address *local_address = NULL;
3301 struct tsocket_address *remote_address = NULL;
3302 const char *locaddr = NULL;
3303 const char *remaddr = NULL;
3304 char *rhost;
3305 int ret;
3307 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3308 if (conn == NULL) {
3309 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3310 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3313 conn->ev_ctx = ev_ctx;
3314 conn->msg_ctx = msg_ctx;
3316 sconn = talloc_zero(conn, struct smbd_server_connection);
3317 if (!sconn) {
3318 exit_server("failed to create smbd_server_connection");
3321 conn->sconn = sconn;
3322 sconn->conn = conn;
3325 * TODO: remove this...:-)
3327 global_smbXsrv_connection = conn;
3329 sconn->ev_ctx = ev_ctx;
3330 sconn->msg_ctx = msg_ctx;
3331 sconn->sock = sock_fd;
3332 sconn->smb1.echo_handler.trusted_fd = -1;
3333 sconn->smb1.echo_handler.socket_lock_fd = -1;
3335 if (!interactive) {
3336 smbd_setup_sig_term_handler(sconn);
3337 smbd_setup_sig_hup_handler(sconn);
3339 if (!serverid_register(messaging_server_id(msg_ctx),
3340 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3341 |FLAG_MSG_DBWRAP
3342 |FLAG_MSG_PRINT_GENERAL)) {
3343 exit_server_cleanly("Could not register myself in "
3344 "serverid.tdb");
3348 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3350 * We're not making the decision here,
3351 * we're just allowing the client
3352 * to decide between SMB1 and SMB2
3353 * with the first negprot
3354 * packet.
3356 sconn->using_smb2 = true;
3359 /* Ensure child is set to blocking mode */
3360 set_blocking(sconn->sock,True);
3362 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3363 set_socket_options(sconn->sock, lp_socket_options());
3365 sa = (struct sockaddr *)(void *)&ss;
3366 sa_socklen = sizeof(ss);
3367 ret = getpeername(sconn->sock, sa, &sa_socklen);
3368 if (ret != 0) {
3369 int level = (errno == ENOTCONN)?2:0;
3370 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3371 exit_server_cleanly("getpeername() failed.\n");
3373 ret = tsocket_address_bsd_from_sockaddr(sconn,
3374 sa, sa_socklen,
3375 &remote_address);
3376 if (ret != 0) {
3377 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3378 __location__, strerror(errno)));
3379 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3382 sa = (struct sockaddr *)(void *)&ss;
3383 sa_socklen = sizeof(ss);
3384 ret = getsockname(sconn->sock, sa, &sa_socklen);
3385 if (ret != 0) {
3386 int level = (errno == ENOTCONN)?2:0;
3387 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3388 exit_server_cleanly("getsockname() failed.\n");
3390 ret = tsocket_address_bsd_from_sockaddr(sconn,
3391 sa, sa_socklen,
3392 &local_address);
3393 if (ret != 0) {
3394 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3395 __location__, strerror(errno)));
3396 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3399 sconn->local_address = local_address;
3400 sconn->remote_address = remote_address;
3402 if (tsocket_address_is_inet(local_address, "ip")) {
3403 locaddr = tsocket_address_inet_addr_string(
3404 sconn->local_address,
3405 talloc_tos());
3406 if (locaddr == NULL) {
3407 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3408 __location__, strerror(errno)));
3409 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3411 } else {
3412 locaddr = "0.0.0.0";
3415 if (tsocket_address_is_inet(remote_address, "ip")) {
3416 remaddr = tsocket_address_inet_addr_string(
3417 sconn->remote_address,
3418 talloc_tos());
3419 if (remaddr == NULL) {
3420 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3421 __location__, strerror(errno)));
3422 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3424 } else {
3425 remaddr = "0.0.0.0";
3428 /* this is needed so that we get decent entries
3429 in smbstatus for port 445 connects */
3430 set_remote_machine_name(remaddr, false);
3431 reload_services(sconn, conn_snum_used, true);
3434 * Before the first packet, check the global hosts allow/ hosts deny
3435 * parameters before doing any parsing of packets passed to us by the
3436 * client. This prevents attacks on our parsing code from hosts not in
3437 * the hosts allow list.
3440 ret = get_remote_hostname(remote_address,
3441 &rhost,
3442 talloc_tos());
3443 if (ret < 0) {
3444 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3445 __location__, strerror(errno)));
3446 exit_server_cleanly("get_remote_hostname failed.\n");
3448 if (strequal(rhost, "UNKNOWN")) {
3449 rhost = talloc_strdup(talloc_tos(), remaddr);
3451 sconn->remote_hostname = talloc_move(sconn, &rhost);
3453 sub_set_socket_ids(remaddr,
3454 sconn->remote_hostname,
3455 locaddr);
3457 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3458 sconn->remote_hostname,
3459 remaddr)) {
3461 * send a negative session response "not listening on calling
3462 * name"
3464 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3465 DEBUG( 1, ("Connection denied from %s to %s\n",
3466 tsocket_address_string(remote_address, talloc_tos()),
3467 tsocket_address_string(local_address, talloc_tos())));
3468 (void)srv_send_smb(sconn,(char *)buf, false,
3469 0, false, NULL);
3470 exit_server_cleanly("connection denied");
3473 DEBUG(10, ("Connection allowed from %s to %s\n",
3474 tsocket_address_string(remote_address, talloc_tos()),
3475 tsocket_address_string(local_address, talloc_tos())));
3477 if (lp_preload_modules()) {
3478 smb_load_modules(lp_preload_modules());
3481 smb_perfcount_init();
3483 if (!init_account_policy()) {
3484 exit_server("Could not open account policy tdb.\n");
3487 if (*lp_rootdir(talloc_tos())) {
3488 if (chroot(lp_rootdir(talloc_tos())) != 0) {
3489 DEBUG(0,("Failed to change root to %s\n",
3490 lp_rootdir(talloc_tos())));
3491 exit_server("Failed to chroot()");
3493 if (chdir("/") == -1) {
3494 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir(talloc_tos())));
3495 exit_server("Failed to chroot()");
3497 DEBUG(0,("Changed root to %s\n", lp_rootdir(talloc_tos())));
3500 if (!srv_init_signing(sconn)) {
3501 exit_server("Failed to init smb_signing");
3504 if (!file_init(sconn)) {
3505 exit_server("file_init() failed");
3508 /* Setup oplocks */
3509 if (!init_oplocks(sconn))
3510 exit_server("Failed to init oplocks");
3512 /* register our message handlers */
3513 messaging_register(sconn->msg_ctx, sconn,
3514 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3515 messaging_register(sconn->msg_ctx, sconn,
3516 MSG_SMB_CLOSE_FILE, msg_close_file);
3517 messaging_register(sconn->msg_ctx, sconn,
3518 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3520 id_cache_register_msgs(sconn->msg_ctx);
3521 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3522 messaging_register(sconn->msg_ctx, sconn,
3523 ID_CACHE_KILL, smbd_id_cache_kill);
3525 messaging_deregister(sconn->msg_ctx,
3526 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3527 messaging_register(sconn->msg_ctx, sconn,
3528 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3531 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3532 * MSGs to all child processes
3534 messaging_deregister(sconn->msg_ctx,
3535 MSG_DEBUG, NULL);
3536 messaging_register(sconn->msg_ctx, NULL,
3537 MSG_DEBUG, debug_message);
3539 if ((lp_keepalive() != 0)
3540 && !(event_add_idle(ev_ctx, NULL,
3541 timeval_set(lp_keepalive(), 0),
3542 "keepalive", keepalive_fn,
3543 sconn))) {
3544 DEBUG(0, ("Could not add keepalive event\n"));
3545 exit(1);
3548 if (!(event_add_idle(ev_ctx, NULL,
3549 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3550 "deadtime", deadtime_fn, sconn))) {
3551 DEBUG(0, ("Could not add deadtime event\n"));
3552 exit(1);
3555 if (!(event_add_idle(ev_ctx, NULL,
3556 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3557 "housekeeping", housekeeping_fn, sconn))) {
3558 DEBUG(0, ("Could not add housekeeping event\n"));
3559 exit(1);
3562 #ifdef CLUSTER_SUPPORT
3564 if (lp_clustering()) {
3566 * We need to tell ctdb about our client's TCP
3567 * connection, so that for failover ctdbd can send
3568 * tickle acks, triggering a reconnection by the
3569 * client.
3572 struct sockaddr_storage srv, clnt;
3574 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3575 NTSTATUS status;
3576 status = smbd_register_ips(sconn, &srv, &clnt);
3577 if (!NT_STATUS_IS_OK(status)) {
3578 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3579 nt_errstr(status)));
3581 } else {
3582 int level = (errno == ENOTCONN)?2:0;
3583 DEBUG(level,("Unable to get tcp info for "
3584 "smbd_register_ips: %s\n",
3585 strerror(errno)));
3586 exit_server_cleanly("client_get_tcp_info() failed.\n");
3590 #endif
3592 sconn->nbt.got_session = false;
3594 sconn->smb1.negprot.max_recv = MIN(lp_max_xmit(),BUFFER_SIZE);
3596 sconn->smb1.sessions.done_sesssetup = false;
3597 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3598 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3600 if (!init_dptrs(sconn)) {
3601 exit_server("init_dptrs() failed");
3604 sconn->smb1.fde = tevent_add_fd(ev_ctx,
3605 sconn,
3606 sconn->sock,
3607 TEVENT_FD_READ,
3608 smbd_server_connection_handler,
3609 sconn);
3610 if (!sconn->smb1.fde) {
3611 exit_server("failed to create smbd_server_connection fde");
3614 sconn->conn->local_address = sconn->local_address;
3615 sconn->conn->remote_address = sconn->remote_address;
3616 sconn->conn->remote_hostname = sconn->remote_hostname;
3617 sconn->conn->protocol = PROTOCOL_NONE;
3619 TALLOC_FREE(frame);
3621 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3623 while (True) {
3624 frame = talloc_stackframe_pool(8192);
3626 errno = 0;
3627 if (tevent_loop_once(ev_ctx) == -1) {
3628 if (errno != EINTR) {
3629 DEBUG(3, ("tevent_loop_once failed: %s,"
3630 " exiting\n", strerror(errno) ));
3631 break;
3635 TALLOC_FREE(frame);
3638 exit_server_cleanly(NULL);
3641 bool req_is_in_chain(const struct smb_request *req)
3643 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3645 * We're right now handling a subsequent request, so we must
3646 * be in a chain
3648 return true;
3651 if (!is_andx_req(req->cmd)) {
3652 return false;
3655 if (req->wct < 2) {
3657 * Okay, an illegal request, but definitely not chained :-)
3659 return false;
3662 return (CVAL(req->vwv+0, 0) != 0xFF);